📄 ddr_wpath.v
字号:
//---------------------------------------------------------------------------- 2 // 3 // Wishbone DDR Controller -- fast write data-path 4 // 5 // (c) Joerg Bornschein (<jb@capsec.org>) 6 // 7 //---------------------------------------------------------------------------- 8 9 `include "ddr_include.v" 10 11 module ddr_wpath ( 12 input clk, 13 input clk90, 14 input reset, 15 // CBA async fifo 16 input cba_clk, 17 input [`CBA_RNG] cba_din, 18 input cba_wr, 19 output cba_full, 20 // WDATA async fifo 21 input wdata_clk, 22 input [`WFIFO_RNG] wdata_din, 23 input wdata_wr, 24 output wdata_full, 25 // sample to rdata 26 output sample, 27 // DDR 28 output ddr_clk, 29 output ddr_clk_n, 30 output ddr_ras_n, 31 output ddr_cas_n, 32 output ddr_we_n, 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, 38 output ddr_dqs_oe 39 ); 40 41 wire gnd = 1'b0; 42 wire vcc = 1'b1; 43 44 //---------------------------------------------------------------------------- 45 // CBA async. fifo 46 //---------------------------------------------------------------------------- 47 wire [`CBA_RNG] cba_data; 48 wire cba_empty; 49 wire cba_ack; 50 51 wire cba_avail = ~cba_empty; 52 53 async_fifo #( 54 .DATA_WIDTH( `CBA_WIDTH ), 55 .ADDRESS_WIDTH( 3 ) 56 ) cba_fifo ( 57 .Data_out( cba_data ), 58 .Empty_out( cba_empty ), 59 .ReadEn_in( cba_ack ), 60 .RClk( clk ), 61 // 62 .Data_in( cba_din ), 63 .WriteEn_in( cba_wr ), 64 .Full_out( cba_full ), 65 .WClk( cba_clk ), 66 .Clear_in( reset ) 67 ); 68 69 //---------------------------------------------------------------------------- 70 // WDATA async. fifo 71 //---------------------------------------------------------------------------- 72 wire [`WFIFO_RNG] wdata_data; 73 wire wdata_empty; 74 wire wdata_ack; 75 76 wire wdata_avail = ~wdata_empty; 77 78 async_fifo #( 79 .DATA_WIDTH( `WFIFO_WIDTH ), 80 .ADDRESS_WIDTH( 3 ) 81 ) wdata_fifo ( 82 .Data_out( wdata_data ), 83 .Empty_out( wdata_empty ), 84 .ReadEn_in( wdata_ack ), 85 .RClk( ~clk90 ), 86 // 87 .Data_in( wdata_din ), 88 .WriteEn_in( wdata_wr ), 89 .Full_out( wdata_full ), 90 .WClk( wdata_clk ), 91 .Clear_in( reset ) 92 ); 93 94 95 //---------------------------------------------------------------------------- 96 // Handle CBA 97 //---------------------------------------------------------------------------- 98 reg [3:0] delay_count; 99 100 reg [`CBA_RNG] ddr_cba; 101 wire [`CBA_RNG] CBA_NOP = { `DDR_CMD_NOP, 15'b0 }; 102 103 assign cba_ack = cba_avail & (delay_count == 0); 104 105 wire [`CMD_RNG] cba_cmd = cba_data[(`CBA_WIDTH-1):(`CBA_WIDTH-3)]; 106 107 always @(posedge clk) 108 begin 109 if (reset) begin 110 delay_count <= 0; 111 ddr_cba <= CBA_NOP; 112 end else begin 113 if (delay_count != 0) begin 114 delay_count <= delay_count - 1; 115 ddr_cba <= CBA_NOP; 116 end 117 118 if (!cba_ack) begin 119 ddr_cba <= CBA_NOP; 120 end else begin 121 ddr_cba <= cba_data; 122 123 case (cba_cmd) 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 130 endcase 131 end 132 end 133 end 134 135 136 //---------------------------------------------------------------------------- 137 // READ-SHIFT-REGISTER 138 //---------------------------------------------------------------------------- 139 reg [0:7] read_shr; 140 wire read_cmd = (cba_cmd == `DDR_CMD_READ) & cba_ack; 141 assign sample = read_shr[1]; 142 143 always @(posedge clk) 144 begin 145 if (reset) 146 read_shr <= 'b0; 147 else begin 148 if (read_cmd) 149 read_shr <= { 8'b00011111 }; 150 else 151 read_shr <= { read_shr[1:7], 1'b0 }; 152 end 153 end 154 155 //---------------------------------------------------------------------------- 156 // WRITE-SHIFT-REGISTER 157 //---------------------------------------------------------------------------- 158 159 reg [0:4] write_shr; 160 wire write_cmd = (cba_cmd == `DDR_CMD_WRITE) & cba_ack; 161 162 always @(posedge clk) 163 begin 164 if (reset) 165 write_shr <= 'b0; 166 else begin 167 if (write_cmd) 168 write_shr <= { 5'b11111 }; 169 else 170 write_shr <= { write_shr[1:4], 1'b0 }; 171 end 172 end 173 174 //---------------------------------------------------------------------------- 175 // DDR_DQS, DDR_DQS_OE 176 //---------------------------------------------------------------------------- 177 genvar i; 178 179 reg ddr_dqs_oe_reg; 180 assign ddr_dqs_oe = ddr_dqs_oe_reg; 181 182 always @(negedge clk) 183 begin 184 ddr_dqs_oe_reg <= write_shr[0]; 185 end 186 187 FDDRRSE ddr_clk_reg ( 188 .Q( ddr_clk ), 189 .C0( clk90 ), 190 .C1( ~clk90 ), 191 .CE( vcc ), 192 .D0( vcc ), 193 .D1( gnd ), 194 .R( gnd ), 195 .S( gnd ) 196 ); 197 198 FDDRRSE ddr_clk_n_reg ( 199 .Q( ddr_clk_n ), 200 .C0( clk90 ), 201 .C1( ~clk90 ), 202 .CE( vcc ), 203 .D0( gnd ), 204 .D1( vcc ), 205 .R( gnd ), 206 .S( gnd ) 207 ); 208 209 210 generate 211 for (i=0; i<`DQS_WIDTH; i=i+1) begin : DQS 212 FDDRRSE ddr_dqs_reg ( 213 .Q( ddr_dqs[i] ), 214 .C0( clk ), 215 .C1( ~clk ), 216 .CE( vcc ), 217 .D0( write_shr[1] ), 218 .D1( gnd ), 219 .R( gnd ), 220 .S( gnd ) 221 ); 222 end 223 endgenerate 224 225 226 //---------------------------------------------------------------------------- 227 // DQ data output 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 233 234 assign buf_d0 = wdata_data[`WFIFO_D0_RNG]; 235 assign buf_m0 = wdata_data[`WFIFO_M0_RNG]; 236 237 always @(negedge clk90) 238 begin 239 buf_d1 <= wdata_data[`WFIFO_D1_RNG]; 240 buf_m1 <= wdata_data[`WFIFO_M1_RNG]; 241 end 242 243 assign wdata_ack = write_shr[1]; 244 245 // generate DDR_DQ register 246 generate 247 for (i=0; i<`DQ_WIDTH; i=i+1) begin : DQ_REG 248 FDDRRSE ddr_dq_reg ( 249 .Q( ddr_dq[i] ), 250 .C0( ~clk90 ), 251 .C1( clk90 ), 252 .CE( vcc ), 253 .D0( buf_d0[i] ), 254 .D1( buf_d1[i] ), 255 .R( gnd ), 256 .S( gnd ) 257 ); 258 end 259 endgenerate 260 261 // generate DDR_DM register 262 generate 263 for (i=0; i<`DM_WIDTH; i=i+1) begin : DM_REG 264 FDDRRSE ddr_dm_reg ( 265 .Q( ddr_dm[i] ), 266 .C0( ~clk90 ), 267 .C1( clk90 ), 268 .CE( vcc ), 269 .D0( buf_m0[i] ), 270 .D1( buf_m1[i] ), 271 .R( gnd ), 272 .S( gnd ) 273 ); 274 end 275 endgenerate 276 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)]; 285 286 endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -