mirror of https://github.com/openXC7/prjxray.git
153 lines
2.8 KiB
Verilog
153 lines
2.8 KiB
Verilog
`default_nettype none
|
|
|
|
// ============================================================================
|
|
|
|
module iserdes_sdr_ddr_test #
|
|
(
|
|
parameter DATA_WIDTH = 8,
|
|
parameter DATA_RATE = "SDR"
|
|
)
|
|
(
|
|
// Clock and reset
|
|
input wire CLK,
|
|
input wire RST,
|
|
|
|
// Data pin
|
|
inout wire IO_DAT,
|
|
|
|
// Error indicator
|
|
output wire O_ERROR
|
|
);
|
|
|
|
// ============================================================================
|
|
// IOB
|
|
wire iob_o;
|
|
wire iob_i;
|
|
|
|
OBUFT obuf
|
|
(
|
|
.I (iob_o),
|
|
.T (1'b0),
|
|
.O (IO_DAT)
|
|
);
|
|
|
|
IBUF ibuf
|
|
(
|
|
.I (IO_DAT),
|
|
.O (iob_i)
|
|
);
|
|
|
|
// ============================================================================
|
|
|
|
wire tx_stb;
|
|
wire [DATA_WIDTH-1:0] tx_dat;
|
|
|
|
wire rx_stb;
|
|
wire [DATA_WIDTH-1:0] rx_dat;
|
|
wire rx_bitslip;
|
|
|
|
wire s_clk;
|
|
|
|
// Transmitter
|
|
transmitter #
|
|
(
|
|
.WIDTH (DATA_WIDTH),
|
|
.MODE (DATA_RATE)
|
|
)
|
|
transmitter
|
|
(
|
|
.CLK (CLK),
|
|
.RST (RST),
|
|
|
|
.O_STB (tx_stb),
|
|
.O_DAT (tx_dat),
|
|
|
|
.S_CLK (s_clk),
|
|
.S_DAT (iob_o)
|
|
);
|
|
|
|
// Receiver
|
|
receiver #
|
|
(
|
|
.WIDTH (DATA_WIDTH),
|
|
.MODE (DATA_RATE)
|
|
)
|
|
receiver
|
|
(
|
|
.CLK (CLK),
|
|
.RST (RST),
|
|
|
|
.I_CLK (s_clk),
|
|
.I_DAT (iob_i),
|
|
|
|
.O_STB (rx_stb),
|
|
.O_DAT (rx_dat),
|
|
.O_BITSLIP (rx_bitslip)
|
|
);
|
|
|
|
// The comparator module generates bitslip signal for the receiver. However
|
|
// the bitslip can shift only modulo DATA_WIDTH. Therefore additional delay is
|
|
// added which can delay the transmitted data that we compare to by a number
|
|
// of full words.
|
|
|
|
// Count bitslip pulses to know how much to delay words
|
|
reg [3:0] rx_bitslip_cnt;
|
|
always @(posedge CLK)
|
|
if (RST)
|
|
rx_bitslip_cnt <= 0;
|
|
else if (rx_bitslip) begin
|
|
if (rx_bitslip_cnt == (2*DATA_WIDTH - 1))
|
|
rx_bitslip_cnt <= 0;
|
|
else
|
|
rx_bitslip_cnt <= rx_bitslip_cnt + 1;
|
|
end
|
|
|
|
// Word delay
|
|
reg [1:0] tx_dly_cnt;
|
|
reg [DATA_WIDTH-1:0] tx_dat_dly_a;
|
|
reg [DATA_WIDTH-1:0] tx_dat_dly_b;
|
|
reg [DATA_WIDTH-1:0] tx_dat_dly_c;
|
|
reg [DATA_WIDTH-1:0] tx_dat_dly_d;
|
|
wire [DATA_WIDTH-1:0] tx_dat_dly;
|
|
|
|
always @(posedge CLK)
|
|
if (RST)
|
|
tx_dly_cnt <= 0;
|
|
else if(rx_bitslip && rx_bitslip_cnt == (2*DATA_WIDTH - 1))
|
|
tx_dly_cnt <= tx_dly_cnt + 1;
|
|
|
|
always @(posedge CLK)
|
|
if (tx_stb) begin
|
|
tx_dat_dly_d <= tx_dat_dly_c;
|
|
tx_dat_dly_c <= tx_dat_dly_b;
|
|
tx_dat_dly_b <= tx_dat_dly_a;
|
|
tx_dat_dly_a <= tx_dat;
|
|
end
|
|
|
|
assign tx_dat_dly = (tx_dly_cnt == 0) ? tx_dat_dly_a :
|
|
(tx_dly_cnt == 1) ? tx_dat_dly_b :
|
|
(tx_dly_cnt == 2) ? tx_dat_dly_c :
|
|
/*(tx_dly_cnt == 3) ?*/tx_dat_dly_d;
|
|
|
|
// Comparator
|
|
comparator #
|
|
(
|
|
.WIDTH (DATA_WIDTH)
|
|
)
|
|
comparator
|
|
(
|
|
.CLK (CLK),
|
|
.RST (RST),
|
|
|
|
.TX_STB (tx_stb),
|
|
.TX_DAT (tx_dat_dly),
|
|
|
|
.RX_STB (rx_stb),
|
|
.RX_DAT (rx_dat),
|
|
.RX_BITSLIP (rx_bitslip),
|
|
|
|
.O_ERROR (O_ERROR)
|
|
);
|
|
|
|
endmodule
|