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 `include "instance_defines.bsv"
17 `define SDR_RFSH_TIMER_W 12
18 `define SDR_RFSH_ROW_CNT_W 3
20 `define ACTPRE_DELAY 8'h0
21 `define PREACT_DELAY 8'h8
22 `define ACT_RW_DELAY 8'h10
23 `define EN_SDRAM 8'h18
25 `define MODE_REG 8'h28
26 `define CAS_LATNCY 8'h30
27 `define AUTO_REFRESH 8'h38
28 `define RECRY_DELAY 8'h40
29 `define RFRSH_TIMER 8'h48
30 `define RFRSH_ROW_CNT 8'h50
31 `define SDR_INIT_DONE 8'h58
32 `define SDR_WIDTH 8'h60
33 `define SDR_COLBITS 8'h68
34 `define SDR_CLK_DELAY 8'h78
39 import Semi_FIFOF :: *;
40 import AXI4_Types :: *;
41 import AXI4_Fabric :: *;
42 import bsvmksdrc_top :: *;
44 import Connectable ::*;
50 interface Ifc_sdram_out;
51 (*always_enabled, always_ready*)
52 interface Put#(Bit#(64)) ipad_sdr_din;
53 interface Get#(Bit#(64)) osdr_dout;
54 interface Get#(Bit#(64)) osdr_den_n;
55 interface Get#(Bit#(1)) osdr_cke;
56 interface Get#(Bit#(1)) osdr_cs_n;
57 interface Get#(Bit#(1)) osdr_ras_n;
58 interface Get#(Bit#(1)) osdr_cas_n;
59 interface Get#(Bit#(1)) osdr_we_n;
60 interface Get#(Bit#(8)) osdr_dqm;
61 interface Get#(Bit#(2)) osdr_ba;
62 interface Get#(Bit#(13)) osdr_addr;
63 interface Get#(Bit#(1)) osdr_clock;
67 interface Ifc_sdr_slave;
68 interface AXI4_Slave_IFC#(`PADDR, `Reg_width,`USERSPACE) axi4_slave_sdram;
69 interface AXI4_Slave_IFC#(`PADDR, `Reg_width,`USERSPACE) axi4_slave_cntrl_reg;
70 interface Ifc_sdram_out ifc_sdram_out;
80 } Write_state deriving(Bits, Eq, FShow);
87 } Read_state deriving(Bits, Eq,FShow);
93 } Write_split_states deriving(Bits, Eq, FShow);
97 function (Bit#(9)) fn_wr_len(Bit#(8) length, Bit#(3) awsize, Bit#(3) lwr_addr);
103 w_packet = lwr_addr >> awsize;
104 s_length = ((zeroExtend(length) + zeroExtend(w_packet)) >> 3) + 1;
107 w_packet = lwr_addr >> awsize;
108 s_length = ((zeroExtend(length) + zeroExtend(w_packet)) >> 2) + 1;
109 //`ifdef verbose $display($time(),"\t SSSS w_packet %b s_lenght %h length %h", w_packet, s_length, length); `endif
112 //w_packet = lwr_addr >> awsize;
113 // s_length = ((s_length + w_packets) >> 1) + 1;
114 s_length = zeroExtend(length >> 1) + 1;
117 s_length = zeroExtend(length) + 1;
125 function Bit#(64) fn_wr_split_data(Bit#(64) data, Bit#(8) wstrb);
128 data0[7:0] = data[7:0];
133 data0[15:8] = data[15:8];
138 data0[23:16] = data[23:16];
143 data0[31:24] = data[31:24];
148 data0[39:32] = data[39:32];
153 data0[47:40] = data[47:40];
158 data0[55:48] = data[55:48];
163 data0[63:56] = data[63:56];
170 function Bit#(26) fn_wr_address(Bit#(`PADDR) address);
171 Bit#(29) sdr_addr = address[31:3];
172 return sdr_addr[25:0];
175 function Bit#(64) fn_rd_data(Bit#(3) bsize,Bit#(4) lwr_addr,Bit#(64) data);
181 return duplicate(data[7:0]);
184 return duplicate(data[15:8]);
187 return duplicate(data[23:16]);
190 return duplicate(data[31:24]);
193 return duplicate(data[39:32]);
196 return duplicate(data[47:40]);
199 return duplicate(data[55:48]);
202 return duplicate(data[63:56]);
210 return duplicate(data[15:0]);
213 return duplicate(data[31:16]);
216 return duplicate(data[47:32]);
219 return duplicate(data[63:48]);
227 return duplicate(data[31:0]);
230 return duplicate(data[63:32]);
247 module mksdr_axi4_slave#(Clock clk0) (Ifc_sdr_slave);
249 Reset rst0 <- mkAsyncResetFromCR (0, clk0);
251 Reg#(Bit#(9)) rg_delay_count <- mkReg(0,clocked_by clk0, reset_by rst0);
252 Reg#(Bit#(9)) rg_rd_actual_len <- mkReg(0,clocked_by clk0, reset_by rst0);
253 Reg#(bit) rg_app_req <- mkDReg(0,clocked_by clk0, reset_by rst0);
254 Reg#(bit) rg_app_req_wrap <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
255 Reg#(Bit#(26)) rg_app_req_addr <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
256 Reg#(Bit#(4)) rg_cfg_sdr_tras_d <- mkConfigReg(4'h4,clocked_by clk0, reset_by rst0);
257 Reg#(Bit#(4)) rg_cfg_sdr_trp_d <- mkConfigReg(4'h2,clocked_by clk0, reset_by rst0);
258 Reg#(Bit#(4)) rg_cfg_sdr_trcd_d <- mkConfigReg(4'h2,clocked_by clk0, reset_by rst0);
259 Reg#(bit) rg_cfg_sdr_en <- mkConfigReg(1'h0,clocked_by clk0, reset_by rst0);
260 Reg#(Bit#(2)) rg_cfg_req_depth <- mkConfigReg(2'h3,clocked_by clk0, reset_by rst0);
261 Reg#(Bit#(13)) rg_cfg_sdr_mode_reg <- mkConfigReg(13'h032,clocked_by clk0, reset_by rst0);
262 Reg#(Bit#(3)) rg_cfg_sdr_cas <- mkConfigReg(3'h3,clocked_by clk0, reset_by rst0);
263 Reg#(Bit#(4)) rg_cfg_sdr_trcar_d <- mkConfigReg(4'h7,clocked_by clk0, reset_by rst0);
264 Reg#(Bit#(4)) rg_cfg_sdr_twr_d <- mkConfigReg(4'h1,clocked_by clk0, reset_by rst0);
265 Reg#(Bit#(2)) rg_cfg_sdr_width <- mkConfigReg(2'b0,clocked_by clk0, reset_by rst0);
266 Reg#(Bit#(2)) rg_cfg_colbits <- mkConfigReg(2'b01,clocked_by clk0, reset_by rst0);
267 Reg#(Bit#(8)) rg_cfg_sdr_clk_delay <- mkConfigReg(8'b00001000,clocked_by clk0, reset_by rst0);
269 Reg#(Bit#(`SDR_RFSH_TIMER_W )) rg_cfg_sdr_rfsh <- mkConfigReg(12'h100,clocked_by clk0, reset_by rst0);
270 Reg#(Bit#(`SDR_RFSH_ROW_CNT_W)) rg_cfg_sdr_rfmax <- mkConfigReg(3'h6,clocked_by clk0, reset_by rst0);
271 Reg#(Bit#(9)) rg_app_req_len <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
272 Reg#(Bit#(4)) rg_lwraddr <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
273 Reg#(Bit#(3)) rg_arsize <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
274 Reg#(bit) rg_app_req_wr_n <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
275 Reg#(Bit#(8)) rg_app_wr_en_n <- mkDWire(8'hFF,clocked_by clk0, reset_by rst0);
276 Reg#(Bit#(64)) rg_app_wr_data <- mkDWire(0,clocked_by clk0, reset_by rst0);
277 Wire#(Bool) wr_sdr_init_done <- mkDWire(False,clocked_by clk0, reset_by rst0);
278 Wire#(Bool) wr_app_req_ack <- mkDWire(False,clocked_by clk0, reset_by rst0);
279 Wire#(Bool) wr_app_wr_next_req <- mkDWire(False,clocked_by clk0, reset_by rst0);
280 Wire#(Bool) wr_app_rd_valid <- mkDWire(False,clocked_by clk0, reset_by rst0);
281 Wire#(Bool) wr_app_last_rd <- mkDWire(False,clocked_by clk0, reset_by rst0);
282 Wire#(Bool) wr_app_last_wr <- mkDWire(False,clocked_by clk0, reset_by rst0);
283 Wire#(Bit#(64)) wr_app_rd_data <- mkWire(clocked_by clk0, reset_by rst0);
286 Reg#(Bit#(4)) rg_rid <- mkReg(0, clocked_by clk0, reset_by rst0);
287 Reg#(bit) rg_rd_not_active_flag <- mkSyncRegToCC(0,clk0, rst0);
288 Reg#(Bit#(4)) rg_ctrl_rid <- mkReg(0);
289 Reg#(Bit#(4)) rg_wid <- mkReg(0);
291 Reg#(Write_split_states) rg_wr_split_states <- mkReg(IDLE);
292 Reg#(Bit#(3)) rg_awsize <- mkReg(0);
293 Reg#(Bit#(9)) rg_ac_count <- mkReg(0);
294 Reg#(Bit#(6)) rg_single_burst <- mkReg(0);
295 Reg#(Bit#(64)) rg_wr_ac_data <- mkReg(0);
296 Reg#(Bit#(8)) rg_wr_ac_wstrb <- mkReg(0);
297 Reg#(Bit#(4)) rg_wr_lwr_addr <- mkReg(0);
298 Reg#(Bit#(9)) rg_local_actual_wr_length <- mkReg(0);
299 Reg#(Bit#(9)) rg_actual_wr_length <- mkSyncRegFromCC(0,clk0);
300 Reg#(Bit#(32)) rg_wr_address <- mkSyncRegFromCC(0,clk0);
302 Reg#(Bit#(3)) rg_awsize_sclk <- mkSyncRegFromCC(0,clk0);
304 Reg#(Bit#(9)) rg_burst_counter <- mkReg(0);
306 Bool burst_eq = (rg_burst_counter == rg_local_actual_wr_length);
308 Reg#(Bit#(3)) rg_packets <- mkReg(0);
309 Reg#(Bit#(3)) rg_packet_counter <- mkReg(0);
312 Reg#(Write_state) rg_write_states <- mkReg(IDLE,clocked_by clk0, reset_by rst0);
313 Reg#(Read_state) rg_read_states <- mkReg(IDLE,clocked_by clk0, reset_by rst0);
315 FIFOF#(AXI4_Wr_Addr#(`PADDR,`USERSPACE)) ff_wr_addr <- mkSizedFIFOF(13);
316 FIFOF#(AXI4_Wr_Data#(`Reg_width)) ff_wr_data <- mkSizedFIFOF(13);
317 SyncFIFOIfc#(Bit#(`Reg_width)) ff_ac_wr_data <- mkSyncFIFOFromCC(13,clk0);
318 SyncFIFOIfc#(Bit#(8)) ff_ac_wr_wstrb <- mkSyncFIFOFromCC(13,clk0);
320 SyncFIFOIfc#(Bool) ff_sync_write_response<-mkSyncFIFOToCC(1,clk0,rst0);
322 //FIFOF#(AXI4_Rd_Addr#(`PADDR,`USERSPACE)) ff_rd_addr <- mkSizedFIFOF(3);
323 FIFOF#(Bit#(64)) ff_rd_data <- mkSizedFIFOF(86,clocked_by clk0, reset_by rst0);
324 SyncFIFOIfc#(AXI4_Rd_Addr#(`PADDR,`USERSPACE)) ff_rd_addr <- mkSyncFIFOFromCC(30,clk0);
325 SyncFIFOIfc#(AXI4_Rd_Data#(`Reg_width,`USERSPACE)) ff_sync_read_response <-mkSyncFIFOToCC(13,clk0,rst0);
327 SyncFIFOIfc#(Tuple2#(Bit#(`PADDR),Bit#(`Reg_width))) ff_sync_ctrl_write<- mkSyncFIFOFromCC(1,clk0);
328 SyncFIFOIfc#(Bit#(`PADDR)) ff_sync_ctrl_read<- mkSyncFIFOFromCC(1,clk0);
329 SyncFIFOIfc#(Bit#(`Reg_width)) ff_sync_ctrl_read_response<- mkSyncFIFOToCC(1,clk0,rst0);
332 Reg#(Bit#(2)) rg_poll_cnt <- mkReg(0,clocked_by clk0, reset_by rst0);
333 Reg#(Bool) rg_polling_status <- mkSyncRegToCC(False,clk0,rst0);
334 Reg#(Bool) rg_polling_status_clk0 <- mkReg(False,clocked_by clk0, reset_by rst0);
335 Reg#(Bool) rg_rd_trnc_flg <- mkReg(False);
336 Reg#(Bool) rg_wr_trnc_flg <- mkReg(False);
337 Reg#(bit) rg_odd_len <- mkReg(0);
339 AXI4_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor_sdram <- mkAXI4_Slave_Xactor;
340 AXI4_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor_cntrl_reg <- mkAXI4_Slave_Xactor;
341 Ifc_sdram sdr_cntrl <- mksdrc_top(clocked_by clk0, reset_by rst0);
343 function Action fn_wr_cntrl_reg(Bit#(64) data, Bit#(8) address);
347 `ACTPRE_DELAY : rg_cfg_sdr_tras_d <= data[3:0];
349 `PREACT_DELAY : rg_cfg_sdr_trp_d <= data[3:0];
351 `ACT_RW_DELAY : rg_cfg_sdr_trcd_d <= data[3:0];
353 `EN_SDRAM : rg_cfg_sdr_en <= data[0];
355 `MAX_REQ : rg_cfg_req_depth <= data[1:0];
357 `MODE_REG : rg_cfg_sdr_mode_reg <= data[12:0];
359 `CAS_LATNCY : rg_cfg_sdr_cas <= data[2:0];
361 `AUTO_REFRESH : rg_cfg_sdr_trcar_d <= data[3:0];
363 `RECRY_DELAY : rg_cfg_sdr_twr_d <= data[3:0];
365 `RFRSH_TIMER : rg_cfg_sdr_rfsh <= data[11:0];
367 `RFRSH_ROW_CNT : rg_cfg_sdr_rfmax <= data[2:0];
369 `SDR_WIDTH : rg_cfg_sdr_width <= data [1:0];
371 `SDR_COLBITS : rg_cfg_colbits <= data [1:0];
374 `SDR_CLK_DELAY : rg_cfg_sdr_clk_delay <= data [7:0];
382 function Bit#(64) fn_rd_cntrl_reg(Bit#(8) address);
385 `ACTPRE_DELAY : return extend(rg_cfg_sdr_tras_d);
387 `PREACT_DELAY : return extend(rg_cfg_sdr_trp_d);
389 `ACT_RW_DELAY : return extend(rg_cfg_sdr_trcd_d);
391 `EN_SDRAM : return extend(rg_cfg_sdr_en);
393 `MAX_REQ : return extend(rg_cfg_req_depth);
395 `MODE_REG : return extend(rg_cfg_sdr_mode_reg);
397 `CAS_LATNCY : return extend(rg_cfg_sdr_cas);
399 `AUTO_REFRESH : return extend(rg_cfg_sdr_trcar_d);
401 `RECRY_DELAY : return extend(rg_cfg_sdr_twr_d);
403 `RFRSH_TIMER : return extend(rg_cfg_sdr_rfsh);
405 `RFRSH_ROW_CNT : return extend(rg_cfg_sdr_rfmax);
407 `SDR_INIT_DONE : return extend(pack(wr_sdr_init_done));
409 `SDR_WIDTH : return extend(rg_cfg_sdr_width);
411 `SDR_COLBITS : return extend(rg_cfg_colbits);
414 `SDR_CLK_DELAY : return extend(rg_cfg_sdr_clk_delay);
419 //(*preempts="(rl_pop_read_request, rl_send_rd_data, rl_send_read_data, rl_flush_redundant_data), rl_write_transaction_write_start"*)
421 rule rl_for_writing_ctrl_reg(ff_sync_ctrl_write.notFull);
422 let aw <- pop_o(s_xactor_cntrl_reg.o_wr_addr);
423 let w <- pop_o(s_xactor_cntrl_reg.o_wr_data);
424 `ifdef verbose $display($time,"\tSDRAM: control_reg written addr %x data %x", aw.awaddr, w.wdata); `endif
425 ff_sync_ctrl_write.enq(tuple2(aw.awaddr,w.wdata));
426 let w_resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, buser: 0, bid: aw.awid};
427 s_xactor_cntrl_reg.i_wr_resp.enq(w_resp);
430 rule rl_perform_write_to_ctrl(ff_sync_ctrl_write.notEmpty);
431 let {awaddr,wdata}=ff_sync_ctrl_write.first;
432 `ifdef verbose $display("\tSDRAM: "); `endif
433 ff_sync_ctrl_write.deq;
434 `ifdef verbose $display($time,"\tSDRAM: Actually writing data: %h to addr: %h", wdata, awaddr); `endif
435 fn_wr_cntrl_reg(wdata , truncate(awaddr));
438 rule rl_for_read_cntrl_reg;
439 let ar <- pop_o(s_xactor_cntrl_reg.o_rd_addr);
440 ff_sync_ctrl_read.enq(ar.araddr);
441 rg_ctrl_rid<=ar.arid;
444 rule rl_send_ctrl_read_response(ff_sync_ctrl_read.notEmpty);
445 ff_sync_ctrl_read_response.enq(fn_rd_cntrl_reg(truncate(ff_sync_ctrl_read.first)));
446 ff_sync_ctrl_read.deq;
449 rule sync_ctr_response(ff_sync_ctrl_read_response.notEmpty);
450 ff_sync_ctrl_read_response.deq;
451 let r = AXI4_Rd_Data {rresp: AXI4_OKAY, rdata:ff_sync_ctrl_read_response.first , rlast: True, ruser: 0, rid: rg_ctrl_rid};
452 s_xactor_cntrl_reg.i_rd_data.enq(r);
455 rule rl_direct_connection_insdram;
456 sdr_cntrl.iapp_req(rg_app_req);
457 sdr_cntrl.iapp_req_wrap(rg_app_req_wrap);
458 sdr_cntrl.iapp_req_addr(rg_app_req_addr);
459 sdr_cntrl.iapp_req_len(rg_app_req_len);
460 sdr_cntrl.iapp_req_wr_n(rg_app_req_wr_n);
461 sdr_cntrl.iapp_wr_data(rg_app_wr_data);
462 sdr_cntrl.iapp_wr_en_n(rg_app_wr_en_n);
465 rule rl_direct_connection_outsdram;
466 wr_sdr_init_done <= sdr_cntrl.osdr_init_done ;
467 wr_app_req_ack <= sdr_cntrl.oapp_req_ack ();
468 wr_app_wr_next_req <= sdr_cntrl.oapp_wr_next_req ();
469 wr_app_rd_valid <= sdr_cntrl.oapp_rd_valid ();
470 wr_app_last_rd <= sdr_cntrl.oapp_last_rd ();
471 wr_app_last_wr <= sdr_cntrl.oapp_last_wr ();
472 wr_app_rd_data <= sdr_cntrl.oapp_rd_data ();
475 rule rl_direct_connection_config_reg;
476 sdr_cntrl.icfg_sdr_tras_d(rg_cfg_sdr_tras_d);
477 sdr_cntrl.icfg_sdr_trp_d(rg_cfg_sdr_trp_d);
478 sdr_cntrl.icfg_sdr_trcd_d(rg_cfg_sdr_trcd_d);
479 sdr_cntrl.icfg_sdr_en(rg_cfg_sdr_en);
480 sdr_cntrl.icfg_req_depth(rg_cfg_req_depth);
481 sdr_cntrl.icfg_sdr_mode_reg(rg_cfg_sdr_mode_reg);
482 sdr_cntrl.icfg_sdr_cas(rg_cfg_sdr_cas);
483 sdr_cntrl.icfg_sdr_trcar_d(rg_cfg_sdr_trcar_d);
484 sdr_cntrl.icfg_sdr_twr_d(rg_cfg_sdr_twr_d);
485 sdr_cntrl.icfg_sdr_rfsh(rg_cfg_sdr_rfsh);
486 sdr_cntrl.icfg_sdr_rfmax(rg_cfg_sdr_rfmax);
487 sdr_cntrl.icfg_sdr_width(rg_cfg_sdr_width);
488 sdr_cntrl.icfg_colbits(rg_cfg_colbits);
491 rule rl_intial_polling(rg_polling_status_clk0 == False && wr_sdr_init_done == True);
492 `ifdef verbose $display($time,"\tSDRAM: POLLING MODE: %d",rg_poll_cnt); `endif
496 rg_app_req_addr <= 0;
498 rg_app_req_wr_n <= 0;
499 rg_app_wr_en_n <= 'hFF;
501 rg_poll_cnt <= rg_poll_cnt + 1;
505 rg_app_req_addr <= 0;
507 rg_app_req_wr_n <= 0;
508 rg_app_wr_en_n <= 'hFF;
510 rg_poll_cnt <= rg_poll_cnt + 1;
514 rg_app_req_addr <= 0;
515 rg_app_wr_en_n <= 'hFF;
517 if(wr_app_wr_next_req == True)
518 rg_poll_cnt <= rg_poll_cnt + 1;
521 rg_polling_status <= True;
522 rg_polling_status_clk0<=True;
527 /******************* WRITE TRANSACTION ****************/
529 rule rl_parallel_data_enq(rg_polling_status == True && rg_rd_trnc_flg == False);
530 let aw <- pop_o(s_xactor_sdram.o_wr_addr);
531 let w <- pop_o(s_xactor_sdram.o_wr_data);
534 rg_wr_trnc_flg <= True;
535 `ifdef verbose $display($time,"\tSDRAM: WRITE_FIRST Parallel enq %h addr: %h",w.wdata,aw.awaddr); `endif
538 rule rl_write_split_state(rg_wr_split_states == IDLE);
539 let aw = ff_wr_addr.first();
540 if(aw.awsize != 3) begin
541 rg_actual_wr_length <= fn_wr_len(aw.awlen, aw.awsize, aw.awaddr[2:0]);
543 rg_local_actual_wr_length <= extend(aw.awlen);
546 rg_actual_wr_length <= extend(aw.awlen) + 1;
547 rg_local_actual_wr_length <= extend(aw.awlen);
550 rg_awsize <= aw.awsize;
551 rg_awsize_sclk <= aw.awsize;
552 rg_wr_address <= aw.awaddr;
553 rg_wr_lwr_addr <= extend(aw.awaddr[2:0]);
554 rg_wr_split_states <= START_SPLIT;
555 rg_packets <= (aw.awsize==0)?7:(aw.awsize==1)?3:(aw.awsize == 2)? 1 : (aw.awsize == 3) ? 0 : 0; //(64 >> (aw.awsize+4)); //1 << ~aw.awsize[1:0];
556 rg_packet_counter <= (aw.awaddr[2:0]) >> aw.awsize;
557 `ifdef verbose $display($time,"Initial Values -- Starting IDLE to START_SPLIT"); `endif
558 //$display("Initial Values: rg_packets: %h rg_packet_counter: %h ",(64>>(aw.awsize+4)),aw.awaddr[2:0]>>aw.awsize);
559 rg_burst_counter <= 0;
563 rule rl_write_data_splitting0(rg_wr_split_states == START_SPLIT && rg_awsize != 3);
564 rg_wr_ac_data <= rg_wr_ac_data | fn_wr_split_data(ff_wr_data.first.wdata,ff_wr_data.first.wstrb);
565 rg_wr_ac_wstrb <= rg_wr_ac_wstrb | ff_wr_data.first.wstrb;
566 rg_burst_counter <= rg_burst_counter + 1;
567 `ifdef verbose $display($time,"burst_eq: %h rg_packets: %h rg_packet_counter: %d rg_burst_counter: %d rg_local_actual_wr_length %d rg_wr_ac_data %h rg_wr_ac_wstrb %b",burst_eq,rg_packets,rg_packet_counter,rg_burst_counter,rg_local_actual_wr_length, fn_wr_split_data(ff_wr_data.first.wdata,ff_wr_data.first.wstrb), ff_wr_data.first.wstrb); `endif
568 if(burst_eq || rg_packets == rg_packet_counter) begin
569 rg_wr_split_states <= SEND_VALUE;
572 rg_packet_counter <= rg_packet_counter + 1;
578 rule rl_write_data_splitting1(rg_wr_split_states == SEND_VALUE && rg_awsize != 3);
579 `ifdef verbose $display($stime,"Splitting1 Enqueued data rg_wr_ac_data %h rg_wr_ac_wstrb %b", rg_wr_ac_data, rg_wr_ac_wstrb); `endif
580 ff_ac_wr_data.enq(rg_wr_ac_data);
581 ff_ac_wr_wstrb.enq(rg_wr_ac_wstrb);
585 rg_packet_counter <= 0;
586 `ifdef verbose $display($time,"Sending Value to the SDRAM"); `endif
587 rg_wr_split_states <= START_SPLIT;
591 rule rl_write_data_spliting3(rg_wr_split_states == START_SPLIT && rg_awsize == 3);
592 ff_ac_wr_data.enq(ff_wr_data.first.wdata);
593 ff_ac_wr_wstrb.enq(ff_wr_data.first.wstrb);
599 rule rl_start_write_transaction(rg_write_states == IDLE && wr_sdr_init_done == True);
600 if(ff_ac_wr_data.notEmpty()) begin
601 if(rg_awsize_sclk == 0)
602 rg_write_states <= WAIT_DELAY;
604 rg_write_states <= WRITE_START;
605 `ifdef verbose $display($time,"\tSDRAM: Going to write start state"); `endif
609 rule rl_wait_delay(rg_write_states == WAIT_DELAY);
610 if(rg_delay_count == 14) begin
611 rg_write_states <= WRITE_START;
615 rg_delay_count <= rg_delay_count + 1;
618 rule rl_write_transaction_write_start(rg_write_states == WRITE_START && wr_sdr_init_done == True && rg_read_states == IDLE);
619 `ifdef verbose $display($time,"\tSDRAM: WRITE_START state Controller Length %d",rg_actual_wr_length); `endif
621 rg_app_req_addr <= fn_wr_address(rg_wr_address);
622 rg_app_req_len <= extend(rg_actual_wr_length);
623 rg_app_req_wr_n <= 0;
625 rg_app_wr_en_n <= 8'hFF;
626 rg_write_states <= WRITE_FIRST;
627 rg_delay_count <= extend(rg_actual_wr_length) - 1;
630 rule rl_write_transaction_write_first(rg_write_states == WRITE_FIRST && wr_app_wr_next_req == False);
631 `ifdef verbose $display($time,"\tSDRAM: WRITE_FIRST state next is false data %x",ff_ac_wr_data.first); `endif
633 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
634 rg_app_wr_data <= ff_ac_wr_data.first();
637 rule rl_write_transaction_write_data(rg_write_states == WRITE_FIRST && wr_app_wr_next_req == True);
638 `ifdef verbose $display($time,"\tSDRAM: WRITE_DATA state next is true sending data %x %b",ff_ac_wr_data.first,wr_app_wr_next_req); `endif
640 rg_app_wr_data <= ff_ac_wr_data.first();
641 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
644 rg_delay_count <= rg_delay_count - 1;
645 if(rg_delay_count == 0) begin
646 rg_write_states <= IDLE;
647 ff_sync_write_response.enq(True);
651 rule synchronize_write_response(ff_sync_write_response.notEmpty);
652 ff_sync_write_response.deq;
653 let w_resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, buser: 0, bid: rg_wid}; //TODO user value is null
654 s_xactor_sdram.i_wr_resp.enq(w_resp);
655 rg_wr_split_states <= IDLE;
657 rg_wr_trnc_flg <= False;
658 `ifdef verbose $display($time,"\tSDRAM: WRITE complete state true"); `endif
661 /****************** Read Transaction ********************/
663 // rule display_read_states;
664 // $display($time,"\tSDRAM: Read State: ",fshow(rg_read_states));
667 rule rl_paralel_read_req_enq(rg_polling_status == True && rg_wr_trnc_flg == False);
668 let ar <- pop_o(s_xactor_sdram.o_rd_addr);
670 rg_rd_trnc_flg <= True;
671 `ifdef verbose $display($time,"\tSDRAM: Got Read request from AXI for AddresS: %h",ar.araddr); `endif
674 rule rl_read_idle_state(rg_read_states == IDLE);
675 if(ff_rd_addr.notEmpty() == True) begin
676 rg_read_states <= START_READ;
677 rg_rd_not_active_flag <= 0;
678 `ifdef verbose $display($time,"\tSDRAM: READ IDLE state"); `endif
683 rule rl_pop_read_request(wr_sdr_init_done == True && rg_read_states == START_READ && (rg_write_states == IDLE || rg_write_states == WRITE_START));
684 let ar = ff_rd_addr.first;
685 `ifdef verbose $display($time,"\tSDRAM: STAR_READ state ar.arlen %d ar.arsize %d ar.araddr %h ar.arburst %b", ar.arlen,ar.arsize, ar.araddr, ar.arburst); `endif
689 rg_app_req_wrap <= 1;
691 rg_app_req_wrap <= 0;
692 rg_lwraddr <= extend(ar.araddr[2:0]);
693 rg_arsize <= ar.arsize;
694 rg_app_req_addr <= fn_wr_address(ar.araddr);
695 rg_app_req_len <= fn_wr_len(ar.arlen, ar.arsize, ar.araddr[2:0]);
696 rg_rd_actual_len <= extend(ar.arlen);
697 rg_app_req_wr_n <= 1;
699 rg_read_states <= READ_DATA;
701 `ifdef verbose $display($time,"\t SSSSS SDRAM START_READ length "); `endif
704 rule rl_send_rd_data(wr_app_rd_valid == True);
705 `ifdef verbose $display($time,"\tSDRAM: READ DATA1 state %x",wr_app_rd_data); `endif
706 ff_rd_data.enq(wr_app_rd_data);
709 rule rl_send_read_data(rg_read_states==READ_DATA);
710 `ifdef verbose $display($time,"\tSDRAM: Response from BFM. RequestLenght: %d CurrentCount: %d",rg_rd_actual_len,rg_delay_count); `endif
711 rg_app_req_wrap <= 0;
712 if(rg_lwraddr < 8) begin
713 let r = AXI4_Rd_Data {rresp: AXI4_OKAY, rdata: fn_rd_data(rg_arsize, rg_lwraddr, ff_rd_data.first), rlast: (rg_rd_actual_len == rg_delay_count), ruser: 0, rid: rg_rid};
714 ff_sync_read_response.enq(r);
717 rg_lwraddr <= rg_lwraddr + (1 << rg_arsize);
720 `ifdef verbose $display($time,"\tSDRAM: SENDING READ DATA : %h, rg_lwraddr %b rg_arsize %d", fn_rd_data(rg_arsize, rg_lwraddr, ff_rd_data.first),rg_lwraddr, rg_arsize); `endif
721 `ifdef verbose $display($time,"\tSDRAM: Removing Request for Addr : %h",ff_rd_addr.first.araddr); `endif
722 if(rg_delay_count == rg_rd_actual_len) begin
723 `ifdef verbose $display($time,"\tSDRAM: SENT ALL READ DATA state rg_delay_count %d rg_rd_actual_len %d", rg_delay_count, rg_rd_actual_len); `endif
724 rg_read_states <= READ_FLUSH;
725 rg_rd_not_active_flag <= 1;
729 rg_delay_count <= rg_delay_count + 1;
731 else if(rg_lwraddr > 7) begin
732 `ifdef verbose $display($time,"\tSDRAM: Dequeuing ff READ"); `endif
738 rule rl_flush_redundant_data(rg_read_states == READ_FLUSH);
740 rg_read_states <= IDLE;
743 rule send_synchronized_read_response(ff_sync_read_response.notEmpty);
744 let r=ff_sync_read_response.first;
745 `ifdef verbose $display($time,"\tSDRAM: Sending Read response: %h rlast: %b",r.rdata,r.rlast); `endif
746 ff_sync_read_response.deq;
747 if(rg_rd_not_active_flag == 1)
748 rg_rd_trnc_flg <= False;
749 s_xactor_sdram.i_rd_data.enq(r);
756 interface Ifc_sdram_out ifc_sdram_out;
758 interface ipad_sdr_din = interface Put
759 method Action put(Bit#(64) in)
760 sdr_cntrl.ipad_sdr_din <= in;
764 interface osdr_dout = interface Get
765 method ActionValue#(Bit#(64)) get;
766 return sdr_cntrl.osdr_dout();
770 interface osdr_den_n = interface Get
771 method ActionValue#(Bit#(64)) get;
773 for (int i=0; i<8; i=i+1) begin
774 temp[i*8] = sdr_cntrl.osdr_den_n[i];
780 interface osdr_cke = interface Get
781 method ActionValue#(Bit#(1)) get;
782 return pack(sdr_cntrl.osdr_cke());
786 interface osdr_cs_n = interface Get
787 method ActionValue#(Bit#(1)) get;
788 return pack(sdr_cntrl.osdr_cs_n());
792 interface osdr_ras_n = interface Get
793 method ActionValue#(Bit#(1)) get;
794 return pack(sdr_cntrl.osdr_ras_n);
798 interface osdr_cas_n = interface Get
799 method ActionValue#(Bit#(1)) get;
800 return pack(sdr_cntrl.osdr_cas_n);
804 interface osdr_we_n = interface Get
805 method ActionValue#(Bit#(1)) get;
806 return pack(sdr_cntrl.osdr_we_n);
810 interface osdr_dqm = interface Get
811 method ActionValue#(Bit#(8)) get;
812 return sdr_cntrl.osdr_dqm;
816 interface osdr_ba = interface Get
817 method ActionValue#(Bit#(2)) get;
818 return sdr_cntrl.osdr_ba;
822 interface osdr_addr = interface Get
823 method ActionValue#(Bit#(13)) get;
824 return sdr_cntrl.osdr_addr;
828 interface osdr_clock = interface Get
829 method ActionValue#(Bit#(1)) get;
835 interface axi4_slave_sdram = s_xactor_sdram.axi_side;
836 interface axi4_slave_cntrl_reg = s_xactor_cntrl_reg.axi_side;