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 Transalates AXI master request to VME master request
20 /* ======== Package imports ======= */
24 import AXI4_Types ::*;
25 import AXI4_Fabric ::*;
26 import Semi_FIFOF ::*;
28 /*================================== */
30 /*========= Project imports ======== */
31 `include "vme_parameters.bsv"
32 `include "defined_parameters.bsv"
33 import defined_types ::*;
35 import vme_master :: *;
36 import vme_defines :: *;
37 /*================================== */
40 interface Ifc_vme_top;
41 interface Vme_out proc_ifc;
42 interface Data_bus_inf proc_dbus;
43 interface AXI4_Slave_IFC#(`PADDR,`Reg_width,`USERSPACE) slave_axi_vme;
44 method Action rd_ipl(Bit#(3) ip);
45 /*-============================================================================= */
48 typedef enum {DATA,INST} Priority_cache deriving (Bits, Eq, FShow);
49 typedef enum {DATA_MODE_8_READ,DATA_MODE_16_READ,DATA_MODE_32_READ,DATA_MODE_8_WRITE,DATA_MODE_16_WRITE,DATA_MODE_32_WRITE,INST_MODE} Data_mode deriving (Bits, Eq, FShow);
51 function Bit#(2) modeconv_vme(Bit#(3) transfer_size );
52 if(transfer_size==0)//8 bit transfer
54 else if (transfer_size==1)//16 bit transfer
57 return 2'b00;//32 bit transfer
61 module mkvme_top(Ifc_vme_top);
63 AXI4_Slave_Xactor_IFC #(`PADDR,`Reg_width,`USERSPACE) s_xactor <- mkAXI4_Slave_Xactor;
64 Vme_master proc_master <-mkvmemaster;
65 Reg#(Bit#(`Reg_width_vme_slave)) response_buff <-mkReg(0);//To buffer multiple cycle transfers
66 FIFOF#(Bit#(4)) ff_id <-mkSizedFIFOF(2);//To store request address of instruction
67 FIFOF#(Bit#(`Reg_width_vme_slave)) ff_address <-mkSizedFIFOF(2);//To store request address of instruction
68 FIFOF#(Data_mode) ff_req<-mkFIFOF;//To keep track of last pending request
69 Reg#(Bit#(2)) port_count <- mkReg(0);
70 Reg#(Bit#(32)) inst_rcvd <- mkReg(0);
71 //.....................................................SEND_REQUEST_TO_MEMORY.........................................................................................................................//
72 //....................................................................................................................................................................................................//
75 rule check_wr_request_to_memory;
76 let info<-pop_o(s_xactor.o_wr_addr);
77 let data<-pop_o(s_xactor.o_wr_data);
78 let request=Req_vme{addr:truncate(info.awaddr),wr_data:truncate(data.wdata),mode:modeconv_vme(info.awsize),fun_code:3'b010,rd_req:0};
79 if(info.awaddr[27:0]==28'hFFFF_FFF)
80 request.fun_code=3'b111;
81 proc_master.get_req(request);
83 $display("Enqueing request onto VME");
84 ff_address.enq(info.awaddr);
86 2'b00 :ff_req.enq(DATA_MODE_32_WRITE);
87 2'b01 :ff_req.enq(DATA_MODE_8_WRITE);
88 2'b10 :ff_req.enq(DATA_MODE_16_WRITE);
94 rule check_read_request_to_memory;
95 let info<- pop_o(s_xactor.o_rd_addr);
97 ff_address.enq(info.araddr);
98 let request=Req_vme{addr:truncate(info.araddr),wr_data:?,mode:modeconv_vme(info.arsize),fun_code:3'b010,rd_req:1};
101 2'b00 :ff_req.enq(DATA_MODE_32_READ);
102 2'b01 :ff_req.enq(DATA_MODE_8_READ);
103 2'b10 :ff_req.enq(DATA_MODE_16_READ);
106 proc_master.get_req(request);
110 (* preempts = "check_read_request_to_memory,check_wr_request_to_memory"*)
112 //...............................................................SEND RESPONSE TO MEMORY................................................................................................................//
114 // Data is retreived from a Big-Endian memory and sent back in little Endian format
116 (* mutually_exclusive="send_read_response_from_memory_to_mem_stage_8,send_read_response_from_memory_to_mem_stage_16,send_read_response_from_memory_to_mem_stage_32,send_write_response_from_memory_to_mem_stage_8,send_write_response_from_memory_to_mem_stage_16,send_write_response_from_memory_to_mem_stage_32"*)
119 rule send_read_response_from_memory_to_mem_stage_8(ff_req.first==DATA_MODE_8_READ);
120 let response <-proc_master.resp();
122 let r = AXI4_Rd_Data {rresp: AXI4_OKAY, rdata:duplicate(response.data[7:0]),rlast:True, ruser: 0, rid: ff_id.first };
123 if(response.berr==1'b1)
124 r.rresp = AXI4_SLVERR;
125 // if(ff_address.first[4]==1)
126 // r.rdata={response.data,32'b0};
128 s_xactor.i_rd_data.enq(r);
129 $display("Data received %h from address %h to mem_stage",response.data,ff_id.first());
133 rule send_read_response_from_memory_to_mem_stage_16(ff_req.first==DATA_MODE_16_READ);
134 let response <-proc_master.resp();
135 if(response.port_type==2'b10 )
138 let r = AXI4_Rd_Data {rresp: AXI4_OKAY, rdata:duplicate(response.data[15:0]),rlast:True, ruser: 0, rid: ff_id.first };
139 if(response.berr==1'b1)
140 r.rresp = AXI4_SLVERR;
142 // if(ff_address.first[4]==1)
143 // r.rdata={response.data,32'b0};
145 s_xactor.i_rd_data.enq(r);
146 //let resp = To_Cpu_Mem {data_word:zeroExtend(response.data),bus_error:response.berr==1'b1,misaligned_error:1'b0,address:ff_id.first(),load_store:Load};
148 $display("Data received %h from address %h to mem_stage",response.data,ff_id.first());
150 else if(response.port_type==2'b01)
153 response_buff<=response.data;
154 port_count<=port_count+1;
160 let r = AXI4_Rd_Data {rresp: AXI4_OKAY, rdata:duplicate({response.data[7:0],response_buff[7:0]}),rlast:True,ruser: 0,rid: ff_id.first };
161 if(response.berr==1'b1)
162 r.rresp = AXI4_SLVERR;
164 // if(ff_address.first[4]==1)
165 // r.rdata={16'b0,{response.data[7:0],response_buff[7:0]},32'b0};
167 s_xactor.i_rd_data.enq(r);
169 //let resp = To_Cpu_Mem {data_word:zeroExtend({response.data[7:0],response_buff[7:0]}),bus_error:response.berr==1'b1,misaligned_error:1'b0,address:ff_id.first( ),load_store:Load};
171 $display("Data received %h from address %h to mem_stage",{response.data[7:0],response_buff[7:0]},ff_id.first());
182 let r = AXI4_Rd_Data{rresp: AXI4_OKAY, rdata:duplicate(response.data[15:0]),rlast:True,ruser: 0,rid: ff_id.first };
183 if(response.berr==1'b1)
184 r.rresp = AXI4_SLVERR;
185 // if(ff_address.first[4]==1)
186 // r.rdata={response.data,32'b0};
188 s_xactor.i_rd_data.enq(r);
190 $display("Data received %h from address %h mem_stage",{response.data[15:0]},ff_id.first());
195 rule send_read_response_from_memory_to_mem_stage_32(ff_req.first==DATA_MODE_32_READ);
196 let response <-proc_master.resp();
197 if(response.port_type==2'b00)
200 let r = AXI4_Rd_Data{rresp: AXI4_OKAY, rdata:duplicate({response.data}),rlast:True,ruser: 0,rid: ff_id.first };
201 if(response.berr==1'b1)
202 r.rresp = AXI4_SLVERR;
203 // if(ff_address.first[4]==1)
204 // r.rdata={response.data,32'b0};
206 s_xactor.i_rd_data.enq(r);
208 $display("Data received %h from address %h from mem_stage",response.data,ff_id.first());
212 else if(response.port_type==2'b10)
216 response_buff<=response.data;
217 port_count<=port_count+1;
227 let r = AXI4_Rd_Data{rresp: AXI4_OKAY, rdata:duplicate({response.data[15:0],response_buff[15:0]}),rlast:True,ruser: 0,rid: ff_id.first };
228 if(response.berr==1'b1)
229 r.rresp = AXI4_SLVERR;
230 // if(ff_address.first[4]==1)
231 // r.rdata={{response.data[15:0],response_buff[15:0]},32'b0};
233 s_xactor.i_rd_data.enq(r);
234 $display("Data received %h from address %h from mem_stage",{response.data[15:0],response_buff[15:0]},ff_id.first());
238 else if(response.port_type==2'b01)
243 response_buff<={response.data[7:0],response_buff[23:0]};
244 port_count<=port_count+1;
252 let r = AXI4_Rd_Data{rresp: AXI4_OKAY, rdata:duplicate({response.data[7:0],response_buff[23:0]}),rlast:True,ruser: 0,rid: ff_id.first };
253 if(response.berr==1'b1)
254 r.rresp = AXI4_SLVERR;
255 // if(ff_address.first[4]==1)
256 // r.rdata={{response.data[15:0],response_buff[15:0]},32'b0};
258 s_xactor.i_rd_data.enq(r);
261 $display("Data received %h from address %h to mem_stage",{response.data[7:0],response_buff[23:0]},ff_id.first());
271 /* rule send_read_response_from_memory_to_fetch(ff_req.first==INST_MODE); //MEMORY READ RESP TO ICACHE
272 let response <-proc_master.resp();
273 if(response.port_type==2'b00)
277 inst_rcvd <= response.data;
278 let resp = To_Cpu{data_word:zeroExtend(response.data),bus_error:response.berr==1'b1,misaligned_error:1'b0,address:ff_id_imem.first()};
279 $display("Data received %h from address %h to fetch_stage",response.data,ff_id_imem.first());
283 else if(response.port_type==2'b10)
287 response_buff<=response.data;
288 port_count<=port_count+1;
296 inst_rcvd <= {response.data[15:0],response_buff[15:0]};
297 let resp= To_Cpu{data_word:zeroExtend({response.data[15:0],response_buff[15:0]}),bus_error:response.berr==1'b1,misaligned_error:1'b0,address:ff_id_imem.first()};
298 $display("Data received %h from address %h to fetch_stage",{response.data[15:0],response_buff[15:0]},ff_id_imem.first());
304 rule send_write_response_from_memory_to_mem_stage_8(ff_req.first==DATA_MODE_8_WRITE);//MEMORY WRITE RESP TO DCACHE
306 let response <-proc_master.resp();
308 let resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, bid: ff_id.first};
309 if (response.berr==1'b1)
310 resp.bresp=AXI4_SLVERR;
314 s_xactor.i_wr_resp.enq(resp);
315 `ifdef verbose $display($time,"\t CORE: Received Write Response:"); `endif
318 rule send_write_response_from_memory_to_mem_stage_16(ff_req.first==DATA_MODE_16_WRITE);
319 let response <-proc_master.resp();
320 $display("Received respons from port_type %h",response.port_type);
321 if(response.port_type==2'b10 )
325 `ifdef verbose $display($time,"CORE: Received Write Response:"); `endif
326 //let resp = To_Cpu_Mem {data_word:?,bus_error:response.berr==1'b1,misaligned_error:1'b0,address:ff_id.first(),load_store:Store};
327 let resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, bid: ff_id.first};
330 if (response.berr==1'b1)
331 resp.bresp=AXI4_SLVERR;
332 s_xactor.i_wr_resp.enq(resp);
335 else if(response.port_type==2'b01)
338 port_count<=port_count+1;
348 `ifdef verbose $display($time,"CORE: Received Write Response:"); `endif
349 /// let resp = To_Cpu_Mem {data_word:?,bus_error:response.berr==1'b1,misaligned_error:1'b0,address:ff_id.first(),load_store:Store};
350 let resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, bid: ff_id.first};
351 if (response.berr==1'b1)
352 resp.bresp=AXI4_SLVERR;
354 s_xactor.i_wr_resp.enq(resp);
368 `ifdef verbose $display($time,"CORE: Received Write Response:"); `endif
369 //let resp = To_Cpu_Mem {data_word:?,bus_error:response.berr==1'b1,misaligned_error:1'b0,address:ff_id.first(),load_store:Store};
370 let resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, bid: ff_id.first};
371 if (response.berr==1'b1)
372 resp.bresp=AXI4_SLVERR;
374 s_xactor.i_wr_resp.enq(resp);
380 rule send_write_response_from_memory_to_mem_stage_32(ff_req.first==DATA_MODE_32_WRITE);
381 let response <-proc_master.resp();
382 if(response.port_type==2'b00)
391 `ifdef verbose $display($time,"CORE: Received Write Response:"); `endif
393 //let resp = To_Cpu_Mem {data_word:?,bus_error:response.berr==1'b1,misaligned_error:1'b0,address:ff_id.first(),load_store:Store};
395 let resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, bid: ff_id.first};
396 if (response.berr==1'b1)
397 resp.bresp=AXI4_SLVERR;
400 s_xactor.i_wr_resp.enq(resp);
403 else if(response.port_type==2'b10)
407 port_count<=port_count+1;
419 let resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, bid: ff_id.first};
420 if (response.berr==1'b1)
421 resp.bresp=AXI4_SLVERR;
422 s_xactor.i_wr_resp.enq(resp);
423 // let resp = To_Cpu_Mem {data_word:?,bus_error:response.berr==1'b1,misaligned_error:1'b0,address:ff_id.first(),load_store:Store};
425 `ifdef verbose $display($time,"CORE: Received Write Response:"); `endif
428 else if(response.port_type==2'b01)
432 port_count<=port_count+1;
441 let resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, bid: ff_id.first};
442 if (response.berr==1'b1)
443 resp.bresp=AXI4_SLVERR;
445 // let resp = To_Cpu_Mem {data_word:?,bus_error:response.berr==1'b1,misaligned_error:1'b0,address:ff_id.first(),load_store:Store};
446 s_xactor.i_wr_resp.enq(resp);
448 `ifdef verbose $display($time,"CORE: Received Write Response:"); `endif
452 interface proc_ifc = proc_master.vme_interface;
453 interface proc_dbus = proc_master.data_bus;
454 interface slave_axi_vme = s_xactor.axi_side;