ISERDESE3端口如下:
Port |
I/O |
Type |
Description |
CLK |
Input |
Clock |
High-speed clock input. Clock Serial input data stream. |
CLK_B |
Input |
Clock |
Inverted version of CLK when IS_CLK_INVERTED = 0 and IS_CLK_B_INVERTED = 0. |
CLKDIV |
Input |
Clock |
Low-speed divided clock input. |
D |
Input |
Data |
Serial input data Synchronous to CLK/CLK_B |
Q[7:0] |
Output |
Data |
Registered outputs. Synchronous to FIFO_RD_CLK when FIFO_ENABLE is TRUE. |
RST |
Input |
Reset |
Asynchronous reset. Deassert synchronously. |
FIFO_RD_CLK |
Input |
Clock |
FIFO read clock. |
FIFO_RD_EN |
Input |
Enable |
Enables reading the FIFO when asserted. |
FIFO_EMPTY |
Output |
Indicates the FIFO is empty when asserted. |
|
INTERNAL_DIVCLK |
Output |
Clock |
Reserved |
注:ISERDESE3包含了一个数据位宽为8的FIFO,这个FIFO可以用于时钟域的转换。如果不使用FIFO,FIFO的控制信号接地。
The ISERDESE3 also contains a shallow eight entry FIFO that can optionally be used for clock domain transfers. When not used, the FIFO control signals should be connected to GND. When using the FIFO, the FIFO_RD_EN should be driven by the inverted FIFO_EMPTY signal to ensure the FIFO_write and read pointers do not overlap every eight clock cycles.
ISERDESE3属性如下:
Attribute |
Values |
Dfault |
Type |
Description |
DATA_WIDTH |
4 or 8 |
8 |
Decimal |
Defines the serial-to-parrallel converter width |
FIFO_ENABLE |
TRUE/FALSE |
FALSE |
String |
The FIFO is used when the attribute is set TRUE and bypassed when the attribute is set FALSE |
FIFO_SYNC_MODE |
TRUE/FALSE |
FALSE |
String |
Set to FALSE when the ISERDES internal FIFO write clock and the FIFO read clock accessed from FPGA logic are from separate or common clock domains. |
IS_CLK_INVERTED |
1 or 0 |
0 |
Bit |
Sets a local clock inversion for CLK input |
IS_CLK_B_INVERTED |
1 or 0 |
0 |
Bit |
Sets a local clock inversion for CLK_B input . When IS_CLK_B_INVERTED=1,CLK and CLK_B must be driven by the same global clock buffer. When IS_CLK_B_INVERTED=0, CLK_B must be driven by the same global clock buffer as CLK through an inverter. |
IS_RST_INVERTED |
1 or 0 |
0 |
Bit |
Sets a local inversion for RST input when 1. |
SIM_DEVICE |
ULTRASCALE ULTRASCALE_PLUS ULTRASCALE_PLUS_ES1 ULTRASCALE_PLUS_ES1 |
ULTRASCALE |
String |
Device family for behavioral simulation. |
ISERDESE3在SDR和DDR模式下的输出连接:
SDR or DDR |
Required Ratio |
DATA_WIDTH Attribute to Apply to ISERDESE3 |
SerDes Output Data Bits to Use |
DDR |
1:8 |
8 |
Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0 |
DDR |
1:4 |
4 |
Q3,Q2,Q1,Q0 |
SDR |
1:8 |
N/A |
N/A |
SDR |
1:4 |
8 |
Q6,Q4,Q2,Q0 |
SDR |
1:2 |
4 |
Q2,Q0 |
注:
手册中关于DATA_RATE是DDR还是SDR专门进行了相关说明,使用selectio相关原语时,默认就是DDR模式。也可以在XDC文件中做如下约束
set_property DATA_RATE_SDR|DDR [get_ports port_name]
一个字节中最先接收到的Bit是Q0
ISERDES 时序:
DATA_WIDTH设置为8,DDR模式
DATA_WIDTH设置为4,DDR模式
OSERDES延时:下图中DATA_WIDTH=8,延时3个CLK;DATA_WIDTH=4,延时1个CLK。
OSERDESE3在SDR和DDR模式下的输出连接:
SDR or DDR |
Required Ratio |
DATA_WIDTH Attribute to Apply to OSERDESE3 |
Data Bits to Connect to the SerDes |
DDR |
8:1 |
8 |
D7,D6,D5,D4,D3,D2,D1,D0 |
DDR |
4:1 |
4 |
0,0,0,0,D3,D2,D1,D0 |
SDR |
8:1 |
N/A |
N/A |
SDR |
4:1 |
8 |
D3,D3,D2,D2,D1,D1,D0,D0 |
SDR |
2:1 |
4 |
0,0,0,0,D1,D1,D0,D0 |
注:
给SerDes输入的D0在所有情况下都是最先传输的Bit,可参考下面的时序图理解
SDR模式下,4:1的比例的Block图和时序图:
OSERDESE3端口如下:
Port |
I/O |
Description |
CLK |
Input |
High-speed clock input |
CLKDIV |
Input |
Low-speed divided clock input |
D[7:0] |
Input |
Parallel data inputs for serialization synchronous to CLKDIV |
OQ |
Output |
datapath output |
RST |
Input |
Asynchronous reset. Deassert synchronously. |
T_OUT |
Output |
3-state control output to IOB |
T |
Input |
3-state input from internal logic, combinational 3-state T to T_OUT path. A logic High means the data is 3-stated and a logic LOW means the data is not 3-stated. |
OSERDESE3属性如下:
Attribute |
Values |
Default |
Type |
Description |
DATA_WIDTH |
4 or 8 |
8 |
Decimal |
Defines the parallel-to-serial data converter width |
INIT |
1 or 0 |
0 |
Binary |
Initializes the OSERDESE3 flip-flops to the value specified. |
ODDR_MODE |
TRUE/FALSE |
FALSE |
String |
|
OSERDES_D_BYPASS |
TRUE/FALSE |
FALSE |
String |
When TRUE,D[0] is passed onto OQ. When FALSE, serialized D[0] and D[5] is output on T_OUT. |
OSERDES_T_BYPASS |
TRUE/FALSE |
FALSE |
String |
When TRUE, D[1] is passed onto T_OUT. When FALSE, serialized D[1] and D[5] is output on T_OUT. |
IS_CLK_INVERTED |
1 or 0 |
0 |
Bit |
Sets a local clock inversion for CLK input when 1. |
IS_CLKDIV_INVERTED |
1 or 0 |
0 |
Bit |
Sets a local clock inversion for CLKDIV input when 1. |
IS_RST_INVERTED |
1 or 0 |
0 |
Bit |
Sets a local inversion for RST input when 1. |
SIM_DEVICE |
ULTRASCALE, ULTRASCALE_PLUS, ULTRASCALE_PLUS_ES1, ULTRASCALE_PLUS_ES2 |
ULTRASCALE |
String |
Device family for behavioral simulation |
框图如下:
DATA_WIDTH设置为8,DDR模式:
verilog代码:
`timescale 1ns / 1ps
module ioserdes(
input i_clk , //100MHz
input i_rst ,
input i_data_p ,
input i_data_n ,
input i_clk_200 ,
input [8:0] i_cnt_value ,
input i_en_vtc ,
input i_ce ,
input i_inc ,
input i_load ,
output [8:0] o_cnt_value ,
output o_idelay_rdy
);
wire w_data_in ;
wire w_clk_25 ;
wire w_clk_100 ;
// wire w_t_out ;
wire w_iobuf_o ;
wire w_iobuf_i ;
wire w_idelay_o ;
wire w_odelay_i ;
wire [7:0] w_iserdes_o ;
// wire w_i_o_data ;
// assign w_i_o_data = w_t_out ? 1'dz : w_data_in;
assign w_iobuf_o = w_data_in;
BUFG BUFG_inst (
.O (w_clk_100 ), // 1-bit output: Clock output
.I (i_clk ) // 1-bit input: Clock input
);
BUFGCE_DIV #(
.BUFGCE_DIVIDE (4 ), // 1-8
// Programmable Inversion Attributes: Specifies built-in programmable inversion on specific pins
.IS_CE_INVERTED (1'b0 ), // Optional inversion for CE
.IS_CLR_INVERTED (1'b0 ), // Optional inversion for CLR
.IS_I_INVERTED (1'b0 ) // Optional inversion for I
)
BUFGCE_DIV_inst (
.O (w_clk_25 ), // 1-bit output: Buffer
.CE (1'b1 ), // 1-bit input: Buffer enable
.CLR (1'b0 ), // 1-bit input: Asynchronous clear
.I (i_clk ) // 1-bit input: Buffer
);
IBUFDS IBUFDS_inst (
.O (w_data_in ), // 1-bit output: Buffer output
.I (i_data_p ), // 1-bit input: Diff_p buffer input (connect directly to top-level port)
.IB (i_data_n ) // 1-bit input: Diff_n buffer input (connect directly to top-level port)
);
IDELAYCTRL #(
.SIM_DEVICE ("ULTRASCALE" ) // Must be set to "ULTRASCALE"
)
IDELAYCTRL_inst (
.RDY (o_idelay_rdy ), // 1-bit output: Ready output
.REFCLK (i_clk_200 ), // 1-bit input: Reference clock input
.RST (i_rst ) // 1-bit input: Active high reset input. Asynchronous assert, synchronous deassert to
// REFCLK.
);
IDELAYE3 #(
.CASCADE ("NONE" ), // Cascade setting (MASTER, NONE, SLAVE_END, SLAVE_MIDDLE)
.DELAY_FORMAT ("TIME" ), // Units of the DELAY_VALUE (COUNT, TIME)
.DELAY_SRC ("IDATAIN" ), // Delay input (DATAIN, IDATAIN)
// .DELAY_TYPE ("FIXED" ), // Set the type of tap delay line (FIXED, VARIABLE, VAR_LOAD)
// .DELAY_TYPE ("VARIABLE" ), // Set the type of tap delay line (FIXED, VARIABLE, VAR_LOAD)
.DELAY_TYPE ("VAR_LOAD" ), // Set the type of tap delay line (FIXED, VARIABLE, VAR_LOAD)
.DELAY_VALUE (0 ), // Input delay value setting
.IS_CLK_INVERTED (1'b0 ), // Optional inversion for CLK
.IS_RST_INVERTED (1'b0 ), // Optional inversion for RST
.REFCLK_FREQUENCY (200.0 ), // IDELAYCTRL clock input frequency in MHz (200.0-2667.0)
.SIM_DEVICE ("ULTRASCALE_PLUS" ), // Set the device version (ULTRASCALE, ULTRASCALE_PLUS,
// ULTRASCALE_PLUS_ES1, ULTRASCALE_PLUS_ES2)
.UPDATE_MODE ("ASYNC" ) // Determines when updates to the delay will take effect (ASYNC, MANUAL,
// SYNC)
)
IDELAYE3_inst (
.CASC_OUT ( ), // 1-bit output: Cascade delay output to ODELAY input cascade
.CNTVALUEOUT (o_cnt_value ), // 9-bit output: Counter value output
.DATAOUT (w_idelay_o ), // 1-bit output: Delayed data output
.CASC_IN (1'b0 ), // 1-bit input: Cascade delay input from slave ODELAY CASCADE_OUT
.CASC_RETURN (1'b0 ), // 1-bit input: Cascade delay returning from slave ODELAY DATAOUT
.CE (i_ce ), // 1-bit input: Active high enable increment/decrement input
.CLK (w_clk_25 ), // 1-bit input: Clock input
.CNTVALUEIN (i_cnt_value ), // 9-bit input: Counter value input
.DATAIN (1'b0 ), // 1-bit input: Data input from the logic
.EN_VTC (i_en_vtc ), // 1-bit input: Keep delay constant over VT
// .IDATAIN (w_data_in ), // 1-bit input: Data input from the IOBUF
.IDATAIN (w_iobuf_o ), // 1-bit input: Data input from the IOBUF
.INC (i_inc ), // 1-bit input: Increment / Decrement tap delay input
.LOAD (i_load ), // 1-bit input: Load DELAY_VALUE input
.RST (i_rst ) // 1-bit input: Asynchronous Reset to the DELAY_VALUE
);
//data 8bit fre 4:1 SDR q6 q4 q2 q0
ISERDESE3 #(
.DATA_WIDTH (8 ), // Parallel data width (4,8)
.FIFO_ENABLE ("FALSE" ), // Enables the use of the FIFO
.FIFO_SYNC_MODE ("FALSE" ), // Enables the use of internal 2-stage synchronizers on the FIFO
.IS_CLK_B_INVERTED (1'b0 ), // Optional inversion for CLK_B
.IS_CLK_INVERTED (1'b0 ), // Optional inversion for CLK
.IS_RST_INVERTED (1'b0 ), // Optional inversion for RST
.SIM_DEVICE ("ULTRASCALE_PLUS" ) // Set the device version (ULTRASCALE, ULTRASCALE_PLUS,
// ULTRASCALE_PLUS_ES1, ULTRASCALE_PLUS_ES2)
)
ISERDESE3_inst (
.FIFO_EMPTY ( ), // 1-bit output: FIFO empty flag
.INTERNAL_DIVCLK ( ), // 1-bit output: Internally divided down clock used when FIFO is
// disabled (do not connect)
.Q (w_iserdes_o ), // 8-bit registered output
.CLK (w_clk_100 ), // 1-bit input: High-speed clock
.CLKDIV (w_clk_25 ), // 1-bit input: Divided Clock
.CLK_B (~w_clk_100 ), // 1-bit input: Inversion of High-speed clock CLK
.D (w_idelay_o ), // 1-bit input: Serial Data Input
.FIFO_RD_CLK ( ), // 1-bit input: FIFO read clock
.FIFO_RD_EN ( ), // 1-bit input: Enables reading the FIFO when asserted
.RST (i_rst ) // 1-bit input: Asynchronous Reset
);
ODELAYE3 #(
.CASCADE ("NONE" ), // Cascade setting (MASTER, NONE, SLAVE_END, SLAVE_MIDDLE)
.DELAY_FORMAT ("TIME" ), // (COUNT, TIME)
// .DELAY_TYPE ("FIXED" ), // Set the type of tap delay line (FIXED, VARIABLE, VAR_LOAD)
// .DELAY_TYPE ("VARIABLE" ), // Set the type of tap delay line (FIXED, VARIABLE, VAR_LOAD)
.DELAY_TYPE ("VAR_LOAD" ), // Set the type of tap delay line (FIXED, VARIABLE, VAR_LOAD)
// .DELAY_VALUE (1000 ), // Output delay tap setting
.DELAY_VALUE (0 ), // Output delay tap setting
.IS_CLK_INVERTED (1'b0 ), // Optional inversion for CLK
.IS_RST_INVERTED (1'b0 ), // Optional inversion for RST
.REFCLK_FREQUENCY (200.0 ), // IDELAYCTRL clock input frequency in MHz (200.0-2667.0).
// .REFCLK_FREQUENCY (500.0 ), // IDELAYCTRL clock input frequency in MHz (200.0-2667.0).
.SIM_DEVICE ("ULTRASCALE_PLUS" ), // Set the device version (ULTRASCALE, ULTRASCALE_PLUS,
// ULTRASCALE_PLUS_ES1, ULTRASCALE_PLUS_ES2)
.UPDATE_MODE ("ASYNC" ) // Determines when updates to the delay will take effect (ASYNC, MANUAL,
// SYNC)
)
ODELAYE3_inst (
.CASC_OUT ( ), // 1-bit output: Cascade delay output to IDELAY input cascade
.CNTVALUEOUT (o_cnt_value ), // 9-bit output: Counter value output
.DATAOUT (w_iobuf_i ), // 1-bit output: Delayed data from ODATAIN input port
.CASC_IN (1'b0 ), // 1-bit input: Cascade delay input from slave IDELAY CASCADE_OUT
.CASC_RETURN (1'b0 ), // 1-bit input: Cascade delay returning from slave IDELAY DATAOUT
.CE (i_ce ), // 1-bit input: Active high enable increment/decrement input
.CLK (w_clk_25 ), // 1-bit input: Clock input
.CNTVALUEIN (i_cnt_value ), // 9-bit input: Counter value input
.EN_VTC (i_en_vtc ), // 1-bit input: Keep delay constant over VT
.INC (i_inc ), // 1-bit input: Increment/Decrement tap delay input
.LOAD (i_load ), // 1-bit input: Load DELAY_VALUE input
.ODATAIN (w_odelay_i ), // 1-bit input: Data input
.RST (i_rst ) // 1-bit input: Asynchronous Reset to the DELAY_VALUE
);
//data 8bit fre 4:1 SDR q6 q4 q2 q0
OSERDESE3 #(
.DATA_WIDTH (8 ), // Parallel Data Width (4-8)
.INIT (1'b0 ), // Initialization value of the OSERDES flip-flops
.IS_CLKDIV_INVERTED (1'b0 ), // Optional inversion for CLKDIV
.IS_CLK_INVERTED (1'b0 ), // Optional inversion for CLK
.IS_RST_INVERTED (1'b0 ), // Optional inversion for RST
.SIM_DEVICE ("ULTRASCALE_PLUS" ) // Set the device version (ULTRASCALE, ULTRASCALE_PLUS,
// ULTRASCALE_PLUS_ES1, ULTRASCALE_PLUS_ES2)
)
OSERDESE3_inst (
.OQ (w_odelay_i ), // 1-bit output: Serial Output Data
// .T_OUT (w_t_out ), // 1-bit output: 3-state control output to IOB
.T_OUT ( ), // 1-bit output: 3-state control output to IOB
.CLK (w_clk_100 ), // 1-bit input: High-speed clock
.CLKDIV (w_clk_25 ), // 1-bit input: Divided Clock
.D (w_iserdes_o ), // 8-bit input: Parallel Data Input
.RST (i_rst ), // 1-bit input: Asynchronous Reset
.T ( ) // 1-bit input: Tristate input from fabric
);
// IOBUF IOBUF_inst (
// .O (w_iobuf_o ), // 1-bit output: Buffer output
// .I (w_iobuf_i ), // 1-bit input: Buffer input
// .IO (w_i_o_data ), // 1-bit inout: Buffer inout (connect directly to top-level port)
// .T (w_t_out ) // 1-bit input: 3-state enable input
// );
endmodule
仿真结果说明:
数据流,w_data_in为差分转单端后的输入串行数据,assign给w_iobuf_o,经过IDELAYE3延时后得到w_idelay_o;输入给ISERDESE3,得到并行数据w_iserdes_o(8bit);输入给OSERDESE3,得到串行数据w_odelay_i,经过ODELAYE3延时后得到w_iobuf_i。
ISERDESE3输出的并行数据[7:0]w_iserdes_o,对应[7:0]Q 。
数据率说明:100MHz * 2(DDR模式,双边沿采样) = 200M的数据率
下图中蓝色的MARKER,依次编号1/2/3/4/5/6/7/8,1~2之间给到ISERDESE3的原始数据(串行输入之前的并行数据8’haa),3~4之间给到ISERDESE3的原始数据(串行输入之前的并行数据8’h11),5~6之间给到ISERDESE3的原始数据(串行输入之前的并行数据8’h33),7~8之间给到ISERDESE3的原始数据(串行输入之前的并行数据8’h55)。
根据iserdes的8位宽DDR时序图,在CLK和CLKDIV上升沿之后,第一个CLK下降沿开始采样。
测试工程中需要理清楚IDELAYCTRL的参考时钟(REFCLK,由IDELAYE3/ODELAYE3的属性REFCLK_FREQUENCY决定,测试工程中给200MHz)、IDELAYE3的输入时钟(CLK,与ISERDESE3的CLKDIV相同)、ISERDESE3的串行数据采样时钟(CLK)和并行数据输出时钟(CLKDIV)、ODELAYE3的输入时钟(CLK,与OSERDESE3的CLKDIV相同)、OSERDESE3的并行数据采样时钟(CLKDIV)和串行数据输出时钟(CLK)。
测试工程中输出采样为DDR模式。
由于输入是小端模式,输出是大端模式,因此8'haa(8'b1010_1010)给到iserdes,iserdes从低位开始取,即8'b0101_0101,输出按照大端,得到8'b1010_1010,即8'haa。后面依次输出8'h11,8'h33,8'h55