1 //----------------------------------------------------------------------------
3 // Wishbone DDR Controller -- fast write data-path
5 // (c) Joerg Bornschein (<jb@capsec.org>)
7 //----------------------------------------------------------------------------
9 `include "ddr_include.v"
17 input [`CBA_RNG] cba_din,
22 input [`WFIFO_RNG] wdata_din,
33 output [ `A_RNG] ddr_a,
34 output [ `BA_RNG] ddr_ba,
35 output [ `DM_RNG] ddr_dm,
36 output [ `DQ_RNG] ddr_dq,
37 output [`DQS_RNG] ddr_dqs,
44 //----------------------------------------------------------------------------
46 //----------------------------------------------------------------------------
47 wire [`CBA_RNG] cba_data;
51 wire cba_avail = ~cba_empty;
54 .DATA_WIDTH( `CBA_WIDTH ),
57 .Data_out( cba_data ),
58 .Empty_out( cba_empty ),
59 .ReadEn_in( cba_ack ),
63 .WriteEn_in( cba_wr ),
64 .Full_out( cba_full ),
69 //----------------------------------------------------------------------------
71 //----------------------------------------------------------------------------
72 wire [`WFIFO_RNG] wdata_data;
76 wire wdata_avail = ~wdata_empty;
79 .DATA_WIDTH( `WFIFO_WIDTH ),
82 .Data_out( wdata_data ),
83 .Empty_out( wdata_empty ),
84 .ReadEn_in( wdata_ack ),
87 .Data_in( wdata_din ),
88 .WriteEn_in( wdata_wr ),
89 .Full_out( wdata_full ),
95 //----------------------------------------------------------------------------
97 //----------------------------------------------------------------------------
98 reg [3:0] delay_count;
100 reg [`CBA_RNG] ddr_cba;
101 wire [`CBA_RNG] CBA_NOP = { `DDR_CMD_NOP, 15'b0 };
103 assign cba_ack = cba_avail & (delay_count == 0);
105 wire [`CMD_RNG] cba_cmd = cba_data[(`CBA_WIDTH-1):(`CBA_WIDTH-3)];
107 always @(posedge clk)
113 if (delay_count != 0) begin
114 delay_count <= delay_count - 1;
124 `DDR_CMD_MRS : delay_count <= 2;
125 `DDR_CMD_AR : delay_count <= 14;
126 `DDR_CMD_ACT : delay_count <= 4;
127 `DDR_CMD_PRE : delay_count <= 2;
128 `DDR_CMD_READ : delay_count <= 6; // XXX
129 `DDR_CMD_WRITE : delay_count <= 8; // XXX
136 //----------------------------------------------------------------------------
137 // READ-SHIFT-REGISTER
138 //----------------------------------------------------------------------------
140 wire read_cmd = (cba_cmd == `DDR_CMD_READ) & cba_ack;
141 assign sample = read_shr[1];
143 always @(posedge clk)
149 read_shr <= { 8'b00011111 };
151 read_shr <= { read_shr[1:7], 1'b0 };
155 //----------------------------------------------------------------------------
156 // WRITE-SHIFT-REGISTER
157 //----------------------------------------------------------------------------
160 wire write_cmd = (cba_cmd == `DDR_CMD_WRITE) & cba_ack;
162 always @(posedge clk)
168 write_shr <= { 5'b11111 };
170 write_shr <= { write_shr[1:4], 1'b0 };
174 //----------------------------------------------------------------------------
175 // DDR_DQS, DDR_DQS_OE
176 //----------------------------------------------------------------------------
180 assign ddr_dqs_oe = ddr_dqs_oe_reg;
182 always @(negedge clk)
184 ddr_dqs_oe_reg <= write_shr[0];
187 FDDRRSE ddr_clk_reg (
198 FDDRRSE ddr_clk_n_reg (
211 for (i=0; i<`DQS_WIDTH; i=i+1) begin : DQS
212 FDDRRSE ddr_dqs_reg (
226 //----------------------------------------------------------------------------
228 //----------------------------------------------------------------------------
229 wire [`DQ_RNG] buf_d0;
230 wire [`DM_RNG] buf_m0;
231 reg [`DQ_RNG] buf_d1; // pipleine high word data
232 reg [`DM_RNG] buf_m1; // pipleine high word mask
234 assign buf_d0 = wdata_data[`WFIFO_D0_RNG];
235 assign buf_m0 = wdata_data[`WFIFO_M0_RNG];
237 always @(negedge clk90)
239 buf_d1 <= wdata_data[`WFIFO_D1_RNG];
240 buf_m1 <= wdata_data[`WFIFO_M1_RNG];
243 assign wdata_ack = write_shr[1];
245 // generate DDR_DQ register
247 for (i=0; i<`DQ_WIDTH; i=i+1) begin : DQ_REG
261 // generate DDR_DM register
263 for (i=0; i<`DM_WIDTH; i=i+1) begin : DM_REG
277 //----------------------------------------------------------------------------
278 // Connect ddr_cba to actual DDR pins
279 //----------------------------------------------------------------------------
280 assign ddr_a = ddr_cba[(`A_WIDTH-1):0];
281 assign ddr_ba = ddr_cba[(`A_WIDTH+`BA_WIDTH-1):(`A_WIDTH)];
282 assign ddr_ras_n = ddr_cba[(`CBA_WIDTH-1)];
283 assign ddr_cas_n = ddr_cba[(`CBA_WIDTH-2)];
284 assign ddr_we_n = ddr_cba[(`CBA_WIDTH-3)];