1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/wb_sdram.v Mon Aug 09 20:45:49 2010 +0100 1.3 @@ -0,0 +1,157 @@ 1.4 +/**************************************************************************** 1.5 + * 1.6 + * 1.7 + ****************************************************************************/ 1.8 + 1.9 +module wb_sdram ( 1.10 + // Clocks and resets 1.11 + input wb_clk_i, // WISHBONE clock 1.12 + input wb_rst_i, // WISHBONE reset 1.13 + 1.14 + // WISHBONE bus 1.15 + input [31:0] wb_adr_i, // WISHBONE address 1.16 + input [31:0] wb_dat_i, // WISHBONE data in 1.17 + output reg [31:0] wb_dat_o, // WISHBONE data out 1.18 + input [3:0] wb_sel_i, // WISHBONE byte select 1.19 + input wb_we_i, // WISHBONE write enable (R/#W) 1.20 + input wb_cyc_i, // WISHBONE cycle 1.21 + input wb_stb_i, // WISHBONE strobe 1.22 + output wb_ack_o, // WISHBONE cycle acknowledge (data available, DTACK) 1.23 + output wb_err_o, // WISHBONE bus error 1.24 + output wb_rty_o, // WISHBONE retry-later 1.25 + 1.26 + // SDRAM 1.27 + output reg sdram_cke, // SDRAM clock enable 1.28 + output sdram_cs_n, // SDRAM chip select (active low) 1.29 + output sdram_ras_n, // SDRAM row address strobe (active low) 1.30 + output sdram_cas_n, // SDRAM column address strobe (active low) 1.31 + output sdram_we_n, // SDRAM write enable (active low) 1.32 + output [11:0] sdram_a, // SDRAM address 1.33 + output reg [1:0] sdram_ba, // SDRAM bank address 1.34 + output reg [3:0] sdram_dqm, // SDRAM data mask (OE#; 0=active, 1=disabled) 1.35 + inout [31:0] sdram_dq, // SDRAM data bus 1.36 + 1.37 + // Debugging 1.38 + output reg [2:0] debug // debug bits 1.39 +); 1.40 + 1.41 + 1.42 +/**** 1.43 + * SDRAM data output buffer 1.44 + ****/ 1.45 +// OE=1 for output mode, 0 for input 1.46 +reg sdram_dq_oe; 1.47 +// SDRAM output register 1.48 +reg [31:0] sdram_dq_r; 1.49 +assign sdram_dq = sdram_dq_oe ? sdram_dq_r : 32'hZZZZ; 1.50 + 1.51 + 1.52 + 1.53 +/**** 1.54 + * State timer 1.55 + * This is used to ensure that the state machine abides by RAM timing 1.56 + * restrictions. 1.57 + ****/ 1.58 +reg [31:0] timer; 1.59 + 1.60 + 1.61 +/**** 1.62 + * MODE logic 1.63 + ****/ 1.64 +reg [5:0] sdram_mode; 1.65 +reg [11:0] sdram_addr; 1.66 +assign sdram_cs_n = sdram_mode[3]; 1.67 +assign sdram_ras_n = sdram_mode[2]; 1.68 +assign sdram_cas_n = sdram_mode[1]; 1.69 +assign sdram_we_n = sdram_mode[0]; 1.70 +assign sdram_a = {sdram_addr[11], (sdram_mode[5] ? sdram_mode[4] : sdram_addr[10]), sdram_addr[9:0]}; 1.71 + 1.72 +// SDRAM chip instructions 1.73 +// The bit order is as specified in the ISSI datasheet: A10 Override, A10, CS#, RAS#, CAS#, WE#. 1.74 +// If A10 Override is set, then A10 will be overridden to the value specified in the M_ constant. 1.75 +localparam M_BankActivate = 6'b0X0011; 1.76 +localparam M_PrechargeBank = 6'b100010; 1.77 +localparam M_PrechargeAll = 6'b110010; 1.78 +localparam M_Write = 6'b100100; 1.79 +localparam M_WritePrecharge = 6'b110100; 1.80 +localparam M_Read = 6'b100101; 1.81 +localparam M_ReadPrecharge = 6'b110101; 1.82 +localparam M_ModeRegister = 6'b0X0000; 1.83 +localparam M_Nop = 6'b0X0111; 1.84 +localparam M_BurstStop = 6'b0X0110; 1.85 +localparam M_Inhibit = 6'b0X1XXX; // maybe X1111? 1.86 +localparam M_AutoRefresh = 6'b0X0001; 1.87 + 1.88 + 1.89 +/**** 1.90 + * Finite State Machine 1.91 + ****/ 1.92 +localparam ST_INIT1 = 32'd0; 1.93 +localparam ST_INIT2 = 32'd1; 1.94 +localparam ST_NOP = 32'd999; 1.95 + 1.96 +reg [31:0] state; 1.97 +always @(posedge wb_clk_i) begin 1.98 + if (wb_rst_i) begin 1.99 + // Initialise state machine and timer 1.100 + state <= ST_INIT1; 1.101 + debug <= 3'd0; 1.102 + timer <= 32'd0; 1.103 + 1.104 + // Initialisation state for SDRAM 1.105 + sdram_cke <= 1'b0; 1.106 + sdram_mode <= M_Inhibit; 1.107 + sdram_addr <= 12'h000; 1.108 + sdram_ba <= 2'b00; 1.109 + sdram_dqm <= 4'b0000; 1.110 + sdram_dq_oe <= 1'b0; // data output disabled 1.111 + sdram_dq_r <= 32'd0; 1.112 + end else begin 1.113 + // timer logic 1.114 + if (timer > 32'd0) begin 1.115 + timer <= timer - 32'd1; 1.116 + end 1.117 + 1.118 + // state machine logic 1.119 + case (state) 1.120 + ST_INIT1: begin 1.121 + // INIT1: Set up for initial power-up wait 1.122 + state <= ST_INIT2; 1.123 + timer <= 32'd50_000; // TODO: dependent on core clock rate. Needs to be >= 100us 1.124 + 1.125 + // SDRAM state 1.126 + sdram_cke <= 1'b0; // clock disabled 1.127 + sdram_mode <= M_Inhibit; 1.128 + sdram_addr <= 12'h000; 1.129 + sdram_ba <= 2'b00; 1.130 + sdram_dqm <= 4'b1111; 1.131 + sdram_dq_oe <= 1'b0; // data output disabled 1.132 + sdram_dq_r <= 32'd0; 1.133 + end 1.134 + 1.135 + ST_INIT2: begin 1.136 + // INIT2: Power-up wait. Keep CKE low until ~50 cycles before 1.137 + // the end of the power-up wait, then bring CKE high. 1.138 + if (timer == 32'd0) begin 1.139 + // Timer hit zero. Send a NOP. 1.140 + state <= ST_NOP; 1.141 + end else if (timer <= 32'd50) begin 1.142 + // Timer value is more than zero but less than 50; CKE is on, but 1.143 + // keep waiting for the timer to actually expire. 1.144 + sdram_cke <= 1'b1; 1.145 + state <= ST_INIT2; 1.146 + debug <= 3'd1; 1.147 + end 1.148 + sdram_mode <= M_Inhibit; 1.149 + end 1.150 + 1.151 + ST_NOP: begin 1.152 + // Spinstate. Hold SDRAM in NOP. 1.153 + debug <= 3'd7; 1.154 + state <= ST_NOP; 1.155 + end 1.156 + endcase 1.157 + end 1.158 +end 1.159 + 1.160 +endmodule