📄 sdramcnt.v
字号:
autorefresh_cntr_l <= `LO; // reset Trc delay counter next_state <= `state_auto_refresh; end // This is powerup run, so go and set modereg 4'b110x: begin autorefresh_cntr_l <= `LO; // reset Trc delay counter doing_refresh <= `LO; // refresh cycle is done refresh_cntr_l <= `LO; // ..reset refresh counter next_state <= `state_modeset; end 4'b1111: begin autorefresh_cntr_l <= `LO; // reset Trc delay counter doing_refresh <= `LO; // refresh cycle is done refresh_cntr_l <= `LO; // ..reset refresh counter next_state <= `state_set_ras; // go service a pending read or write if any end 4'b1110: begin autorefresh_cntr_l <= `LO; // reset Trc delay counter doing_refresh <= `LO; // refresh cycle is done refresh_cntr_l <= `LO; // ..reset refresh counter next_state <= `state_idle; // go service a pending read or write if any end endcase*/ // Wait for Trc if (autorefresh_cntr == 4'h6) begin autorefresh_cntr_l <= `LO; // reset Trc delay counter // Check if the number of specified back-back refreshes are done if (refresh_cntr == cntr_limit) begin doing_refresh <= `LO; // refresh cycle is done refresh_cntr_l <= `LO; // ..reset refresh counter // if this is not a power-up sequence, and there are pending // requests, then service it. if (~pwrup) if (do_write | do_read) next_state <= `state_set_ras; // go service a pending read or write if any else next_state <= `state_idle; // if there are no peding RD or WR, then go to idle state // if this is part of power-up sequencing, we need to go and // set mode register. else next_state <= `state_modeset; end // IF refresh cycles not done yet, keep issuing autorefresh commands else next_state <= `state_auto_refresh; end // If Trc has not expired else begin next_state <= `state_auto_refresh_dly; do_refresh_ack <= `LO; end end // MODE SET state `state_modeset: begin next_state <= `state_idle; sd_wr_l <= `LO; sd_cs_l <= `LO; sd_ras_l <= `LO; sd_cas_l <= `LO; sd_addx_mux <= 2'b10; sd_addx10_mux <= 2'b10; doing_refresh <= `LO; // deassert if (pwrup) pwrup <= `LO; // ..no more in power up mode if (do_mode_set) do_modeset_ack <= `LO; end // IDLE state `state_idle: begin sd_wr_l <= `HI; sd_cs_l <= `HI; sd_ras_l <= `HI; sd_cas_l <= `HI; sd_data_ena <= `LO; // turn off the data bus drivers mp_data_mux <= `LO; // drive the SD data bus with normal data sd_addx_mux <= 2'b00; // select ROW (A[19:10]) of mp_addx to SDRAM sd_addx10_mux <= 2'b00; // select ROW (A[20]) " " // if we've just come out of system reset (or powerup) // then we need to go and do initialization sequence. // Or, if a refresh is requested, go and service it. if (do_refresh | pwrup) begin doing_refresh <= `HI; // indicate that we're doing refresh refresh_cntr_l <= `HI; // allow refresh cycle counter to count up next_state <= `state_auto_refresh; end // if a single word rad or write request is pending, go and service it else if (do_write | do_read ) next_state <= `state_set_ras; // if a mode register set is requested, go and service it else if (do_mode_set) begin do_modeset_ack <= `HI; // acknowledge the mode set request next_state <= `state_modeset; doing_refresh <= `HI; // techincally we're not doing refresh, but end // this signal is used to prevent the do_write be deasserted // by the mode_set command. end // SET RAS state `state_set_ras: begin sd_cs_l <= `LO; // enable SDRAM sd_ras_l <= `LO; // enable the RAS next_state <= `state_ras_dly; // wait for a bit end // RAS delay state. // This delay is needed to meet Trcd delay. This is the RAS to CAS delay. // for most parts this is 20nS. So for 100MHz operation, there needs to be // at least 1 NOP cycle. `state_ras_dly: begin sd_cs_l <= `HI; // disable SDRAM sd_ras_l <= `HI; // disble the RAS sd_addx_mux <= 2'b01; // select COLUMN sd_addx10_mux <= 2'b01; // select COLUMN if (do_write) begin sd_data_ena <= `HI; // turn on the data bus drivers sd_dqm <= decoded_dqm; // masks the data which is meant to be next_state <= `state_write; // if write, do the write end else begin sd_dqm <= 4'h0; next_state <= `state_set_cas; // if read, do the read end end // WRITE state `state_write: begin sd_cs_l <= `LO; // enable SDRAM sd_cas_l <= `LO; // enable the CAS sd_wr_l <= `LO; // enable the write do_write_ack<= `HI; // acknowledge the write request sd_dqm <= 4'hF; next_state <= `state_delay_Tras1; end `state_delay_Tras1: begin sd_wr_l <= `HI; sd_cs_l <= `HI; sd_ras_l <= `HI; sd_cas_l <= `HI; sd_dqm <= 4'hF; sd_addx_mux <= 2'b00; // send ROW (A[19:10]) of mp_addx to SDRAM sd_addx10_mux <= 2'b00; // send ROW (A[20]) " " mp_data_mux <= `HI; // drive the SD data bus with all zeros next_state <= `state_delay_Tras2; end `state_delay_Tras2: begin next_state <= `state_precharge; end // SET CAS state `state_set_cas: begin sd_cs_l <= `LO; sd_cas_l <= `LO; sd_dqm <= 4'h0; next_state <= `state_cas_latency1; end `state_cas_latency1: begin sd_cs_l <= `HI; // disable CS sd_cas_l <= `HI; // disable CAS sd_dqm <= 4'hF; if (modereg_cas_latency==3'b010) begin do_read_ack <= `HI; // acknowledge the read request (do it here due to the latency) next_state <= `state_read; // 2 cycles of lantency done. burst_cntr_ena <= `HI; // enable he burst lenght counter end else next_state <= `state_cas_latency2; // 3 cycles of latency end `state_cas_latency2: begin next_state <= `state_read; burst_cntr_ena <= `HI; // enable the burst lenght counter do_read_ack <= `HI; // acknowledge the read request (do it here due to the latency) end `state_read: begin if (burst_length_cntr == modereg_burst_count) begin burst_cntr_ena <= `LO; // done counting; sd_rd_ena <= `LO; // done with the reading next_state <= `state_precharge; sd_wr_l <= `HI; sd_cs_l <= `HI; sd_ras_l <= `HI; sd_cas_l <= `HI; sd_addx_mux <= 2'b00; // send ROW (A[19:10]) of mp_addx to SDRAM sd_addx10_mux <= 2'b00; // send ROW (A[20]) " " mp_data_mux <= `HI; // drive the SD data bus with all zeros end else begin sd_rd_ena <= `HI; // enable the read latch on the next state next_state <= `state_read; end end endcase // This counter is used to generate a delay right after the // auto-refresh command is issued to the SDRAMalways @(posedge sys_clk or negedge autorefresh_cntr_l) if (~autorefresh_cntr_l) autorefresh_cntr <= 4'h0; else autorefresh_cntr <= autorefresh_cntr + 1;// This mux selects the cycle limit value for the // auto refresh counter. // During power-up sequencing, we need to do `power_up_ref_cntr_limit// number of back=back refreshes.// During regular operation, we need to do `auto_ref_cntr_limit number of// back-back refreshes. This, for most cases is just 1, but if we're doing// "burst" type of refreshes, it could be more than 1.always @(pwrup) case (pwrup) `HI: cntr_limit <= `power_up_ref_cntr_limit; default: cntr_limit <= `auto_ref_cntr_limit; endcase //// BURST LENGHT COUNTER//// This is the burst length counter. always @(posedge sys_clk or negedge burst_cntr_ena) if (~burst_cntr_ena) burst_length_cntr <= 3'b000; // reset whenever 'burst_cntr_ena' is low else burst_length_cntr <= burst_length_cntr + 1;//// REFRESH_CNTR//// This counter keeps track of the number of back-back refreshes we're// doing. For most cases this would just be 1, but it allows "burst"// refresh, where all refrehses are done back to back.always @(posedge sys_clk or negedge refresh_cntr_l) if (~refresh_cntr_l) refresh_cntr <= 13'h0000; else if (next_state == `state_auto_refresh) refresh_cntr <= refresh_cntr + 1;//// BURST LENGTH SELECTOR//always @(modereg_burst_length) case (modereg_burst_length) 3'b000: modereg_burst_count <= 4'h1; 3'b001: modereg_burst_count <= 4'h2; 3'b010: modereg_burst_count <= 4'h4; default modereg_burst_count <= 4'h8; endcase//// REFRESH Request generator//assign do_refresh = (refresh_state == `state_halt);always @(posedge sys_clk or negedge sys_rst_l) if (~sys_rst_l) begin refresh_state <= `state_count; refresh_timer <= 8'h00; end else case (refresh_state) // COUNT // count up the refresh interval counter. If the // timer reaches the refresh-expire time, then go next state `state_count: if (refresh_timer != `RC) begin refresh_timer <= refresh_timer + 1; refresh_state <= `state_count; end else begin refresh_state <= `state_halt; refresh_timer <= 0; end // HALT // wait for the SDRAM to complete any ongoing reads or // writes. If the SDRAM has acknowledged the do_refresh, // (i.e. it is now doing the refresh) // then go to next state `state_halt: /* if (next_state==`state_auto_refresh | next_state==`state_auto_refresh_dly | next_state==`state_precharge ) refresh_state <= `state_reset;*/ if (do_refresh_ack) refresh_state <= `state_count; // RESET // if the SDRAM refresh is completed, then reset the counter // and start counting up again. `state_reset: if (next_state==`state_idle) begin refresh_state <= `state_count; refresh_timer <= 8'h00; end endcase endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -