Tue, 10 Aug 2010 13:23:58 +0100
implement (almost) complete SDRAM init sequence
wb_sdram.v | file | annotate | diff | revisions |
1.1 --- a/wb_sdram.v Tue Aug 10 12:58:34 2010 +0100 1.2 +++ b/wb_sdram.v Tue Aug 10 13:23:58 2010 +0100 1.3 @@ -76,7 +76,7 @@ 1.4 localparam M_WritePrecharge = 6'b110100; 1.5 localparam M_Read = 6'b100101; 1.6 localparam M_ReadPrecharge = 6'b110101; 1.7 -localparam M_ModeRegister = 6'b0X0000; 1.8 +localparam M_LoadModeRegister = 6'b0X0000; 1.9 localparam M_Nop = 6'b0X0111; 1.10 localparam M_BurstStop = 6'b0X0110; 1.11 localparam M_Inhibit = 6'b0X1XXX; // maybe X1111? 1.12 @@ -86,9 +86,18 @@ 1.13 /**** 1.14 * Finite State Machine 1.15 ****/ 1.16 -localparam ST_INIT1 = 32'd0; 1.17 -localparam ST_INIT2 = 32'd1; 1.18 -localparam ST_NOP = 32'd999; 1.19 +localparam ST_INIT1 = 32'd0; 1.20 +localparam ST_INIT2 = 32'd1; 1.21 +localparam ST_NOP1 = 32'd2; 1.22 +localparam ST_PrechargeAll = 32'd3; 1.23 +localparam ST_PrechargeAll_Wait = 32'd4; 1.24 +localparam ST_AutoRefresh1 = 32'd5; 1.25 +localparam ST_AutoRefresh1_Wait = 32'd6; 1.26 +localparam ST_AutoRefresh2 = 32'd7; 1.27 +localparam ST_AutoRefresh2_Wait = 32'd8; 1.28 +localparam ST_LoadModeRegister = 32'd9; 1.29 +localparam ST_LoadModeRegister_Wait = 32'd10; 1.30 +localparam ST_Spin = 32'd999; 1.31 1.32 reg [31:0] state; 1.33 always @(posedge wb_clk_i) begin 1.34 @@ -134,7 +143,7 @@ 1.35 // the end of the power-up wait, then bring CKE high. 1.36 if (timer == 32'd0) begin 1.37 // Timer hit zero. Send a NOP. 1.38 - state <= ST_NOP; 1.39 + state <= ST_NOP1; 1.40 end else if (timer < 32'd50) begin 1.41 // Timer value is more than zero but less than 50; CKE is on, but 1.42 // keep waiting for the timer to actually expire. 1.43 @@ -145,11 +154,95 @@ 1.44 sdram_mode <= M_Inhibit; 1.45 end 1.46 1.47 - ST_NOP: begin 1.48 - // Spinstate. Hold SDRAM in NOP. 1.49 - debug <= 3'd7; 1.50 + ST_NOP1: begin 1.51 + // Apply one or more NOP commands to the SDRAM 1.52 + sdram_mode <= M_Nop; 1.53 + state <= ST_PrechargeAll; 1.54 + end 1.55 + 1.56 + ST_PrechargeAll: begin 1.57 + // Precharge All, then wait T_rp (20ns) 1.58 + sdram_mode <= M_PrechargeAll; 1.59 + timer <= 32'd0; // wait 1tcy (40ns) ---> TIMER HERE 1.60 + state <= ST_PrechargeAll_Wait; 1.61 + end 1.62 + 1.63 + ST_PrechargeAll_Wait: begin 1.64 + // Wait for T_rp after Precharge All 1.65 + sdram_mode <= M_Nop; 1.66 + if (timer == 32'd0) begin 1.67 + // Timer hit zero. Continue 1.68 + state <= ST_AutoRefresh1; 1.69 + end 1.70 + end 1.71 + 1.72 + ST_AutoRefresh1: begin 1.73 + // Auto Refresh 1 of 2, wait T_rfc (70ns) after each 1.74 + sdram_mode <= M_AutoRefresh; 1.75 + timer <= 32'd1; // wait 2tcy (80ns) ---> TIMER HERE 1.76 + state <= ST_AutoRefresh1_Wait; 1.77 + end 1.78 + 1.79 + ST_AutoRefresh1_Wait: begin 1.80 + // Wait for T_rfc 1.81 sdram_mode <= M_Nop; 1.82 - state <= ST_NOP; 1.83 + if (timer == 32'd0) begin 1.84 + // Timer hit zero. Continue 1.85 + state <= ST_AutoRefresh2; 1.86 + end 1.87 + end 1.88 + 1.89 + ST_AutoRefresh2: begin 1.90 + // Auto Refresh 2 of 2, wait T_rfc (70ns) after each 1.91 + sdram_mode <= M_AutoRefresh; 1.92 + timer <= 32'd1; // wait 2tcy (80ns) ---> TIMER HERE 1.93 + state <= ST_AutoRefresh2_Wait; 1.94 + end 1.95 + 1.96 + ST_AutoRefresh2_Wait: begin 1.97 + // Wait for T_rfc 1.98 + sdram_mode <= M_Nop; 1.99 + if (timer == 32'd0) begin 1.100 + // Timer hit zero. Continue 1.101 + state <= ST_LoadModeRegister; 1.102 + end 1.103 + end 1.104 + 1.105 + ST_LoadModeRegister: begin 1.106 + // Load Mode Register 1.107 + /** 1.108 + * Mode register: 1.109 + * - BS0,1 = 00 [RFU] 1.110 + * - A11,10 = 00 [RFU] 1.111 + * - A9 = 0 [WBL -- write burst length same as read burst length] 1.112 + * - A8,7 = 00 [Test Mode off] 1.113 + * - A6..4 = 010 [CAS Latency = 2 clocks] 1.114 + * - A3 = 0 [Burst type = sequential] 1.115 + * - A2..0 = 000 [Burst length = 1 word] 1.116 + */ 1.117 + sdram_ba <= 2'b00; 1.118 + sdram_addr <= 12'b00_0_00_010_000; 1.119 + sdram_mode <= M_LoadModeRegister; 1.120 + 1.121 + // Wait T_mrd (2 clock cycles) 1.122 + timer <= 32'd1; // (2cy)-1 ---> TIMER HERE 1.123 + state <= ST_LoadModeRegister_Wait; 1.124 + end 1.125 + 1.126 + ST_LoadModeRegister_Wait: begin 1.127 + // Wait for LMR to complete 1.128 + sdram_mode <= M_Nop; 1.129 + sdram_ba <= 2'd0; 1.130 + sdram_addr <= 12'd0; 1.131 + if (timer == 32'd0) begin 1.132 + // Timer hit zero. Continue 1.133 + state <= ST_Spin; 1.134 + end 1.135 + end 1.136 + 1.137 + ST_Spin: begin 1.138 + sdram_mode <= M_Inhibit; 1.139 + state <= ST_Spin; 1.140 end 1.141 endcase 1.142 end