⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddr_wpath.v

📁 ddr ram controller vhdl code
💻 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 + -