📄 ddr_ctrl.v
字号:
//---------------------------------------------------------------------------- 2 // Pipelined, asyncronous DDR Controller 3 // 4 // (c) Joerg Bornschein (<jb@capsec.org>) 5 //---------------------------------------------------------------------------- 6 module ddr_ctrl 7 #( 8 parameter clk_freq = 50000000, 9 parameter clk_multiply = 12, 10 parameter clk_divide = 5, 11 parameter phase_shift = 0, 12 parameter wait200_init = 26 13 ) ( 14 input clk, 15 input reset, 16 // DDR ports 17 output ddr_clk, 18 output ddr_clk_n, 19 input ddr_clk_fb, 20 output ddr_ras_n, 21 output ddr_cas_n, 22 output ddr_we_n, 23 output ddr_cke, 24 output ddr_cs_n, 25 output [ `A_RNG] ddr_a, 26 output [ `BA_RNG] ddr_ba, 27 inout [ `DQ_RNG] ddr_dq, 28 inout [`DQS_RNG] ddr_dqs, 29 output [ `DM_RNG] ddr_dm, 30 // FML (FastMemoryLink) 31 input fml_wr, 32 input fml_rd, 33 output reg fml_done, 34 input [`FML_ADR_RNG] fml_adr, 35 input [`FML_DAT_RNG] fml_din, 36 input [`FML_MSK_RNG] fml_msk, 37 output reg [`FML_DAT_RNG] fml_dout, 38 // Temporary DCM control input 39 input [2:0] rot // XXX 40 ); 41 42 wire [ `DQ_RNG] ddr_dq_i, ddr_dq_o; 43 wire [`DQS_RNG] ddr_dqs_i, ddr_dqs_o; 44 wire ddr_dqs_oe; 45 46 //---------------------------------------------------------------------------- 47 // clock generator 48 //---------------------------------------------------------------------------- 49 wire clk_locked; 50 wire write_clk, write_clk90; 51 wire read_clk; 52 53 wire reset_int = reset | ~clk_locked; 54 55 ddr_clkgen #( 56 .phase_shift( phase_shift ), 57 .clk_multiply( clk_multiply ), 58 .clk_divide( clk_divide ) 59 ) clkgen ( 60 .clk( clk ), 61 .reset( reset ), 62 .locked( clk_locked ), 63 // ddr-clk 64 .read_clk( read_clk ), 65 .write_clk( write_clk ), 66 .write_clk90( write_clk90 ), 67 // phase shift control 68 .rot( rot ) // XXX 69 ); 70 71 //---------------------------------------------------------------------------- 72 // async_fifos (cmd, wdata, rdata) 73 //---------------------------------------------------------------------------- 74 wire cba_fifo_full; 75 reg [`CBA_RNG] cba_fifo_din; 76 reg cba_fifo_we; 77 78 wire wfifo_full; 79 reg [`WFIFO_RNG] wfifo_din; 80 reg wfifo_we; 81 82 83 wire [`RFIFO_RNG] rfifo_dout; 84 wire rfifo_empty; 85 wire rfifo_next; 86 87 //---------------------------------------------------------------------------- 88 // High-speed cmd, write and read datapath 89 //---------------------------------------------------------------------------- 90 ddr_wpath wpath0 ( 91 .clk( write_clk ), 92 .clk90( write_clk90 ), 93 .reset( reset_int ), 94 // CBA async fifo 95 .cba_clk( clk ), 96 .cba_din( cba_fifo_din ), 97 .cba_wr( cba_fifo_we ), 98 .cba_full( cba_fifo_full ), 99 // WDATA async fifo 100 .wdata_clk( clk ), 101 .wdata_din( wfifo_din ), 102 .wdata_wr( wfifo_we ), 103 .wdata_full( wfifo_full ), 104 // 105 .sample( sample ), 106 // DDR 107 .ddr_clk( ddr_clk ), 108 .ddr_clk_n( ddr_clk_n ), 109 .ddr_ras_n( ddr_ras_n ), 110 .ddr_cas_n( ddr_cas_n ), 111 .ddr_we_n( ddr_we_n ), 112 .ddr_a( ddr_a ), 113 .ddr_ba( ddr_ba ), 114 .ddr_dm( ddr_dm ), 115 .ddr_dq( ddr_dq_o ), 116 .ddr_dqs( ddr_dqs_o ), 117 .ddr_dqs_oe( ddr_dqs_oe ) 118 ); 119 120 ddr_rpath rpath0 ( 121 .clk( read_clk ), 122 .reset( reset_int ), 123 // 124 .sample( sample ), 125 // 126 .rfifo_clk( clk ), 127 .rfifo_empty( rfifo_empty), 128 .rfifo_dout( rfifo_dout ), 129 .rfifo_next( rfifo_next ), 130 // DDR 131 .ddr_dq( ddr_dq_i ), 132 .ddr_dqs( ddr_dqs_i ) 133 ); 134 135 //---------------------------------------------------------------------------- 136 // 7.8 us pulse generator 137 //---------------------------------------------------------------------------- 138 wire pulse78; 139 reg ar_req; 140 reg ar_done; 141 142 ddr_pulse78 #( 143 .clk_freq( clk_freq ) 144 ) pulse78_gen ( 145 .clk( clk ), 146 .reset( reset_int ), 147 .pulse78( pulse78 ) 148 ); 149 150 //---------------------------------------------------------------------------- 151 // Auto Refresh request generator 152 //---------------------------------------------------------------------------- 153 always @(posedge clk) 154 if (reset_int) 155 ar_req <= 0; 156 else 157 ar_req <= pulse78 | (ar_req & ~ar_done); 158 159 // operations we might want to submit 160 wire [`CBA_RNG] ar_pre_cba; 161 wire [`CBA_RNG] ar_ar_cba; 162 163 assign ar_pre_cba = { `DDR_CMD_PRE, 2'b00, 13'b1111111111111 }; 164 assign ar_ar_cba = { `DDR_CMD_AR, 2'b00, 13'b0000000000000 }; 165 166 //---------------------------------------------------------------------------- 167 // Init & management 168 //---------------------------------------------------------------------------- 169 wire init_req; 170 reg init_ack; 171 wire [`CBA_RNG] init_cba; 172 wire init_done; 173 wire wait200; 174 175 ddr_init #( 176 .wait200_init( wait200_init ) 177 ) init ( 178 .clk( clk ), 179 .reset( reset_int ), 180 .pulse78( pulse78 ), 181 .wait200( wait200 ), 182 .init_done( init_done ), 183 // 184 .mngt_req( init_req ), 185 .mngt_ack( init_ack ), 186 .mngt_cba( init_cba ) 187 ); 188 189 //---------------------------------------------------------------------------- 190 // Active Bank Information 191 //---------------------------------------------------------------------------- 192 reg [`ROW_RNG] ba_row [3:0]; 193 reg [3:0] ba_active; 194 195 //---------------------------------------------------------------------------- 196 // Handle write FIFO 197 //---------------------------------------------------------------------------- 198 wire wfifo_proc_reset; 199 wire wfifo_proc_start; 200 reg wfifo_proc_done; 201 202 parameter w_idle = 0; 203 parameter w_1 = 1; 204 parameter w_2 = 2; 205 parameter w_3 = 3; 206 parameter w_finish = 4; 207 208 reg [2:0] wstate; 209 210 always @(posedge clk) 211 begin 212 if (reset_int) begin 213 wstate <= w_idle; 214 wfifo_proc_done <= 0; 215 end else begin 216 wfifo_we <= 0; 217 218 case (wstate) 219 w_idle: begin 220 if (wfifo_proc_start & ~wfifo_full) begin 221 wfifo_din[`WFIFO_D0_RNG] <= fml_din[15: 0]; 222 wfifo_din[`WFIFO_D1_RNG] <= fml_din[31:16]; 223 wfifo_din[`WFIFO_M0_RNG] <= fml_msk[ 1: 0]; 224 wfifo_din[`WFIFO_M1_RNG] <= fml_msk[ 3: 2]; 225 wfifo_we <= 1; 226 wstate <= w_1; 227 end 228 end 229 w_1: begin 230 if (~wfifo_full) begin 231 wfifo_din[`WFIFO_D0_RNG] <= fml_din[47:32]; 232 wfifo_din[`WFIFO_D1_RNG] <= fml_din[63:48]; 233 wfifo_din[`WFIFO_M0_RNG] <= fml_msk[ 5: 4]; 234 wfifo_din[`WFIFO_M1_RNG] <= fml_msk[ 7: 6]; 235 wfifo_we <= 1; 236 wstate <= w_2; 237 end 238 end 239 w_2: begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -