📄 phy_write.v
字号:
wr_stages[3] <= wr_stages[2]; wr_stages[4] <= wr_stages[3]; wr_stages[5] <= wr_stages[4]; wr_stages[6] <= wr_stages[5]; wr_stages[7] <= wr_stages[6]; wr_stages[8] <= wr_stages[7]; wr_stages[9] <= wr_stages[8]; wr_stages[10] <= wr_stages[9]; end // intermediate synchronization to CLK270 always @(negedge clk90) begin dq_oe_270 <= dq_oe_0; dqs_oe_270 <= dqs_oe_0; dqs_rst_270 <= dqs_rst_0; wdf_rden_270 <= wdf_rden_0; end // synchronize DQS signals to CLK180 always @(negedge clk0) begin dqs_oe_n_180_r1 <= ~dqs_oe_270; dqs_rst_n_180_r1 <= ~dqs_rst_270; end // All write data-related signals synced to CLK90 always @(posedge clk90) begin dq_oe_n_90_r1 <= ~dq_oe_270; wdf_rden_90_r <= wdf_rden_270; end // generate for wdf_rden and calib rden. These signals // are asserted based on write latency. For write // latency of 2, the extra register stage is taken out. generate if (WR_LATENCY > 2) begin always @(posedge clk90) begin // assert wdf rden only for non calibration opertations wdf_rden_90_r1 <= wdf_rden_90_r & phy_init_data_sel; // rden for calibration calib_rden_90_r <= wdf_rden_90_r; end end else begin always @(*) begin wdf_rden_90_r1 = wdf_rden_90_r & phy_init_data_sel; calib_rden_90_r = wdf_rden_90_r; end end // else: !if(WR_LATENCY > 2) endgenerate // dm CE signal to stop dm oscilation always @(negedge clk90)begin dm_ce_r <= dm_ce_0; dm_ce <= dm_ce_r; end // When in ECC mode the upper byte [71:64] will have the // ECC parity. Mapping the bytes which have valid data // to the upper byte in ecc mode. Also in ecc mode there // is an extra register stage to account for timing. genvar mask_i; generate if(ECC_ENABLE) begin for (mask_i = 0; mask_i < (2*DQ_WIDTH)/72; mask_i = mask_i+1) begin: gen_mask assign wdf_ecc_mask[((mask_i*9)+9)-1:(mask_i*9)] = {&wdf_mask_data[(mask_i*8)+(7+mask_i):mask_i*9], wdf_mask_data[(mask_i*8)+(7+mask_i):mask_i*9]}; end end endgenerate generate if (ECC_ENABLE) begin:gen_ecc_reg always @(posedge clk90)begin if(phy_init_data_sel) wdf_mask_r <= wdf_ecc_mask; else wdf_mask_r <= {(2*DQ_WIDTH/8){1'b0}}; end end else begin always@(posedge clk90) begin if (phy_init_data_sel) wdf_mask_r <= wdf_mask_data; else wdf_mask_r <= {(2*DQ_WIDTH/8){1'b0}}; end end endgenerate always @(posedge clk90) begin if(phy_init_data_sel) wdf_data_r <= wdf_data; else wdf_data_r <={init_data_f,init_data_r}; end // Error generation block during simulation. // Error will be displayed when all the DM // bits are not zero. The error will be // displayed only during the start of the sequence // for errors that are continous over many cycles. generate if (ECC_ENABLE) begin: gen_ecc_error always @(posedge clk90) begin //synthesis translate_off wdf_mask_r1 <= wdf_mask_r; if(DQ_WIDTH > 72) ecc_dm_error_r <= ( (~wdf_mask_r1[35] && (|wdf_mask_r1[34:27])) || (~wdf_mask_r1[26] && (|wdf_mask_r1[25:18])) || (~wdf_mask_r1[17] && (|wdf_mask_r1[16:9])) || (~wdf_mask_r1[8] && (|wdf_mask_r1[7:0]))) && phy_init_data_sel; else ecc_dm_error_r <= ((~wdf_mask_r1[17] && (|wdf_mask_r1[16:9])) || (~wdf_mask_r1[8] && (|wdf_mask_r1[7:0]))) && phy_init_data_sel; ecc_dm_error_r1 <= ecc_dm_error_r ; if (ecc_dm_error_r && ~ecc_dm_error_r1) // assert the error only once. $display ("ECC DM ERROR. "); //synthesis translate_on end end endgenerate //*************************************************************************** // State logic to write calibration training patterns //*************************************************************************** always @(posedge clk90) begin if (rst90_r) begin init_wdf_cnt_r <= 4'd0; init_data_r <= {64{1'bx}}; init_data_f <= {64{1'bx}}; end else begin init_wdf_cnt_r <= init_wdf_cnt_r + calib_rden_90_r; casex (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'b00xx: begin init_data_r <= {DQ_WIDTH{1'b1}}; init_data_f <= {DQ_WIDTH{1'b0}}; end // Second stage calibration. Pattern = 1(r)->1(f)->0(r)->0(f) 4'b01x0: begin init_data_r <= {DQ_WIDTH{1'b1}}; init_data_f <= {DQ_WIDTH{1'b1}}; end 4'b01x1: begin init_data_r <= {DQ_WIDTH{1'b0}}; init_data_f <= {DQ_WIDTH{1'b0}}; end // MIG 2.1: Changed Stage 3/4 training pattern // Third and fourth stage calibration patern = // 11(r)->ee(f)->ee(r)->11(f)-11(r)->ee(f)->ee(r)->11(f) 4'b1000: begin init_data_r <= {DQ_WIDTH/4{4'h1}}; init_data_f <= {DQ_WIDTH/4{4'hE}}; end 4'b1001: begin init_data_r <= {DQ_WIDTH/4{4'hE}}; init_data_f <= {DQ_WIDTH/4{4'h1}}; end 4'b1010: begin init_data_r <= {(DQ_WIDTH/4){4'h1}}; init_data_f <= {(DQ_WIDTH/4){4'hE}}; end 4'b1011: begin init_data_r <= {(DQ_WIDTH/4){4'hE}}; init_data_f <= {(DQ_WIDTH/4){4'h1}}; end default: begin init_data_f <= {(2*DQ_WIDTH){1'bx}}; init_data_r <= {(2*DQ_WIDTH){1'bx}}; end endcase end end //*************************************************************************** always @(posedge clk90) dq_oe_n <= dq_oe_n_90_r1; always @(negedge clk0) dqs_oe_n <= dqs_oe_n_180_r1; always @(negedge clk0) dqs_rst_n <= dqs_rst_n_180_r1; // generate for odt. odt is asserted based on // write latency. For write latency of 2 // the extra register stage is taken out. generate if (ODT_WR_LATENCY > 2) begin always @(posedge clk0) odt <= odt_0; end else begin always @ (*) odt = odt_0; end endgenerate assign wdf_rden = wdf_rden_90_r1; //*************************************************************************** // Format write data/mask: Data is in format: {fall, rise} //*************************************************************************** assign wr_data_rise = wdf_data_r[DQ_WIDTH-1:0]; assign wr_data_fall = wdf_data_r[(2*DQ_WIDTH)-1:DQ_WIDTH]; assign mask_data_rise = wdf_mask_r[MASK_WIDTH-1:0]; assign mask_data_fall = wdf_mask_r[(2*MASK_WIDTH)-1:MASK_WIDTH];endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -