assign in
[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 GetPut:: *;
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 interface Get#(Bit#(1)) osdr_clock;
65
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#(8)) rg_cfg_sdr_clk_delay <- mkConfigReg(8'b00001000,clocked_by clk0, reset_by rst0);
269
270 Reg#(Bit#(`SDR_RFSH_TIMER_W )) rg_cfg_sdr_rfsh <- mkConfigReg(12'h100,clocked_by clk0, reset_by rst0);
271 Reg#(Bit#(`SDR_RFSH_ROW_CNT_W)) rg_cfg_sdr_rfmax <- mkConfigReg(3'h6,clocked_by clk0, reset_by rst0);
272 Reg#(Bit#(9)) rg_app_req_len <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
273 Reg#(Bit#(4)) rg_lwraddr <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
274 Reg#(Bit#(3)) rg_arsize <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
275 Reg#(bit) rg_app_req_wr_n <- mkConfigReg(0,clocked_by clk0, reset_by rst0);
276 Reg#(Bit#(8)) rg_app_wr_en_n <- mkDWire(8'hFF,clocked_by clk0, reset_by rst0);
277 Reg#(Bit#(64)) rg_app_wr_data <- mkDWire(0,clocked_by clk0, reset_by rst0);
278 Wire#(Bool) wr_sdr_init_done <- mkDWire(False,clocked_by clk0, reset_by rst0);
279 Wire#(Bool) wr_app_req_ack <- mkDWire(False,clocked_by clk0, reset_by rst0);
280 Wire#(Bool) wr_app_wr_next_req <- mkDWire(False,clocked_by clk0, reset_by rst0);
281 Wire#(Bool) wr_app_rd_valid <- mkDWire(False,clocked_by clk0, reset_by rst0);
282 Wire#(Bool) wr_app_last_rd <- mkDWire(False,clocked_by clk0, reset_by rst0);
283 Wire#(Bool) wr_app_last_wr <- mkDWire(False,clocked_by clk0, reset_by rst0);
284 Wire#(Bit#(64)) wr_app_rd_data <- mkWire(clocked_by clk0, reset_by rst0);
285
286
287 Reg#(Bit#(4)) rg_rid <- mkReg(0, clocked_by clk0, reset_by rst0);
288 Reg#(bit) rg_rd_not_active_flag <- mkSyncRegToCC(0,clk0, rst0);
289 Reg#(Bit#(4)) rg_ctrl_rid <- mkReg(0);
290 Reg#(Bit#(4)) rg_wid <- mkReg(0);
291
292 Reg#(Write_split_states) rg_wr_split_states <- mkReg(IDLE);
293 Reg#(Bit#(3)) rg_awsize <- mkReg(0);
294 Reg#(Bit#(9)) rg_ac_count <- mkReg(0);
295 Reg#(Bit#(6)) rg_single_burst <- mkReg(0);
296 Reg#(Bit#(64)) rg_wr_ac_data <- mkReg(0);
297 Reg#(Bit#(8)) rg_wr_ac_wstrb <- mkReg(0);
298 Reg#(Bit#(4)) rg_wr_lwr_addr <- mkReg(0);
299 Reg#(Bit#(9)) rg_local_actual_wr_length <- mkReg(0);
300 Reg#(Bit#(9)) rg_actual_wr_length <- mkSyncRegFromCC(0,clk0);
301 Reg#(Bit#(32)) rg_wr_address <- mkSyncRegFromCC(0,clk0);
302
303 Reg#(Bit#(3)) rg_awsize_sclk <- mkSyncRegFromCC(0,clk0);
304
305 Reg#(Bit#(9)) rg_burst_counter <- mkReg(0);
306
307 Bool burst_eq = (rg_burst_counter == rg_local_actual_wr_length);
308
309 Reg#(Bit#(3)) rg_packets <- mkReg(0);
310 Reg#(Bit#(3)) rg_packet_counter <- mkReg(0);
311
312
313 Reg#(Write_state) rg_write_states <- mkReg(IDLE,clocked_by clk0, reset_by rst0);
314 Reg#(Read_state) rg_read_states <- mkReg(IDLE,clocked_by clk0, reset_by rst0);
315
316 FIFOF#(AXI4_Wr_Addr#(`PADDR,`USERSPACE)) ff_wr_addr <- mkSizedFIFOF(13);
317 FIFOF#(AXI4_Wr_Data#(`Reg_width)) ff_wr_data <- mkSizedFIFOF(13);
318 SyncFIFOIfc#(Bit#(`Reg_width)) ff_ac_wr_data <- mkSyncFIFOFromCC(13,clk0);
319 SyncFIFOIfc#(Bit#(8)) ff_ac_wr_wstrb <- mkSyncFIFOFromCC(13,clk0);
320
321 SyncFIFOIfc#(Bool) ff_sync_write_response<-mkSyncFIFOToCC(1,clk0,rst0);
322
323 //FIFOF#(AXI4_Rd_Addr#(`PADDR,`USERSPACE)) ff_rd_addr <- mkSizedFIFOF(3);
324 FIFOF#(Bit#(64)) ff_rd_data <- mkSizedFIFOF(86,clocked_by clk0, reset_by rst0);
325 SyncFIFOIfc#(AXI4_Rd_Addr#(`PADDR,`USERSPACE)) ff_rd_addr <- mkSyncFIFOFromCC(30,clk0);
326 SyncFIFOIfc#(AXI4_Rd_Data#(`Reg_width,`USERSPACE)) ff_sync_read_response <-mkSyncFIFOToCC(13,clk0,rst0);
327
328 SyncFIFOIfc#(Tuple2#(Bit#(`PADDR),Bit#(`Reg_width))) ff_sync_ctrl_write<- mkSyncFIFOFromCC(1,clk0);
329 SyncFIFOIfc#(Bit#(`PADDR)) ff_sync_ctrl_read<- mkSyncFIFOFromCC(1,clk0);
330 SyncFIFOIfc#(Bit#(`Reg_width)) ff_sync_ctrl_read_response<- mkSyncFIFOToCC(1,clk0,rst0);
331
332 // Polling Registers
333 Reg#(Bit#(2)) rg_poll_cnt <- mkReg(0,clocked_by clk0, reset_by rst0);
334 Reg#(Bool) rg_polling_status <- mkSyncRegToCC(False,clk0,rst0);
335 Reg#(Bool) rg_polling_status_clk0 <- mkReg(False,clocked_by clk0, reset_by rst0);
336 Reg#(Bool) rg_rd_trnc_flg <- mkReg(False);
337 Reg#(Bool) rg_wr_trnc_flg <- mkReg(False);
338 Reg#(bit) rg_odd_len <- mkReg(0);
339
340 AXI4_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor_sdram <- mkAXI4_Slave_Xactor;
341 AXI4_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor_cntrl_reg <- mkAXI4_Slave_Xactor;
342 Ifc_sdram sdr_cntrl <- mksdrc_top(clocked_by clk0, reset_by rst0);
343
344 function Action fn_wr_cntrl_reg(Bit#(64) data, Bit#(8) address);
345 action
346 case(address)
347
348 `ACTPRE_DELAY : rg_cfg_sdr_tras_d <= data[3:0];
349
350 `PREACT_DELAY : rg_cfg_sdr_trp_d <= data[3:0];
351
352 `ACT_RW_DELAY : rg_cfg_sdr_trcd_d <= data[3:0];
353
354 `EN_SDRAM : rg_cfg_sdr_en <= data[0];
355
356 `MAX_REQ : rg_cfg_req_depth <= data[1:0];
357
358 `MODE_REG : rg_cfg_sdr_mode_reg <= data[12:0];
359
360 `CAS_LATNCY : rg_cfg_sdr_cas <= data[2:0];
361
362 `AUTO_REFRESH : rg_cfg_sdr_trcar_d <= data[3:0];
363
364 `RECRY_DELAY : rg_cfg_sdr_twr_d <= data[3:0];
365
366 `RFRSH_TIMER : rg_cfg_sdr_rfsh <= data[11:0];
367
368 `RFRSH_ROW_CNT : rg_cfg_sdr_rfmax <= data[2:0];
369
370 `SDR_WIDTH : rg_cfg_sdr_width <= data [1:0];
371
372 `SDR_COLBITS : rg_cfg_colbits <= data [1:0];
373
374
375 `SDR_CLK_DELAY : rg_cfg_sdr_clk_delay <= data [7:0];
376
377 default : noAction;
378 endcase
379 endaction
380 endfunction
381
382
383 function Bit#(64) fn_rd_cntrl_reg(Bit#(8) address);
384 case(address)
385
386 `ACTPRE_DELAY : return extend(rg_cfg_sdr_tras_d);
387
388 `PREACT_DELAY : return extend(rg_cfg_sdr_trp_d);
389
390 `ACT_RW_DELAY : return extend(rg_cfg_sdr_trcd_d);
391
392 `EN_SDRAM : return extend(rg_cfg_sdr_en);
393
394 `MAX_REQ : return extend(rg_cfg_req_depth);
395
396 `MODE_REG : return extend(rg_cfg_sdr_mode_reg);
397
398 `CAS_LATNCY : return extend(rg_cfg_sdr_cas);
399
400 `AUTO_REFRESH : return extend(rg_cfg_sdr_trcar_d);
401
402 `RECRY_DELAY : return extend(rg_cfg_sdr_twr_d);
403
404 `RFRSH_TIMER : return extend(rg_cfg_sdr_rfsh);
405
406 `RFRSH_ROW_CNT : return extend(rg_cfg_sdr_rfmax);
407
408 `SDR_INIT_DONE : return extend(pack(wr_sdr_init_done));
409
410 `SDR_WIDTH : return extend(rg_cfg_sdr_width);
411
412 `SDR_COLBITS : return extend(rg_cfg_colbits);
413
414
415 `SDR_CLK_DELAY : return extend(rg_cfg_sdr_clk_delay);
416
417 endcase
418 endfunction
419
420 //(*preempts="(rl_pop_read_request, rl_send_rd_data, rl_send_read_data, rl_flush_redundant_data), rl_write_transaction_write_start"*)
421
422 rule rl_for_writing_ctrl_reg(ff_sync_ctrl_write.notFull);
423 let aw <- pop_o(s_xactor_cntrl_reg.o_wr_addr);
424 let w <- pop_o(s_xactor_cntrl_reg.o_wr_data);
425 `ifdef verbose $display($time,"\tSDRAM: control_reg written addr %x data %x", aw.awaddr, w.wdata); `endif
426 ff_sync_ctrl_write.enq(tuple2(aw.awaddr,w.wdata));
427 let w_resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, buser: 0, bid: aw.awid};
428 s_xactor_cntrl_reg.i_wr_resp.enq(w_resp);
429 endrule
430
431 rule rl_perform_write_to_ctrl(ff_sync_ctrl_write.notEmpty);
432 let {awaddr,wdata}=ff_sync_ctrl_write.first;
433 `ifdef verbose $display("\tSDRAM: "); `endif
434 ff_sync_ctrl_write.deq;
435 `ifdef verbose $display($time,"\tSDRAM: Actually writing data: %h to addr: %h", wdata, awaddr); `endif
436 fn_wr_cntrl_reg(wdata , truncate(awaddr));
437 endrule
438
439 rule rl_for_read_cntrl_reg;
440 let ar <- pop_o(s_xactor_cntrl_reg.o_rd_addr);
441 ff_sync_ctrl_read.enq(ar.araddr);
442 rg_ctrl_rid<=ar.arid;
443 endrule
444
445 rule rl_send_ctrl_read_response(ff_sync_ctrl_read.notEmpty);
446 ff_sync_ctrl_read_response.enq(fn_rd_cntrl_reg(truncate(ff_sync_ctrl_read.first)));
447 ff_sync_ctrl_read.deq;
448 endrule
449
450 rule sync_ctr_response(ff_sync_ctrl_read_response.notEmpty);
451 ff_sync_ctrl_read_response.deq;
452 let r = AXI4_Rd_Data {rresp: AXI4_OKAY, rdata:ff_sync_ctrl_read_response.first , rlast: True, ruser: 0, rid: rg_ctrl_rid};
453 s_xactor_cntrl_reg.i_rd_data.enq(r);
454 endrule
455
456 rule rl_direct_connection_insdram;
457 sdr_cntrl.iapp_req(rg_app_req);
458 sdr_cntrl.iapp_req_wrap(rg_app_req_wrap);
459 sdr_cntrl.iapp_req_addr(rg_app_req_addr);
460 sdr_cntrl.iapp_req_len(rg_app_req_len);
461 sdr_cntrl.iapp_req_wr_n(rg_app_req_wr_n);
462 sdr_cntrl.iapp_wr_data(rg_app_wr_data);
463 sdr_cntrl.iapp_wr_en_n(rg_app_wr_en_n);
464 endrule
465
466 rule rl_direct_connection_outsdram;
467 wr_sdr_init_done <= sdr_cntrl.osdr_init_done ;
468 wr_app_req_ack <= sdr_cntrl.oapp_req_ack ();
469 wr_app_wr_next_req <= sdr_cntrl.oapp_wr_next_req ();
470 wr_app_rd_valid <= sdr_cntrl.oapp_rd_valid ();
471 wr_app_last_rd <= sdr_cntrl.oapp_last_rd ();
472 wr_app_last_wr <= sdr_cntrl.oapp_last_wr ();
473 wr_app_rd_data <= sdr_cntrl.oapp_rd_data ();
474 endrule
475
476 rule rl_direct_connection_config_reg;
477 sdr_cntrl.icfg_sdr_tras_d(rg_cfg_sdr_tras_d);
478 sdr_cntrl.icfg_sdr_trp_d(rg_cfg_sdr_trp_d);
479 sdr_cntrl.icfg_sdr_trcd_d(rg_cfg_sdr_trcd_d);
480 sdr_cntrl.icfg_sdr_en(rg_cfg_sdr_en);
481 sdr_cntrl.icfg_req_depth(rg_cfg_req_depth);
482 sdr_cntrl.icfg_sdr_mode_reg(rg_cfg_sdr_mode_reg);
483 sdr_cntrl.icfg_sdr_cas(rg_cfg_sdr_cas);
484 sdr_cntrl.icfg_sdr_trcar_d(rg_cfg_sdr_trcar_d);
485 sdr_cntrl.icfg_sdr_twr_d(rg_cfg_sdr_twr_d);
486 sdr_cntrl.icfg_sdr_rfsh(rg_cfg_sdr_rfsh);
487 sdr_cntrl.icfg_sdr_rfmax(rg_cfg_sdr_rfmax);
488 sdr_cntrl.icfg_sdr_width(rg_cfg_sdr_width);
489 sdr_cntrl.icfg_colbits(rg_cfg_colbits);
490 endrule
491
492 rule rl_intial_polling(rg_polling_status_clk0 == False && wr_sdr_init_done == True);
493 `ifdef verbose $display($time,"\tSDRAM: POLLING MODE: %d",rg_poll_cnt); `endif
494 case (rg_poll_cnt)
495 0: begin
496 rg_app_req <= 1;
497 rg_app_req_addr <= 0;
498 rg_app_req_len <= 1;
499 rg_app_req_wr_n <= 0;
500 rg_app_wr_en_n <= 'hFF;
501 rg_app_wr_data <= 0;
502 rg_poll_cnt <= rg_poll_cnt + 1;
503 end
504 1: begin
505 rg_app_req <= 1;
506 rg_app_req_addr <= 0;
507 rg_app_req_len <= 1;
508 rg_app_req_wr_n <= 0;
509 rg_app_wr_en_n <= 'hFF;
510 rg_app_wr_data <= 0;
511 rg_poll_cnt <= rg_poll_cnt + 1;
512 end
513 2: begin
514 rg_app_req <= 0;
515 rg_app_req_addr <= 0;
516 rg_app_wr_en_n <= 'hFF;
517 rg_app_wr_data <= 0;
518 if(wr_app_wr_next_req == True)
519 rg_poll_cnt <= rg_poll_cnt + 1;
520 end
521 3: begin
522 rg_polling_status <= True;
523 rg_polling_status_clk0<=True;
524 end
525 endcase
526 endrule
527
528 /******************* WRITE TRANSACTION ****************/
529
530 rule rl_parallel_data_enq(rg_polling_status == True && rg_rd_trnc_flg == False);
531 let aw <- pop_o(s_xactor_sdram.o_wr_addr);
532 let w <- pop_o(s_xactor_sdram.o_wr_data);
533 ff_wr_addr.enq(aw);
534 ff_wr_data.enq(w);
535 rg_wr_trnc_flg <= True;
536 `ifdef verbose $display($time,"\tSDRAM: WRITE_FIRST Parallel enq %h addr: %h",w.wdata,aw.awaddr); `endif
537 endrule
538
539 rule rl_write_split_state(rg_wr_split_states == IDLE);
540 let aw = ff_wr_addr.first();
541 if(aw.awsize != 3) begin
542 rg_actual_wr_length <= fn_wr_len(aw.awlen, aw.awsize, aw.awaddr[2:0]);
543
544 rg_local_actual_wr_length <= extend(aw.awlen);
545 end
546 else begin
547 rg_actual_wr_length <= extend(aw.awlen) + 1;
548 rg_local_actual_wr_length <= extend(aw.awlen);
549 end
550 rg_wid <= aw.awid;
551 rg_awsize <= aw.awsize;
552 rg_awsize_sclk <= aw.awsize;
553 rg_wr_address <= aw.awaddr;
554 rg_wr_lwr_addr <= extend(aw.awaddr[2:0]);
555 rg_wr_split_states <= START_SPLIT;
556 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];
557 rg_packet_counter <= (aw.awaddr[2:0]) >> aw.awsize;
558 `ifdef verbose $display($time,"Initial Values -- Starting IDLE to START_SPLIT"); `endif
559 //$display("Initial Values: rg_packets: %h rg_packet_counter: %h ",(64>>(aw.awsize+4)),aw.awaddr[2:0]>>aw.awsize);
560 rg_burst_counter <= 0;
561 endrule
562
563
564 rule rl_write_data_splitting0(rg_wr_split_states == START_SPLIT && rg_awsize != 3);
565 rg_wr_ac_data <= rg_wr_ac_data | fn_wr_split_data(ff_wr_data.first.wdata,ff_wr_data.first.wstrb);
566 rg_wr_ac_wstrb <= rg_wr_ac_wstrb | ff_wr_data.first.wstrb;
567 rg_burst_counter <= rg_burst_counter + 1;
568 `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
569 if(burst_eq || rg_packets == rg_packet_counter) begin
570 rg_wr_split_states <= SEND_VALUE;
571 end
572 else begin
573 rg_packet_counter <= rg_packet_counter + 1;
574 end
575 ff_wr_data.deq();
576 ff_wr_addr.deq();
577 endrule
578
579 rule rl_write_data_splitting1(rg_wr_split_states == SEND_VALUE && rg_awsize != 3);
580 `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
581 ff_ac_wr_data.enq(rg_wr_ac_data);
582 ff_ac_wr_wstrb.enq(rg_wr_ac_wstrb);
583 rg_wr_ac_data <= 0;
584 rg_wr_ac_wstrb <= 0;
585 rg_wr_lwr_addr <= 0;
586 rg_packet_counter <= 0;
587 `ifdef verbose $display($time,"Sending Value to the SDRAM"); `endif
588 rg_wr_split_states <= START_SPLIT;
589 endrule
590
591
592 rule rl_write_data_spliting3(rg_wr_split_states == START_SPLIT && rg_awsize == 3);
593 ff_ac_wr_data.enq(ff_wr_data.first.wdata);
594 ff_ac_wr_wstrb.enq(ff_wr_data.first.wstrb);
595 ff_wr_data.deq();
596 ff_wr_addr.deq();
597 endrule
598
599
600 rule rl_start_write_transaction(rg_write_states == IDLE && wr_sdr_init_done == True);
601 if(ff_ac_wr_data.notEmpty()) begin
602 if(rg_awsize_sclk == 0)
603 rg_write_states <= WAIT_DELAY;
604 else
605 rg_write_states <= WRITE_START;
606 `ifdef verbose $display($time,"\tSDRAM: Going to write start state"); `endif
607 end
608 endrule
609
610 rule rl_wait_delay(rg_write_states == WAIT_DELAY);
611 if(rg_delay_count == 14) begin
612 rg_write_states <= WRITE_START;
613 rg_delay_count <= 0;
614 end
615 else
616 rg_delay_count <= rg_delay_count + 1;
617 endrule
618
619 rule rl_write_transaction_write_start(rg_write_states == WRITE_START && wr_sdr_init_done == True && rg_read_states == IDLE);
620 `ifdef verbose $display($time,"\tSDRAM: WRITE_START state Controller Length %d",rg_actual_wr_length); `endif
621 rg_app_req <= 1;
622 rg_app_req_addr <= fn_wr_address(rg_wr_address);
623 rg_app_req_len <= extend(rg_actual_wr_length);
624 rg_app_req_wr_n <= 0;
625 rg_app_wr_data <= 0;
626 rg_app_wr_en_n <= 8'hFF;
627 rg_write_states <= WRITE_FIRST;
628 rg_delay_count <= extend(rg_actual_wr_length) - 1;
629 endrule
630
631 rule rl_write_transaction_write_first(rg_write_states == WRITE_FIRST && wr_app_wr_next_req == False);
632 `ifdef verbose $display($time,"\tSDRAM: WRITE_FIRST state next is false data %x",ff_ac_wr_data.first); `endif
633 rg_app_req <= 0;
634 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
635 rg_app_wr_data <= ff_ac_wr_data.first();
636 endrule
637
638 rule rl_write_transaction_write_data(rg_write_states == WRITE_FIRST && wr_app_wr_next_req == True);
639 `ifdef verbose $display($time,"\tSDRAM: WRITE_DATA state next is true sending data %x %b",ff_ac_wr_data.first,wr_app_wr_next_req); `endif
640 rg_app_req <= 0;
641 rg_app_wr_data <= ff_ac_wr_data.first();
642 rg_app_wr_en_n <= ~(ff_ac_wr_wstrb.first());
643 ff_ac_wr_data.deq;
644 ff_ac_wr_wstrb.deq;
645 rg_delay_count <= rg_delay_count - 1;
646 if(rg_delay_count == 0) begin
647 rg_write_states <= IDLE;
648 ff_sync_write_response.enq(True);
649 end
650 endrule
651
652 rule synchronize_write_response(ff_sync_write_response.notEmpty);
653 ff_sync_write_response.deq;
654 let w_resp = AXI4_Wr_Resp {bresp: AXI4_OKAY, buser: 0, bid: rg_wid}; //TODO user value is null
655 s_xactor_sdram.i_wr_resp.enq(w_resp);
656 rg_wr_split_states <= IDLE;
657 rg_ac_count <= 0;
658 rg_wr_trnc_flg <= False;
659 `ifdef verbose $display($time,"\tSDRAM: WRITE complete state true"); `endif
660 endrule
661
662 /****************** Read Transaction ********************/
663 // `ifdef verbose
664 // rule display_read_states;
665 // $display($time,"\tSDRAM: Read State: ",fshow(rg_read_states));
666 // endrule
667 // `endif
668 rule rl_paralel_read_req_enq(rg_polling_status == True && rg_wr_trnc_flg == False);
669 let ar <- pop_o(s_xactor_sdram.o_rd_addr);
670 ff_rd_addr.enq(ar);
671 rg_rd_trnc_flg <= True;
672 `ifdef verbose $display($time,"\tSDRAM: Got Read request from AXI for AddresS: %h",ar.araddr); `endif
673 endrule
674
675 rule rl_read_idle_state(rg_read_states == IDLE);
676 if(ff_rd_addr.notEmpty() == True) begin
677 rg_read_states <= START_READ;
678 rg_rd_not_active_flag <= 0;
679 `ifdef verbose $display($time,"\tSDRAM: READ IDLE state"); `endif
680 end
681
682 endrule
683
684 rule rl_pop_read_request(wr_sdr_init_done == True && rg_read_states == START_READ && (rg_write_states == IDLE || rg_write_states == WRITE_START));
685 let ar = ff_rd_addr.first;
686 `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
687
688 rg_app_req <= 1;
689 if(ar.arburst == 2)
690 rg_app_req_wrap <= 1;
691 else
692 rg_app_req_wrap <= 0;
693 rg_lwraddr <= extend(ar.araddr[2:0]);
694 rg_arsize <= ar.arsize;
695 rg_app_req_addr <= fn_wr_address(ar.araddr);
696 rg_app_req_len <= fn_wr_len(ar.arlen, ar.arsize, ar.araddr[2:0]);
697 rg_rd_actual_len <= extend(ar.arlen);
698 rg_app_req_wr_n <= 1;
699 rg_delay_count <= 0;
700 rg_read_states <= READ_DATA;
701 rg_rid <= ar.arid;
702 `ifdef verbose $display($time,"\t SSSSS SDRAM START_READ length "); `endif
703 endrule
704
705 rule rl_send_rd_data(wr_app_rd_valid == True);
706 `ifdef verbose $display($time,"\tSDRAM: READ DATA1 state %x",wr_app_rd_data); `endif
707 ff_rd_data.enq(wr_app_rd_data);
708 endrule
709
710 rule rl_send_read_data(rg_read_states==READ_DATA);
711 `ifdef verbose $display($time,"\tSDRAM: Response from BFM. RequestLenght: %d CurrentCount: %d",rg_rd_actual_len,rg_delay_count); `endif
712 rg_app_req_wrap <= 0;
713 if(rg_lwraddr < 8) begin
714 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};
715 ff_sync_read_response.enq(r);
716 ff_rd_addr.deq;
717 if(rg_arsize!=3)
718 rg_lwraddr <= rg_lwraddr + (1 << rg_arsize);
719 else
720 ff_rd_data.deq;
721 `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
722 `ifdef verbose $display($time,"\tSDRAM: Removing Request for Addr : %h",ff_rd_addr.first.araddr); `endif
723 if(rg_delay_count == rg_rd_actual_len) begin
724 `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
725 rg_read_states <= READ_FLUSH;
726 rg_rd_not_active_flag <= 1;
727 rg_delay_count <= 0;
728 end
729 else
730 rg_delay_count <= rg_delay_count + 1;
731 end
732 else if(rg_lwraddr > 7) begin
733 `ifdef verbose $display($time,"\tSDRAM: Dequeuing ff READ"); `endif
734 rg_lwraddr <= 0;
735 ff_rd_data.deq;
736 end
737 endrule
738
739 rule rl_flush_redundant_data(rg_read_states == READ_FLUSH);
740 ff_rd_data.clear();
741 rg_read_states <= IDLE;
742 endrule
743
744 rule send_synchronized_read_response(ff_sync_read_response.notEmpty);
745 let r=ff_sync_read_response.first;
746 `ifdef verbose $display($time,"\tSDRAM: Sending Read response: %h rlast: %b",r.rdata,r.rlast); `endif
747 ff_sync_read_response.deq;
748 if(rg_rd_not_active_flag == 1)
749 rg_rd_trnc_flg <= False;
750 s_xactor_sdram.i_rd_data.enq(r);
751 endrule
752
753
754
755
756
757 interface Ifc_sdram_out ifc_sdram_out;
758
759 interface ipad_sdr_din = interface Put
760 method Action put(Bit#(64) in);
761 sdr_cntrl.ipad_sdr_din(in);
762 endmethod
763 endinterface;
764
765 interface osdr_dout = interface Get
766 method ActionValue#(Bit#(64)) get;
767 return sdr_cntrl.osdr_dout();
768 endmethod
769 endinterface;
770
771 interface osdr_den_n = interface Get
772 method ActionValue#(Bit#(64)) get;
773 Bit#(64) temp;
774 for (int i=0; i<8; i=i+1) begin
775 temp[i*8] = sdr_cntrl.osdr_den_n[i];
776 end
777 return temp;
778 endmethod
779 endinterface;
780
781 interface osdr_cke = interface Get
782 method ActionValue#(Bit#(1)) get;
783 return pack(sdr_cntrl.osdr_cke());
784 endmethod
785 endinterface;
786
787 interface osdr_cs_n = interface Get
788 method ActionValue#(Bit#(1)) get;
789 return pack(sdr_cntrl.osdr_cs_n());
790 endmethod
791 endinterface;
792
793 interface osdr_ras_n = interface Get
794 method ActionValue#(Bit#(1)) get;
795 return pack(sdr_cntrl.osdr_ras_n);
796 endmethod
797 endinterface;
798
799 interface osdr_cas_n = interface Get
800 method ActionValue#(Bit#(1)) get;
801 return pack(sdr_cntrl.osdr_cas_n);
802 endmethod
803 endinterface;
804
805 interface osdr_we_n = interface Get
806 method ActionValue#(Bit#(1)) get;
807 return pack(sdr_cntrl.osdr_we_n);
808 endmethod
809 endinterface;
810
811 interface osdr_dqm = interface Get
812 method ActionValue#(Bit#(8)) get;
813 return sdr_cntrl.osdr_dqm;
814 endmethod
815 endinterface;
816
817 interface osdr_ba = interface Get
818 method ActionValue#(Bit#(2)) get;
819 return sdr_cntrl.osdr_ba;
820 endmethod
821 endinterface;
822
823 interface osdr_addr = interface Get
824 method ActionValue#(Bit#(13)) get;
825 return sdr_cntrl.osdr_addr;
826 endmethod
827 endinterface;
828
829 interface osdr_clock = interface Get
830 method ActionValue#(Bit#(1)) get;
831 return ?;
832 endmethod
833 endinterface;
834 endinterface
835
836 interface axi4_slave_sdram = s_xactor_sdram.axi_side;
837 interface axi4_slave_cntrl_reg = s_xactor_cntrl_reg.axi_side;
838
839 endmodule
840 endpackage