📄 sdcnt.v
字号:
//if(burst_length_cntr == 9'd255) //写猝发长度是256 进行precharge,注意这里
//modereg_burst_count始终等于1,对于猝发写入时
//直接换成出发长度
if(burst_length_cntr == 9'd254)
do_write_ack<=`LO;//shut down AD_FIFO
else if(burst_length_cntr == 9'd255) //这里改为写猝发长度是255 进行precharge
begin
burst_cntr_ena <= `LO; // done counting;
// sd_wr_ena <= `LO; // 数据输出使能信号(数据输向SDRAM)
doing_precharge<=`HI;
next_state<=`state_precharge;
//doing_precharge<=`LO;
sd_addx10_mux <= 2'b11; // precharge all banks
end
else
begin
next_state<=`state_write_wait; ////write burst not finished
doing_precharge<=`LO;
do_write_ack<= `HI; // write burst in progress
end
end
//----------------------------------------------------------------------------------------------------------------
//state_terminate 发出终止页猝发命令
/* `state_terminate:
begin
sd_wr_l <= `LO; //terminate
sd_ras_l <= `HI; // terminate
sd_cas_l <= `HI; // terminate
doing_precharge<=`HI; //next state is precharge
do_write_ack<= `LO;
do_read_ack <= `LO;
next_state<=`state_precharge;
end */
//------------------------------------------------------------------------------------------------------
// SET CAS state // 发出read命令
`state_set_cas: begin
// sd_cs_l <= `LO;
sd_cas_l <= `LO;
sd_dqm <= 4'h0;
next_state <= `state_cas_latency1;
//更改为:
/*
burst_cntr_ena <= `HI; // enable the burst lenght counter
do_read_ack <= `HI;
// sd_rd_ena <= `HI; // 下个周期数据有效,所以读使能应提前打开
next_state<=`state_read;//caslatency设置为1,下一个状态为read
*/
end
//------------------------------------------------------------------------------------------------
//暂时屏蔽latency1和latency2
/*
`state_cas_latency1: begin // CAS delay
// sd_cs_l <= `HI; // disable CS
sd_cas_l <= `HI; // disable CAS
sd_dqm <= 4'h0;
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 the burst lenght counter
end
else
next_state <= `state_cas_latency2; // 3 cycles of latency
end
`state_cas_latency2: begin ///cas delay
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 /// 在这个状态读数据有效,sdram不进行任何操作
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; ///NOP
//sd_cs_l <= `HI; ///NOP
sd_ras_l <= `HI; //NOP
sd_cas_l <= `HI; //NOP
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
*/
//-------------------------------------------------------------------------------------------------
`state_cas_latency1: begin // CAS delay
// sd_cs_l <= `HI; // disable CS
sd_cas_l <= `HI; // disable CAS
sd_dqm <= 4'h0;
// do_read_ack <= `HI; // acknowledge the read request (do it here due to the latency)
//调试屏蔽 burst_cntr_ena <= `HI; //下个周期数据有效,所以读使能应提前打开
//next_state <= `state_read; // 2 cycles of lantency done.
next_state <= `state_cas_latency2; //cas latency=3
// enable the burst lenght counter
end
//-----------------------------------------------------------------------------------
`state_cas_latency2: begin ///cas delay
//burst_cntr_ena <= `HI; // enable the burst lenght counter
do_read_ack <= `HI; // acknowledge the read request (do it here due to the latency)
next_state <= `state_read;
end
//----------------------------------------------------------------------------------
//state read
`state_read: begin /// 在这个状态读数据有效,等待读猝发进行完毕,sdram不进行任何操作
sd_wr_l <= `HI; ///NOP
//sd_cs_l <= `HI;
sd_ras_l <= `HI; //NOP
sd_cas_l <= `HI; //NOP
//doing_precharge<=`LO;
if (burst_length_cntr == 9'd251) begin //读猝发完成 ,根据实际情况设置长度!!!
burst_cntr_ena <= `LO; // done counting;
sd_addx10_mux<=2'b11; // 为下一个状态的precharge命令 precharge all banks
//sd_rd_ena <= `LO; // done with the reading
doing_precharge<=`HI;//下个周期进行PRECHARGE
next_state <= `state_precharge;
//doing_precharge<=`LO;
// next_state<=`state_terminate;// 发出终止猝发命令 , terminate 命令要提前一个周期发送
//sd_addx_mux <= 2'b00; // send ROW (A[19:10]) of mp_addx to SDRAM //为下一个状态的precharge命令提供行地址//没有必要提供行地址
//sd_addx10_mux <= 2'b00; // send ROW (A[20])
//sd_addx_mux <= 2'b00;
// 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
burst_cntr_ena <= `HI;
do_read_ack <= `HI;//read burstin progress
doing_precharge<=`LO;
next_state <= `state_read;
end
end
default: next_state <= `state_idle;
endcase
//-----------------------------------------------------------------------------------------------------------
// This counter is used to generate a delay right after the // generate Trc delay
// auto-refresh command is issued to the SDRAM
always @(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; //2
default: cntr_limit <= `auto_ref_cntr_limit;// 1
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 <= 9'd0; // 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;
refresh_cntr<=2'd0;
else if (next_state == `state_auto_refresh)
refresh_cntr <= refresh_cntr + 1;
//
// BURST LENGTH SELECTOR
// 这里写的不对,因为在hostcon中,powerup结束后,modereg_burst_length始终为1
/*
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 <= 10'd0;
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 != 11'd1638) begin // 对于105M时钟 ,15.6us的间隔等于858个时钟周期
refresh_timer <= refresh_timer + 1;
refresh_state <= `state_count;
end
else begin
refresh_state <= `state_halt;
refresh_timer <= 10'd0;
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;
*/
begin
if (do_refresh_ack) //得到自刷新响应后进行刷新计数,否则停在这个状态
refresh_state <= `state_count;
else refresh_state<=`state_halt;
end
// 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 + -