181f6decb7ed0505ed49342bf03a81fe25f92c2e
[shakti-peripherals.git] / src / peripherals / sdram / sdr_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 `include "instance_defines.bsv"
16 `define DELAY 250
17 `define SDR_RFSH_TIMER_W 12
18 `define SDR_RFSH_ROW_CNT_W 3
19
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
24 `define MAX_REQ 8'h20
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
36 `define verbose
37
38 package sdr_top;
39
40 import Semi_FIFOF :: *;
41 import AXI4_Types :: *;
42 import AXI4_Fabric :: *;
43 import bsvmksdrc_top :: *;
44 import BUtils ::*;
45 import Connectable ::*;
46 import ConfigReg ::*;
47 import DReg::*;
48 import FIFOF::*;
49 import Clocks::*;
50
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;
64
65 endinterface
66
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;
73 endinterface
74
75 typedef enum{
76 IDLE,
77 WRITE_START,
78 WAIT_DELAY,
79 WRITE_FIRST,
80 WRITE_DATA0,
81 WRITE_DATA1
82 } Write_state deriving(Bits, Eq, FShow);
83
84 typedef enum{
85 IDLE,
86 START_READ,
87 READ_DATA,
88 READ_FLUSH
89 } Read_state deriving(Bits, Eq,FShow);
90
91 typedef enum {
92 IDLE,
93 START_SPLIT,
94 SEND_VALUE
95 } Write_split_states deriving(Bits, Eq, FShow);
96
97
98
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;
102 case(awsize)
103
104 'd0 : begin
105 w_packet = lwr_addr >> awsize;
106 s_length = ((zeroExtend(length) + zeroExtend(w_packet)) >> 3) + 1;
107 end
108 'd1: begin
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
112 end
113 'd2 : begin
114 //w_packet = lwr_addr >> awsize;
115 // s_length = ((s_length + w_packets) >> 1) + 1;
116 s_length = zeroExtend(length >> 1) + 1;
117 end
118 'd3 : begin
119 s_length = zeroExtend(length) + 1;
120 end
121 endcase
122
123 return s_length;
124 endfunction
125
126
127 function Bit#(64) fn_wr_split_data(Bit#(64) data, Bit#(8) wstrb);
128 Bit#(64) data0 = 0;
129 if(wstrb[0] == 1)
130 data0[7:0] = data[7:0];
131 else
132 data0[7:0] = 0;
133
134 if(wstrb[1] == 1)
135 data0[15:8] = data[15:8];
136 else
137 data0[15:8] = 0;
138
139 if(wstrb[2] == 1)
140 data0[23:16] = data[23:16];
141 else
142 data0[23:16] = 0;
143
144 if(wstrb[3] == 1)
145 data0[31:24] = data[31:24];
146 else
147 data0[31:24] = 0;
148
149 if(wstrb[4] == 1)
150 data0[39:32] = data[39:32];
151 else
152 data0[39:32] = 0;
153
154 if(wstrb[5] == 1)
155 data0[47:40] = data[47:40];
156 else
157 data0[47:40] = 0;
158
159 if(wstrb[6] == 1)
160 data0[55:48] = data[55:48];
161 else
162 data0[55:48] = 0;
163
164 if(wstrb[7] == 1)
165 data0[63:56] = data[63:56];
166 else
167 data0[63:56] = 0;
168
169 return data0;
170 endfunction
171
172 function Bit#(26) fn_wr_address(Bit#(`PADDR) address);
173 Bit#(29) sdr_addr = address[31:3];
174 return sdr_addr[25:0];
175 endfunction
176
177 function Bit#(64) fn_rd_data(Bit#(3) bsize,Bit#(4) lwr_addr,Bit#(64) data);
178
179 case(bsize)
180 'b000: begin
181 case(lwr_addr)
182 'b000: begin
183 return duplicate(data[7:0]);
184 end
185 'b001: begin
186 return duplicate(data[15:8]);
187 end
188 'b010: begin
189 return duplicate(data[23:16]);
190 end
191 'b011: begin
192 return duplicate(data[31:24]);
193 end
194 'b100: begin
195 return duplicate(data[39:32]);
196 end
197 'b101: begin
198 return duplicate(data[47:40]);
199 end
200 'b110: begin
201 return duplicate(data[55:48]);
202 end
203 'b111: begin
204 return duplicate(data[63:56]);
205 end
206 endcase
207 end
208
209 'b001: begin
210 case(lwr_addr)
211 'b000: begin
212 return duplicate(data[15:0]);
213 end
214 'b010: begin
215 return duplicate(data[31:16]);
216 end
217 'b100: begin
218 return duplicate(data[47:32]);
219 end
220 'b110: begin
221 return duplicate(data[63:48]);
222 end
223 endcase
224 end
225
226 'b010: begin
227 case(lwr_addr)
228 'b000: begin
229 return duplicate(data[31:0]);
230 end
231 'b100: begin
232 return duplicate(data[63:32]);
233 end
234 endcase
235 end
236
237 'b011: begin
238 return data;
239 end
240 endcase
241 endfunction
242
243
244
245
246
247 (*synthesize*)
248
249 module mksdr_axi4_slave#(Clock clk0) (Ifc_sdr_slave);
250
251 Reset rst0 <- mkAsyncResetFromCR (0, clk0);
252
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);
271
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);
287
288
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);
293
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);
304
305 Reg#(Bit#(3)) rg_awsize_sclk <- mkSyncRegFromCC(0,clk0);
306
307 Reg#(Bit#(9)) rg_burst_counter <- mkReg(0);
308
309 Bool burst_eq = (rg_burst_counter == rg_local_actual_wr_length);
310
311 Reg#(Bit#(3)) rg_packets <- mkReg(0);
312 Reg#(Bit#(3)) rg_packet_counter <- mkReg(0);
313
314
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);
317
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);
322
323 SyncFIFOIfc#(Bool) ff_sync_write_response<-mkSyncFIFOToCC(1,clk0,rst0);
324
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);
329
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);
333
334 // Polling Registers
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);
341
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);
345
346 function Action fn_wr_cntrl_reg(Bit#(64) data, Bit#(8) address);
347 action
348 case(address)
349
350 `ACTPRE_DELAY : rg_cfg_sdr_tras_d <= data[3:0];
351
352 `PREACT_DELAY : rg_cfg_sdr_trp_d <= data[3:0];
353
354 `ACT_RW_DELAY : rg_cfg_sdr_trcd_d <= data[3:0];
355
356 `EN_SDRAM : rg_cfg_sdr_en <= data[0];
357
358 `MAX_REQ : rg_cfg_req_depth <= data[1:0];
359
360 `MODE_REG : rg_cfg_sdr_mode_reg <= data[12:0];
361
362 `CAS_LATNCY : rg_cfg_sdr_cas <= data[2:0];
363
364 `AUTO_REFRESH : rg_cfg_sdr_trcar_d <= data[3:0];
365
366 `RECRY_DELAY : rg_cfg_sdr_twr_d <= data[3:0];
367
368 `RFRSH_TIMER : rg_cfg_sdr_rfsh <= data[11:0];
369
370 `RFRSH_ROW_CNT : rg_cfg_sdr_rfmax <= data[2:0];
371
372 `SDR_WIDTH : rg_cfg_sdr_width <= data [1:0];
373
374 `SDR_COLBITS : rg_cfg_colbits <= data [1:0];
375
376 `SDR_SDIO_CTRL : rg_cfg_sdio_ctrl <= data [8:0];
377
378 `SDR_CLK_DELAY : rg_cfg_sdr_clk_delay <= data [7:0];
379
380 default : noAction;
381 endcase
382 endaction
383 endfunction
384
385
386 function Bit#(64) fn_rd_cntrl_reg(Bit#(8) address);
387 case(address)
388
389 `ACTPRE_DELAY : return extend(rg_cfg_sdr_tras_d);
390
391 `PREACT_DELAY : return extend(rg_cfg_sdr_trp_d);
392
393 `ACT_RW_DELAY : return extend(rg_cfg_sdr_trcd_d);
394
395 `EN_SDRAM : return extend(rg_cfg_sdr_en);
396
397 `MAX_REQ : return extend(rg_cfg_req_depth);
398
399 `MODE_REG : return extend(rg_cfg_sdr_mode_reg);
400
401 `CAS_LATNCY : return extend(rg_cfg_sdr_cas);
402
403 `AUTO_REFRESH : return extend(rg_cfg_sdr_trcar_d);
404
405 `RECRY_DELAY : return extend(rg_cfg_sdr_twr_d);
406
407 `RFRSH_TIMER : return extend(rg_cfg_sdr_rfsh);
408
409 `RFRSH_ROW_CNT : return extend(rg_cfg_sdr_rfmax);
410
411 `SDR_INIT_DONE : return extend(pack(wr_sdr_init_done));
412
413 `SDR_WIDTH : return extend(rg_cfg_sdr_width);
414
415 `SDR_COLBITS : return extend(rg_cfg_colbits);
416
417 `SDR_SDIO_CTRL : return extend(rg_cfg_sdio_ctrl);
418
419 `SDR_CLK_DELAY : return extend(rg_cfg_sdr_clk_delay);
420
421 endcase
422 endfunction
423
424 //(*preempts="(rl_pop_read_request, rl_send_rd_data, rl_send_read_data, rl_flush_redundant_data), rl_write_transaction_write_start"*)
425
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);
433 endrule
434
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));
441 endrule
442
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;
447 endrule
448
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;
452 endrule
453
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);
458 endrule
459
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);
468 endrule
469
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 ();
478 endrule
479
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);
494 endrule
495
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
498 case (rg_poll_cnt)
499 0: begin
500 rg_app_req <= 1;
501 rg_app_req_addr <= 0;
502 rg_app_req_len <= 1;
503 rg_app_req_wr_n <= 0;
504 rg_app_wr_en_n <= 'hFF;
505 rg_app_wr_data <= 0;
506 rg_poll_cnt <= rg_poll_cnt + 1;
507 end
508 1: begin
509 rg_app_req <= 1;
510 rg_app_req_addr <= 0;
511 rg_app_req_len <= 1;
512 rg_app_req_wr_n <= 0;
513 rg_app_wr_en_n <= 'hFF;
514 rg_app_wr_data <= 0;
515 rg_poll_cnt <= rg_poll_cnt + 1;
516 end
517 2: begin
518 rg_app_req <= 0;
519 rg_app_req_addr <= 0;
520 rg_app_wr_en_n <= 'hFF;
521 rg_app_wr_data <= 0;
522 if(wr_app_wr_next_req == True)
523 rg_poll_cnt <= rg_poll_cnt + 1;
524 end
525 3: begin
526 rg_polling_status <= True;
527 rg_polling_status_clk0<=True;
528 end
529 endcase
530 endrule
531
532 /******************* WRITE TRANSACTION ****************/
533
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);
537 ff_wr_addr.enq(aw);
538 ff_wr_data.enq(w);
539 rg_wr_trnc_flg <= True;
540 `ifdef verbose $display($time,"\tSDRAM: WRITE_FIRST Parallel enq %h addr: %h",w.wdata,aw.awaddr); `endif
541 endrule
542
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]);
547
548 rg_local_actual_wr_length <= extend(aw.awlen);
549 end
550 else begin
551 rg_actual_wr_length <= extend(aw.awlen) + 1;
552 rg_local_actual_wr_length <= extend(aw.awlen);
553 end
554 rg_wid <= aw.awid;
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;
565 endrule
566
567
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;
575 end
576 else begin
577 rg_packet_counter <= rg_packet_counter + 1;
578 end
579 ff_wr_data.deq();
580 ff_wr_addr.deq();
581 endrule
582
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);
587 rg_wr_ac_data <= 0;
588 rg_wr_ac_wstrb <= 0;
589 rg_wr_lwr_addr <= 0;
590 rg_packet_counter <= 0;
591 `ifdef verbose $display($time,"Sending Value to the SDRAM"); `endif
592 rg_wr_split_states <= START_SPLIT;
593 endrule
594
595
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);
599 ff_wr_data.deq();
600 ff_wr_addr.deq();
601 endrule
602
603
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;
608 else
609 rg_write_states <= WRITE_START;
610 `ifdef verbose $display($time,"\tSDRAM: Going to write start state"); `endif
611 end
612 endrule
613
614 rule rl_wait_delay(rg_write_states == WAIT_DELAY);
615 if(rg_delay_count == 14) begin
616 rg_write_states <= WRITE_START;
617 rg_delay_count <= 0;
618 end
619 else
620 rg_delay_count <= rg_delay_count + 1;
621 endrule
622
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
625 rg_app_req <= 1;
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;
629 rg_app_wr_data <= 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;
633 endrule
634
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
637 rg_app_req <= 0;
638 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
639 rg_app_wr_data <= ff_ac_wr_data.first();
640 endrule
641
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
644 rg_app_req <= 0;
645 rg_app_wr_data <= ff_ac_wr_data.first();
646 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
647 ff_ac_wr_data.deq;
648 ff_ac_wr_wstrb.deq;
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);
653 end
654 endrule
655
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;
661 rg_ac_count <= 0;
662 rg_wr_trnc_flg <= False;
663 `ifdef verbose $display($time,"\tSDRAM: WRITE complete state true"); `endif
664 endrule
665
666 /****************** Read Transaction ********************/
667 // `ifdef verbose
668 // rule display_read_states;
669 // $display($time,"\tSDRAM: Read State: ",fshow(rg_read_states));
670 // endrule
671 // `endif
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);
674 ff_rd_addr.enq(ar);
675 rg_rd_trnc_flg <= True;
676 `ifdef verbose $display($time,"\tSDRAM: Got Read request from AXI for AddresS: %h",ar.araddr); `endif
677 endrule
678
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
684 end
685
686 endrule
687
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
691
692 rg_app_req <= 1;
693 if(ar.arburst == 2)
694 rg_app_req_wrap <= 1;
695 else
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;
703 rg_delay_count <= 0;
704 rg_read_states <= READ_DATA;
705 rg_rid <= ar.arid;
706 `ifdef verbose $display($time,"\t SSSSS SDRAM START_READ length "); `endif
707 endrule
708
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);
712 endrule
713
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);
720 ff_rd_addr.deq;
721 if(rg_arsize!=3)
722 rg_lwraddr <= rg_lwraddr + (1 << rg_arsize);
723 else
724 ff_rd_data.deq;
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;
731 rg_delay_count <= 0;
732 end
733 else
734 rg_delay_count <= rg_delay_count + 1;
735 end
736 else if(rg_lwraddr > 7) begin
737 `ifdef verbose $display($time,"\tSDRAM: Dequeuing ff READ"); `endif
738 rg_lwraddr <= 0;
739 ff_rd_data.deq;
740 end
741 endrule
742
743 rule rl_flush_redundant_data(rg_read_states == READ_FLUSH);
744 ff_rd_data.clear();
745 rg_read_states <= IDLE;
746 endrule
747
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);
755 endrule
756
757
758
759
760
761 interface Ifc_sdram_out ifc_sdram_out;
762
763 interface ipad_sdr_din = interface Put
764 method Action put(Bit#(64) in)
765 sdr_cntrl.ipad_sdr_din <= in;
766 endmethod
767 endinterface;
768
769 interface osdr_dout = interface Get
770 method ActionValue#(Bit#(64)) get;
771 return sdr_cntrl.osdr_dout();
772 endmethod
773 endinterface;
774
775 interface osdr_den_n = interface Get
776 method ActionValue#(Bit#(64)) get;
777 Bit#(64) temp;
778 for (int i=0; i<8; i=i+1) begin
779 temp[i*8] = sdr_cntrl.osdr_den_n[i];
780 end
781 return temp;
782 endmethod
783 endinterface;
784
785 interface osdr_cke = interface Get
786 method ActionValue#(Bit#(1)) get;
787 return pack(sdr_cntrl.osdr_cke());
788 endmethod
789 endinterface;
790
791 interface osdr_cs_n = interface Get
792 method ActionValue#(Bit#(1)) get;
793 return pack(sdr_cntrl.osdr_cs_n());
794 endmethod
795 endinterface;
796
797 interface osdr_ras_n = interface Get
798 method ActionValue#(Bit#(1)) get;
799 return pack(sdr_cntrl.osdr_ras_n);
800 endmethod
801 endinterface;
802
803 interface osdr_cas_n = interface Get
804 method ActionValue#(Bit#(1)) get;
805 return pack(sdr_cntrl.osdr_cas_n);
806 endmethod
807 endinterface;
808
809 interface osdr_we_n = interface Get
810 method ActionValue#(Bit#(1)) get;
811 return pack(sdr_cntrl.osdr_we_n);
812 endmethod
813 endinterface;
814
815 interface osdr_dqm = interface Get
816 method ActionValue#(Bit#(8)) get;
817 return sdr_cntrl.osdr_dqm;
818 endmethod
819 endinterface;
820
821 interface osdr_ba = interface Get
822 method ActionValue#(Bit#(2)) get;
823 return sdr_cntrl.osdr_ba;
824 endmethod
825 endinterface;
826
827 interface osdr_addr = interface Get
828 method ActionValue#(Bit#(13)) get;
829 return sdr_cntrl.osdr_addr;
830 endmethod
831 endinterface;
832
833 endinterface
834
835 interface sdram_clk = clk0;
836 method Bit#(9) sdram_sdio_ctrl();
837 return rg_cfg_sdio_ctrl;
838 endmethod
839
840 interface axi4_slave_sdram = s_xactor_sdram.axi_side;
841 interface axi4_slave_cntrl_reg = s_xactor_cntrl_reg.axi_side;
842
843 endmodule
844 endpackage