赞
踩
当使用FPGA进行ADC数据的处理时,由于目前一些ADC的工作频率已达到GHz,使得FPGA并不能直接处理这么高速的信号,这就需要对高速信号进行串并转换,实现数据的降速。
FPGA资源中,我们可以通过直接例化ISERDESE/OSERDESE资源来实现数据的串并转换和并串转换。
1、在vivado18.3 Language Templates中可以查找serdes资源的原语。
如上图所示,不同的FPGA系列,有不同的原语。这里使用的是Kintex UltraScale系列,所以我们选择ISERDESE3原语进行例化。
2、ISERDESE3模块的详细介绍参考Xilinx官方文档ug571。
3、本工程使用ISERDESE3进行1:4串并转换,传输的数据为data=32’b10010010101010001010100101011011。
4、serdes例化代码:
`timescale 1ns / 1ps module serdes( output wire [3:0] iserdes_q , // serdes的输出信号,并行数据 input wire clk , // 串行时钟,500M,DDR input wire clkdiv , // 并行时钟,250M,SDR input wire rst_n , // 复位信号,低有效 input wire iserdes_d // serdes的输入信号,串行数据 ); // ISERDESE3: Input SERial/DESerializer // Kintex UltraScale // Xilinx HDL Language Template, version 2018.3 ISERDESE3 #( .DATA_WIDTH(4), // 1:4串并转换 .FIFO_ENABLE("FALSE"), // Enables the use of the FIFO .FIFO_SYNC_MODE("FALSE"), // Always set to FALSE. TRUE is reserved for later use. .IS_CLK_B_INVERTED(1'b1), // 设置为1时,会将CLK_B的输入信号进行反相,此时CLK_B和CLK应为同一驱动源 .IS_CLK_INVERTED(1'b0), // Optional inversion for CLK .IS_RST_INVERTED(1'b1), // 设置为1时,会将RST的输入信号进行反相 .SIM_DEVICE("ULTRASCALE") // 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(iserdes_q), // 4-bit registered output .CLK(clk), // 1-bit input: High-speed clock .CLKDIV(clkdiv), // 1-bit input: Divided Clock .CLK_B(clk), // 1-bit input: Inversion of High-speed clock CLK .D(iserdes_d), // 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(rst_n) // 1-bit input: Asynchronous Reset ); endmodule
仿真激励文件代码
`timescale 1ns / 1ps module serdes_tb( ); reg clk ; // 串行时钟,500M,DDR reg clkdiv ; // 并行时钟,250M,SDR reg clk_data ; // 数据时钟,用于产生串行数据,使得clk的沿正好对准串行数据 reg rst_n ; // 复位信号,低有效 wire iserdes_d ; // serdes的输入信号,串行数据 wire [3:0] iserdes_q ; // serdes的输出信号,并行数据 reg [31:0] data ; // 预先设定的需要传输的数据 initial begin clk = 1'b0 ; clkdiv = 1'b0 ; clk_data = 1'b0 ; rst_n = 1'b0 ; data = 32'b0 ; #5 rst_n = 1'b1 ; #199 data = 32'b10010010101010001010100101011011; end always #1 clk = ~clk ; initial begin #3 clkdiv = 1'b1; forever begin #2 clkdiv = ~clkdiv; end end initial begin #0.5 clk_data = 1'b1; forever begin #1 clk_data = ~clk_data; end end assign iserdes_d = data[31]; always @(posedge clk_data or negedge clk_data) begin data <= {data[30:0], 1'b0} ; end serdes serdes_inst( .iserdes_q ( iserdes_q ), .clk ( clk ), .clkdiv ( clkdiv ), .rst_n ( rst_n ), .iserdes_d ( iserdes_d ) ); endmodule
仿真结果
值得注意的是,iserdese3输出的信号是先转换的数据在低位,后转换的数据在高位。如下图所示,由于没有注意这个问题,导致我一直以为仿真数据出错了。
5、如果需要进行串并1:8转换,只需要相应的修改DATA_WIDTH和输出数据的数据宽度即可。同理,oserdese3的使用相同,只不过是iserdese3的反过程,这里就不再赘述了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。