📄 ddr2_32mx32_controller_0.v
字号:
end
//******************************************************************************
// autoref_count - This counter is used to issue AUTO REFRESH command to
// the memory for every 7.8125us.
// (Auto Refresh Request is raised for every 7.7 us to allow for termination
// of any ongoing bus transfer).For example at 200MHz frequency
// autoref_count = refresh_time_period/clock_period = 7.7us/5ns = 1540
//******************************************************************************
always @ (negedge clk) begin
if (rst180_r == 1'b1) begin
rfc_counter_value <= `RFC_COUNT_VALUE;
ref_freq_cnt <= `MAX_REF_CNT;
end
else begin
rfc_counter_value <= `RFC_COUNT_VALUE;
ref_freq_cnt <= `MAX_REF_CNT;
autoref_value <= (autoref_count == ref_freq_cnt);
end
end
always @(negedge clk) begin
if(rst180_r)
autoref_count <= `MAX_REF_WIDTH'b0;
else if(autoref_value)
autoref_count <= `MAX_REF_WIDTH'b0;
else
autoref_count <= autoref_count + 1'b1;
end
always @ (negedge clk) begin
if (rst180_r == 1'b1) begin
auto_ref_detect1 <= 1'b0;
auto_ref1 <= 1'b0;
end
else begin
auto_ref_detect1 <= autoref_value && init_done;
auto_ref1 <= auto_ref_detect1;
end
end
assign ar_done_p = (ar_done_reg == 1'b1) ? 1'b1 : 1'b0;
always @ (negedge clk) begin
if (rst180_r == 1'b1) begin
auto_ref_wait <= 1'b0;
ar_done <= 1'b0;
auto_ref_issued <= 1'b0;
end
else begin
if (auto_ref1 && !auto_ref_wait)
auto_ref_wait <= 1'b1;
else if (auto_ref_issued_p)
auto_ref_wait <= 1'b0;
else
auto_ref_wait <= auto_ref_wait;
ar_done <= ar_done_p;
auto_ref_issued <= auto_ref_issued_p;
end
end
always @ (negedge clk) begin
if (rst180_r == 1'b1) begin
auto_ref_wait1 <= 1'b0;
auto_ref_wait2 <= 1'b0;
auto_ref <= 1'b0;
end
else begin
if (auto_ref_issued_p) begin
auto_ref_wait1 <= 1'b0;
auto_ref_wait2 <= 1'b0;
auto_ref <= 1'b0;
end
else begin
auto_ref_wait1 <= auto_ref_wait;
auto_ref_wait2 <= auto_ref_wait1;
auto_ref <= auto_ref_wait2;
end
end
end
assign auto_ref_req = auto_ref_wait;
assign auto_ref_issued_p = (current_state == AUTO_REFRESH);
//******************************************************************************
// Common counter for the Initialization sequence
//******************************************************************************
always @(negedge clk) begin
if(rst180_r)
count6 <= 6'b000000;
else if(init_current_state == INIT_AUTO_REFRESH || init_current_state ==
INIT_PRECHARGE || init_current_state == INIT_LOAD_MODE_REG)
count6 <= CNTNEXT;
else if(count6 != 6'd0)
count6 <= count6 - 1'b1;
else
count6 <= 6'b000000;
end
//******************************************************************************
// While doing consecutive READs or WRITEs, the burst_cnt_max value determines
// when the next READ or WRITE command should be issued. burst_cnt_max shows the
// number of clock cycles for each burst.
// e.g burst_cnt_max = 2 for a burst length of 4
// = 4 for a burst length of 8
//******************************************************************************
assign burst_cnt_max = (burst_length == 3'b010) ? 3'b010 :
(burst_length == 3'b011) ? 3'b100 :
3'b000;
always @( negedge clk) begin
if(rst180_r)
cas_count <= 3'b000;
else if(current_state == BURST_READ)
cas_count <= burst_cnt_max - 1'b1;
else if(cas_count != 3'b000)
cas_count <= cas_count - 1'b1;
end
always @( negedge clk ) begin
if(rst180_r)
wrburst_end_cnt <= 3'b000;
else if((current_state == FIRST_WRITE) || (current_state == BURST_WRITE))
wrburst_end_cnt <= burst_cnt_max;
else if(wrburst_end_cnt != 3'b000)
wrburst_end_cnt <= wrburst_end_cnt - 1'b1;
end
always @ (negedge clk) begin
if (rst180_r == 1'b1)
rdburst_end_1 <= 1'b0;
else begin
rdburst_end_2 <= rdburst_end_1;
if (burst_done == 1'b1)
rdburst_end_1 <= 1'b1;
else
rdburst_end_1 <= 1'b0;
end
end
assign rdburst_end = rdburst_end_1 || rdburst_end_2 ;
always @ (negedge clk) begin
if (rst180_r == 1'b1)
wrburst_end_1 <= 1'b0;
else begin
wrburst_end_2 <= wrburst_end_1;
wrburst_end_3 <= wrburst_end_2;
if (burst_done == 1'b1)
wrburst_end_1 <= 1'b1;
else
wrburst_end_1 <= 1'b0;
end
end
assign wrburst_end = wrburst_end_1 || wrburst_end_2 || wrburst_end_3;
//******************************************************************************
// dqs_enable and dqs_reset signals are used to generate DQS signal during write
// data.
//******************************************************************************
assign dqs_enable = dqs_enable2;
assign dqs_reset = dqs_reset2_clk0;
always @ (negedge clk) begin
if (rst180_r == 1'b1) begin
dqs_enable_int <= 1'b0;
dqs_reset_int <= 1'b0;
end
else begin
dqs_enable_int <= ((current_state == FIRST_WRITE) ||
(current_state == BURST_WRITE) ||
(wrburst_end_cnt != 3'b000));
dqs_reset_int <= (current_state == FIRST_WRITE);
end
end
always @ (posedge clk) begin
if (rst0_r == 1'b1) begin
dqs_enable1 <= 1'b0;
dqs_enable2 <= 1'b0;
dqs_enable3 <= 1'b0;
dqs_reset1_clk0 <= 1'b0;
dqs_reset2_clk0 <= 1'b0;
dqs_reset3_clk0 <= 1'b0;
end
else begin
dqs_enable1 <= dqs_enable_int;
dqs_enable2 <= dqs_enable1;
dqs_enable3 <= dqs_enable2;
dqs_reset1_clk0 <= dqs_reset_int;
dqs_reset2_clk0 <= dqs_reset1_clk0;
dqs_reset3_clk0 <= dqs_reset2_clk0;
end
end
//******************************************************************************
//Write Enable signal to the datapath
//******************************************************************************
always @ (negedge clk) begin
if (rst180_r == 1'b1)
write_enable <= 1'b0;
else if(wrburst_end_cnt != 3'b000)
write_enable <= 1'b1;
else
write_enable <= 1'b0;
end
assign cmd_ack = ack_reg;
FD ack_reg_inst1
(
.Q (ack_reg),
.D (ack_o),
.C (~clk)
);
assign ack_o = ((write_cmd_in == 1'b1) || (write_cmd1 == 1'b1) ||
(read_cmd == 1'b1) || (read_cmd1 == 1'b1));
//******************************************************************************
// init_done will be asserted when initialization sequence is complete
//******************************************************************************
always @ (negedge clk) begin
if (rst180_r == 1'b1) begin
init_memory <= 1'b0;
init_done <= 1'b0;
init_done_r1 <= 1'b0;
end
else begin
init_memory <= init_mem;
init_done <= init_done_value && (init_count == 4'b1011);
init_done_r1 <= init_done;
end
end
//synthesis translate_off
always @ (negedge clk) begin
if (rst180_r == 1'b0)
if (init_done == 1'b1 && init_done_r1 == 1'b0)
$display ("INITIALIZATION_DONE");
end
//synthesis translate_on
always @ (negedge clk) begin
if (initialize_memory) begin
init_pre_count <= 7'b101_0000;
end
else begin
init_pre_count <= init_pre_count - 7'h1;
end
end
always @( negedge clk ) begin
if ( rst180_r )
init_mem <= 1'b0;
else if ( initialize_memory )
init_mem <= 1'b1;
else if ( (init_count == 4'b1011) && (count6 == 6'd1) )
init_mem <= 1'b0;
else
init_mem <= init_mem;
end
always @( negedge clk ) begin
if ( rst180_r )
init_count <= 4'b0;
else if (((init_current_state == INIT_PRECHARGE) ||
(init_current_state == INIT_LOAD_MODE_REG)
|| (init_current_state == INIT_AUTO_REFRESH))
&& init_memory == 1'b1)
init_count <= init_count + 1'b1;
else
init_count <= init_count;
end
assign init_done_value = (dll_rst_count == 8'b0000_0001) ;
//Counter to count 200 clock cycles When DLL reset is issued during
//initialization.
always @( negedge clk ) begin
if( rst180_r )
dll_rst_count <= 8'd0;
else if(init_count == 4'b0011)
dll_rst_count <= 8'd200;
else if(dll_rst_count != 8'b0000_0001)
dll_rst_count <= dll_rst_count - 8'b0000_0001;
else
dll_rst_count <= dll_rst_count;
end
assign go_to_active_value =((write_cmd_in == 1'b1) && (write_cmd1 != 1'b1))
|| ((read_cmd == 1'b1) && (read_cmd1 != 1'b1))
? 1'b1 : 1'b0;
always @ (negedge clk) begin
if (rst180_r == 1'b1) begin
go_to_active <= 1'b0;
end
else begin
go_to_active <= go_to_active_value;
end
end
always @ (negedge clk) begin
if (rst180_r == 1'b1) begin
rp_count <= 3'b000;
rfc_count_reg <= 1'b0;
ar_done_reg <= 1'b0;
rpcnt0 <= 1'b1;
end
else begin
rp_count <= rp_cnt_value;
if(rfc_count == 6'b000010 )
ar_done_reg <= 1'b1;
else
ar_done_reg <= 1'b0;
if(ar_done_reg == 1'b1)
rfc_count_reg <= 1'b1;
else if(init_done == 1'b1 && init_mem == 1'b0 &&
rfc_count == 6'b000000)
rfc_count_reg <= 1'b1;
else if (auto_ref_issued == 1'b1)
rfc_count_reg <= 1'b0;
else
rfc_count_reg <= rfc_count_reg;
rpcnt0 <= (rp_count[2] == 1'b0 && rp_count[1] == 1'b0
&& !rp_cnt_value[2]);
end
end
//******************************************************************************
// Initialization state machine
//******************************************************************************
always @ (negedge clk) begin
if (rst180_r == 1'b1)
init_current_state <= INIT_IDLE;
else
init_current_state <= init_next_state;
end
always @ (*) begin
if (rst180_r == 1'b1)
init_next_state = INIT_IDLE;
else begin
case (init_current_state)
INIT_IDLE : begin
if (init_memory == 1'b1) begin
case (init_count)
4'b0000 : begin
if(init_pre_count == 7'b000_0001)
init_next_state = INIT_PRECHARGE;
else
init_next_state = INIT_IDLE;
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -