📄 mem_interface_top_phy_init_0.v
字号:
//***************************************************************************
// State logic to write calibration training patterns to write data FIFO
//***************************************************************************
always @(posedge clk0) begin
if (rst0) begin
init_wdf_cnt_r <= 4'd0;
init_wren_r <= 1'b0;
init_done_r <= 1'b0;
init_data_r <= {64{1'bx}};
end else begin
init_wdf_cnt_r <= init_wdf_cnt_r + 1;
init_wren_r <= 1'b1;
case (init_wdf_cnt_r)
// First stage calibration. Pattern (rise/fall) = 1(r)->0(f)
// The rise data and fall data are already interleaved in the manner
// required for data into the WDF write FIFO
4'h0, 4'h1, 4'h2, 4'h3:
init_data_r <= {4{{8{1'b0}},{8{1'b1}}}};
// Second stage calibration. Pattern = 1(r)->1(f)->0(r)->0(f)
4'h4: init_data_r <= {64{1'b1}};
4'h5: init_data_r <= {64{1'b0}};
4'h6: init_data_r <= {64{1'b1}};
4'h7: init_data_r <= {64{1'b0}};
// Third stage calibration. Pattern = FF->FF->AA->AA->55->55->00->00
// Also make sure that last word is all zeros (because init_data_r is
// OR'ed with app_wdf_data.
4'h8: init_data_r <= {64{1'b1}};
4'h9: init_data_r <= {32{2'b10}};
4'hA: init_data_r <= {32{2'b01}};
// finished, stay in this state, and deassert WREN
4'hB: begin
init_data_r <= {64{1'b0}};
init_done_r <= 1'b1;
init_wdf_cnt_r <= init_wdf_cnt_r;
if (init_done_r)
init_wren_r <= 1'b0;
else
init_wren_r <= 1'b1;
end
default: begin
init_data_r <= {(2*DQ_WIDTH){1'bx}};
init_wren_r <= 1'bx;
init_done_r <= 1'bx;
init_wdf_cnt_r <= 4'bxxxx;
end
endcase
end
end
//***************************************************************************
//***************************************************************************
// Initialization state machine
//***************************************************************************
// synthesis attribute max_fanout of init_cnt_r is 1
always @(posedge clk0)
// every time we need to initialize another rank of memory, need to
// reset init count, and repeat the entire initialization (but not
// calibration) sequence
if (rst0 || (init_state_r == INIT_DEEP_MEMORY_ST))
init_cnt_r <= 4'd0;
else if (!DDR2_ENABLE && (init_state_r == INIT_PRECHARGE) &&
(init_cnt_r == 4'h1))
// skip EMR(2) and EMR(3) register loads
init_cnt_r <= 4'h4;
else if (!DDR2_ENABLE && (init_state_r == INIT_LOAD_MODE) &&
(init_cnt_r == 4'h9))
// skip OCD calibration for DDR1
init_cnt_r <= 4'hC;
else if ((init_state_r == INIT_LOAD_MODE) ||
(init_state_r == INIT_PRECHARGE) ||
(init_state_r == INIT_AUTO_REFRESH) ||
(init_state_r == INIT_CNT_200))
init_cnt_r <= init_cnt_r + 1;
always @(posedge clk0) begin
if ((init_state_r == INIT_IDLE) && (init_cnt_r == 4'hE)) begin
phy_init_done_r <= 1'b1;
end else
phy_init_done_r <= 1'b0;
end
//synthesis attribute max_fanout of phy_init_done is 1
always @(posedge clk0)
phy_init_done <= phy_init_done_r;
//synthesis translate_off
always @(posedge phy_init_done_r)
$display ("Calibration completed");
//synthesis translate_on
//*****************************************************************
//synthesis attribute max_fanout of init_state_r is 3
//synthesis attribute max_fanout of init_state_r1 is 3
//synthesis attribute max_fanout of init_state_r2 is 3
always @(posedge clk0)
if (rst0) begin
init_state_r <= INIT_IDLE;
init_state_r1 <= INIT_IDLE;
init_state_r2 <= INIT_IDLE;
calib_done_r <= 4'b0000;
end else begin
init_state_r <= init_next_state;
init_state_r1 <= init_state_r;
init_state_r2 <= init_state_r1;
calib_done_r <= calib_done; // register for timing
end
always @(*) begin
init_next_state = init_state_r;
case (init_state_r)
INIT_IDLE: begin
if (done_200us_r) begin
case (init_cnt_r) // synthesis parallel_case full_case
4'h0:
init_next_state = INIT_CNT_200;
4'h1:
if (cnt_200_cycle_done_r)
init_next_state = INIT_PRECHARGE;
4'h2:
init_next_state = INIT_LOAD_MODE; // EMR(2)
4'h3:
init_next_state = INIT_LOAD_MODE; // EMR(3);
4'h4:
init_next_state = INIT_LOAD_MODE; // EMR, enable DLL
4'h5:
init_next_state = INIT_LOAD_MODE; // MR, reset DLL
4'h6:
init_next_state = INIT_PRECHARGE;
4'h7:
init_next_state = INIT_AUTO_REFRESH;
4'h8:
init_next_state = INIT_AUTO_REFRESH;
4'h9:
init_next_state = INIT_LOAD_MODE; // MR, unreset DLL
4'hA:
init_next_state = INIT_LOAD_MODE; // EMR, OCD default
4'hB:
init_next_state = INIT_LOAD_MODE; // EMR, enable OCD exit
4'hC: begin
// Deep memory state/support disabled
// if ((chip_cnt_r < CS_NUM-1))
// init_next_state = INIT_DEEP_MEMORY_ST;
//else
if (cnt_200_cycle_done_r)
init_next_state = INIT_DUMMY_ACTIVE;
else
init_next_state = INIT_IDLE;
end
4'hD:
init_next_state = INIT_PRECHARGE;
4'hE:
init_next_state = INIT_IDLE;
default :
init_next_state = INIT_IDLE;
endcase
end
end
INIT_CNT_200:
init_next_state = INIT_CNT_200_WAIT;
INIT_CNT_200_WAIT:
if (cnt_200_cycle_done_r)
init_next_state = INIT_IDLE;
INIT_PRECHARGE:
init_next_state = INIT_PRECHARGE_WAIT;
INIT_PRECHARGE_WAIT:
if (cnt6_r == CNTNEXT)
init_next_state = INIT_IDLE;
INIT_LOAD_MODE:
init_next_state = INIT_MODE_REGISTER_WAIT;
INIT_MODE_REGISTER_WAIT:
if (cnt6_r == CNTNEXT)
init_next_state = INIT_IDLE;
INIT_AUTO_REFRESH:
init_next_state = INIT_AUTO_REFRESH_WAIT;
INIT_AUTO_REFRESH_WAIT:
if (cnt6_r == CNTNEXT)
init_next_state = INIT_IDLE;
INIT_DEEP_MEMORY_ST:
init_next_state = INIT_IDLE;
// single row activate. All subsequent calibration writes and read will
// take place in this row
INIT_DUMMY_ACTIVE:
init_next_state = INIT_DUMMY_ACTIVE_WAIT;
INIT_DUMMY_ACTIVE_WAIT:
if (cnt6_r == CNTNEXT)
init_next_state = INIT_CAL1_WRITE;
// Stage 1 calibration (write and continuous read)
INIT_CAL1_WRITE:
if (burst_addr_r == 2'b11)
init_next_state = INIT_CAL1_WRITE_READ;
INIT_CAL1_WRITE_READ:
if (cnt6_r == CNTNEXT)
init_next_state = INIT_CAL1_READ;
INIT_CAL1_READ:
if (calib_done_r[0])
init_next_state = INIT_CAL1_READ_WAIT;
INIT_CAL1_READ_WAIT:
if (cnt6_r == CNTNEXT)
init_next_state = INIT_CAL2_WRITE;
// Stage 2 calibration (write and continuous read)
INIT_CAL2_WRITE:
if (burst_addr_r == 2'b11)
init_next_state = INIT_CAL2_WRITE_READ;
INIT_CAL2_WRITE_READ:
if (cnt6_r == CNTNEXT)
init_next_state = INIT_CAL2_READ;
INIT_CAL2_READ:
if (calib_done_r[1])
init_next_state = INIT_CAL2_READ_WAIT;
INIT_CAL2_READ_WAIT:
if(cnt6_r == CNTNEXT)
init_next_state = INIT_CAL3_WRITE;
// Stage 3 calibration (write and continuous read)
INIT_CAL3_WRITE:
if (burst_addr_r == 2'b11)
init_next_state = INIT_CAL3_WRITE_READ;
INIT_CAL3_WRITE_READ:
if (cnt6_r == CNTNEXT)
init_next_state = INIT_CAL3_READ;
INIT_CAL3_READ:
if (burst_addr_r == 2'b11)
init_next_state = INIT_CAL3_READ_WAIT;
INIT_CAL3_READ_WAIT: begin
if (cnt6_r == CNTNEXT)
if (calib_done_r[2]) begin
if (DQS_GATE_EN)
init_next_state = INIT_CAL4_READ;
else
init_next_state = INIT_PRECHARGE;
end else
init_next_state = INIT_CAL3_READ;
end
// Stage 4 calibration (continuous read only, same pattern as stage 3)
// only used if DQS_GATE supported
INIT_CAL4_READ:
if (burst_addr_r == 2'b11)
init_next_state = INIT_CAL4_READ_WAIT;
INIT_CAL4_READ_WAIT: begin
if (cnt6_r == CNTNEXT)
if (calib_done_r[3])
init_next_state = INIT_PRECHARGE;
else
init_next_state = INIT_CAL4_READ;
end
endcase
end
//***************************************************************************
// Memory control/address
//***************************************************************************
always @(posedge clk0)
if ((init_state_r == INIT_DUMMY_ACTIVE) ||
(init_state_r == INIT_PRECHARGE) ||
(init_state_r == INIT_LOAD_MODE) ||
(init_state_r == INIT_AUTO_REFRESH))
ddr_ras_n_r <= 1'b0;
else
ddr_ras_n_r <= 1'b1;
always @(posedge clk0)
if ((init_state_r == INIT_LOAD_MODE) ||
(init_state_r == INIT_AUTO_REFRESH) ||
(cal_write_read && (burst_cnt_r == 2'b00)))
ddr_cas_n_r <= 1'b0;
else
ddr_cas_n_r <= 1'b1;
always @(posedge clk0)
if ((init_state_r == INIT_LOAD_MODE) ||
(init_state_r == INIT_PRECHARGE) ||
(cal_write && (burst_cnt_r == 2'b00)))
ddr_we_n_r <= 1'b0;
else
ddr_we_n_r <= 1'b1;
//*****************************************************************
// memory address during init
//*****************************************************************
always @(posedge clk0) begin
if (init_state_r == INIT_PRECHARGE) begin
// Precharge all - set A10 = 1
ddr_addr_r <= {ROW_WIDTH{1'b0}};
ddr_addr_r[10] <= 1'b1;
end else if (init_state_r == INIT_LOAD_MODE) begin
ddr_ba_r <= {BANK_WIDTH{1'b0}};
ddr_addr_r <= {ROW_WIDTH{1'b0}};
case (init_cnt_r)
// EMR (2)
4'h2: begin
ddr_ba_r[1:0] <= 2'b10;
ddr_addr_r <= {ROW_WIDTH{1'b0}};
end
// EMR (3)
4'h3: begin
ddr_ba_r[1:0] <= 2'b11;
ddr_addr_r <= {ROW_WIDTH{1'b0}};
end
// EMR write - A0 = 0 for DLL enable
4'h4: begin
ddr_ba_r[1:0] <= 2'b01;
ddr_addr_r <= ext_mode_reg[ROW_WIDTH-1:0];
end
// MR write, reset DLL (A8=1)
4'h5: begin
ddr_ba_r[1:0] <= 2'b00;
ddr_addr_r <= load_mode_reg[ROW_WIDTH-1:0];
ddr_addr_r[8] <= 1'b1;
end
// MR write, unreset DLL (A8=0)
4'h9: begin
ddr_ba_r[1:0] <= 2'b00;
ddr_addr_r <= load_mode_reg[ROW_WIDTH-1:0];
end
// EMR write, OCD default state
4'hA: begin
ddr_ba_r[1:0] <= 2'b01;
ddr_addr_r <= ext_mode_reg[ROW_WIDTH-1:0];
ddr_addr_r[9:7] <= 3'b111;
end
// EMR write - OCD exit
4'hB: begin
ddr_ba_r[1:0] <= 2'b01;
ddr_addr_r <= ext_mode_reg[ROW_WIDTH-1:0];
end
default: begin
ddr_ba_r <= {BANK_WIDTH{1'bx}};
ddr_addr_r <= {ROW_WIDTH{1'bx}};
end
endcase
end else if (cal_write_read) begin
// when writing or reading for Stages 2-4, since training pattern is
// either 4 (stage 2) or 8 (stage 3-4) long, if BURST LEN < 8, then
// need to issue multiple bursts to read entire training pattern
ddr_addr_r[ROW_WIDTH-1:3] <= {ROW_WIDTH-4{1'b0}};
ddr_addr_r[2:0] <= {burst_addr_r, 1'b0};
ddr_ba_r <= {BANK_WIDTH-1{1'b0}};
end else if (init_state_r == INIT_DUMMY_ACTIVE) begin
// all calibration writing read takes place in row 0x0 only
ddr_ba_r <= {BANK_WIDTH{1'b0}};
ddr_addr_r <= {ROW_WIDTH{1'b0}};
end else begin
// otherwise, cry me a river
ddr_ba_r <= {BANK_WIDTH{1'bx}};
ddr_addr_r <= {ROW_WIDTH{1'bx}};
end
end
// Keep CKE asserted after initial power-on delay
always @(posedge clk0)
ddr_cke_r <= {CKE_WIDTH{done_200us_r}};
// register commands to memory. Two clock cycle delay from state -> output
always @(posedge clk0) begin
ddr_addr_r1 <= ddr_addr_r;
ddr_ba_r1 <= ddr_ba_r;
ddr_cas_n_r1 <= ddr_cas_n_r;
ddr_ras_n_r1 <= ddr_ras_n_r;
ddr_we_n_r1 <= ddr_we_n_r;
end
assign phy_init_addr = ddr_addr_r1;
assign phy_init_ba = ddr_ba_r1;
assign phy_init_cas_n = ddr_cas_n_r1;
assign phy_init_cke = ddr_cke_r;
assign phy_init_cs_n = ddr_cs_n_r;
assign phy_init_ras_n = ddr_ras_n_r1;
assign phy_init_we_n = ddr_we_n_r1;
assign phy_init_wdf_wren = init_wren_r;
assign phy_init_wdf_data = init_data_r;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -