2 Copyright (c) 2013, IIT Madras
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 * Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
15 Generating VME master requests
20 //import TriState ::*;
22 import vme_defines ::*;
31 1.STATE 0 : receives req (function codes,r/w,siz1,siz0,addrbus) latched
33 2.STATE 1 : assert address strobe and data strobe
37 4. STATE 3 : Check for acknowledgement
39 5. STATE 4 : latch data
41 6. STATE 5: Release address strobe and data strobe(acknowledge lines will be released one cycle later)
46 1.STATE 0: receives req (function codes,r/w,siz1,siz0,addrbus) latched
48 2.STATE 1 : assert address strobe
50 3. STATE 2 : place data on the bus and wait for acknowledgement
52 4. STATE 3 : assert data and strobe and enable required data lines
54 5. STATE 4 : No operation
56 6. STATE 5:Release address strobe and data strobe(acknowledge lines will be released one cycle later)READ CYCLE
66 {RCV_REQ,PRC_REQ_1,PRC_REQ_2,PRC_REQ_3,LATCH_DATA,END_REQ,ADDR_INVALID,HALT
67 }State_master deriving (Bits,Eq);
70 {LW,BYTE,WORD,TRI_BYTE}Data_mode deriving (Bits,Eq);
73 (*always_enabled,always_ready*)
74 method Bit#(1) wr_as_l();
75 (*always_enabled,always_ready*)
76 method Bit#(1) wr_ds_l();
77 (*always_enabled,always_ready*)
78 method Bit#(1) wr_wr_l();
80 method Action rd_dsack_0_l(Bit#(1) x);
82 method Action rd_dsack_1_l(Bit#(1) y);
84 method Action rd_berr_l(Bit#(1) z);
86 method Action rd_halt_l(Bit#(1) u);
89 interface Data_bus_inf;
91 method Bit#(8) wr_byte_31_24();
92 (*always_enabled,always_ready*)
93 method Bit#(1) wr_siz1();
94 (*always_enabled,always_ready*)
95 method Bit#(1) wr_siz0();
96 method Bool wr_mode_en();
97 (*always_enabled,always_ready*)
98 method Bit#(32) wr_addr();
99 method Bool wr_addr_en();
100 method Bit#(4) wr_en();
102 method Bit#(3) wr_fun_code();
103 method Bool wr_fun_code_en();
104 method Bit#(8) wr_byte_23_16();
105 method Bit#(8) wr_byte_15_8();
106 method Bit#(8) wr_byte_7_0();
108 method Action rd_byte_31_24(Bit #(8) d3);
109 method Action rd_byte_23_16(Bit #(8) d2);
110 method Action rd_byte_15_8 (Bit #(8) d1);
111 method Action rd_byte_7_0 (Bit #(8) d0);
115 interface Vme_master ;
116 method Action get_req (Req_vme req);
117 interface Vme_out vme_interface;
118 interface Data_bus_inf data_bus;
119 method ActionValue #(Resp_vme) resp();
120 endinterface:Vme_master
124 module mkvmemaster(Vme_master);
127 //Fifos to get request and send response
128 FIFOF #(Req_vme) cpu_req <- mkFIFOF;
129 FIFOF #(Resp_vme) cpu_resp <- mkFIFOF;
130 //............................................................//
132 Reg #(State_master) master_state <- mkReg (RCV_REQ);
133 Reg#(Bit#(2)) mode<-mkReg(0);
134 Reg#(Bool) mode_en<-mkReg(False);//Enable SIZ1,SIZ0
135 Reg#(Bit#(3)) fun_code<-mkReg(0);
136 Reg#(Bool) fun_code_en<-mkReg(False);
137 Reg#(Bit#(1)) as_l<-mkReg(1);//address_stop
138 Reg#(Bit#(1)) ds_l<-mkReg(1);//data_strobe
139 Reg#(Bit#(1)) stop<-mkReg(0);//Indicates processor stopped
140 Reg#(Bit#(1)) retry<-mkReg(0);//Indicates retry mode
141 Wire#(Bit#(1)) dsack_0_l<-mkDWire(1);//ack from VIC controller,indicates port size 0-32 bit port,1-8 bit port,2-16 bit port
142 Wire#(Bit#(1)) dsack_1_l<-mkDWire(1);
143 Wire#(Bit#(1)) berr_l <-mkDWire(1);//Bus error from slave
144 Wire#(Bit#(1)) halt_l<-mkDWire(1);//halt signal from the slave
145 //Wire#(Bit#(3)) ipl_l<-mkDWire(1);//interrupt prioritylevel
147 Reg #(Bit#(32)) addr<-mkReg(0);//addr_bus
148 Reg #(Bool) addr_en<-mkReg(False);
149 Reg #(Bit#(8)) data_out_4<-mkReg(0);//wr_data_4
150 Reg #(Bit#(8)) data_out_3<-mkReg(0);//wr_data_3
151 Reg #(Bit#(8)) data_out_2<-mkReg(0);//wr_data_2
152 Reg #(Bit#(8)) data_out_1<-mkReg(0);//wr_data_1
154 Wire #(Bit#(8)) data_in_4<-mkDWire(0);//rd_data_4
155 Wire #(Bit#(8)) data_in_3<-mkDWire(0);//rd_data_3
156 Wire #(Bit#(8)) data_in_2<-mkDWire(0);//rd_data_2
157 Wire #(Bit#(8)) data_in_1<-mkDWire(0);//rd_data_1
160 Reg #(Bit#(1)) wr_l <-mkReg(1'd1);//read : 1,write:0
161 Reg #(Bit#(4)) data_control <-mkReg(0);//Enable bits to data and control registers
162 Reg #(Bit#(2)) cntl_wd<-mkReg(0); //To synchronize if more than one cycle is required to r/w data
163 //.........Tristate signals...............//
168 (* mutually_exclusive = "rcv_req_new,prc_req,prc_req_1,prc_req_2,req_wait,end_req" *)
170 /* REQ_RCV master_state....
171 1. Master receives request
172 2. address,FC2-FC0,Data,Write lines are driven
174 rule rcv_req_new(master_state==RCV_REQ && cntl_wd==2'b00 && (halt_l==1'b1) && (berr_l==1'b1)) ;//To recieve new request
176 let req =cpu_req.first();
177 $display("MASTER_STATE 1: receiving request to address %h req_type:%h",req.addr,req.rd_req,$time);
184 $display("mode of operation %b",req.mode);
185 fun_code<=req.fun_code;
187 master_state<=PRC_REQ_1;
189 //............Multiplexing logic to route data to data bus......................................................................................................
191 if (req.mode==2'b01)//For 8 bit data operations
192 case({req.addr[1],req.addr[0]})
194 2'b00:data_out_4<=req.wr_data[7:0];
197 data_out_4<=req.wr_data[7:0];
198 data_out_3<=req.wr_data[7:0];
202 data_out_4<=req.wr_data[7:0];
203 data_out_2<=req.wr_data[7:0];
206 data_out_4<=req.wr_data[7:0];
207 data_out_3<=req.wr_data[7:0];
208 data_out_1<=req.wr_data[7:0];
213 else if (req.mode==2'b10)//For 16 data operations
214 case({req.addr[1],req.addr[0]})
218 data_out_4<=req.wr_data[7:0];
219 data_out_3<=req.wr_data[15:8];
224 data_out_4<=req.wr_data[7:0];
225 data_out_3<=req.wr_data[15:8];
226 data_out_1<=req.wr_data[15:8];
227 data_out_2<=req.wr_data[7:0];
231 else if (req.mode==2'b00)//for 32 bit operation
233 case({req.addr[1],req.addr[0]})
237 data_out_1<=req.wr_data[31:24];
238 data_out_2<=req.wr_data[23:16];
239 data_out_3<=req.wr_data[15:8];
240 data_out_4<=req.wr_data[7:0];
241 $display("Data to be written = %h",req.wr_data);
244 //..............................................................................................................................................................
247 rule prc_req(master_state==RCV_REQ && cntl_wd!=2'b00);//If a request takes multiple cycles
249 if(cntl_wd==2'b01)//32 bit operation from 8 bit or 16 bit slave
254 data_out_4<=data_out_3;
255 data_out_3<=data_out_2;
256 data_out_2<=data_out_1;
262 begin//32 bit operation on a 16 bit slave
264 data_out_4<=data_out_2;
265 data_out_3<=data_out_1;
271 master_state<=PRC_REQ_1;
277 1.Address strobe is asserted
279 2.Data Strobe is asserted if it is a read cycle
281 3. Data lines are enabled for write cycle
286 rule prc_req_1(master_state==PRC_REQ_1);
290 $display("MASTER_STATE 2: Activating address strobe",$time);
292 master_state<=PRC_REQ_2;
295 data_control<=4'b1111;
300 1. Data strobe is asserted in write cycle on receiving ack,halt or bus error cycle
302 rule prc_req_2(master_state==PRC_REQ_2);
305 $display("MASTER_STATE_3 ",$time);
306 if (({dsack_0_l,dsack_1_l}!=2'b11)||(berr_l==1'b0)||(halt_l==1'b0))
308 master_state<=PRC_REQ_3;
315 1. Master waits for response
316 2. On receiving response,goes to next state
319 rule req_wait((master_state==PRC_REQ_3)&&(({dsack_0_l,dsack_1_l}!=2'b11)||(berr_l==1'b0)||(halt_l==1'b0)));
325 master_state<=LATCH_DATA;
326 $display(" MASTER_STATE_4:",$time);
327 if({dsack_0_l,dsack_1_l}==mode)
329 // $display("detected response %h",$time);
330 // master_state<=LATCH_DATA;
331 cntl_wd<=2'b00;//Done can take the next request
333 //if a 32 bit word r/w fro/to a 16 bit port
334 else if({dsack_0_l,dsack_1_l}==2'b10 && mode==2'b00)
341 // If a 32 bit word or 1 16 bit is r/w fro/to a 8 bit port
342 else if({dsack_0_l,dsack_1_l}==2'b01 && mode!=2'b01)
352 //.......................Latch_data when not using tristatebuffers.............................................................................
353 //In LATCH DATA state
354 //Latches on-to data and response
355 rule latch_data(master_state==LATCH_DATA);
357 if(berr_l==1'b0 && halt_l==1'b0)
362 else if(berr_l!=1'b0 && halt_l==1'b0)
367 else if(berr_l==1'b0)
371 let resp_data = Resp_vme{ data:{data_in_4,
373 data_in_2,8'b0},berr:1};
374 cpu_resp.enq(resp_data);
379 if (mode==2'b01 )//Receiving 8 bit data
380 case({dsack_0_l,dsack_1_l})
381 //......................................SLAVE PORT..............................//:-32 byte
382 //.......................................................................................
385 case({addr[1],addr[0]})//Position where byte read from depends on A1,A0
387 $display("Master recieved data %h addr:00",data_in_4);
388 let resp_data = Resp_vme{ data:{24'b0,
389 data_in_4},berr:0,port_type:{dsack_0_l,dsack_1_l}};
390 cpu_resp.enq(resp_data);
393 let resp_data = Resp_vme{ data:{24'b0,
395 data_in_3},berr:0,port_type:{dsack_0_l,dsack_1_l}};
396 cpu_resp.enq(resp_data);
397 $display("Master recieved data %h addr 01",data_in_3);
400 let resp_data = Resp_vme{ data:{24'b0,
401 data_in_2},berr:0,port_type:{dsack_0_l,dsack_1_l}};
403 $display("Master recieved data %h addr :10",data_in_2);
404 cpu_resp.enq(resp_data);
407 let resp_data = Resp_vme{ data:{24'b0,
408 data_in_1},berr:0,port_type:{dsack_0_l,dsack_1_l}};
412 $display("Master recieved data %h addr: 11",data_in_1);
413 cpu_resp.enq(resp_data);
416 //If slave is an 8 bit port
419 let resp_data = Resp_vme{data:{24'b0,data_in_4
420 },berr:0,port_type:{dsack_0_l,dsack_1_l}};
421 cpu_resp.enq(resp_data);
424 //if slave is a 16 bit port
428 let resp_data =Resp_vme{ data:{24'b0,data_in_4
429 },berr:0,port_type:{dsack_0_l,dsack_1_l}};
431 cpu_resp.enq(resp_data);
437 let resp_data =Resp_vme{ data:{24'b0,data_in_3
438 },berr:0,port_type:{dsack_0_l,dsack_1_l}};
440 cpu_resp.enq(resp_data);
444 if(mode==2'b10)//Receiving 16 bit data
446 case({dsack_0_l,dsack_1_l})
447 //...........SLAVE PORT....................:-32 byte
450 case({addr[1],addr[0]})//Position where byte read from depends on A1,A0
452 let resp_data = Resp_vme{ data:{16'b0,data_in_3,
453 data_in_4},berr:0,port_type:{dsack_0_l,dsack_1_l}};
454 cpu_resp.enq(resp_data);
458 let resp_data = Resp_vme{ data:{16'b0,data_in_1,
459 data_in_2},berr:0,port_type:{dsack_0_l,dsack_1_l}};
461 cpu_resp.enq(resp_data);
464 //If slave is an 8 bit port
467 let resp_data = Resp_vme{data:{24'b0,data_in_4
468 },berr:0,port_type:{dsack_0_l,dsack_1_l}};
469 cpu_resp.enq(resp_data);
472 //if slave is a 16 bit port
476 let resp_data =Resp_vme{ data:{16'b0,data_in_3,
477 data_in_4},berr:0,port_type:{dsack_0_l,dsack_1_l}};
479 cpu_resp.enq(resp_data);
483 if(mode==2'b00)//Receiving 32 bit data
485 case({dsack_0_l,dsack_1_l})
486 //...........SLAVE PORT....................:-32 bit port
489 let resp_data = Resp_vme{ data:{data_in_1,
490 data_in_2,data_in_3,data_in_4},berr:0,port_type:{dsack_0_l,dsack_1_l}};
491 $display("Master recieved data %h",{data_in_1,data_in_2,data_in_3,data_in_4});
492 cpu_resp.enq(resp_data);
495 //.......................................16 bit port
497 let resp_data = Resp_vme{ data:{16'b0,data_in_3,
498 data_in_4},berr:0,port_type:{dsack_0_l,dsack_1_l}};
500 cpu_resp.enq(resp_data);
503 //........................If slave is an 8 bit port
506 let resp_data = Resp_vme{data:{24'b0,data_in_4
507 },berr:0,port_type:{dsack_0_l,dsack_1_l}};
508 cpu_resp.enq(resp_data);
510 // $display("Data_latched",data_in_4);
519 let resp_data = Resp_vme{data:{24'b0,data_in_4
520 },berr:0,port_type:{dsack_0_l,dsack_1_l}};
521 cpu_resp.enq(resp_data);
526 master_state<=END_REQ;
531 1.Releases address and data strobe and data bus
533 2. DSACK lines are deasserted one cycle after
535 One more stage should be inserted here
538 rule end_req(master_state==END_REQ);
540 $display("\tMASTER_STATE_6:Releasing data strobes",$time);
543 data_control<=4'b0000;
544 master_state<=ADDR_INVALID;
547 rule rel_addr(master_state==ADDR_INVALID);//Release the address and data bus when transfer is finished
549 if(stop==0 && retry==0)
551 if(((dsack_0_l!=0)&&(dsack_1_l!=0))||(berr_l!=1'b0))
552 master_state<=RCV_REQ;
556 $display("\tMASTER_STATE_7:Releasing address strobes",$time);
562 $display("Ready to receive a new request",$time);
572 rule stop_wait(master_state==HALT);
574 //If HALT.....resume when halt signal is negated
579 master_state<=RCV_REQ;
580 $display("\tMASTER_STATE_7:Releasing address strobes",$time);
590 //If Retry.........start retry cycle when bus error and halt are negated
592 if(halt_l!=0 && berr_l!=0)
595 master_state<=PRC_REQ_1;
604 //Methods for driving signals in and out of master
607 interface Vme_out vme_interface;
610 method Bit#(1) wr_as_l();
614 method Bit#(1) wr_ds_l();
619 method Bit#(1) wr_wr_l();
624 method Action rd_dsack_0_l(Bit#(1) x);
628 method Action rd_dsack_1_l(Bit#(1) y);
632 method Action rd_berr_l(Bit#(1) z);
636 method Action rd_halt_l(Bit#(1) u);
641 /*Methods to emulate tristate functionality*/
643 interface Data_bus_inf data_bus;
646 method Bit#(1) wr_siz0();
650 method Bit#(1) wr_siz1();
654 method Bit#(32) wr_addr();
657 method Bit#(8) wr_byte_31_24();
661 method Bit#(8) wr_byte_23_16();
665 method Bit#(8) wr_byte_15_8();
669 method Bit#(3) wr_fun_code();
673 method Bit#(8) wr_byte_7_0();
677 method Action rd_byte_31_24(Bit #(8) d4);
681 method Action rd_byte_23_16(Bit #(8) d3);
685 method Action rd_byte_15_8 (Bit #(8) d2);
689 method Action rd_byte_7_0 (Bit #(8) d1);
694 method Bit#(4) wr_en();
698 method Bool wr_mode_en();
703 method Bool wr_addr_en();
708 method Bool wr_fun_code_en();
715 method Action get_req (Req_vme req) if(!(cpu_req.notEmpty()));
719 method ActionValue #(Resp_vme) resp();
721 return cpu_resp.first();