赞
踩
话不多说,直接测试
1. OUTPUT:LVDS_TX
2. SDR:代表着速率,测试选的SDR(单速率)
3. 8:串换因子,就是一对LVDS转化几bit的并行数据(和后面的clk,clk_div有关系)
4. 8:8对LVDS
5. LVDS都是差分电压,这个根据板卡上的电压选择
6. 类型肯定是差分的
1. 输出差分时钟
2. 时钟类型选择LVDS,和前面匹配
第三页是数据和时钟的延时,默认
下面说一下测试过程
发送端
1. 发送的数据(需要发送十几个周期的同步码,后面是递增数0~255)
2. 输出的差分时钟(频率和clk_in一致,500M)
3. 串行数据的时钟 (测试的500M)clk_in
4. 并行数据的时钟(测试125M)clk_div_in
clk_in和clk_div的关系就是就是图1中的串换因子以及SDR的关系: 8:1(DDR的话就是4:1)
1. LVDS_TX 核的输出时钟,连接在MMCM上
2. 输出500M和125M,用作LVDS_RX的CLK_IN和CLK_DIV_IN
接收端
LVDS接收需要考虑一个问题是:如何将数据和时钟对齐,这里的bitslip叫位移操作,用它来将同步码找出,进行数据的同步
1. 接收数据,先进行数据的同步
2. bitslip用来同步数据
3. clk_in和clk_div_in分别来自MMCM
4. 复位也来自MMCM
注意: bitslip是一个脉冲信号,产生一个脉冲,数据就移位一次,直到找出同步码为止
下面看下仿真的结果
1. 这是发送数据的同步码:EB90_01DC_EF18_EB90
2. 接收端经过bitslip的同步,最终得到的同步码
3.我用的8通道LVDS,所以bitslip是8bit,每个bit都需要移位,所以是FF
,
可以看到,发送的数据和接收的数据都是连续的,说明LVDS通信OK
附上代码
module lvds_module
#(
// parameter LVDS_DATA_HEAD = 64'hFF00_00FF_FF00_FFFF, // 同步码
parameter LVDS_DATA_HEAD = 64'hEB90_01DC_EF18_EB90, // 同步码
parameter LVDS_DATA_HEAD_CNT = 8'h40, // 同步码的frame
parameter BITSLIP_FRAME = 4'h8 // bitslip的参数
)
(
input clk_div_in,
input clk_in,
input clk_reset,
input io_reset
);
wire [63:0] data_out_from_device;
wire [7:0] data_out_to_pins_p;
wire [7:0] data_out_to_pins_n;
wire [63:0] data_in_to_device;
wire [7:0] data_in_from_pins_p;
wire [7:0] data_in_from_pins_n;
reg [7:0] bitslip;
reg [63:0] data;
reg [7:0] head_cnt;
reg [7:0] data_cnt;
reg bitslip_head_flag;
reg [3:0] bitslip_cnt;
wire clk_to_pins_p;
wire clk_to_pins_n;
wire clk_rx;
wire clk_rx_div;
wire locked;
selectio_wiz_0
lvds_tx
(
.data_out_from_device(data_out_from_device), // input [63:0] data_out_from_device
.data_out_to_pins_p(data_out_to_pins_p), // output [7:0] data_out_to_pins_p
.data_out_to_pins_n(data_out_to_pins_n), // output [7:0] data_out_to_pins_n
.clk_to_pins_p(clk_to_pins_p), // output clk_to_pins_p
.clk_to_pins_n(clk_to_pins_n), // output clk_to_pins_n
.clk_in(clk_in), // input clk_in
.clk_div_in(clk_div_in), // input clk_div_in
.clk_reset(clk_reset), // input clk_reset
.io_reset(io_reset) // input io_reset
);
clk_wiz_1 clk_wiz_1
(
// Clock out ports
.clk_out1(clk_rx), // output clk_out1
.clk_out2(clk_rx_div), // output clk_out2
// Status and control signals
.locked(locked), // output locked
// Clock in ports
.clk_in1_p(clk_to_pins_p), // input clk_in1_p
.clk_in1_n(clk_to_pins_n)); // input clk_in1_n
// INST_TAG_END ------ End INSTANTIATION Template ---------
selectio_wiz_3
lvds_rx
(
.data_in_from_pins_p(data_in_from_pins_p), // input [0:0] data_in_from_pins_p
.data_in_from_pins_n(data_in_from_pins_n), // input [0:0] data_in_from_pins_n
.data_in_to_device(data_in_to_device), // output [7:0] data_in_to_device
.bitslip(bitslip), // input bitslip
.clk_in(clk_rx), // input clk_in
.clk_div_in(clk_rx_div), // input clk_div_in
.io_reset(~locked) // input io_reset
);
assign data_out_from_device = data;
assign data_in_from_pins_p = data_out_to_pins_p;
assign data_in_from_pins_n = data_out_to_pins_n;
always @(posedge clk_div_in) begin
// if (io_reset) begin
if (~locked) begin
head_cnt <= 0;
end else if (head_cnt < LVDS_DATA_HEAD_CNT) begin
head_cnt <= head_cnt + 1;
end
end
always @(posedge clk_div_in) begin
// if (io_reset) begin
if (~locked) begin
data_cnt <= 0;
end else if (head_cnt == LVDS_DATA_HEAD_CNT) begin
data_cnt <= data_cnt + 1;
end
end
always @(posedge clk_div_in) begin
// if (io_reset) begin
if (~locked) begin
data <= 0;
end else if (head_cnt == LVDS_DATA_HEAD_CNT) begin
data <= data_cnt;
end else begin
data <= LVDS_DATA_HEAD;
end
end
always @(posedge clk_div_in) begin
// if (io_reset) begin
if (~locked) begin
bitslip_head_flag <= 0;
end else if (data_in_to_device == LVDS_DATA_HEAD) begin
bitslip_head_flag <= 1;
end
end
always @(posedge clk_div_in) begin
// if (io_reset) begin
if (~locked) begin
bitslip_cnt <= 0;
end else if (bitslip_cnt < BITSLIP_FRAME & ~bitslip_head_flag) begin
bitslip_cnt <= bitslip_cnt + 1;
end else begin
bitslip_cnt <= 0;
end
end
always @(posedge clk_div_in) begin
// if (io_reset) begin
if (~locked) begin
bitslip <= 0;
end else if (bitslip_cnt == BITSLIP_FRAME) begin
bitslip <= 8'hff;
end else begin
bitslip <= 0;
end
end
endmodule
激励测试
module tb;
reg clk_in;
reg clk_div_in;
reg clk_reset;
reg io_reset;
lvds_module lvds_module(
//flash_spi flash_spi(
.clk_in(clk_in),
.clk_div_in(clk_div_in),
.clk_reset(clk_reset),
.io_reset(io_reset)
);
initial begin
clk_in <= 0;
clk_div_in <= 1;
clk_reset <= 1;
io_reset <= 1;
#500
clk_reset <= 0;
#500
io_reset <= 0;
#1000_000
$stop;
end
// 500m
always #2 clk_in = ~clk_in;
// 125M
always #8 clk_div_in = ~clk_div_in;
endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。