📄 qdr2_burst_4_body.v
字号:
//*****************************************************************************************
//**
//** www.xilinx.com Copyright (c) 1984-2004 Xilinx, Inc. All rights reserved
//**
//** QDR(tm)-II SRAM Virtex(tm)-II Interface Verilog instanciation
//**
//*****************************************************************************************
//**
//** Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are
//** provided to you \"as is\". Xilinx and its licensors make and you
//** receive no warranties or conditions, express, implied, statutory
//** or otherwise, and Xilinx specifically disclaims any implied
//** warranties of merchantability, non-infringement, or fitness for a
//** particular purpose. Xilinx does not warrant that the functions
//** contained in these designs will meet your requirements, or that the
//** operation of these designs will be uninterrupted or error free, or
//** that defects in the Designs will be corrected. Furthermore, Xilinx
//** does not warrant or make any representations regarding use or the
//** results of the use of the designs in terms of correctness, accuracy,
//** reliability, or otherwise.
//**
//** LIMITATION OF LIABILITY. In no event will Xilinx or its licensors be
//** liable for any loss of data, lost profits, cost or procurement of
//** substitute goods or services, or for any special, incidental,
//** consequential, or indirect damages arising from the use or operation
//** of the designs or accompanying documentation, however caused and on
//** any theory of liability. This limitation will apply even if Xilinx
//** has been advised of the possibility of such damage. This limitation
//** shall apply not-withstanding the failure of the essential purpose of
//** any limited remedies herein.
//**
//*****************************************************************************************
// This module is the top level architecture for the memory interface design.
// The signals connections are describled in the application note.
// The ports naming convention is as follows:
// - user side: USER_INSTNAME
// - memory side: QDR_INSTNAME
`timescale 1 ns/1 ps
module qdr2_burst_4_body (USER_DWL,
USER_DWH,
USER_Q,
USER_A_READ,
USER_A_WRITE,
CLK_BUF,
CLK0E,
CLK90E,
CLK180E,
CLK270E,
LOCKED_DCM_PRI,
USER_R_n,
USER_W_n,
USER_BW_n,
USER_RESET,
USER_DATA_VALID,
QDR_Q,
QDR_D,
QDR_SA,
QDR_R_n,
QDR_W_n,
QDR_BW_n,
QDR_K,
QDR_K_n,
QDR_C,
QDR_C_n,
QDR_CQ,
QDR_CQ_n,
QDR_R_n_ext,
QDR_R_n_int,
TEST_RESET_0);
// Parameters
parameter data_bits = 9 -1; // Size of the data bus -1
parameter addr_bits = 18 -1; // Size of the address bus -1
input [data_bits : 0] USER_DWL;
input [data_bits : 0] USER_DWH;
output [17 : 0] USER_Q;
input [addr_bits : 0] USER_A_READ;
input [addr_bits : 0] USER_A_WRITE;
input CLK_BUF;
input CLK0E;
input CLK90E;
input CLK180E;
input CLK270E;
input LOCKED_DCM_PRI;
input USER_RESET;
input USER_R_n;
input USER_W_n;
input USER_BW_n;
output USER_DATA_VALID;
output [data_bits : 0] QDR_D;
input [data_bits : 0] QDR_Q;
output [addr_bits : 0] QDR_SA;
output QDR_R_n;
output QDR_W_n;
output QDR_BW_n;
output QDR_K;
output QDR_K_n;
output QDR_C;
output QDR_C_n;
input QDR_CQ;
input QDR_CQ_n;
output QDR_R_n_ext;
input QDR_R_n_int;
output TEST_RESET_0;
wire [1:0] CQ;
wire [addr_bits : 0] A_READ_FD;
wire [addr_bits : 0] A_WRITE_FD;
wire RESET;
wire GND;
wire HIGH;
wire O_DDR_K_OBUF;
wire O_DDR_K_n_OBUF;
wire ReadInProgress;
wire LOCKED_DCM_PRI;
wire R_n_FD;
wire W_BAR;
wire R_BAR;
wire [data_bits : 0] D_data;
reg [addr_bits : 0] ADR;
wire noReadCurrent;
wire [4:0] selTap;
wire QDR_R_n_ext_stage1;
wire QDR_R_n_ext_stage2;
wire QDR_R_n_ext_stage3;
wire R_n_recapture;
wire MUX_ADDR;
reg sys_rst0_o;
reg sys_rst0_1;
reg sys_rst0;
reg sys_rst90_o;
reg sys_rst90_1;
reg sys_rst90;
reg sys_rst180_o;
reg sys_rst180_1;
reg sys_rst180;
reg sys_rst270_o;
reg sys_rst270_1;
reg sys_rst270;
// Signals assigment
assign GND = 1'b0;
assign HIGH = 1'b1;
assign noReadCurrent = ~((~USER_R_n) || (USER_DATA_VALID)); // uses output of the user FIFO: make sure that data are automatically pulled out of the FIFO or this needs to ne changed.
assign CQ = {QDR_CQ_n,QDR_CQ};
assign ReadInProgress = QDR_R_n_ext_stage3; // R_n_ext for synchronous scheme to generate pseudo valid data signal
assign RESET = USER_RESET;
assign TEST_RESET_0 = sys_rst0;
// Generation of the reset signal in the different clock domains
always @ (posedge CLK0E) begin
if ((RESET == 1'b1) || (LOCKED_DCM_PRI == 1'b0)) begin
sys_rst0_o <= 1'b1;
sys_rst0_1 <= 1'b1;
sys_rst0 <= 1'b1;
end
else begin
sys_rst0_o <= 1'b0;
sys_rst0_1 <= sys_rst0_o;
sys_rst0 <= sys_rst0_1;
end
end
always @ (posedge CLK90E) begin
if ((RESET == 1'b1) || (LOCKED_DCM_PRI == 1'b0)) begin
sys_rst90_o <= 1'b1;
sys_rst90_1 <= 1'b1;
sys_rst90 <= 1'b1;
end
else begin
sys_rst90_o <= 1'b0;
sys_rst90_1 <= sys_rst90_o;
sys_rst90 <= sys_rst90_1;
end
end
always @ (posedge CLK180E) begin
if ((RESET == 1'b1) || (LOCKED_DCM_PRI == 1'b0)) begin
sys_rst180_o <= 1'b1;
sys_rst180_1 <= 1'b1;
sys_rst180 <= 1'b1;
end
else
begin
sys_rst180_o <= 1'b0;
sys_rst180_1 <= sys_rst180_o;
sys_rst180 <= sys_rst180_1;
end
end
always @ (posedge CLK270E) begin
if ((RESET == 1'b1) || (LOCKED_DCM_PRI == 1'b0)) begin
sys_rst270_o <= 1'b1;
sys_rst270_1 <= 1'b1;
sys_rst270 <= 1'b1;
end
else
begin
sys_rst270_o <= 1'b0;
sys_rst270_1 <= sys_rst270_o;
sys_rst270 <= sys_rst270_1;
end
end
// Input buffers declaration
IBUF_HSTL_II_18 INST_QDR_IBUF_R_n (.O(R_n_recapture), .I(QDR_R_n_int));
OBUF_HSTL_II_18 INST_QDR_OBUF_R_n (.I(ReadInProgress), .O(QDR_R_n_ext));
// OBUF instanciations
OBUF_HSTL_II_18 INST_QDR_OBUF_BW ( .O(QDR_BW_n), .I(USER_BW_n));
// Driving C signals at high
OBUF_HSTL_II_18 INST_QDR_OBUF_C (.O(QDR_C), .I(HIGH));
OBUF_HSTL_II_18 INST_QDR_OBUF_C_n (.O(QDR_C_n), .I(HIGH));
// Write data bus to QDR II SRAM device
OBUF_HSTL_II_18 INST_QDR_OBUF_DWRITE_[data_bits:0] (.I(D_data[data_bits:0]) ,.O(QDR_D[data_bits:0]) );
//QDR_SA_BUF
OBUF_HSTL_II_18 INST_QDR_OBUF_DADDR_[addr_bits:0] (.I(ADR[addr_bits:0]) , .O(QDR_SA[addr_bits:0]) );
OBUF_HSTL_II_18 INST_QDR_OBUF_K (.I(O_DDR_K_OBUF), .O(QDR_K) );
OBUF_HSTL_II_18 INST_QDR_OBUF_K_n (.I(O_DDR_K_n_OBUF), .O(QDR_K_n));
// Other control signals and clocks
OBUF_HSTL_II_18 INST_QDR_OBUF_W_n (.I(W_BAR), .O(QDR_W_n));
OBUF_HSTL_II_18 INST_QDR_OBUF_R_n_tr1 (.I(R_BAR), .O(QDR_R_n));
FDS R_n_FD_pipe (.Q(R_n_FD), .D(USER_R_n), .C(CLK270E), .S(RESET)); // RAKCHOPR - Changed to "FDS" from "FD" to add RESET term to flop
FDDRRSE WRT_FD_R_n (.Q(R_BAR), .C0(CLK270E), .C1(CLK90E), .CE(HIGH), .D0(R_n_FD), .D1(1'b1), .R(GND), .S(RESET)); // RAKCHOPR //DDR register in the IO
// Clock forwarding to the memory device
FDDRRSE FDDR_K (.Q(O_DDR_K_OBUF), .C0(CLK0E), .C1(CLK180E), .CE(HIGH), .D0(HIGH), .D1(GND), .R(GND), .S(GND));
FDDRRSE FDDR_K_n (.Q(O_DDR_K_n_OBUF), .C0(CLK0E), .C1(CLK180E), .CE(HIGH), .D0(GND), .D1(HIGH), .R(GND), .S(GND));
// Write operation module
write_burst_4 INST_Write
(.CLK90 (CLK90E),
.CLK270 (CLK270E),
.D0 (USER_DWH),
.D1 (USER_DWL),
.W_n (USER_W_n),
.W_BAR (W_BAR),
.Q (D_data),
.CLK180 (CLK180E),
.RESET (RESET)); // RAKCHOPR -- Added reset port
//*****************************************************************************************
// Calibration circuit
//*****************************************************************************************
FD FD_NoRead ( .Q(CalNoRead),
.D(noReadCurrent),
.C(CLK0E));
wire CalNoRead; //CalNoRead out of CLK0 enables tap change from the calibration circuit when there is no read current
cal_top cal_inst
(.clk (CLK_BUF),
.clk0 (CLK0E),
.clk0dcmlock (LOCKED_DCM_PRI),
.reset (sys_rst0),
.okToSelTap (CalNoRead),
.tapForDqs (selTap));
// Read datapath implementation
data_path Read_data_path
( .clk (CLK0E),
.clk90 (CLK90E),
.clk180 (CLK180E),
.clk270 (CLK270E),
.reset (sys_rst0),
.reset90 (sys_rst90),
.reset180 (sys_rst180),
.reset270 (sys_rst270),
.rst_cq_div (R_n_recapture),
.delay_sel (selTap),
.u_data_val (USER_DATA_VALID),
.qdr2_cq (CQ),
.qdr2_q (QDR_Q),
.user_output_data (USER_Q));
// Address bus: Read/Write multiplexer
always@(posedge CLK270E)
begin: SEQ
if (!MUX_ADDR) // !USER_W_n !USER_WRITE_E Write command active if USER_WRITE_E == 0
ADR <= USER_A_READ; // AD_Write; USER_A_WRITE A_READ_FD
else
ADR <= A_WRITE_FD; // AD_Read;A_READ_FD
end
FD FD_AW1_[addr_bits:0] (.Q(A_WRITE_FD[addr_bits:0]) , .D(USER_A_WRITE[addr_bits:0]) , .C(CLK270E)); // Pipeline for Write address
// Signal R_n_ext generation for synchronous scheme
FDS FD_R_n_1 (.Q(QDR_R_n_ext_stage1), .C(CLK270E), .D(USER_READ_E), .S(RESET)); // When reset, read command at 1
FDS FD_R_n_2 (.Q(QDR_R_n_ext_stage2), .C(CLK180E), .D(~QDR_R_n_ext_stage1), .S(RESET)); // When reset, read command at 1
FDS FD_R_n_3 (.Q(QDR_R_n_ext_stage3), .C(CLK90E), .D(QDR_R_n_ext_stage2), .S(RESET)); // When reset, read command at 1 modified to CLK90
// State machine for controlling the QDR SRAM interface read and write accesses
qdr2_fsm_access ctrl_access
( .CLK (CLK180E),
.RESET (sys_rst180),
.USER_W_n (USER_W_n),
.USER_R_n (USER_R_n),
.WRITE_E (USER_WRITE_E),
.READ_E (USER_READ_E),
.CLK_A_RD (CLK0E),
.MUX_ADR_RD (MUX_ADDR));
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -