502e0d86576513355b4a8cac22e637fc15a71a3f
[shakti-peripherals.git] / src / peripherals / vme / vme_top.bsv
1 /*
2 Copyright (c) 2013, IIT Madras
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
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.
10
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 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
13 */
14 /*
15 Transalates AXI master request to VME master request
16 */
17 `define PADDR 56
18 package vme_top;
19
20 /* ======== Package imports ======= */
21 import Vector :: *;
22 import FIFO :: *;
23 import ConfigReg ::*;
24 import AXI4_Types ::*;
25 import AXI4_Fabric ::*;
26 import Semi_FIFOF ::*;
27 import BUtils::*;
28 /*================================== */
29
30 /*========= Project imports ======== */
31 `include "vme_parameters.bsv"
32 `include "defined_parameters.bsv"
33 import defined_types ::*;
34 import FIFOF ::*;
35 import vme_master :: *;
36 import vme_defines :: *;
37 /*================================== */
38
39
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 /*-============================================================================= */
46 endinterface
47
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);
50
51 function Bit#(2) modeconv_vme(Bit#(3) transfer_size );
52 if(transfer_size==0)//8 bit transfer
53 return 2'b01;
54 else if (transfer_size==1)//16 bit transfer
55 return 2'b10;
56 else
57 return 2'b00;//32 bit transfer
58 endfunction
59
60 (*synthesize*)
61 module mkvme_top(Ifc_vme_top);
62
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 //....................................................................................................................................................................................................//
73
74
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);
82 ff_id.enq(info.awid);
83 $display("Enqueing request onto VME");
84 ff_address.enq(info.awaddr);
85 case(request.mode)
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);
89 endcase
90
91 endrule
92
93
94 rule check_read_request_to_memory;
95 let info<- pop_o(s_xactor.o_rd_addr);
96 ff_id.enq(info.arid);
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};
99
100 case(request.mode)
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);
104 endcase
105
106 proc_master.get_req(request);
107
108 endrule
109
110 (* preempts = "check_read_request_to_memory,check_wr_request_to_memory"*)
111
112 //...............................................................SEND RESPONSE TO MEMORY................................................................................................................//
113 //
114 // Data is retreived from a Big-Endian memory and sent back in little Endian format
115
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"*)
117
118
119 rule send_read_response_from_memory_to_mem_stage_8(ff_req.first==DATA_MODE_8_READ);
120 let response <-proc_master.resp();
121 ff_req.deq();
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};
127 ff_address.deq();
128 s_xactor.i_rd_data.enq(r);
129 $display("Data received %h from address %h to mem_stage",response.data,ff_id.first());
130 ff_id.deq();
131 endrule
132
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 )
136 begin
137 ff_req.deq();
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;
141
142 // if(ff_address.first[4]==1)
143 // r.rdata={response.data,32'b0};
144 ff_address.deq();
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};
147 ff_id.deq();
148 $display("Data received %h from address %h to mem_stage",response.data,ff_id.first());
149 end
150 else if(response.port_type==2'b01)
151 if(port_count==0)
152 begin
153 response_buff<=response.data;
154 port_count<=port_count+1;
155 end
156 else
157 begin
158
159 ff_req.deq();
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;
163 port_count<=0;
164 // if(ff_address.first[4]==1)
165 // r.rdata={16'b0,{response.data[7:0],response_buff[7:0]},32'b0};
166 ff_address.deq();
167 s_xactor.i_rd_data.enq(r);
168 response_buff<=0;
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};
170 ff_id.deq();
171 $display("Data received %h from address %h to mem_stage",{response.data[7:0],response_buff[7:0]},ff_id.first());
172
173 end
174
175 else
176
177 begin
178
179 ff_req.deq();
180 port_count<=0;
181 response_buff<=0;
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};
187 ff_address.deq();
188 s_xactor.i_rd_data.enq(r);
189 ff_id.deq();
190 $display("Data received %h from address %h mem_stage",{response.data[15:0]},ff_id.first());
191 end
192 endrule
193
194
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)
198 begin
199 ff_req.deq();
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};
205 ff_address.deq;
206 s_xactor.i_rd_data.enq(r);
207 ff_id.deq();
208 $display("Data received %h from address %h from mem_stage",response.data,ff_id.first());
209 end
210
211
212 else if(response.port_type==2'b10)
213
214 if(port_count==0)
215 begin
216 response_buff<=response.data;
217 port_count<=port_count+1;
218 end
219 else
220
221 begin
222
223 ff_id.deq();
224 ff_req.deq();
225 port_count<=0;
226 response_buff<=0;
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};
232 ff_address.deq;
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());
235
236 end
237
238 else if(response.port_type==2'b01)
239 begin
240
241 if(port_count<3)
242 begin
243 response_buff<={response.data[7:0],response_buff[23:0]};
244 port_count<=port_count+1;
245 end
246 else
247 begin
248
249 ff_req.deq();
250 port_count<=0;
251 response_buff<=0;
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};
257 ff_address.deq;
258 s_xactor.i_rd_data.enq(r);
259 ff_id.deq();
260
261 $display("Data received %h from address %h to mem_stage",{response.data[7:0],response_buff[23:0]},ff_id.first());
262
263 end
264
265 end
266 endrule
267
268
269
270
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)
274 begin
275 ff_req.deq();
276 ff_id_imem.deq();
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());
280 end
281
282
283 else if(response.port_type==2'b10)
284
285 if(port_count==0)
286 begin
287 response_buff<=response.data;
288 port_count<=port_count+1;
289 end
290 else
291 begin
292 ff_id_imem.deq();
293 ff_req.deq();
294 port_count<=0;
295 response_buff<=0;
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());
299
300 end
301 endrule
302 */
303
304 rule send_write_response_from_memory_to_mem_stage_8(ff_req.first==DATA_MODE_8_WRITE);//MEMORY WRITE RESP TO DCACHE
305
306 let response <-proc_master.resp();
307 ff_req.deq();
308 let resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, bid: ff_id.first};
309 if (response.berr==1'b1)
310 resp.bresp=AXI4_SLVERR;
311 ff_id.deq();
312
313 ff_address.deq();
314 s_xactor.i_wr_resp.enq(resp);
315 `ifdef verbose $display($time,"\t CORE: Received Write Response:"); `endif
316 endrule
317
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 )
322 begin
323 ff_req.deq();
324 ff_id.deq();
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};
328
329 ff_address.deq();
330 if (response.berr==1'b1)
331 resp.bresp=AXI4_SLVERR;
332 s_xactor.i_wr_resp.enq(resp);
333
334 end
335 else if(response.port_type==2'b01)
336 if(port_count==0)
337 begin
338 port_count<=port_count+1;
339 end
340 else
341
342 begin
343
344 ff_address.deq();
345 // ff_id.deq();
346 ff_req.deq();
347 port_count<=0;
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;
353 ff_id.deq();
354 s_xactor.i_wr_resp.enq(resp);
355
356 end
357
358 else
359
360 begin
361
362 ff_address.deq();
363 // ff_id.deq();
364 ff_req.deq();
365 port_count<=0;
366 response_buff<=0;
367
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;
373 ff_id.deq();
374 s_xactor.i_wr_resp.enq(resp);
375
376 end
377
378 endrule
379
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)
383 begin
384 ff_req.deq();
385 //
386
387
388
389
390
391 `ifdef verbose $display($time,"CORE: Received Write Response:"); `endif
392
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};
394
395 let resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, bid: ff_id.first};
396 if (response.berr==1'b1)
397 resp.bresp=AXI4_SLVERR;
398 ff_id.deq();
399 ff_address.deq();
400 s_xactor.i_wr_resp.enq(resp);
401 end
402
403 else if(response.port_type==2'b10)
404
405 if(port_count==0)
406 begin
407 port_count<=port_count+1;
408 end
409 else
410
411 begin
412
413 // ff_id.deq();
414 ff_req.deq();
415 ff_address.deq();
416 port_count<=0;
417
418 ff_id.deq();
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};
424
425 `ifdef verbose $display($time,"CORE: Received Write Response:"); `endif
426
427 end
428 else if(response.port_type==2'b01)
429 begin
430 if(port_count<3)
431 begin
432 port_count<=port_count+1;
433 end
434 else
435 begin
436
437 // ff_id.deq();
438 ff_req.deq();
439 ff_address.deq();
440 port_count<=0;
441 let resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, bid: ff_id.first};
442 if (response.berr==1'b1)
443 resp.bresp=AXI4_SLVERR;
444 ff_id.deq();
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);
447
448 `ifdef verbose $display($time,"CORE: Received Write Response:"); `endif
449 end
450 end
451 endrule
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;
455 endmodule
456 endpackage