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_SDIO_CTRL 8'h70
35 `define SDR_CLK_DELAY 8'h78
40 import Semi_FIFOF :: *;
41 import AXI4_Types :: *;
42 import AXI4_Fabric :: *;
43 import bsvmksdrc_top :: *;
45 import Connectable ::*;
51 interface Ifc_sdram_out;
52 (*always_enabled, always_ready*)
53 interface Put#(Bit#(64)) ipad_sdr_din;
54 interface Get#(Bit#(64)) osdr_dout;
55 interface Get#(Bit#(64)) osdr_den_n;
56 interface Get#(Bit#(1)) osdr_cke;
57 interface Get#(Bit#(1)) osdr_cs_n;
58 interface Get#(Bit#(1)) osdr_ras_n;
59 interface Get#(Bit#(1)) osdr_cas_n;
60 interface Get#(Bit#(1)) osdr_we_n;
61 interface Get#(Bit#(8)) osdr_dqm;
62 interface Get#(Bit#(2)) osdr_ba;
63 interface Get#(Bit#(13)) osdr_addr;
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;
71 method Bit#(9) sdram_sdio_ctrl;
72 interface Clock sdram_clk;
82 } Write_state deriving(Bits, Eq, FShow);
89 } Read_state deriving(Bits, Eq,FShow);
95 } Write_split_states deriving(Bits, Eq, FShow);
99 function (Bit#(9)) fn_wr_len(Bit#(8) length, Bit#(3) awsize, Bit#(3) lwr_addr);
100 Bit#(3) w_packet = 0;
101 Bit#(9) s_length = 0;
105 w_packet = lwr_addr >> awsize;
106 s_length = ((zeroExtend(length) + zeroExtend(w_packet)) >> 3) + 1;
109 w_packet = lwr_addr >> awsize;
110 s_length = ((zeroExtend(length) + zeroExtend(w_packet)) >> 2) + 1;
111 //`ifdef verbose $display($time(),"\t SSSS w_packet %b s_lenght %h length %h", w_packet, s_length, length); `endif
114 //w_packet = lwr_addr >> awsize;
115 // s_length = ((s_length + w_packets) >> 1) + 1;
116 s_length = zeroExtend(length >> 1) + 1;
119 s_length = zeroExtend(length) + 1;
127 function Bit#(64) fn_wr_split_data(Bit#(64) data, Bit#(8) wstrb);
130 data0[7:0] = data[7:0];
135 data0[15:8] = data[15:8];
140 data0[23:16] = data[23:16];
145 data0[31:24] = data[31:24];
150 data0[39:32] = data[39:32];
155 data0[47:40] = data[47:40];
160 data0[55:48] = data[55:48];
165 data0[63:56] = data[63:56];
172 function Bit#(26) fn_wr_address(Bit#(`PADDR) address);
173 Bit#(29) sdr_addr = address[31:3];
174 return sdr_addr[25:0];
177 function Bit#(64) fn_rd_data(Bit#(3) bsize,Bit#(4) lwr_addr,Bit#(64) data);
183 return duplicate(data[7:0]);
186 return duplicate(data[15:8]);
189 return duplicate(data[23:16]);
192 return duplicate(data[31:24]);
195 return duplicate(data[39:32]);
198 return duplicate(data[47:40]);
201 return duplicate(data[55:48]);
204 return duplicate(data[63:56]);
212 return duplicate(data[15:0]);
215 return duplicate(data[31:16]);
218 return duplicate(data[47:32]);
221 return duplicate(data[63:48]);
229 return duplicate(data[31:0]);
232 return duplicate(data[63:32]);
249 module mksdr_axi4_slave#(Clock clk0) (Ifc_sdr_slave);
251 Reset rst0 <- mkAsyncResetFromCR (0, clk0);
253 Reg#(Bit#(9)) rg_delay_count <- mkReg(0,clocked_by clk0, reset_by rst0);
254 Reg#(Bit#(9)) rg_rd_actual_len <- mkReg(0,clocked_by clk0, reset_by rst0);
255 Reg#(bit) rg_app_req <- mkDReg(0,clocked_by clk0, reset_by rst0);
256 Reg#(bit) rg_app_req_wrap <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
257 Reg#(Bit#(26)) rg_app_req_addr <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
258 Reg#(Bit#(4)) rg_cfg_sdr_tras_d <- mkConfigReg(4'h4,clocked_by clk0, reset_by rst0);
259 Reg#(Bit#(4)) rg_cfg_sdr_trp_d <- mkConfigReg(4'h2,clocked_by clk0, reset_by rst0);
260 Reg#(Bit#(4)) rg_cfg_sdr_trcd_d <- mkConfigReg(4'h2,clocked_by clk0, reset_by rst0);
261 Reg#(bit) rg_cfg_sdr_en <- mkConfigReg(1'h0,clocked_by clk0, reset_by rst0);
262 Reg#(Bit#(2)) rg_cfg_req_depth <- mkConfigReg(2'h3,clocked_by clk0, reset_by rst0);
263 Reg#(Bit#(13)) rg_cfg_sdr_mode_reg <- mkConfigReg(13'h032,clocked_by clk0, reset_by rst0);
264 Reg#(Bit#(3)) rg_cfg_sdr_cas <- mkConfigReg(3'h3,clocked_by clk0, reset_by rst0);
265 Reg#(Bit#(4)) rg_cfg_sdr_trcar_d <- mkConfigReg(4'h7,clocked_by clk0, reset_by rst0);
266 Reg#(Bit#(4)) rg_cfg_sdr_twr_d <- mkConfigReg(4'h1,clocked_by clk0, reset_by rst0);
267 Reg#(Bit#(2)) rg_cfg_sdr_width <- mkConfigReg(2'b0,clocked_by clk0, reset_by rst0);
268 Reg#(Bit#(2)) rg_cfg_colbits <- mkConfigReg(2'b01,clocked_by clk0, reset_by rst0);
269 Reg#(Bit#(9)) rg_cfg_sdio_ctrl <- mkConfigReg(9'b000100011,clocked_by clk0, reset_by rst0);
270 Reg#(Bit#(8)) rg_cfg_sdr_clk_delay <- mkConfigReg(8'b00001000,clocked_by clk0, reset_by rst0);
272 Reg#(Bit#(`SDR_RFSH_TIMER_W )) rg_cfg_sdr_rfsh <- mkConfigReg(12'h100,clocked_by clk0, reset_by rst0);
273 Reg#(Bit#(`SDR_RFSH_ROW_CNT_W)) rg_cfg_sdr_rfmax <- mkConfigReg(3'h6,clocked_by clk0, reset_by rst0);
274 Reg#(Bit#(9)) rg_app_req_len <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
275 Reg#(Bit#(4)) rg_lwraddr <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
276 Reg#(Bit#(3)) rg_arsize <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
277 Reg#(bit) rg_app_req_wr_n <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
278 Reg#(Bit#(8)) rg_app_wr_en_n <- mkDWire(8'hFF,clocked_by clk0, reset_by rst0);
279 Reg#(Bit#(64)) rg_app_wr_data <- mkDWire(0,clocked_by clk0, reset_by rst0);
280 Wire#(Bool) wr_sdr_init_done <- mkDWire(False,clocked_by clk0, reset_by rst0);
281 Wire#(Bool) wr_app_req_ack <- mkDWire(False,clocked_by clk0, reset_by rst0);
282 Wire#(Bool) wr_app_wr_next_req <- mkDWire(False,clocked_by clk0, reset_by rst0);
283 Wire#(Bool) wr_app_rd_valid <- mkDWire(False,clocked_by clk0, reset_by rst0);
284 Wire#(Bool) wr_app_last_rd <- mkDWire(False,clocked_by clk0, reset_by rst0);
285 Wire#(Bool) wr_app_last_wr <- mkDWire(False,clocked_by clk0, reset_by rst0);
286 Wire#(Bit#(64)) wr_app_rd_data <- mkWire(clocked_by clk0, reset_by rst0);
289 Reg#(Bit#(4)) rg_rid <- mkReg(0, clocked_by clk0, reset_by rst0);
290 Reg#(bit) rg_rd_not_active_flag <- mkSyncRegToCC(0,clk0, rst0);
291 Reg#(Bit#(4)) rg_ctrl_rid <- mkReg(0);
292 Reg#(Bit#(4)) rg_wid <- mkReg(0);
294 Reg#(Write_split_states) rg_wr_split_states <- mkReg(IDLE);
295 Reg#(Bit#(3)) rg_awsize <- mkReg(0);
296 Reg#(Bit#(9)) rg_ac_count <- mkReg(0);
297 Reg#(Bit#(6)) rg_single_burst <- mkReg(0);
298 Reg#(Bit#(64)) rg_wr_ac_data <- mkReg(0);
299 Reg#(Bit#(8)) rg_wr_ac_wstrb <- mkReg(0);
300 Reg#(Bit#(4)) rg_wr_lwr_addr <- mkReg(0);
301 Reg#(Bit#(9)) rg_local_actual_wr_length <- mkReg(0);
302 Reg#(Bit#(9)) rg_actual_wr_length <- mkSyncRegFromCC(0,clk0);
303 Reg#(Bit#(32)) rg_wr_address <- mkSyncRegFromCC(0,clk0);
305 Reg#(Bit#(3)) rg_awsize_sclk <- mkSyncRegFromCC(0,clk0);
307 Reg#(Bit#(9)) rg_burst_counter <- mkReg(0);
309 Bool burst_eq = (rg_burst_counter == rg_local_actual_wr_length);
311 Reg#(Bit#(3)) rg_packets <- mkReg(0);
312 Reg#(Bit#(3)) rg_packet_counter <- mkReg(0);
315 Reg#(Write_state) rg_write_states <- mkReg(IDLE,clocked_by clk0, reset_by rst0);
316 Reg#(Read_state) rg_read_states <- mkReg(IDLE,clocked_by clk0, reset_by rst0);
318 FIFOF#(AXI4_Wr_Addr#(`PADDR,`USERSPACE)) ff_wr_addr <- mkSizedFIFOF(13);
319 FIFOF#(AXI4_Wr_Data#(`Reg_width)) ff_wr_data <- mkSizedFIFOF(13);
320 SyncFIFOIfc#(Bit#(`Reg_width)) ff_ac_wr_data <- mkSyncFIFOFromCC(13,clk0);
321 SyncFIFOIfc#(Bit#(8)) ff_ac_wr_wstrb <- mkSyncFIFOFromCC(13,clk0);
323 SyncFIFOIfc#(Bool) ff_sync_write_response<-mkSyncFIFOToCC(1,clk0,rst0);
325 //FIFOF#(AXI4_Rd_Addr#(`PADDR,`USERSPACE)) ff_rd_addr <- mkSizedFIFOF(3);
326 FIFOF#(Bit#(64)) ff_rd_data <- mkSizedFIFOF(86,clocked_by clk0, reset_by rst0);
327 SyncFIFOIfc#(AXI4_Rd_Addr#(`PADDR,`USERSPACE)) ff_rd_addr <- mkSyncFIFOFromCC(30,clk0);
328 SyncFIFOIfc#(AXI4_Rd_Data#(`Reg_width,`USERSPACE)) ff_sync_read_response <-mkSyncFIFOToCC(13,clk0,rst0);
330 SyncFIFOIfc#(Tuple2#(Bit#(`PADDR),Bit#(`Reg_width))) ff_sync_ctrl_write<- mkSyncFIFOFromCC(1,clk0);
331 SyncFIFOIfc#(Bit#(`PADDR)) ff_sync_ctrl_read<- mkSyncFIFOFromCC(1,clk0);
332 SyncFIFOIfc#(Bit#(`Reg_width)) ff_sync_ctrl_read_response<- mkSyncFIFOToCC(1,clk0,rst0);
335 Reg#(Bit#(2)) rg_poll_cnt <- mkReg(0,clocked_by clk0, reset_by rst0);
336 Reg#(Bool) rg_polling_status <- mkSyncRegToCC(False,clk0,rst0);
337 Reg#(Bool) rg_polling_status_clk0 <- mkReg(False,clocked_by clk0, reset_by rst0);
338 Reg#(Bool) rg_rd_trnc_flg <- mkReg(False);
339 Reg#(Bool) rg_wr_trnc_flg <- mkReg(False);
340 Reg#(bit) rg_odd_len <- mkReg(0);
342 AXI4_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor_sdram <- mkAXI4_Slave_Xactor;
343 AXI4_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor_cntrl_reg <- mkAXI4_Slave_Xactor;
344 Ifc_sdram sdr_cntrl <- mksdrc_top(clocked_by clk0, reset_by rst0);
346 function Action fn_wr_cntrl_reg(Bit#(64) data, Bit#(8) address);
350 `ACTPRE_DELAY : rg_cfg_sdr_tras_d <= data[3:0];
352 `PREACT_DELAY : rg_cfg_sdr_trp_d <= data[3:0];
354 `ACT_RW_DELAY : rg_cfg_sdr_trcd_d <= data[3:0];
356 `EN_SDRAM : rg_cfg_sdr_en <= data[0];
358 `MAX_REQ : rg_cfg_req_depth <= data[1:0];
360 `MODE_REG : rg_cfg_sdr_mode_reg <= data[12:0];
362 `CAS_LATNCY : rg_cfg_sdr_cas <= data[2:0];
364 `AUTO_REFRESH : rg_cfg_sdr_trcar_d <= data[3:0];
366 `RECRY_DELAY : rg_cfg_sdr_twr_d <= data[3:0];
368 `RFRSH_TIMER : rg_cfg_sdr_rfsh <= data[11:0];
370 `RFRSH_ROW_CNT : rg_cfg_sdr_rfmax <= data[2:0];
372 `SDR_WIDTH : rg_cfg_sdr_width <= data [1:0];
374 `SDR_COLBITS : rg_cfg_colbits <= data [1:0];
376 `SDR_SDIO_CTRL : rg_cfg_sdio_ctrl <= data [8:0];
378 `SDR_CLK_DELAY : rg_cfg_sdr_clk_delay <= data [7:0];
386 function Bit#(64) fn_rd_cntrl_reg(Bit#(8) address);
389 `ACTPRE_DELAY : return extend(rg_cfg_sdr_tras_d);
391 `PREACT_DELAY : return extend(rg_cfg_sdr_trp_d);
393 `ACT_RW_DELAY : return extend(rg_cfg_sdr_trcd_d);
395 `EN_SDRAM : return extend(rg_cfg_sdr_en);
397 `MAX_REQ : return extend(rg_cfg_req_depth);
399 `MODE_REG : return extend(rg_cfg_sdr_mode_reg);
401 `CAS_LATNCY : return extend(rg_cfg_sdr_cas);
403 `AUTO_REFRESH : return extend(rg_cfg_sdr_trcar_d);
405 `RECRY_DELAY : return extend(rg_cfg_sdr_twr_d);
407 `RFRSH_TIMER : return extend(rg_cfg_sdr_rfsh);
409 `RFRSH_ROW_CNT : return extend(rg_cfg_sdr_rfmax);
411 `SDR_INIT_DONE : return extend(pack(wr_sdr_init_done));
413 `SDR_WIDTH : return extend(rg_cfg_sdr_width);
415 `SDR_COLBITS : return extend(rg_cfg_colbits);
417 `SDR_SDIO_CTRL : return extend(rg_cfg_sdio_ctrl);
419 `SDR_CLK_DELAY : return extend(rg_cfg_sdr_clk_delay);
424 //(*preempts="(rl_pop_read_request, rl_send_rd_data, rl_send_read_data, rl_flush_redundant_data), rl_write_transaction_write_start"*)
426 rule rl_for_writing_ctrl_reg(ff_sync_ctrl_write.notFull);
427 let aw <- pop_o(s_xactor_cntrl_reg.o_wr_addr);
428 let w <- pop_o(s_xactor_cntrl_reg.o_wr_data);
429 `ifdef verbose $display($time,"\tSDRAM: control_reg written addr %x data %x", aw.awaddr, w.wdata); `endif
430 ff_sync_ctrl_write.enq(tuple2(aw.awaddr,w.wdata));
431 let w_resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, buser: 0, bid: aw.awid};
432 s_xactor_cntrl_reg.i_wr_resp.enq(w_resp);
435 rule rl_perform_write_to_ctrl(ff_sync_ctrl_write.notEmpty);
436 let {awaddr,wdata}=ff_sync_ctrl_write.first;
437 `ifdef verbose $display("\tSDRAM: "); `endif
438 ff_sync_ctrl_write.deq;
439 `ifdef verbose $display($time,"\tSDRAM: Actually writing data: %h to addr: %h", wdata, awaddr); `endif
440 fn_wr_cntrl_reg(wdata , truncate(awaddr));
443 rule rl_for_read_cntrl_reg;
444 let ar <- pop_o(s_xactor_cntrl_reg.o_rd_addr);
445 ff_sync_ctrl_read.enq(ar.araddr);
446 rg_ctrl_rid<=ar.arid;
449 rule rl_send_ctrl_read_response(ff_sync_ctrl_read.notEmpty);
450 ff_sync_ctrl_read_response.enq(fn_rd_cntrl_reg(truncate(ff_sync_ctrl_read.first)));
451 ff_sync_ctrl_read.deq;
454 rule sync_ctr_response(ff_sync_ctrl_read_response.notEmpty);
455 ff_sync_ctrl_read_response.deq;
456 let r = AXI4_Rd_Data {rresp: AXI4_OKAY, rdata:ff_sync_ctrl_read_response.first , rlast: True, ruser: 0, rid: rg_ctrl_rid};
457 s_xactor_cntrl_reg.i_rd_data.enq(r);
460 rule rl_direct_connection_insdram;
461 sdr_cntrl.iapp_req(rg_app_req);
462 sdr_cntrl.iapp_req_wrap(rg_app_req_wrap);
463 sdr_cntrl.iapp_req_addr(rg_app_req_addr);
464 sdr_cntrl.iapp_req_len(rg_app_req_len);
465 sdr_cntrl.iapp_req_wr_n(rg_app_req_wr_n);
466 sdr_cntrl.iapp_wr_data(rg_app_wr_data);
467 sdr_cntrl.iapp_wr_en_n(rg_app_wr_en_n);
470 rule rl_direct_connection_outsdram;
471 wr_sdr_init_done <= sdr_cntrl.osdr_init_done ;
472 wr_app_req_ack <= sdr_cntrl.oapp_req_ack ();
473 wr_app_wr_next_req <= sdr_cntrl.oapp_wr_next_req ();
474 wr_app_rd_valid <= sdr_cntrl.oapp_rd_valid ();
475 wr_app_last_rd <= sdr_cntrl.oapp_last_rd ();
476 wr_app_last_wr <= sdr_cntrl.oapp_last_wr ();
477 wr_app_rd_data <= sdr_cntrl.oapp_rd_data ();
480 rule rl_direct_connection_config_reg;
481 sdr_cntrl.icfg_sdr_tras_d(rg_cfg_sdr_tras_d);
482 sdr_cntrl.icfg_sdr_trp_d(rg_cfg_sdr_trp_d);
483 sdr_cntrl.icfg_sdr_trcd_d(rg_cfg_sdr_trcd_d);
484 sdr_cntrl.icfg_sdr_en(rg_cfg_sdr_en);
485 sdr_cntrl.icfg_req_depth(rg_cfg_req_depth);
486 sdr_cntrl.icfg_sdr_mode_reg(rg_cfg_sdr_mode_reg);
487 sdr_cntrl.icfg_sdr_cas(rg_cfg_sdr_cas);
488 sdr_cntrl.icfg_sdr_trcar_d(rg_cfg_sdr_trcar_d);
489 sdr_cntrl.icfg_sdr_twr_d(rg_cfg_sdr_twr_d);
490 sdr_cntrl.icfg_sdr_rfsh(rg_cfg_sdr_rfsh);
491 sdr_cntrl.icfg_sdr_rfmax(rg_cfg_sdr_rfmax);
492 sdr_cntrl.icfg_sdr_width(rg_cfg_sdr_width);
493 sdr_cntrl.icfg_colbits(rg_cfg_colbits);
496 rule rl_intial_polling(rg_polling_status_clk0 == False && wr_sdr_init_done == True);
497 `ifdef verbose $display($time,"\tSDRAM: POLLING MODE: %d",rg_poll_cnt); `endif
501 rg_app_req_addr <= 0;
503 rg_app_req_wr_n <= 0;
504 rg_app_wr_en_n <= 'hFF;
506 rg_poll_cnt <= rg_poll_cnt + 1;
510 rg_app_req_addr <= 0;
512 rg_app_req_wr_n <= 0;
513 rg_app_wr_en_n <= 'hFF;
515 rg_poll_cnt <= rg_poll_cnt + 1;
519 rg_app_req_addr <= 0;
520 rg_app_wr_en_n <= 'hFF;
522 if(wr_app_wr_next_req == True)
523 rg_poll_cnt <= rg_poll_cnt + 1;
526 rg_polling_status <= True;
527 rg_polling_status_clk0<=True;
532 /******************* WRITE TRANSACTION ****************/
534 rule rl_parallel_data_enq(rg_polling_status == True && rg_rd_trnc_flg == False);
535 let aw <- pop_o(s_xactor_sdram.o_wr_addr);
536 let w <- pop_o(s_xactor_sdram.o_wr_data);
539 rg_wr_trnc_flg <= True;
540 `ifdef verbose $display($time,"\tSDRAM: WRITE_FIRST Parallel enq %h addr: %h",w.wdata,aw.awaddr); `endif
543 rule rl_write_split_state(rg_wr_split_states == IDLE);
544 let aw = ff_wr_addr.first();
545 if(aw.awsize != 3) begin
546 rg_actual_wr_length <= fn_wr_len(aw.awlen, aw.awsize, aw.awaddr[2:0]);
548 rg_local_actual_wr_length <= extend(aw.awlen);
551 rg_actual_wr_length <= extend(aw.awlen) + 1;
552 rg_local_actual_wr_length <= extend(aw.awlen);
555 rg_awsize <= aw.awsize;
556 rg_awsize_sclk <= aw.awsize;
557 rg_wr_address <= aw.awaddr;
558 rg_wr_lwr_addr <= extend(aw.awaddr[2:0]);
559 rg_wr_split_states <= START_SPLIT;
560 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];
561 rg_packet_counter <= (aw.awaddr[2:0]) >> aw.awsize;
562 `ifdef verbose $display($time,"Initial Values -- Starting IDLE to START_SPLIT"); `endif
563 //$display("Initial Values: rg_packets: %h rg_packet_counter: %h ",(64>>(aw.awsize+4)),aw.awaddr[2:0]>>aw.awsize);
564 rg_burst_counter <= 0;
568 rule rl_write_data_splitting0(rg_wr_split_states == START_SPLIT && rg_awsize != 3);
569 rg_wr_ac_data <= rg_wr_ac_data | fn_wr_split_data(ff_wr_data.first.wdata,ff_wr_data.first.wstrb);
570 rg_wr_ac_wstrb <= rg_wr_ac_wstrb | ff_wr_data.first.wstrb;
571 rg_burst_counter <= rg_burst_counter + 1;
572 `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
573 if(burst_eq || rg_packets == rg_packet_counter) begin
574 rg_wr_split_states <= SEND_VALUE;
577 rg_packet_counter <= rg_packet_counter + 1;
583 rule rl_write_data_splitting1(rg_wr_split_states == SEND_VALUE && rg_awsize != 3);
584 `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
585 ff_ac_wr_data.enq(rg_wr_ac_data);
586 ff_ac_wr_wstrb.enq(rg_wr_ac_wstrb);
590 rg_packet_counter <= 0;
591 `ifdef verbose $display($time,"Sending Value to the SDRAM"); `endif
592 rg_wr_split_states <= START_SPLIT;
596 rule rl_write_data_spliting3(rg_wr_split_states == START_SPLIT && rg_awsize == 3);
597 ff_ac_wr_data.enq(ff_wr_data.first.wdata);
598 ff_ac_wr_wstrb.enq(ff_wr_data.first.wstrb);
604 rule rl_start_write_transaction(rg_write_states == IDLE && wr_sdr_init_done == True);
605 if(ff_ac_wr_data.notEmpty()) begin
606 if(rg_awsize_sclk == 0)
607 rg_write_states <= WAIT_DELAY;
609 rg_write_states <= WRITE_START;
610 `ifdef verbose $display($time,"\tSDRAM: Going to write start state"); `endif
614 rule rl_wait_delay(rg_write_states == WAIT_DELAY);
615 if(rg_delay_count == 14) begin
616 rg_write_states <= WRITE_START;
620 rg_delay_count <= rg_delay_count + 1;
623 rule rl_write_transaction_write_start(rg_write_states == WRITE_START && wr_sdr_init_done == True && rg_read_states == IDLE);
624 `ifdef verbose $display($time,"\tSDRAM: WRITE_START state Controller Length %d",rg_actual_wr_length); `endif
626 rg_app_req_addr <= fn_wr_address(rg_wr_address);
627 rg_app_req_len <= extend(rg_actual_wr_length);
628 rg_app_req_wr_n <= 0;
630 rg_app_wr_en_n <= 8'hFF;
631 rg_write_states <= WRITE_FIRST;
632 rg_delay_count <= extend(rg_actual_wr_length) - 1;
635 rule rl_write_transaction_write_first(rg_write_states == WRITE_FIRST && wr_app_wr_next_req == False);
636 `ifdef verbose $display($time,"\tSDRAM: WRITE_FIRST state next is false data %x",ff_ac_wr_data.first); `endif
638 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
639 rg_app_wr_data <= ff_ac_wr_data.first();
642 rule rl_write_transaction_write_data(rg_write_states == WRITE_FIRST && wr_app_wr_next_req == True);
643 `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
645 rg_app_wr_data <= ff_ac_wr_data.first();
646 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
649 rg_delay_count <= rg_delay_count - 1;
650 if(rg_delay_count == 0) begin
651 rg_write_states <= IDLE;
652 ff_sync_write_response.enq(True);
656 rule synchronize_write_response(ff_sync_write_response.notEmpty);
657 ff_sync_write_response.deq;
658 let w_resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, buser: 0, bid: rg_wid}; //TODO user value is null
659 s_xactor_sdram.i_wr_resp.enq(w_resp);
660 rg_wr_split_states <= IDLE;
662 rg_wr_trnc_flg <= False;
663 `ifdef verbose $display($time,"\tSDRAM: WRITE complete state true"); `endif
666 /****************** Read Transaction ********************/
668 // rule display_read_states;
669 // $display($time,"\tSDRAM: Read State: ",fshow(rg_read_states));
672 rule rl_paralel_read_req_enq(rg_polling_status == True && rg_wr_trnc_flg == False);
673 let ar <- pop_o(s_xactor_sdram.o_rd_addr);
675 rg_rd_trnc_flg <= True;
676 `ifdef verbose $display($time,"\tSDRAM: Got Read request from AXI for AddresS: %h",ar.araddr); `endif
679 rule rl_read_idle_state(rg_read_states == IDLE);
680 if(ff_rd_addr.notEmpty() == True) begin
681 rg_read_states <= START_READ;
682 rg_rd_not_active_flag <= 0;
683 `ifdef verbose $display($time,"\tSDRAM: READ IDLE state"); `endif
688 rule rl_pop_read_request(wr_sdr_init_done == True && rg_read_states == START_READ && (rg_write_states == IDLE || rg_write_states == WRITE_START));
689 let ar = ff_rd_addr.first;
690 `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
694 rg_app_req_wrap <= 1;
696 rg_app_req_wrap <= 0;
697 rg_lwraddr <= extend(ar.araddr[2:0]);
698 rg_arsize <= ar.arsize;
699 rg_app_req_addr <= fn_wr_address(ar.araddr);
700 rg_app_req_len <= fn_wr_len(ar.arlen, ar.arsize, ar.araddr[2:0]);
701 rg_rd_actual_len <= extend(ar.arlen);
702 rg_app_req_wr_n <= 1;
704 rg_read_states <= READ_DATA;
706 `ifdef verbose $display($time,"\t SSSSS SDRAM START_READ length "); `endif
709 rule rl_send_rd_data(wr_app_rd_valid == True);
710 `ifdef verbose $display($time,"\tSDRAM: READ DATA1 state %x",wr_app_rd_data); `endif
711 ff_rd_data.enq(wr_app_rd_data);
714 rule rl_send_read_data(rg_read_states==READ_DATA);
715 `ifdef verbose $display($time,"\tSDRAM: Response from BFM. RequestLenght: %d CurrentCount: %d",rg_rd_actual_len,rg_delay_count); `endif
716 rg_app_req_wrap <= 0;
717 if(rg_lwraddr < 8) begin
718 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};
719 ff_sync_read_response.enq(r);
722 rg_lwraddr <= rg_lwraddr + (1 << rg_arsize);
725 `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
726 `ifdef verbose $display($time,"\tSDRAM: Removing Request for Addr : %h",ff_rd_addr.first.araddr); `endif
727 if(rg_delay_count == rg_rd_actual_len) begin
728 `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
729 rg_read_states <= READ_FLUSH;
730 rg_rd_not_active_flag <= 1;
734 rg_delay_count <= rg_delay_count + 1;
736 else if(rg_lwraddr > 7) begin
737 `ifdef verbose $display($time,"\tSDRAM: Dequeuing ff READ"); `endif
743 rule rl_flush_redundant_data(rg_read_states == READ_FLUSH);
745 rg_read_states <= IDLE;
748 rule send_synchronized_read_response(ff_sync_read_response.notEmpty);
749 let r=ff_sync_read_response.first;
750 `ifdef verbose $display($time,"\tSDRAM: Sending Read response: %h rlast: %b",r.rdata,r.rlast); `endif
751 ff_sync_read_response.deq;
752 if(rg_rd_not_active_flag == 1)
753 rg_rd_trnc_flg <= False;
754 s_xactor_sdram.i_rd_data.enq(r);
761 interface Ifc_sdram_out ifc_sdram_out;
763 interface ipad_sdr_din = interface Put
764 method Action put(Bit#(64) in)
765 sdr_cntrl.ipad_sdr_din <= in;
769 interface osdr_dout = interface Get
770 method ActionValue#(Bit#(64)) get;
771 return sdr_cntrl.osdr_dout();
775 interface osdr_den_n = interface Get
776 method ActionValue#(Bit#(64)) get;
778 for (int i=0; i<8; i=i+1) begin
779 temp[i*8] = sdr_cntrl.osdr_den_n[i];
785 interface osdr_cke = interface Get
786 method ActionValue#(Bit#(1)) get;
787 return pack(sdr_cntrl.osdr_cke());
791 interface osdr_cs_n = interface Get
792 method ActionValue#(Bit#(1)) get;
793 return pack(sdr_cntrl.osdr_cs_n());
797 interface osdr_ras_n = interface Get
798 method ActionValue#(Bit#(1)) get;
799 return pack(sdr_cntrl.osdr_ras_n);
803 interface osdr_cas_n = interface Get
804 method ActionValue#(Bit#(1)) get;
805 return pack(sdr_cntrl.osdr_cas_n);
809 interface osdr_we_n = interface Get
810 method ActionValue#(Bit#(1)) get;
811 return pack(sdr_cntrl.osdr_we_n);
815 interface osdr_dqm = interface Get
816 method ActionValue#(Bit#(8)) get;
817 return sdr_cntrl.osdr_dqm;
821 interface osdr_ba = interface Get
822 method ActionValue#(Bit#(2)) get;
823 return sdr_cntrl.osdr_ba;
827 interface osdr_addr = interface Get
828 method ActionValue#(Bit#(13)) get;
829 return sdr_cntrl.osdr_addr;
835 interface sdram_clk = clk0;
836 method Bit#(9) sdram_sdio_ctrl();
837 return rg_cfg_sdio_ctrl;
840 interface axi4_slave_sdram = s_xactor_sdram.axi_side;
841 interface axi4_slave_cntrl_reg = s_xactor_cntrl_reg.axi_side;