📄 sdram_cnt.v
字号:
state_auto_refresh_dly: begin
sd_cs_l <= #1 1'b1;
sd_ras_l <= #1 1'b1;
sd_cas_l <= #1 1'b1;
do_refresh_ack <= #1 1'b0;
// Wait for Trc
if (autorefresh_cntr == refresh2anything_delay_val) begin
autorefresh_cntr_l <= #1 1'b0; // reset Trc delay counter
// Check if the number of specified back-back refreshes are done
if (refresh_cntr == cntr_limit) begin
doing_refresh <= #1 1'b0; // refresh cycle is done
refresh_cntr_l <= #1 1'b0; // ..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)
begin
next_state <= #1 state_set_ras; // go service a pending read or write if any
sd_addx_mux <= #1 2'b00; // select ROW (A[19:10]) of mp_addx to SDRAM
sd_addx10_mux <= #1 2'b00; // select ROW (A[20]) " "
load_address <= #1 1'b1 ;
end
else
next_state <= #1 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
begin
next_state <= #1 state_modeset;
assert_we <= #1 1'b1 ;
sd_addx_mux <= #1 2'b10; // modeset[9:0]
sd_addx10_mux <= #1 2'b10; // modeset[10]
load_address <= #1 1'b1 ;
end
end
// IF refresh cycles not done yet, keep issuing autorefresh commands
else
next_state <= #1 state_auto_refresh;
end
// If Trc has not expired
else
begin
next_state <= #1 state_auto_refresh_dly;
end
end
// MODE SET state
state_modeset: begin
next_state <= #1 state_idle;
sd_cs_l <= #1 1'b0;
sd_ras_l <= #1 1'b0;
sd_cas_l <= #1 1'b0;
load_address <= #1 1'b0 ;
assert_we <= #1 1'b0 ;
doing_refresh <= #1 1'b0; // deassert
if (pwrup)
pwrup <= #1 1'b0; // ..no more in power up mode
if (do_mode_set)
do_modeset_ack <= #1 1'b0;
end
// IDLE state
state_idle: begin
sd_dqm <= #1 4'hF ;
load_dqm <= #1 1'b0;
sd_cs_l <= #1 1'b1;
sd_ras_l <= #1 1'b1;
sd_cas_l <= #1 1'b1;
mp_data_mux <= #1 1'b0; // drive the SD data bus with normal data
do_read_ack <= #1 1'b0 ;
do_write_ack <= #1 1'b0 ;
row_active_time_count_enable <= #1 1'b0 ;
precharge_to_ras_count_enable <= #1 1'b0 ;
sd_rd_ena <= #1 1'b0; // done with the reading
// 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 ( go )
begin
if (do_refresh | pwrup)
begin
doing_refresh <= #1 1'b1; // indicate that we're doing refresh
refresh_cntr_l <= #1 1'b1; // allow refresh cycle counter to count up
next_state <= #1 state_auto_refresh;
busy <= #1 1'b1 ;
end
// if a single word rad or write request is pending, go and service it
else if (do_write | do_read )
begin
next_state <= #1 state_set_ras;
busy <= #1 1'b1 ;
sd_addx_mux <= #1 2'b00; // select ROW (A[19:10]) of mp_addx to SDRAM
sd_addx10_mux <= #1 2'b00; // select ROW (A[20]) " "
load_address <= #1 1'b1 ;
end
// if a mode register set is requested, go and service it
else if (do_mode_set)
begin
do_modeset_ack <= #1 1'b1; // acknowledge the mode set request
next_state <= #1 state_modeset;
busy <= #1 1'b1 ;
doing_refresh <= #1 1'b1; // techincally we're not doing refresh, but
// this signal is used to prevent the do_write be deasserted
// by the mode_set command.
sd_addx_mux <= #1 2'b10; // modeset[9:0]
sd_addx10_mux <= #1 2'b10; // modeset[10]
load_address <= #1 1'b1 ;
assert_we <= #1 1'b1 ;
end
else
busy <= #1 1'b0 ;
end
else
busy <= #1 1'b0 ;
end
// SET RAS state
state_set_ras: begin
sd_cs_l <= #1 1'b0; // enable SDRAM
sd_ras_l <= #1 1'b0; // enable the RAS
row_active_time_count_enable <= #1 1'b1 ;
sd_addx_mux <= #1 2'b01; // select COLUMN
if ( ras2cas_delay_val == 1 )
begin
if ( do_write )
begin
next_state <= #1 state_write ;
assert_we <= #1 1'b1 ;
sd_dqm <= #1 decoded_dqm; // masks the data which is meant to be
load_dqm <= #1 1'b1 ;
load_data <= #1 1'b1 ;
do_write_ack <= #1 1'b1 ;
sd_addx10_mux <= #1 2'b01; // A10 = 0
last_data_in_to_row_precharge_count_enable <= #1 1'b1 ;
end
else
begin
next_state <= #1 state_set_cas; // wait for a bit
sd_dqm <= #1 4'h0;
load_dqm <= #1 1'b1 ;
sd_addx10_mux <= #1 2'b11; // select AUTO_PRECHARGE_ENABLE
end
end
else
begin
next_state <= #1 state_ras_dly ;
ras2cas_delay_count_enable <= #1 1'b1 ;
load_address <= #1 1'b0 ;
end
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 <= #1 1'b1; // disable SDRAM
sd_ras_l <= #1 1'b1; // disble the RAS
if ( ras2cas_delay_count == ras2cas_delay_val )
begin
load_address <= #1 1'b1 ;
ras2cas_delay_count_enable <= #1 1'b0 ;
if (do_write)
begin
next_state <= #1 state_write; // if write, do the write
assert_we <= #1 1'b1 ;
load_dqm <= #1 1'b1 ;
sd_dqm <= #1 decoded_dqm; // masks the data which is meant to be
load_data <= #1 1'b1 ;
do_write_ack <= #1 1'b1 ;
sd_addx10_mux <= #1 2'b01; // A10 = 0
last_data_in_to_row_precharge_count_enable <= #1 1'b1 ;
end
else
begin
next_state <= #1 state_set_cas; // if read, do the read
load_dqm <= #1 1'b1 ;
sd_dqm <= #1 4'h0;
sd_addx10_mux <= #1 2'b11; // select AUTO_PRECHARGE_ENABLE
end
end
else
next_state <= #1 state_ras_dly ;
end
// WRITE state
state_write: begin
sd_cs_l <= #1 1'b0; // enable SDRAM
sd_cas_l <= #1 1'b0; // enable the CAS
do_write_ack<= #1 1'b0;
sd_ras_l <= #1 1'b1; // disble the RAS
load_address <= #1 1'b0 ;
load_data <= #1 1'b0 ;
sd_dqm <= #1 4'hF ;
assert_we <= #1 1'b0 ;
if ( (last_data_in_to_row_precharge_count == 1) && row_can_be_precharged )
begin
next_state <= #1 state_precharge;
assert_we <= #1 1'b1 ;
sd_addx10_mux <= #1 2'b11; // A10 = 1'b1
load_address <= #1 1'b1 ;
precharge_to_ras_count_enable <= #1 1'b1 ;
last_data_in_to_row_precharge_count_enable <= #1 1'b0 ;
end
else
begin
next_state <= #1 state_delay_Tras1;
end
end
state_delay_Tras1: begin
sd_cs_l <= #1 1'b1;
sd_ras_l <= #1 1'b1;
sd_cas_l <= #1 1'b1;
mp_data_mux <= #1 1'b1; // drive the SD data bus with all zeros
load_dqm <= #1 1'b0;
if ((last_data_in_to_row_precharge_count == 1) && row_can_be_precharged)
begin
next_state <= #1 state_precharge;
assert_we <= #1 1'b1 ;
sd_addx10_mux <= #1 2'b11; // A10 = 1'b1
load_address <= #1 1'b1 ;
precharge_to_ras_count_enable <= #1 1'b1 ;
last_data_in_to_row_precharge_count_enable <= #1 1'b0 ;
end
end
state_delay_Tras2:
begin
sd_rd_ena <= #1 1'b0; // done with the reading
do_read_ack <= #1 1'b0;
load_dqm <= #1 1'b0;
if ( row_can_be_precharged )
precharge_to_ras_count_enable <= #1 1'b1 ;
if ( precharge_time_expired && (row_active_time_count == 1) )
next_state <= #1 state_idle ;
end
// SET CAS state
state_set_cas: begin
sd_cs_l <= #1 1'b0;
sd_cas_l <= #1 1'b0;
sd_ras_l <= #1 1'b1 ;
next_state <= #1 state_cas_latency1;
load_address <= #1 1'b0 ;
end
state_cas_latency1: begin
sd_cs_l <= #1 1'b1; // disable CS
sd_cas_l <= #1 1'b1; // disable CAS
if (modereg_cas_latency==3'b010)
begin
do_read_ack <= #1 1'b1; // acknowledge the read request (do it here due to the latency)
next_state <= #1 state_read; // 2 cycles of lantency done.
burst_cntr_ena <= #1 1'b1; // enable he burst lenght counter
end
else
next_state <= #1 state_cas_latency2; // 3 cycles of latency
end
state_cas_latency2: begin
next_state <= #1 state_read;
burst_cntr_ena <= #1 1'b1; // enable the burst lenght counter
do_read_ack <= #1 1'b1; // acknowledge the read request (do it here due to the latency)
end
state_read: begin
sd_cs_l <= #1 1'b1;
sd_ras_l <= #1 1'b1;
sd_cas_l <= #1 1'b1;
mp_data_mux <= #1 1'b1; // drive the SD data bus with all zeros
sd_rd_ena <= #1 1'b1; // enable the read latch on the next state
if (row_can_be_precharged)
begin
if (modereg_cas_latency == 3'b011)
precharge_to_ras_count_enable <= #1 1'b1 ;
else
begin
if (burst_length_cntr != 4)
begin
precharge_to_ras_count_enable <= #1 1'b1 ;
end
end
end
if (burst_length_cntr == 1)
begin
burst_cntr_ena <= #1 1'b0; // done counting;
sd_dqm <= #1 4'hF ;
if ( precharge_time_expired && row_active_time_count == 1)
next_state <= #1 state_idle; // because of auto precharge
else
next_state <= #1 state_delay_Tras2 ;
end
end
endcase
// This counter is used to generate a delay right after the
// auto-refresh command is issued to the SDRAM
always @(posedge sys_clk or negedge sys_rst_l)
if ( !sys_rst_l )
autorefresh_cntr <= #1 4'h2;
else if ( !autorefresh_cntr_l )
autorefresh_cntr <= #1 4'h2;
else
autorefresh_cntr <= #1 autorefresh_cntr + 1;
// This mux selects the cycle limit value for the
// auto refresh counter.
// During power-up sequencing, we need to do `SDRAM_IF_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)
1'b1: cntr_limit = `SDRAM_IF_PWRUP_REF_CNTR_LIMIT;
default: cntr_limit = `SDRAM_IF_AUTO_REF_CNTR_LIMIT;
endcase
//
// BURST LENGHT COUNTER
//
// This is the burst length counter.
always @(posedge sys_clk or negedge sys_rst_l)
if ( !sys_rst_l )
burst_length_cntr <= #1 4'b0001;
else if ( !burst_cntr_ena )
burst_length_cntr <= #1 modereg_burst_count; // reset whenever 'burst_cntr_ena' is low
else
burst_length_cntr <= #1 burst_length_cntr - 1'b1 ;
//
// 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 sys_rst_l)
if ( !sys_rst_l )
refresh_cntr <= #1 13'h0000;
else if ( !refresh_cntr_l )
refresh_cntr <= #1 13'h0000;
else if ( next_state == state_auto_refresh )
refresh_cntr <= #1 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
//
always @(posedge sys_clk or negedge sys_rst_l)
if (~sys_rst_l) begin
refresh_state <= #1 state_count;
refresh_timer <= #1 0;
do_refresh <= #1 1'b0 ;
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 < refresh_timer_val) begin
refresh_timer <= #1 refresh_timer + 1;
refresh_state <= #1 state_count;
end else begin
refresh_state <= #1 state_halt;
do_refresh <= #1 1'b1 ;
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:begin
refresh_timer <= #1 0;
if (do_refresh_ack)
begin
refresh_state <= #1 state_count;
do_refresh <= #1 1'b0 ;
end
end
endcase
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -