Xilinx_SERDES动态延迟加解串的使用

来源:互联网 发布:无线传输数据 编辑:程序博客网 时间:2024/05/22 15:08
Xilinx SELECTIO IP核调用配作可变延迟加输入解串工作模式时信号接口如下表所示:
接口名 方向 注释
DATA_IN_FROM_PINS Input来自外部IO数据输入引脚
DATA_IN_TO_DEVICE OutputCLK_OUT同步后的输出数据
DELAY_BUSY OutputIODELAY校准和相位变化正在进行忙信号
DELAY_CLK InputFPGA内部逻辑同步时钟,可接CLK_DIV_OUT
DELAY_DATA_CAL InputIODELAY相位校正信号
DELAY_DATA_CE Input相位增加(减少)使能信号
DELAY_DATA_INC Input相位增加(高)、减少(低)信号
BITSLIP Input 帧信号对齐命令引脚
CLK_IN Input 外部时钟输入引脚
CLK_DIV_OUT Output时钟输出,用于FPGA内部逻辑同步信号
IO_RESET InputIO模块复位信号,高电平有效
(在ISE中从Instantation template中例化会有一个CLK_RESET信号,但在实际IP核里并没有连接该信号)
ISERDES有三种模式:NETWORKING、NETWORKING_PIPELINED、RETIMED。其中NETWORKING模式无法启用BITSLIP功能。NETWORKING_PIPELINED模式数据输出并未同步到内部全局时钟,但相比于RETIMED模式其具有更少的延迟。RETIMED模式则数据输出同步至全局时钟模块,由CLK_DIV_OUT同步。
BITSLIP用于字对齐的调整,来自DATA_IN_FROM_PINS的数据为LSB first,在调节过程中BITSLIP拉高一个CLKDIVOUT时钟周期,随后拉低至少一个全局时钟周期,其伪代码为:
After reset
If input frame data not equal to required frame pattern then
BITSLIP<=1;
ELSE
BITSLIP<=0;
BITSLIP_COMPLETE<=1;
Wait at least one global clock cycle
Repeat
值得注意的是,在实验过程中发现,在RETIMED模式下,BITSLIP应当至少拉低三个全局时钟周期方能有效进行字对齐。
对于ISERDES的控制,其控制流程如下:
(1) 上电复位
(2) 拉高DELAY_DATA_CAL进行延迟调节
(3) 等待20个全局时钟周期
(4) 置位IO_RESET一个全局时钟周期
(5) 进行BITSLIP控制字调节,若超时返回(2),完成调节则进行下一步
(6) 周期性进行延迟调节(拉高DELAY_DATA_CAL但无需进行IO_RESET)
实验代码如下
//========================================================================================================================================================
// Company: 
// Engineer: 
// Create Date: 
// Design Name:
// Module Name: 
// Target Device: 
// Tool versions: 
// Description: 
// Dependencies:
// Revision:
// Additional Comments:
//========================================================================================================================================================
module ISERDES_TEST#(
parameter DATA_WIDTH=8
)(
input IO_CLK_IN,//IO输入时钟
input IO_DATA_IN,
input reset_n,//复位信号,低电平有效
output [DATA_WIDTH-1:0] DATA_OUT,
output BITSLIP_COMPLETE //帧校准完成信号
);
//========================================================================================================================================================
//内部变量声明
//========================================================================================================================================================
wire [DATA_WIDTH-1:0]deserdes_data_w; //解串数据
wire sys_clk; //系统时钟
wire iserdes_delay_busy;//ISErDES忙标志
wire iserdes_cal;//延迟校准信号
wire iserdes_bitslip;//帧校准信号
wire iserdes_reset;//iserdes复位信号,高电平有效
reg [DATA_WIDTH-1:0]deserdes_data_r;
//========================================================================================================================================================
//ISERDES模块例化
//========================================================================================================================================================
  ISERDES_CORE ISERDES_mod
   (
  // From the system into the device
    .DATA_IN_FROM_PINS(IO_DATA_IN), //串行数据输入
    .DATA_IN_TO_DEVICE(deserdes_data_w), //并行数据输出


    .DELAY_BUSY(iserdes_delay_busy), //忙标志输出
    .DELAY_CLK(sys_clk), //同步时钟输入
    .DELAY_DATA_CAL(iserdes_cal), //延迟校准信号输入
    .DELAY_DATA_CE(1'b0),              
    .DELAY_DATA_INC(1'b0),                    
    .BITSLIP(iserdes_bitslip), //帧校准信号
    .CLK_IN(IO_CLK_IN),        // IO时钟输入
    .CLK_DIV_OUT(sys_clk),    // 同步时钟输出
    .IO_RESET(iserdes_reset)  //ISERDES模块复位信号
);
//========================================================================================================================================================
//ISERDES控制模块例化
//========================================================================================================================================================
ISERDES_CONTROL iserdes_con (
    .sys_clk(sys_clk), 
    .sys_reset_n(reset_n), 
    .deserdes_data_in(deserdes_data_w), 
    .Idelay_reset_o(iserdes_reset), 
    .Idelay_cal_o(iserdes_cal), 
    .Iserdes_bitslip_o(iserdes_bitslip), 
    .Bitslip_complete(BITSLIP_COMPLETE)
    );
//========================================================================================================================================================
//输出数据锁存
//========================================================================================================================================================
always @(posedge sys_clk)
begin
if(!reset_n)
deserdes_data_r<='d0;
else
deserdes_data_r<=deserdes_data_w;
end
assign DATA_OUT=deserdes_data_r;
endmodule
//========================================================================================================================================================
// Company: 
// Engineer: 
// Create Date: 
// Design Name:
// Module Name: 
// Target Device: 
// Tool versions: 
// Description: 
// Dependencies:
// Revision:
// Additional Comments:
//========================================================================================================================================================
module ISERDES_CONTROL#(
parameter CAL_PERIOD=2**10,
parameter SERIAL_RATe=8,
parameter TRAIN_SEQ=8'b1010_1111,
parameter DATA_WIDTH=8
)(
input sys_clk,
input sys_reset_n,//复位信号,低电平有效
input [DATA_WIDTH-1:0]deserdes_data_in, //解串数据
output Idelay_reset_o, //IDELAY2复位信号
output Idelay_cal_o, //IDELAY2校准信号
output Iserdes_bitslip_o, //ISERDES帧对齐调节信号
output Bitslip_complete //帧对齐完成信号
   );
//========================================================================================================================================================
//内部常亮声明
//========================================================================================================================================================
localparam FSM_IDLE=6'b000001,
FSM_Init_CAL =6'b000010,
FSM_Init_WAIT =6'b000100,
FSM_Init_RST =6'b001000,
FSM_BITSLIP =6'b010000,
FSM_Perod_CAL =6'b100000;
//========================================================================================================================================================
//内部常亮声明
//========================================================================================================================================================
reg [$clog2(CAL_PERIOD):0]cal_time_cnt; //校正周期计时器
reg Idelay_cal_r ;//校正信号寄存器及其下一状态
reg Idelay_reset_r;//IDELAY复位信号及下一状态
reg [5:0] Fsm_cs,Fsm_ns; //有限状态机
reg [4:0] Cal_wait_cnt; //cal校正等待信号
reg Bitslip_r,Bitslip_r_n,Bitslip_r_nn;//帧对齐调节信号及其缓存
reg Bitslip_complete_r;//帧对齐完成寄存器
reg [$clog2(10**3):0]Bitslip_cnt; //帧对齐调节时间
//========================================================================================================================================================
//内部状态机
//========================================================================================================================================================
always@(posedge sys_clk )
begin
if(!sys_reset_n )
Fsm_cs<=FSM_IDLE;
else
Fsm_cs<=Fsm_ns;
end
always@(*)
begin
case(Fsm_cs)
FSM_IDLE:
Fsm_ns=FSM_Init_CAL;
FSM_Init_CAL:
Fsm_ns=FSM_Init_WAIT;
FSM_Init_WAIT:
begin
if( Cal_wait_cnt==5'd20 )//等待20个时钟周期
Fsm_ns=FSM_Init_RST;
else
Fsm_ns=FSM_Init_WAIT;
end
FSM_Init_RST:
Fsm_ns=FSM_BITSLIP;
FSM_BITSLIP:
begin
if(Bitslip_cnt<=10**3-1)
begin
if(deserdes_data_in==TRAIN_SEQ)
Fsm_ns=FSM_Perod_CAL;
else
Fsm_ns=Fsm_cs;
end
else
Fsm_ns=FSM_IDLE;
end
FSM_Perod_CAL:
Fsm_ns=FSM_Perod_CAL;
default:Fsm_ns=FSM_IDLE;
endcase
end
//========================================================================================================================================================
//cal校正等待信号计时
//========================================================================================================================================================
always@(posedge sys_clk)
begin
if(!sys_reset_n)
Cal_wait_cnt<=5'd0;
else if(Fsm_cs==FSM_Init_WAIT)
Cal_wait_cnt<=Cal_wait_cnt+1'b1;
else
Cal_wait_cnt<=5'd0;
end
//========================================================================================================================================================
//校正周期计时
//========================================================================================================================================================
always@(posedge sys_clk)
begin
if(!sys_reset_n)
cal_time_cnt<='d0;
else if(Fsm_cs==FSM_Perod_CAL)
begin
if(cal_time_cnt==CAL_PERIOD-1)
cal_time_cnt<='d0;
else
cal_time_cnt<=cal_time_cnt+1'b1;
end
else
cal_time_cnt<='d0;
end
//========================================================================================================================================================
//Bitslip_cnt计时
//========================================================================================================================================================
always@(posedge sys_clk)
begin
if(!sys_reset_n)
Bitslip_cnt<='d0;
else if(Fsm_cs==FSM_BITSLIP)
Bitslip_cnt<=Bitslip_cnt+1'b1;
else
Bitslip_cnt<='d0;
end
//========================================================================================================================================================
//复位信号输出
//========================================================================================================================================================
always@(posedge sys_clk)
begin
if(!sys_reset_n)
Idelay_reset_r<=1'b0;
else if(Fsm_cs==FSM_Init_RST)
Idelay_reset_r<=1'b1;
else
Idelay_reset_r<=1'b0;
end
//========================================================================================================================================================
//校正信号输出
//========================================================================================================================================================
always@(posedge sys_clk)
begin
if(!sys_reset_n)
Idelay_cal_r<=1'b0;
else if(Fsm_cs==FSM_Init_CAL||((Fsm_cs==FSM_Perod_CAL)&&(cal_time_cnt==CAL_PERIOD-1)))
Idelay_cal_r<=1'b1;
else
Idelay_cal_r<=1'b0;
end
//========================================================================================================================================================
//帧调整信号
//========================================================================================================================================================
always@(posedge sys_clk)
begin
if(!sys_reset_n)
Bitslip_r<=1'b0;
else if((Fsm_cs==FSM_BITSLIP)&&(deserdes_data_in!=TRAIN_SEQ))
begin
if(Bitslip_r||Bitslip_r_n ||Bitslip_r_nn) 
Bitslip_r<=1'b0;
else 
Bitslip_r<=1'b1;
end
else
Bitslip_r<=1'b0;
end
always @(posedge sys_clk)
begin
if(!sys_reset_n)
Bitslip_r_n<=1'b0;
else 
Bitslip_r_n<=Bitslip_r;
end
always @(posedge sys_clk)
begin
if(!sys_reset_n)
Bitslip_r_nn<=1'b0;
else 
Bitslip_r_nn<=Bitslip_r_n;
end
//========================================================================================================================================================
//帧调整完成信号
//========================================================================================================================================================
always@(posedge sys_clk)
begin
if(!sys_reset_n)
Bitslip_complete_r<=1'b0;
else if((Fsm_cs==FSM_BITSLIP)&&(deserdes_data_in==TRAIN_SEQ))
Bitslip_complete_r<=1'b1;
else
Bitslip_complete_r<=Bitslip_complete_r;
end
//========================================================================================================================================================
//输出信号连接
//========================================================================================================================================================
assign Idelay_reset_o=Idelay_reset_r;
assign Idelay_cal_o=Idelay_cal_r;
assign Iserdes_bitslip_o=Bitslip_r;
assign Bitslip_complete=Bitslip_complete_r;
endmodule


testbench如下
`timescale 1ns / 1ps


////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:   19:41:07 10/22/2017
// Design Name:   ISERDES_TEST
// Module Name:   C:/Users/Administrator/Desktop/idelay_test/iserdes/IESRDES_TEST/ISERDES_TB.v
// Project Name:  IESRDES_TEST
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: ISERDES_TEST
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////


module ISERDES_TB;


// Inputs
reg IO_CLK_IN;
reg IO_DATA_IN;
reg reset_n;


// Outputs
wire [7:0] DATA_OUT;
wire BITSLIP_COMPLETE;


// Instantiate the Unit Under Test (UUT)
ISERDES_TEST uut (
.IO_CLK_IN(IO_CLK_IN), 
.IO_DATA_IN(IO_DATA_IN), 
.reset_n(reset_n), 
.DATA_OUT(DATA_OUT), 
.BITSLIP_COMPLETE(BITSLIP_COMPLETE)
);


initial begin
// Initialize Inputs
IO_CLK_IN = 0;
IO_DATA_IN = 0;
reset_n = 0;


// Wait 100 ns for global reset to finish
@(posedge IO_CLK_IN);
#300;
        reset_n=1;
@(posedge IO_CLK_IN)
@(posedge IO_CLK_IN)
IO_DATA_IN<=1;
send_data(8'hfd);
send_data(8'h1f);
send_data(8'hcc);
send_data(8'hcc);
send_data(8'hcc);
send_data(8'h4c);
send_data(8'hcc);
send_data(8'hc5);
send_data(8'hfd);
send_data(8'h1f);
send_data(8'hcc);
send_data(8'hcc);
send_data(8'hcc);
send_data(8'h4c);
send_data(8'hcc);
send_data(8'b1010_1111);
send_data(8'hc5);
send_data(8'hcc);
send_data(8'b1010_1111);
repeat(300)
begin
send_data(8'b1010_1111);
end

send_data(8'h36);
send_data(8'h73);
send_data(8'h98);
send_data(8'h56);
repeat(10000)
begin
send_data($random()%256);
end


$stop;
// Add stimulus here


end
always #8 IO_CLK_IN=~IO_CLK_IN;
task send_data(input [7:0] data);
integer i;
begin :data_send_seq

for(i=0;i<=7;i=i+1)
begin
@(posedge IO_CLK_IN)
IO_DATA_IN<=data[i];
end
end
endtask
      
endmodule

原创粉丝点击