ec1d82167c6112fb7b77f9e8dd93d17cfcbb5e85
[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 method Action ipad_sdr_din(Bit#(64) pad_sdr_din);
54 method Bit#(9) sdram_sdio_ctrl();
55 method Bit#(64) osdr_dout();
56 method Bit#(8) osdr_den_n();
57 method Bool osdr_cke();
58 method Bool osdr_cs_n();
59 method Bool osdr_ras_n ();
60 method Bool osdr_cas_n ();
61 method Bool osdr_we_n ();
62 method Bit#(8) osdr_dqm ();
63 method Bit#(2) osdr_ba ();
64 method Bit#(13) osdr_addr ();
65 interface Clock sdram_clk;
66 endinterface
67
68 interface Ifc_sdr_slave;
69 interface AXI4_Slave_IFC#(`PADDR, `Reg_width,`USERSPACE) axi4_slave_sdram;
70 interface AXI4_Slave_IFC#(`PADDR, `Reg_width,`USERSPACE) axi4_slave_cntrl_reg;
71 interface Ifc_sdram_out ifc_sdram_out;
72 endinterface
73
74 typedef enum{
75 IDLE,
76 WRITE_START,
77 WAIT_DELAY,
78 WRITE_FIRST,
79 WRITE_DATA0,
80 WRITE_DATA1
81 } Write_state deriving(Bits, Eq, FShow);
82
83 typedef enum{
84 IDLE,
85 START_READ,
86 READ_DATA,
87 READ_FLUSH
88 } Read_state deriving(Bits, Eq,FShow);
89
90 typedef enum {
91 IDLE,
92 START_SPLIT,
93 SEND_VALUE
94 } Write_split_states deriving(Bits, Eq, FShow);
95
96
97
98 function (Bit#(9)) fn_wr_len(Bit#(8) length, Bit#(3) awsize, Bit#(3) lwr_addr);
99 Bit#(3) w_packet = 0;
100 Bit#(9) s_length = 0;
101 case(awsize)
102
103 'd0 : begin
104 w_packet = lwr_addr >> awsize;
105 s_length = ((zeroExtend(length) + zeroExtend(w_packet)) >> 3) + 1;
106 end
107 'd1: begin
108 w_packet = lwr_addr >> awsize;
109 s_length = ((zeroExtend(length) + zeroExtend(w_packet)) >> 2) + 1;
110 //`ifdef verbose $display($time(),"\t SSSS w_packet %b s_lenght %h length %h", w_packet, s_length, length); `endif
111 end
112 'd2 : begin
113 //w_packet = lwr_addr >> awsize;
114 // s_length = ((s_length + w_packets) >> 1) + 1;
115 s_length = zeroExtend(length >> 1) + 1;
116 end
117 'd3 : begin
118 s_length = zeroExtend(length) + 1;
119 end
120 endcase
121
122 return s_length;
123 endfunction
124
125
126 function Bit#(64) fn_wr_split_data(Bit#(64) data, Bit#(8) wstrb);
127 Bit#(64) data0 = 0;
128 if(wstrb[0] == 1)
129 data0[7:0] = data[7:0];
130 else
131 data0[7:0] = 0;
132
133 if(wstrb[1] == 1)
134 data0[15:8] = data[15:8];
135 else
136 data0[15:8] = 0;
137
138 if(wstrb[2] == 1)
139 data0[23:16] = data[23:16];
140 else
141 data0[23:16] = 0;
142
143 if(wstrb[3] == 1)
144 data0[31:24] = data[31:24];
145 else
146 data0[31:24] = 0;
147
148 if(wstrb[4] == 1)
149 data0[39:32] = data[39:32];
150 else
151 data0[39:32] = 0;
152
153 if(wstrb[5] == 1)
154 data0[47:40] = data[47:40];
155 else
156 data0[47:40] = 0;
157
158 if(wstrb[6] == 1)
159 data0[55:48] = data[55:48];
160 else
161 data0[55:48] = 0;
162
163 if(wstrb[7] == 1)
164 data0[63:56] = data[63:56];
165 else
166 data0[63:56] = 0;
167
168 return data0;
169 endfunction
170
171 function Bit#(26) fn_wr_address(Bit#(`PADDR) address);
172 Bit#(29) sdr_addr = address[31:3];
173 return sdr_addr[25:0];
174 endfunction
175
176 function Bit#(64) fn_rd_data(Bit#(3) bsize,Bit#(4) lwr_addr,Bit#(64) data);
177
178 case(bsize)
179 'b000: begin
180 case(lwr_addr)
181 'b000: begin
182 return duplicate(data[7:0]);
183 end
184 'b001: begin
185 return duplicate(data[15:8]);
186 end
187 'b010: begin
188 return duplicate(data[23:16]);
189 end
190 'b011: begin
191 return duplicate(data[31:24]);
192 end
193 'b100: begin
194 return duplicate(data[39:32]);
195 end
196 'b101: begin
197 return duplicate(data[47:40]);
198 end
199 'b110: begin
200 return duplicate(data[55:48]);
201 end
202 'b111: begin
203 return duplicate(data[63:56]);
204 end
205 endcase
206 end
207
208 'b001: begin
209 case(lwr_addr)
210 'b000: begin
211 return duplicate(data[15:0]);
212 end
213 'b010: begin
214 return duplicate(data[31:16]);
215 end
216 'b100: begin
217 return duplicate(data[47:32]);
218 end
219 'b110: begin
220 return duplicate(data[63:48]);
221 end
222 endcase
223 end
224
225 'b010: begin
226 case(lwr_addr)
227 'b000: begin
228 return duplicate(data[31:0]);
229 end
230 'b100: begin
231 return duplicate(data[63:32]);
232 end
233 endcase
234 end
235
236 'b011: begin
237 return data;
238 end
239 endcase
240 endfunction
241
242
243
244
245
246 (*synthesize*)
247
248 module mksdr_axi4_slave#(Clock clk0) (Ifc_sdr_slave);
249
250 Reset rst0 <- mkAsyncResetFromCR (0, clk0);
251
252 Reg#(Bit#(9)) rg_delay_count <- mkReg(0,clocked_by clk0, reset_by rst0);
253 Reg#(Bit#(9)) rg_rd_actual_len <- mkReg(0,clocked_by clk0, reset_by rst0);
254 Reg#(bit) rg_app_req <- mkDReg(0,clocked_by clk0, reset_by rst0);
255 Reg#(bit) rg_app_req_wrap <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
256 Reg#(Bit#(26)) rg_app_req_addr <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
257 Reg#(Bit#(4)) rg_cfg_sdr_tras_d <- mkConfigReg(4'h4,clocked_by clk0, reset_by rst0);
258 Reg#(Bit#(4)) rg_cfg_sdr_trp_d <- mkConfigReg(4'h2,clocked_by clk0, reset_by rst0);
259 Reg#(Bit#(4)) rg_cfg_sdr_trcd_d <- mkConfigReg(4'h2,clocked_by clk0, reset_by rst0);
260 Reg#(bit) rg_cfg_sdr_en <- mkConfigReg(1'h0,clocked_by clk0, reset_by rst0);
261 Reg#(Bit#(2)) rg_cfg_req_depth <- mkConfigReg(2'h3,clocked_by clk0, reset_by rst0);
262 Reg#(Bit#(13)) rg_cfg_sdr_mode_reg <- mkConfigReg(13'h032,clocked_by clk0, reset_by rst0);
263 Reg#(Bit#(3)) rg_cfg_sdr_cas <- mkConfigReg(3'h3,clocked_by clk0, reset_by rst0);
264 Reg#(Bit#(4)) rg_cfg_sdr_trcar_d <- mkConfigReg(4'h7,clocked_by clk0, reset_by rst0);
265 Reg#(Bit#(4)) rg_cfg_sdr_twr_d <- mkConfigReg(4'h1,clocked_by clk0, reset_by rst0);
266 Reg#(Bit#(2)) rg_cfg_sdr_width <- mkConfigReg(2'b0,clocked_by clk0, reset_by rst0);
267 Reg#(Bit#(2)) rg_cfg_colbits <- mkConfigReg(2'b01,clocked_by clk0, reset_by rst0);
268 Reg#(Bit#(9)) rg_cfg_sdio_ctrl <- mkConfigReg(9'b000100011,clocked_by clk0, reset_by rst0);
269 Reg#(Bit#(8)) rg_cfg_sdr_clk_delay <- mkConfigReg(8'b00001000,clocked_by clk0, reset_by rst0);
270
271 Reg#(Bit#(`SDR_RFSH_TIMER_W )) rg_cfg_sdr_rfsh <- mkConfigReg(12'h100,clocked_by clk0, reset_by rst0);
272 Reg#(Bit#(`SDR_RFSH_ROW_CNT_W)) rg_cfg_sdr_rfmax <- mkConfigReg(3'h6,clocked_by clk0, reset_by rst0);
273 Reg#(Bit#(9)) rg_app_req_len <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
274 Reg#(Bit#(4)) rg_lwraddr <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
275 Reg#(Bit#(3)) rg_arsize <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
276 Reg#(bit) rg_app_req_wr_n <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
277 Reg#(Bit#(8)) rg_app_wr_en_n <- mkDWire(8'hFF,clocked_by clk0, reset_by rst0);
278 Reg#(Bit#(64)) rg_app_wr_data <- mkDWire(0,clocked_by clk0, reset_by rst0);
279 Wire#(Bool) wr_sdr_init_done <- mkDWire(False,clocked_by clk0, reset_by rst0);
280 Wire#(Bool) wr_app_req_ack <- mkDWire(False,clocked_by clk0, reset_by rst0);
281 Wire#(Bool) wr_app_wr_next_req <- mkDWire(False,clocked_by clk0, reset_by rst0);
282 Wire#(Bool) wr_app_rd_valid <- mkDWire(False,clocked_by clk0, reset_by rst0);
283 Wire#(Bool) wr_app_last_rd <- mkDWire(False,clocked_by clk0, reset_by rst0);
284 Wire#(Bool) wr_app_last_wr <- mkDWire(False,clocked_by clk0, reset_by rst0);
285 Wire#(Bit#(64)) wr_app_rd_data <- mkWire(clocked_by clk0, reset_by rst0);
286
287
288 Reg#(Bit#(4)) rg_rid <- mkReg(0, clocked_by clk0, reset_by rst0);
289 Reg#(bit) rg_rd_not_active_flag <- mkSyncRegToCC(0,clk0, rst0);
290 Reg#(Bit#(4)) rg_ctrl_rid <- mkReg(0);
291 Reg#(Bit#(4)) rg_wid <- mkReg(0);
292
293 Reg#(Write_split_states) rg_wr_split_states <- mkReg(IDLE);
294 Reg#(Bit#(3)) rg_awsize <- mkReg(0);
295 Reg#(Bit#(9)) rg_ac_count <- mkReg(0);
296 Reg#(Bit#(6)) rg_single_burst <- mkReg(0);
297 Reg#(Bit#(64)) rg_wr_ac_data <- mkReg(0);
298 Reg#(Bit#(8)) rg_wr_ac_wstrb <- mkReg(0);
299 Reg#(Bit#(4)) rg_wr_lwr_addr <- mkReg(0);
300 Reg#(Bit#(9)) rg_local_actual_wr_length <- mkReg(0);
301 Reg#(Bit#(9)) rg_actual_wr_length <- mkSyncRegFromCC(0,clk0);
302 Reg#(Bit#(32)) rg_wr_address <- mkSyncRegFromCC(0,clk0);
303
304 Reg#(Bit#(3)) rg_awsize_sclk <- mkSyncRegFromCC(0,clk0);
305
306 Reg#(Bit#(9)) rg_burst_counter <- mkReg(0);
307
308 Bool burst_eq = (rg_burst_counter == rg_local_actual_wr_length);
309
310 Reg#(Bit#(3)) rg_packets <- mkReg(0);
311 Reg#(Bit#(3)) rg_packet_counter <- mkReg(0);
312
313
314 Reg#(Write_state) rg_write_states <- mkReg(IDLE,clocked_by clk0, reset_by rst0);
315 Reg#(Read_state) rg_read_states <- mkReg(IDLE,clocked_by clk0, reset_by rst0);
316
317 FIFOF#(AXI4_Wr_Addr#(`PADDR,`USERSPACE)) ff_wr_addr <- mkSizedFIFOF(13);
318 FIFOF#(AXI4_Wr_Data#(`Reg_width)) ff_wr_data <- mkSizedFIFOF(13);
319 SyncFIFOIfc#(Bit#(`Reg_width)) ff_ac_wr_data <- mkSyncFIFOFromCC(13,clk0);
320 SyncFIFOIfc#(Bit#(8)) ff_ac_wr_wstrb <- mkSyncFIFOFromCC(13,clk0);
321
322 SyncFIFOIfc#(Bool) ff_sync_write_response<-mkSyncFIFOToCC(1,clk0,rst0);
323
324 //FIFOF#(AXI4_Rd_Addr#(`PADDR,`USERSPACE)) ff_rd_addr <- mkSizedFIFOF(3);
325 FIFOF#(Bit#(64)) ff_rd_data <- mkSizedFIFOF(86,clocked_by clk0, reset_by rst0);
326 SyncFIFOIfc#(AXI4_Rd_Addr#(`PADDR,`USERSPACE)) ff_rd_addr <- mkSyncFIFOFromCC(30,clk0);
327 SyncFIFOIfc#(AXI4_Rd_Data#(`Reg_width,`USERSPACE)) ff_sync_read_response <-mkSyncFIFOToCC(13,clk0,rst0);
328
329 SyncFIFOIfc#(Tuple2#(Bit#(`PADDR),Bit#(`Reg_width))) ff_sync_ctrl_write<- mkSyncFIFOFromCC(1,clk0);
330 SyncFIFOIfc#(Bit#(`PADDR)) ff_sync_ctrl_read<- mkSyncFIFOFromCC(1,clk0);
331 SyncFIFOIfc#(Bit#(`Reg_width)) ff_sync_ctrl_read_response<- mkSyncFIFOToCC(1,clk0,rst0);
332
333 // Polling Registers
334 Reg#(Bit#(2)) rg_poll_cnt <- mkReg(0,clocked_by clk0, reset_by rst0);
335 Reg#(Bool) rg_polling_status <- mkSyncRegToCC(False,clk0,rst0);
336 Reg#(Bool) rg_polling_status_clk0 <- mkReg(False,clocked_by clk0, reset_by rst0);
337 Reg#(Bool) rg_rd_trnc_flg <- mkReg(False);
338 Reg#(Bool) rg_wr_trnc_flg <- mkReg(False);
339 Reg#(bit) rg_odd_len <- mkReg(0);
340
341 AXI4_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor_sdram <- mkAXI4_Slave_Xactor;
342 AXI4_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor_cntrl_reg <- mkAXI4_Slave_Xactor;
343 Ifc_sdram sdr_cntrl <- mksdrc_top(clocked_by clk0, reset_by rst0);
344
345 function Action fn_wr_cntrl_reg(Bit#(64) data, Bit#(8) address);
346 action
347 case(address)
348
349 `ACTPRE_DELAY : rg_cfg_sdr_tras_d <= data[3:0];
350
351 `PREACT_DELAY : rg_cfg_sdr_trp_d <= data[3:0];
352
353 `ACT_RW_DELAY : rg_cfg_sdr_trcd_d <= data[3:0];
354
355 `EN_SDRAM : rg_cfg_sdr_en <= data[0];
356
357 `MAX_REQ : rg_cfg_req_depth <= data[1:0];
358
359 `MODE_REG : rg_cfg_sdr_mode_reg <= data[12:0];
360
361 `CAS_LATNCY : rg_cfg_sdr_cas <= data[2:0];
362
363 `AUTO_REFRESH : rg_cfg_sdr_trcar_d <= data[3:0];
364
365 `RECRY_DELAY : rg_cfg_sdr_twr_d <= data[3:0];
366
367 `RFRSH_TIMER : rg_cfg_sdr_rfsh <= data[11:0];
368
369 `RFRSH_ROW_CNT : rg_cfg_sdr_rfmax <= data[2:0];
370
371 `SDR_WIDTH : rg_cfg_sdr_width <= data [1:0];
372
373 `SDR_COLBITS : rg_cfg_colbits <= data [1:0];
374
375 `SDR_SDIO_CTRL : rg_cfg_sdio_ctrl <= data [8:0];
376
377 `SDR_CLK_DELAY : rg_cfg_sdr_clk_delay <= data [7:0];
378
379 default : noAction;
380 endcase
381 endaction
382 endfunction
383
384
385 function Bit#(64) fn_rd_cntrl_reg(Bit#(8) address);
386 case(address)
387
388 `ACTPRE_DELAY : return extend(rg_cfg_sdr_tras_d);
389
390 `PREACT_DELAY : return extend(rg_cfg_sdr_trp_d);
391
392 `ACT_RW_DELAY : return extend(rg_cfg_sdr_trcd_d);
393
394 `EN_SDRAM : return extend(rg_cfg_sdr_en);
395
396 `MAX_REQ : return extend(rg_cfg_req_depth);
397
398 `MODE_REG : return extend(rg_cfg_sdr_mode_reg);
399
400 `CAS_LATNCY : return extend(rg_cfg_sdr_cas);
401
402 `AUTO_REFRESH : return extend(rg_cfg_sdr_trcar_d);
403
404 `RECRY_DELAY : return extend(rg_cfg_sdr_twr_d);
405
406 `RFRSH_TIMER : return extend(rg_cfg_sdr_rfsh);
407
408 `RFRSH_ROW_CNT : return extend(rg_cfg_sdr_rfmax);
409
410 `SDR_INIT_DONE : return extend(pack(wr_sdr_init_done));
411
412 `SDR_WIDTH : return extend(rg_cfg_sdr_width);
413
414 `SDR_COLBITS : return extend(rg_cfg_colbits);
415
416 `SDR_SDIO_CTRL : return extend(rg_cfg_sdio_ctrl);
417
418 `SDR_CLK_DELAY : return extend(rg_cfg_sdr_clk_delay);
419
420 endcase
421 endfunction
422
423 //(*preempts="(rl_pop_read_request, rl_send_rd_data, rl_send_read_data, rl_flush_redundant_data), rl_write_transaction_write_start"*)
424
425 rule rl_for_writing_ctrl_reg(ff_sync_ctrl_write.notFull);
426 let aw <- pop_o(s_xactor_cntrl_reg.o_wr_addr);
427 let w <- pop_o(s_xactor_cntrl_reg.o_wr_data);
428 `ifdef verbose $display($time,"\tSDRAM: control_reg written addr %x data %x", aw.awaddr, w.wdata); `endif
429 ff_sync_ctrl_write.enq(tuple2(aw.awaddr,w.wdata));
430 let w_resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, buser: 0, bid: aw.awid};
431 s_xactor_cntrl_reg.i_wr_resp.enq(w_resp);
432 endrule
433
434 rule rl_perform_write_to_ctrl(ff_sync_ctrl_write.notEmpty);
435 let {awaddr,wdata}=ff_sync_ctrl_write.first;
436 `ifdef verbose $display("\tSDRAM: "); `endif
437 ff_sync_ctrl_write.deq;
438 `ifdef verbose $display($time,"\tSDRAM: Actually writing data: %h to addr: %h", wdata, awaddr); `endif
439 fn_wr_cntrl_reg(wdata , truncate(awaddr));
440 endrule
441
442 rule rl_for_read_cntrl_reg;
443 let ar <- pop_o(s_xactor_cntrl_reg.o_rd_addr);
444 ff_sync_ctrl_read.enq(ar.araddr);
445 rg_ctrl_rid<=ar.arid;
446 endrule
447
448 rule rl_send_ctrl_read_response(ff_sync_ctrl_read.notEmpty);
449 ff_sync_ctrl_read_response.enq(fn_rd_cntrl_reg(truncate(ff_sync_ctrl_read.first)));
450 ff_sync_ctrl_read.deq;
451 endrule
452
453 rule sync_ctr_response(ff_sync_ctrl_read_response.notEmpty);
454 ff_sync_ctrl_read_response.deq;
455 let r = AXI4_Rd_Data {rresp: AXI4_OKAY, rdata:ff_sync_ctrl_read_response.first , rlast: True, ruser: 0, rid: rg_ctrl_rid};
456 s_xactor_cntrl_reg.i_rd_data.enq(r);
457 endrule
458
459 rule rl_direct_connection_insdram;
460 sdr_cntrl.iapp_req(rg_app_req);
461 sdr_cntrl.iapp_req_wrap(rg_app_req_wrap);
462 sdr_cntrl.iapp_req_addr(rg_app_req_addr);
463 sdr_cntrl.iapp_req_len(rg_app_req_len);
464 sdr_cntrl.iapp_req_wr_n(rg_app_req_wr_n);
465 sdr_cntrl.iapp_wr_data(rg_app_wr_data);
466 sdr_cntrl.iapp_wr_en_n(rg_app_wr_en_n);
467 endrule
468
469 rule rl_direct_connection_outsdram;
470 wr_sdr_init_done <= sdr_cntrl.osdr_init_done ;
471 wr_app_req_ack <= sdr_cntrl.oapp_req_ack ();
472 wr_app_wr_next_req <= sdr_cntrl.oapp_wr_next_req ();
473 wr_app_rd_valid <= sdr_cntrl.oapp_rd_valid ();
474 wr_app_last_rd <= sdr_cntrl.oapp_last_rd ();
475 wr_app_last_wr <= sdr_cntrl.oapp_last_wr ();
476 wr_app_rd_data <= sdr_cntrl.oapp_rd_data ();
477 endrule
478
479 rule rl_direct_connection_config_reg;
480 sdr_cntrl.icfg_sdr_tras_d(rg_cfg_sdr_tras_d);
481 sdr_cntrl.icfg_sdr_trp_d(rg_cfg_sdr_trp_d);
482 sdr_cntrl.icfg_sdr_trcd_d(rg_cfg_sdr_trcd_d);
483 sdr_cntrl.icfg_sdr_en(rg_cfg_sdr_en);
484 sdr_cntrl.icfg_req_depth(rg_cfg_req_depth);
485 sdr_cntrl.icfg_sdr_mode_reg(rg_cfg_sdr_mode_reg);
486 sdr_cntrl.icfg_sdr_cas(rg_cfg_sdr_cas);
487 sdr_cntrl.icfg_sdr_trcar_d(rg_cfg_sdr_trcar_d);
488 sdr_cntrl.icfg_sdr_twr_d(rg_cfg_sdr_twr_d);
489 sdr_cntrl.icfg_sdr_rfsh(rg_cfg_sdr_rfsh);
490 sdr_cntrl.icfg_sdr_rfmax(rg_cfg_sdr_rfmax);
491 sdr_cntrl.icfg_sdr_width(rg_cfg_sdr_width);
492 sdr_cntrl.icfg_colbits(rg_cfg_colbits);
493 endrule
494
495 rule rl_intial_polling(rg_polling_status_clk0 == False && wr_sdr_init_done == True);
496 `ifdef verbose $display($time,"\tSDRAM: POLLING MODE: %d",rg_poll_cnt); `endif
497 case (rg_poll_cnt)
498 0: begin
499 rg_app_req <= 1;
500 rg_app_req_addr <= 0;
501 rg_app_req_len <= 1;
502 rg_app_req_wr_n <= 0;
503 rg_app_wr_en_n <= 'hFF;
504 rg_app_wr_data <= 0;
505 rg_poll_cnt <= rg_poll_cnt + 1;
506 end
507 1: begin
508 rg_app_req <= 1;
509 rg_app_req_addr <= 0;
510 rg_app_req_len <= 1;
511 rg_app_req_wr_n <= 0;
512 rg_app_wr_en_n <= 'hFF;
513 rg_app_wr_data <= 0;
514 rg_poll_cnt <= rg_poll_cnt + 1;
515 end
516 2: begin
517 rg_app_req <= 0;
518 rg_app_req_addr <= 0;
519 rg_app_wr_en_n <= 'hFF;
520 rg_app_wr_data <= 0;
521 if(wr_app_wr_next_req == True)
522 rg_poll_cnt <= rg_poll_cnt + 1;
523 end
524 3: begin
525 rg_polling_status <= True;
526 rg_polling_status_clk0<=True;
527 end
528 endcase
529 endrule
530
531 /******************* WRITE TRANSACTION ****************/
532
533 rule rl_parallel_data_enq(rg_polling_status == True && rg_rd_trnc_flg == False);
534 let aw <- pop_o(s_xactor_sdram.o_wr_addr);
535 let w <- pop_o(s_xactor_sdram.o_wr_data);
536 ff_wr_addr.enq(aw);
537 ff_wr_data.enq(w);
538 rg_wr_trnc_flg <= True;
539 `ifdef verbose $display($time,"\tSDRAM: WRITE_FIRST Parallel enq %h addr: %h",w.wdata,aw.awaddr); `endif
540 endrule
541
542 rule rl_write_split_state(rg_wr_split_states == IDLE);
543 let aw = ff_wr_addr.first();
544 if(aw.awsize != 3) begin
545 rg_actual_wr_length <= fn_wr_len(aw.awlen, aw.awsize, aw.awaddr[2:0]);
546
547 rg_local_actual_wr_length <= extend(aw.awlen);
548 end
549 else begin
550 rg_actual_wr_length <= extend(aw.awlen) + 1;
551 rg_local_actual_wr_length <= extend(aw.awlen);
552 end
553 rg_wid <= aw.awid;
554 rg_awsize <= aw.awsize;
555 rg_awsize_sclk <= aw.awsize;
556 rg_wr_address <= aw.awaddr;
557 rg_wr_lwr_addr <= extend(aw.awaddr[2:0]);
558 rg_wr_split_states <= START_SPLIT;
559 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];
560 rg_packet_counter <= (aw.awaddr[2:0]) >> aw.awsize;
561 `ifdef verbose $display($time,"Initial Values -- Starting IDLE to START_SPLIT"); `endif
562 //$display("Initial Values: rg_packets: %h rg_packet_counter: %h ",(64>>(aw.awsize+4)),aw.awaddr[2:0]>>aw.awsize);
563 rg_burst_counter <= 0;
564 endrule
565
566
567 rule rl_write_data_splitting0(rg_wr_split_states == START_SPLIT && rg_awsize != 3);
568 rg_wr_ac_data <= rg_wr_ac_data | fn_wr_split_data(ff_wr_data.first.wdata,ff_wr_data.first.wstrb);
569 rg_wr_ac_wstrb <= rg_wr_ac_wstrb | ff_wr_data.first.wstrb;
570 rg_burst_counter <= rg_burst_counter + 1;
571 `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
572 if(burst_eq || rg_packets == rg_packet_counter) begin
573 rg_wr_split_states <= SEND_VALUE;
574 end
575 else begin
576 rg_packet_counter <= rg_packet_counter + 1;
577 end
578 ff_wr_data.deq();
579 ff_wr_addr.deq();
580 endrule
581
582 rule rl_write_data_splitting1(rg_wr_split_states == SEND_VALUE && rg_awsize != 3);
583 `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
584 ff_ac_wr_data.enq(rg_wr_ac_data);
585 ff_ac_wr_wstrb.enq(rg_wr_ac_wstrb);
586 rg_wr_ac_data <= 0;
587 rg_wr_ac_wstrb <= 0;
588 rg_wr_lwr_addr <= 0;
589 rg_packet_counter <= 0;
590 `ifdef verbose $display($time,"Sending Value to the SDRAM"); `endif
591 rg_wr_split_states <= START_SPLIT;
592 endrule
593
594
595 rule rl_write_data_spliting3(rg_wr_split_states == START_SPLIT && rg_awsize == 3);
596 ff_ac_wr_data.enq(ff_wr_data.first.wdata);
597 ff_ac_wr_wstrb.enq(ff_wr_data.first.wstrb);
598 ff_wr_data.deq();
599 ff_wr_addr.deq();
600 endrule
601
602
603 rule rl_start_write_transaction(rg_write_states == IDLE && wr_sdr_init_done == True);
604 if(ff_ac_wr_data.notEmpty()) begin
605 if(rg_awsize_sclk == 0)
606 rg_write_states <= WAIT_DELAY;
607 else
608 rg_write_states <= WRITE_START;
609 `ifdef verbose $display($time,"\tSDRAM: Going to write start state"); `endif
610 end
611 endrule
612
613 rule rl_wait_delay(rg_write_states == WAIT_DELAY);
614 if(rg_delay_count == 14) begin
615 rg_write_states <= WRITE_START;
616 rg_delay_count <= 0;
617 end
618 else
619 rg_delay_count <= rg_delay_count + 1;
620 endrule
621
622 rule rl_write_transaction_write_start(rg_write_states == WRITE_START && wr_sdr_init_done == True && rg_read_states == IDLE);
623 `ifdef verbose $display($time,"\tSDRAM: WRITE_START state Controller Length %d",rg_actual_wr_length); `endif
624 rg_app_req <= 1;
625 rg_app_req_addr <= fn_wr_address(rg_wr_address);
626 rg_app_req_len <= extend(rg_actual_wr_length);
627 rg_app_req_wr_n <= 0;
628 rg_app_wr_data <= 0;
629 rg_app_wr_en_n <= 8'hFF;
630 rg_write_states <= WRITE_FIRST;
631 rg_delay_count <= extend(rg_actual_wr_length) - 1;
632 endrule
633
634 rule rl_write_transaction_write_first(rg_write_states == WRITE_FIRST && wr_app_wr_next_req == False);
635 `ifdef verbose $display($time,"\tSDRAM: WRITE_FIRST state next is false data %x",ff_ac_wr_data.first); `endif
636 rg_app_req <= 0;
637 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
638 rg_app_wr_data <= ff_ac_wr_data.first();
639 endrule
640
641 rule rl_write_transaction_write_data(rg_write_states == WRITE_FIRST && wr_app_wr_next_req == True);
642 `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
643 rg_app_req <= 0;
644 rg_app_wr_data <= ff_ac_wr_data.first();
645 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
646 ff_ac_wr_data.deq;
647 ff_ac_wr_wstrb.deq;
648 rg_delay_count <= rg_delay_count - 1;
649 if(rg_delay_count == 0) begin
650 rg_write_states <= IDLE;
651 ff_sync_write_response.enq(True);
652 end
653 endrule
654
655 rule synchronize_write_response(ff_sync_write_response.notEmpty);
656 ff_sync_write_response.deq;
657 let w_resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, buser: 0, bid: rg_wid}; //TODO user value is null
658 s_xactor_sdram.i_wr_resp.enq(w_resp);
659 rg_wr_split_states <= IDLE;
660 rg_ac_count <= 0;
661 rg_wr_trnc_flg <= False;
662 `ifdef verbose $display($time,"\tSDRAM: WRITE complete state true"); `endif
663 endrule
664
665 /****************** Read Transaction ********************/
666 // `ifdef verbose
667 // rule display_read_states;
668 // $display($time,"\tSDRAM: Read State: ",fshow(rg_read_states));
669 // endrule
670 // `endif
671 rule rl_paralel_read_req_enq(rg_polling_status == True && rg_wr_trnc_flg == False);
672 let ar <- pop_o(s_xactor_sdram.o_rd_addr);
673 ff_rd_addr.enq(ar);
674 rg_rd_trnc_flg <= True;
675 `ifdef verbose $display($time,"\tSDRAM: Got Read request from AXI for AddresS: %h",ar.araddr); `endif
676 endrule
677
678 rule rl_read_idle_state(rg_read_states == IDLE);
679 if(ff_rd_addr.notEmpty() == True) begin
680 rg_read_states <= START_READ;
681 rg_rd_not_active_flag <= 0;
682 `ifdef verbose $display($time,"\tSDRAM: READ IDLE state"); `endif
683 end
684
685 endrule
686
687 rule rl_pop_read_request(wr_sdr_init_done == True && rg_read_states == START_READ && (rg_write_states == IDLE || rg_write_states == WRITE_START));
688 let ar = ff_rd_addr.first;
689 `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
690
691 rg_app_req <= 1;
692 if(ar.arburst == 2)
693 rg_app_req_wrap <= 1;
694 else
695 rg_app_req_wrap <= 0;
696 rg_lwraddr <= extend(ar.araddr[2:0]);
697 rg_arsize <= ar.arsize;
698 rg_app_req_addr <= fn_wr_address(ar.araddr);
699 rg_app_req_len <= fn_wr_len(ar.arlen, ar.arsize, ar.araddr[2:0]);
700 rg_rd_actual_len <= extend(ar.arlen);
701 rg_app_req_wr_n <= 1;
702 rg_delay_count <= 0;
703 rg_read_states <= READ_DATA;
704 rg_rid <= ar.arid;
705 `ifdef verbose $display($time,"\t SSSSS SDRAM START_READ length "); `endif
706 endrule
707
708 rule rl_send_rd_data(wr_app_rd_valid == True);
709 `ifdef verbose $display($time,"\tSDRAM: READ DATA1 state %x",wr_app_rd_data); `endif
710 ff_rd_data.enq(wr_app_rd_data);
711 endrule
712
713 rule rl_send_read_data(rg_read_states==READ_DATA);
714 `ifdef verbose $display($time,"\tSDRAM: Response from BFM. RequestLenght: %d CurrentCount: %d",rg_rd_actual_len,rg_delay_count); `endif
715 rg_app_req_wrap <= 0;
716 if(rg_lwraddr < 8) begin
717 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};
718 ff_sync_read_response.enq(r);
719 ff_rd_addr.deq;
720 if(rg_arsize!=3)
721 rg_lwraddr <= rg_lwraddr + (1 << rg_arsize);
722 else
723 ff_rd_data.deq;
724 `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
725 `ifdef verbose $display($time,"\tSDRAM: Removing Request for Addr : %h",ff_rd_addr.first.araddr); `endif
726 if(rg_delay_count == rg_rd_actual_len) begin
727 `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
728 rg_read_states <= READ_FLUSH;
729 rg_rd_not_active_flag <= 1;
730 rg_delay_count <= 0;
731 end
732 else
733 rg_delay_count <= rg_delay_count + 1;
734 end
735 else if(rg_lwraddr > 7) begin
736 `ifdef verbose $display($time,"\tSDRAM: Dequeuing ff READ"); `endif
737 rg_lwraddr <= 0;
738 ff_rd_data.deq;
739 end
740 endrule
741
742 rule rl_flush_redundant_data(rg_read_states == READ_FLUSH);
743 ff_rd_data.clear();
744 rg_read_states <= IDLE;
745 endrule
746
747 rule send_synchronized_read_response(ff_sync_read_response.notEmpty);
748 let r=ff_sync_read_response.first;
749 `ifdef verbose $display($time,"\tSDRAM: Sending Read response: %h rlast: %b",r.rdata,r.rlast); `endif
750 ff_sync_read_response.deq;
751 if(rg_rd_not_active_flag == 1)
752 rg_rd_trnc_flg <= False;
753 s_xactor_sdram.i_rd_data.enq(r);
754 endrule
755
756
757
758
759
760 interface Ifc_sdram_out ifc_sdram_out;
761
762 method Action ipad_sdr_din(Bit#(64) pad_sdr_din);
763 sdr_cntrl.ipad_sdr_din(pad_sdr_din);
764 endmethod
765 method Bit#(9) sdram_sdio_ctrl();
766 return rg_cfg_sdio_ctrl;
767 endmethod
768 method Bit#(64) osdr_dout();
769 return sdr_cntrl.osdr_dout();
770 endmethod
771 method Bit#(8) osdr_den_n();
772 return sdr_cntrl.osdr_den_n();
773 endmethod
774 method Bool osdr_cke();
775 return sdr_cntrl.osdr_cke();
776 endmethod
777
778 method Bool osdr_cs_n();
779 return sdr_cntrl.osdr_cs_n();
780 endmethod
781
782 method Bool osdr_ras_n ();
783 return sdr_cntrl.osdr_ras_n;
784 endmethod
785
786 method Bool osdr_cas_n ();
787 return sdr_cntrl.osdr_cas_n;
788 endmethod
789
790 method Bool osdr_we_n ();
791 return sdr_cntrl.osdr_we_n;
792 endmethod
793
794 method Bit#(8) osdr_dqm ();
795 return sdr_cntrl.osdr_dqm;
796 endmethod
797
798 method Bit#(2) osdr_ba ();
799 return sdr_cntrl.osdr_ba;
800 endmethod
801
802 method Bit#(13) osdr_addr ();
803 return sdr_cntrl.osdr_addr;
804 endmethod
805
806 interface sdram_clk = clk0;
807 endinterface
808
809
810 interface axi4_slave_sdram = s_xactor_sdram.axi_side;
811 interface axi4_slave_cntrl_reg = s_xactor_cntrl_reg.axi_side;
812
813 endmodule
814 endpackage