1ab55e4559ffe058260cc673b7a0d7552e9a80ef
[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_CLK_DELAY 8'h78
35 `define verbose
36
37 package sdr_top;
38
39 import Semi_FIFOF :: *;
40 import AXI4_Types :: *;
41 import AXI4_Fabric :: *;
42 import bsvmksdrc_top :: *;
43 import BUtils ::*;
44 import Connectable ::*;
45 import ConfigReg ::*;
46 import DReg::*;
47 import FIFOF::*;
48 import Clocks::*;
49
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;
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 endinterface
72
73 typedef enum{
74 IDLE,
75 WRITE_START,
76 WAIT_DELAY,
77 WRITE_FIRST,
78 WRITE_DATA0,
79 WRITE_DATA1
80 } Write_state deriving(Bits, Eq, FShow);
81
82 typedef enum{
83 IDLE,
84 START_READ,
85 READ_DATA,
86 READ_FLUSH
87 } Read_state deriving(Bits, Eq,FShow);
88
89 typedef enum {
90 IDLE,
91 START_SPLIT,
92 SEND_VALUE
93 } Write_split_states deriving(Bits, Eq, FShow);
94
95
96
97 function (Bit#(9)) fn_wr_len(Bit#(8) length, Bit#(3) awsize, Bit#(3) lwr_addr);
98 Bit#(3) w_packet = 0;
99 Bit#(9) s_length = 0;
100 case(awsize)
101
102 'd0 : begin
103 w_packet = lwr_addr >> awsize;
104 s_length = ((zeroExtend(length) + zeroExtend(w_packet)) >> 3) + 1;
105 end
106 'd1: begin
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
110 end
111 'd2 : begin
112 //w_packet = lwr_addr >> awsize;
113 // s_length = ((s_length + w_packets) >> 1) + 1;
114 s_length = zeroExtend(length >> 1) + 1;
115 end
116 'd3 : begin
117 s_length = zeroExtend(length) + 1;
118 end
119 endcase
120
121 return s_length;
122 endfunction
123
124
125 function Bit#(64) fn_wr_split_data(Bit#(64) data, Bit#(8) wstrb);
126 Bit#(64) data0 = 0;
127 if(wstrb[0] == 1)
128 data0[7:0] = data[7:0];
129 else
130 data0[7:0] = 0;
131
132 if(wstrb[1] == 1)
133 data0[15:8] = data[15:8];
134 else
135 data0[15:8] = 0;
136
137 if(wstrb[2] == 1)
138 data0[23:16] = data[23:16];
139 else
140 data0[23:16] = 0;
141
142 if(wstrb[3] == 1)
143 data0[31:24] = data[31:24];
144 else
145 data0[31:24] = 0;
146
147 if(wstrb[4] == 1)
148 data0[39:32] = data[39:32];
149 else
150 data0[39:32] = 0;
151
152 if(wstrb[5] == 1)
153 data0[47:40] = data[47:40];
154 else
155 data0[47:40] = 0;
156
157 if(wstrb[6] == 1)
158 data0[55:48] = data[55:48];
159 else
160 data0[55:48] = 0;
161
162 if(wstrb[7] == 1)
163 data0[63:56] = data[63:56];
164 else
165 data0[63:56] = 0;
166
167 return data0;
168 endfunction
169
170 function Bit#(26) fn_wr_address(Bit#(`PADDR) address);
171 Bit#(29) sdr_addr = address[31:3];
172 return sdr_addr[25:0];
173 endfunction
174
175 function Bit#(64) fn_rd_data(Bit#(3) bsize,Bit#(4) lwr_addr,Bit#(64) data);
176
177 case(bsize)
178 'b000: begin
179 case(lwr_addr)
180 'b000: begin
181 return duplicate(data[7:0]);
182 end
183 'b001: begin
184 return duplicate(data[15:8]);
185 end
186 'b010: begin
187 return duplicate(data[23:16]);
188 end
189 'b011: begin
190 return duplicate(data[31:24]);
191 end
192 'b100: begin
193 return duplicate(data[39:32]);
194 end
195 'b101: begin
196 return duplicate(data[47:40]);
197 end
198 'b110: begin
199 return duplicate(data[55:48]);
200 end
201 'b111: begin
202 return duplicate(data[63:56]);
203 end
204 endcase
205 end
206
207 'b001: begin
208 case(lwr_addr)
209 'b000: begin
210 return duplicate(data[15:0]);
211 end
212 'b010: begin
213 return duplicate(data[31:16]);
214 end
215 'b100: begin
216 return duplicate(data[47:32]);
217 end
218 'b110: begin
219 return duplicate(data[63:48]);
220 end
221 endcase
222 end
223
224 'b010: begin
225 case(lwr_addr)
226 'b000: begin
227 return duplicate(data[31:0]);
228 end
229 'b100: begin
230 return duplicate(data[63:32]);
231 end
232 endcase
233 end
234
235 'b011: begin
236 return data;
237 end
238 endcase
239 endfunction
240
241
242
243
244
245 (*synthesize*)
246
247 module mksdr_axi4_slave#(Clock clk0) (Ifc_sdr_slave);
248
249 Reset rst0 <- mkAsyncResetFromCR (0, clk0);
250
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);
268
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);
284
285
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);
290
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);
301
302 Reg#(Bit#(3)) rg_awsize_sclk <- mkSyncRegFromCC(0,clk0);
303
304 Reg#(Bit#(9)) rg_burst_counter <- mkReg(0);
305
306 Bool burst_eq = (rg_burst_counter == rg_local_actual_wr_length);
307
308 Reg#(Bit#(3)) rg_packets <- mkReg(0);
309 Reg#(Bit#(3)) rg_packet_counter <- mkReg(0);
310
311
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);
314
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);
319
320 SyncFIFOIfc#(Bool) ff_sync_write_response<-mkSyncFIFOToCC(1,clk0,rst0);
321
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);
326
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);
330
331 // Polling Registers
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);
338
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);
342
343 function Action fn_wr_cntrl_reg(Bit#(64) data, Bit#(8) address);
344 action
345 case(address)
346
347 `ACTPRE_DELAY : rg_cfg_sdr_tras_d <= data[3:0];
348
349 `PREACT_DELAY : rg_cfg_sdr_trp_d <= data[3:0];
350
351 `ACT_RW_DELAY : rg_cfg_sdr_trcd_d <= data[3:0];
352
353 `EN_SDRAM : rg_cfg_sdr_en <= data[0];
354
355 `MAX_REQ : rg_cfg_req_depth <= data[1:0];
356
357 `MODE_REG : rg_cfg_sdr_mode_reg <= data[12:0];
358
359 `CAS_LATNCY : rg_cfg_sdr_cas <= data[2:0];
360
361 `AUTO_REFRESH : rg_cfg_sdr_trcar_d <= data[3:0];
362
363 `RECRY_DELAY : rg_cfg_sdr_twr_d <= data[3:0];
364
365 `RFRSH_TIMER : rg_cfg_sdr_rfsh <= data[11:0];
366
367 `RFRSH_ROW_CNT : rg_cfg_sdr_rfmax <= data[2:0];
368
369 `SDR_WIDTH : rg_cfg_sdr_width <= data [1:0];
370
371 `SDR_COLBITS : rg_cfg_colbits <= data [1:0];
372
373
374 `SDR_CLK_DELAY : rg_cfg_sdr_clk_delay <= data [7:0];
375
376 default : noAction;
377 endcase
378 endaction
379 endfunction
380
381
382 function Bit#(64) fn_rd_cntrl_reg(Bit#(8) address);
383 case(address)
384
385 `ACTPRE_DELAY : return extend(rg_cfg_sdr_tras_d);
386
387 `PREACT_DELAY : return extend(rg_cfg_sdr_trp_d);
388
389 `ACT_RW_DELAY : return extend(rg_cfg_sdr_trcd_d);
390
391 `EN_SDRAM : return extend(rg_cfg_sdr_en);
392
393 `MAX_REQ : return extend(rg_cfg_req_depth);
394
395 `MODE_REG : return extend(rg_cfg_sdr_mode_reg);
396
397 `CAS_LATNCY : return extend(rg_cfg_sdr_cas);
398
399 `AUTO_REFRESH : return extend(rg_cfg_sdr_trcar_d);
400
401 `RECRY_DELAY : return extend(rg_cfg_sdr_twr_d);
402
403 `RFRSH_TIMER : return extend(rg_cfg_sdr_rfsh);
404
405 `RFRSH_ROW_CNT : return extend(rg_cfg_sdr_rfmax);
406
407 `SDR_INIT_DONE : return extend(pack(wr_sdr_init_done));
408
409 `SDR_WIDTH : return extend(rg_cfg_sdr_width);
410
411 `SDR_COLBITS : return extend(rg_cfg_colbits);
412
413
414 `SDR_CLK_DELAY : return extend(rg_cfg_sdr_clk_delay);
415
416 endcase
417 endfunction
418
419 //(*preempts="(rl_pop_read_request, rl_send_rd_data, rl_send_read_data, rl_flush_redundant_data), rl_write_transaction_write_start"*)
420
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);
428 endrule
429
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));
436 endrule
437
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;
442 endrule
443
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;
447 endrule
448
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);
453 endrule
454
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);
463 endrule
464
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 ();
473 endrule
474
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);
489 endrule
490
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
493 case (rg_poll_cnt)
494 0: begin
495 rg_app_req <= 1;
496 rg_app_req_addr <= 0;
497 rg_app_req_len <= 1;
498 rg_app_req_wr_n <= 0;
499 rg_app_wr_en_n <= 'hFF;
500 rg_app_wr_data <= 0;
501 rg_poll_cnt <= rg_poll_cnt + 1;
502 end
503 1: begin
504 rg_app_req <= 1;
505 rg_app_req_addr <= 0;
506 rg_app_req_len <= 1;
507 rg_app_req_wr_n <= 0;
508 rg_app_wr_en_n <= 'hFF;
509 rg_app_wr_data <= 0;
510 rg_poll_cnt <= rg_poll_cnt + 1;
511 end
512 2: begin
513 rg_app_req <= 0;
514 rg_app_req_addr <= 0;
515 rg_app_wr_en_n <= 'hFF;
516 rg_app_wr_data <= 0;
517 if(wr_app_wr_next_req == True)
518 rg_poll_cnt <= rg_poll_cnt + 1;
519 end
520 3: begin
521 rg_polling_status <= True;
522 rg_polling_status_clk0<=True;
523 end
524 endcase
525 endrule
526
527 /******************* WRITE TRANSACTION ****************/
528
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);
532 ff_wr_addr.enq(aw);
533 ff_wr_data.enq(w);
534 rg_wr_trnc_flg <= True;
535 `ifdef verbose $display($time,"\tSDRAM: WRITE_FIRST Parallel enq %h addr: %h",w.wdata,aw.awaddr); `endif
536 endrule
537
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]);
542
543 rg_local_actual_wr_length <= extend(aw.awlen);
544 end
545 else begin
546 rg_actual_wr_length <= extend(aw.awlen) + 1;
547 rg_local_actual_wr_length <= extend(aw.awlen);
548 end
549 rg_wid <= aw.awid;
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;
560 endrule
561
562
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;
570 end
571 else begin
572 rg_packet_counter <= rg_packet_counter + 1;
573 end
574 ff_wr_data.deq();
575 ff_wr_addr.deq();
576 endrule
577
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);
582 rg_wr_ac_data <= 0;
583 rg_wr_ac_wstrb <= 0;
584 rg_wr_lwr_addr <= 0;
585 rg_packet_counter <= 0;
586 `ifdef verbose $display($time,"Sending Value to the SDRAM"); `endif
587 rg_wr_split_states <= START_SPLIT;
588 endrule
589
590
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);
594 ff_wr_data.deq();
595 ff_wr_addr.deq();
596 endrule
597
598
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;
603 else
604 rg_write_states <= WRITE_START;
605 `ifdef verbose $display($time,"\tSDRAM: Going to write start state"); `endif
606 end
607 endrule
608
609 rule rl_wait_delay(rg_write_states == WAIT_DELAY);
610 if(rg_delay_count == 14) begin
611 rg_write_states <= WRITE_START;
612 rg_delay_count <= 0;
613 end
614 else
615 rg_delay_count <= rg_delay_count + 1;
616 endrule
617
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
620 rg_app_req <= 1;
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;
624 rg_app_wr_data <= 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;
628 endrule
629
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
632 rg_app_req <= 0;
633 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
634 rg_app_wr_data <= ff_ac_wr_data.first();
635 endrule
636
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
639 rg_app_req <= 0;
640 rg_app_wr_data <= ff_ac_wr_data.first();
641 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
642 ff_ac_wr_data.deq;
643 ff_ac_wr_wstrb.deq;
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);
648 end
649 endrule
650
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;
656 rg_ac_count <= 0;
657 rg_wr_trnc_flg <= False;
658 `ifdef verbose $display($time,"\tSDRAM: WRITE complete state true"); `endif
659 endrule
660
661 /****************** Read Transaction ********************/
662 // `ifdef verbose
663 // rule display_read_states;
664 // $display($time,"\tSDRAM: Read State: ",fshow(rg_read_states));
665 // endrule
666 // `endif
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);
669 ff_rd_addr.enq(ar);
670 rg_rd_trnc_flg <= True;
671 `ifdef verbose $display($time,"\tSDRAM: Got Read request from AXI for AddresS: %h",ar.araddr); `endif
672 endrule
673
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
679 end
680
681 endrule
682
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
686
687 rg_app_req <= 1;
688 if(ar.arburst == 2)
689 rg_app_req_wrap <= 1;
690 else
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;
698 rg_delay_count <= 0;
699 rg_read_states <= READ_DATA;
700 rg_rid <= ar.arid;
701 `ifdef verbose $display($time,"\t SSSSS SDRAM START_READ length "); `endif
702 endrule
703
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);
707 endrule
708
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);
715 ff_rd_addr.deq;
716 if(rg_arsize!=3)
717 rg_lwraddr <= rg_lwraddr + (1 << rg_arsize);
718 else
719 ff_rd_data.deq;
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;
726 rg_delay_count <= 0;
727 end
728 else
729 rg_delay_count <= rg_delay_count + 1;
730 end
731 else if(rg_lwraddr > 7) begin
732 `ifdef verbose $display($time,"\tSDRAM: Dequeuing ff READ"); `endif
733 rg_lwraddr <= 0;
734 ff_rd_data.deq;
735 end
736 endrule
737
738 rule rl_flush_redundant_data(rg_read_states == READ_FLUSH);
739 ff_rd_data.clear();
740 rg_read_states <= IDLE;
741 endrule
742
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);
750 endrule
751
752
753
754
755
756 interface Ifc_sdram_out ifc_sdram_out;
757
758 interface ipad_sdr_din = interface Put
759 method Action put(Bit#(64) in)
760 sdr_cntrl.ipad_sdr_din <= in;
761 endmethod
762 endinterface;
763
764 interface osdr_dout = interface Get
765 method ActionValue#(Bit#(64)) get;
766 return sdr_cntrl.osdr_dout();
767 endmethod
768 endinterface;
769
770 interface osdr_den_n = interface Get
771 method ActionValue#(Bit#(64)) get;
772 Bit#(64) temp;
773 for (int i=0; i<8; i=i+1) begin
774 temp[i*8] = sdr_cntrl.osdr_den_n[i];
775 end
776 return temp;
777 endmethod
778 endinterface;
779
780 interface osdr_cke = interface Get
781 method ActionValue#(Bit#(1)) get;
782 return pack(sdr_cntrl.osdr_cke());
783 endmethod
784 endinterface;
785
786 interface osdr_cs_n = interface Get
787 method ActionValue#(Bit#(1)) get;
788 return pack(sdr_cntrl.osdr_cs_n());
789 endmethod
790 endinterface;
791
792 interface osdr_ras_n = interface Get
793 method ActionValue#(Bit#(1)) get;
794 return pack(sdr_cntrl.osdr_ras_n);
795 endmethod
796 endinterface;
797
798 interface osdr_cas_n = interface Get
799 method ActionValue#(Bit#(1)) get;
800 return pack(sdr_cntrl.osdr_cas_n);
801 endmethod
802 endinterface;
803
804 interface osdr_we_n = interface Get
805 method ActionValue#(Bit#(1)) get;
806 return pack(sdr_cntrl.osdr_we_n);
807 endmethod
808 endinterface;
809
810 interface osdr_dqm = interface Get
811 method ActionValue#(Bit#(8)) get;
812 return sdr_cntrl.osdr_dqm;
813 endmethod
814 endinterface;
815
816 interface osdr_ba = interface Get
817 method ActionValue#(Bit#(2)) get;
818 return sdr_cntrl.osdr_ba;
819 endmethod
820 endinterface;
821
822 interface osdr_addr = interface Get
823 method ActionValue#(Bit#(13)) get;
824 return sdr_cntrl.osdr_addr;
825 endmethod
826 endinterface;
827
828 interface osdr_clock = interface Get
829 method ActionValue#(Bit#(1)) get;
830 return ?;
831 endmethod
832 endinterface;
833 endinterface
834
835 interface axi4_slave_sdram = s_xactor_sdram.axi_side;
836 interface axi4_slave_cntrl_reg = s_xactor_cntrl_reg.axi_side;
837
838 endmodule
839 endpackage