?? mem_interface_top_tap_ctrl_0.txt
字號:
if (reset_int == 1'b1)
second_edge_tap_count[5:0] <= 6'b000000;
else if ((transition[1:0] == 2'b10) && (second_edge == 1'b0))
second_edge_tap_count[5:0] <= tap_counter[5:0];
end
always @ (posedge CLK) begin
if (reset_int == 1'b1)
pulse_width_tap_count[5:0] <= 6'b000000;
else if (second_edge_r1 == 1'b1)
pulse_width_tap_count[5:0] <= (second_edge_tap_count[5:0] -
first_edge_tap_count[5:0]);
end
always @ (posedge CLK) begin
if (reset_int == 1'b1)
pulse_center_tap_count[5:0] <= 6'b000000;
else if (second_edge_r2 == 1'b1)
pulse_center_tap_count[5:0] <= pulse_width_tap_count[5:0] >> 1;
// Shift right to divide by 2 and find pulse center
end
always @ (posedge CLK) begin
if (reset_int == 1'b1)
data_bit_tap_count[5:0] <= 6'b000000;
else if (second_edge_r3 == 1'b1) // 2 edges detected
data_bit_tap_count[5:0] <= first_edge_tap_count[5:0] +
pulse_center_tap_count[5:0];
else if ((transition[1:0] == 2'b01) && ((tap_counter[5:0] == 6'b111111)))
// Only 1 edge detected
if (first_edge_tap_count[5] == 1'b0)
data_bit_tap_count[5:0] <= first_edge_tap_count[5:0] + 6'b010000;
else
data_bit_tap_count[5:0] <= first_edge_tap_count[5:0] - 6'b010000;
else if ((transition[1:0] == 2'b00) && ((tap_counter[5:0] == 6'b111111)))
// No edges detected
data_bit_tap_count[5:0] <= 6'b100000;
end
// Logic required to determine whether the registered DQS is on the edge of
// meeting setup time in the FPGA clock domain. If DQS is on the edge, then
// the vector 'flag' will not be "1111" or "0000" and edge detection will not
// be executed.
// If DQS is not on the edge, then the vector 'flag' will be "1111" or "0000"
// and edge detection will be executed.
always @ (posedge CLK) begin
if (reset_int == 1'b1) begin
flag[3:0] <= 4'b0000;
end
else if (detect_edge_idle_r3 == 1'b1 || idelay_inc_idle_r3 == 1'b1 ||
idelay_rst_idle_r3 == 1'b1) begin
if (curr_dqs_level != prev_dqs_level)
flag[0] <= 1'b0;
else
flag[0] <= 1'b1;
end
else if (detect_edge_idle_r4 == 1'b1 || idelay_inc_idle_r4 == 1'b1 ||
idelay_rst_idle_r4 == 1'b1) begin
if (curr_dqs_level != prev_dqs_level)
flag[1] <= 1'b0;
else
flag[1] <= 1'b1;
end
else if (detect_edge_idle_r5 == 1'b1 || idelay_inc_idle_r5 == 1'b1 ||
idelay_rst_idle_r5 == 1'b1) begin
if (curr_dqs_level != prev_dqs_level)
flag[2] <= 1'b0;
else
flag[2] <= 1'b1;
end
else if (detect_edge_idle_r6 == 1'b1 || idelay_inc_idle_r6 == 1'b1 ||
idelay_rst_idle_r6 == 1'b1) begin
if (curr_dqs_level != prev_dqs_level)
flag[3] <= 1'b0;
else
flag[3] <= 1'b1;
end
end
// First and second edge detection logic
always @ (posedge CLK) begin
if (reset_int == 1'b1) begin
transition[1:0] <= 2'b00;
end
else if ((dly_after_first_cnt == 4'b0000) && (state[2:0] == detect_edge)&&
((flag[3:0] == 4'h0) || (flag[3:0] == 4'hF))) begin
if ((curr_dqs_level != prev_dqs_level) && (transition_rst == 1'b0) &&
(tap_counter > 6'b000000) ) begin
transition[1:0] <= transition[1:0] + 1'b1;
end
end
else if (transition_rst == 1'b1)
transition[1:0] <= 2'b00;
else
transition[1:0] <= transition[1:0];
end
always @ (posedge CLK) begin
if (reset_int == 1'b1) begin
transition_rst <= 1'b0;
first_edge <= 1'b0;
second_edge <= 1'b0;
end
else begin
case (transition[1:0])
2'b01: begin
first_edge <= 1'b1;
end
2'b10: begin
if (transition_rst == 1'b1)
begin
second_edge <= 1'b0;
transition_rst <= 1'b0;
end
else
begin
second_edge <= 1'b1;
transition_rst <= 1'b1;
end
end
default: begin
first_edge <= 1'b0;
second_edge <= 1'b0;
end
endcase
end
end
// State Machine for edge detection and midpoint determination
always @ (posedge CLK) begin
if (reset_int == 1'b1) begin // DQS IDELAY in reset
dly_rst <= 1'b1;
dly_ce <= 1'b0;
dly_inc <= 1'b0;
idelay_rst_idle <= 1'b0;
detect_edge_idle <= 1'b0;
idelay_inc_idle <= 1'b0;
prev_dqs_level <= curr_dqs_level;
state[2:0] <= idelay_rst;
end
else if ((CTRL_DUMMYREAD_START == 1'b1) && (sel_complete == 1'b0)) begin
case (state[2:0])
3'b000: begin // idelay_rst
dly_rst <= 1'b1;
dly_ce <= 1'b0;
dly_inc <= 1'b0;
idelay_rst_idle <= 1'b1;
state[2:0] <= idle;
end
3'b001: begin // idle
dly_rst <= 1'b0;
dly_ce <= 1'b0;
dly_inc <= 1'b0;
idelay_rst_idle <= 1'b0;
detect_edge_idle <= 1'b0;
idelay_inc_idle <= 1'b0;
if (idelay_rst_idle_r5 == 1'b1)
state[2:0] <= idelay_inc;
else if ((idelay_inc_idle_r6 == 1'b1) ||
((detect_edge_idle_r6 == 1'b1) && (second_edge_r2== 1'b0)
&& (tap_counter[5:0] != 6'b111111)))//changed from _r5 to _r6
state[2:0] <= detect_edge;
else
state[2:0] <= idle;
end
3'b010: begin // idelay_inc
dly_rst <= 1'b0;
dly_ce <= 1'b1;
dly_inc <= 1'b1;
idelay_inc_idle <= 1'b1;
state[2:0] <= idle;
if((flag[3:0] == 4'h0) || (flag[3:0] == 4'hF))
prev_dqs_level <= curr_dqs_level;
else
prev_dqs_level <= prev_dqs_level;
end
3'b011: begin // detect_edge
dly_rst <= 1'b0;
dly_ce <= 1'b1;
dly_inc <= 1'b1;
detect_edge_idle <= 1'b1;
state[2:0] <= idle;
if((flag[3:0] == 4'h0) || (flag[3:0] == 4'hF))
prev_dqs_level <= curr_dqs_level;
else
prev_dqs_level <= prev_dqs_level;
end
default: begin
dly_rst <= 1'b0;
dly_ce <= 1'b0;
dly_inc <= 1'b0;
idelay_rst_idle <= 1'b0;
detect_edge_idle <= 1'b0;
idelay_inc_idle <= 1'b0;
prev_dqs_level <= curr_dqs_level;
state[2:0] <= idle;
end
endcase
end
else
begin
dly_rst <= 1'b0;
dly_ce <= 1'b0;
dly_inc <= 1'b0;
idelay_rst_idle <= 1'b0;
detect_edge_idle <= 1'b0;
idelay_inc_idle <= 1'b0;
prev_dqs_level <= curr_dqs_level;
state[2:0] <= idelay_rst;
end
end
endmodule
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -