使用OSERDESE2原语实现多个dds合成一个波形,达到面积换速度的目的

这篇具有很好参考价值的文章主要介绍了使用OSERDESE2原语实现多个dds合成一个波形,达到面积换速度的目的。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

如何使用OSERDESE2原语实现多个dds合成一个波形

使用OSERDESE2原语实现多个dds合成一个波形,达到面积换速度的目的,射频低电平控制系统,fpga开发

  • 要实现一个高频波形的数字呈现时,可以将其拆分成4个甚至8个相同频率不同初始相位的低频波形,多个低频dds生成的波形使用OSERDESE2原语合成最终的高频波形,这样占用了更多资源,但是降低了运行速度。
  • 如图所示彩色的波形由四个不同颜色构成,一共由36个点构成一个完整的正弦波。当使用一个dds生成时,必然运行时钟频率要求更高。当我们将其拆成四个小的波形,每个波形由9个点构成,相当于四分之一倍低频频率的dds;或者说在原本单位周期要完成36个点的计算,现在只需要完成9个点的计算,只不过这样的计算模块有四个。相当于同样一件事原先交给一个人完成,那他就需要焦头烂额地在固定周期内完成工作;如果将工作拆成4个小任务交由四个人分别完成,那么每个人的压力就会很小,工作也会很悠闲。这种方式通常称为面积换速度。
  • 在FPGA(Field-Programmable Gate Array)中,“面积”(Area)、“功耗”(Power)和"速度"(Performance)是 FPGA 设计的关键指标,通常被称为 “Area, Power, Speed”(APS)三角。
  • 面积(Area): 指的是 FPGA 芯片上被设计电路占据的物理空间。在FPGA中,资源包括逻辑单元(Lookup
    Tables)、寄存器、布线资源等。更大的面积通常表示能够容纳更多的逻辑元素,但也可能会增加功耗和成本。
  • 功耗(Power): FPGA 设计中的功耗是指电路在运行时所消耗的电能。功耗与 FPGA
    设计的电路结构、时钟频率、电压等因素有关。在一些功耗敏感的应用中,需要设计者在满足性能要求的前提下尽量降低功耗。
  • 速度(Speed): 在 FPGA
    设计中,速度通常指的是电路在运行时的时钟频率。更高的时钟频率允许电路更快地执行操作,但同时也可能增加功耗和面积。
  • 这三个指标之间存在权衡关系,通常被描述为 “Area, Power, Speed” 三角。设计者需要在这三者之间做出取舍,根据具体的应用需求和设计约束做出权衡。例如,提高时钟频率可能会导致更大的功耗,而减小面积可能会限制电路的复杂性。

使用OSERDESE2原语实现多个dds合成一个波形,达到面积换速度的目的,射频低电平控制系统,fpga开发

OSERDESE2原语的应用

如下方程序所示:

`timescale 1ns / 1ps
///////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:  		jiangquan
// 
// Design Name: 
// Module Name:		txdata_oserd_e2
// Project Name:    
// Target Devices:  Kintex-7
// Tool Versions:   Vivado 2019.1
// Description: 
// OSERDESE2,DAC data output interface
//
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Create Date: 2021/03/09
// Additional Comments:
//
//
// Revision 0.02 - File update
// Update Date: year/mounth/date
// Additional Comments:
//
// 
///////////////////////////////////////////////////////////////////////
module txdata_oserd_e2 #(
    parameter  BUS_W   = 8'd16,
    parameter  SERD_W  = 4'd4,
    parameter  DCI_SEQ = 5'b01010,  // DCI SEQUENCE: 0 1 0 1 0
    parameter  SERD_MD = "DDR",     // DDR Mode support Data_Width:2,4,6,8,10,14
                                    // SDR Mode support Data_Width:2,3,4,5,6,7,8
    parameter  DAT_W   = 8'd224     //14 * BUS_W
    
    )
(
    // Global Clock And Reset
    input               i_rst,
    input               i_tx_clk,
    input               i_tx_clkdiv,
    // dac external interface
    output  [15:0]      o_tx_dout_p,
    output  [15:0]      o_tx_dout_n,
    output              o_tx_dci_p,
    output              o_tx_dci_n,
    // dac fpga internal interface
    input  [223:0]      i_tx_data
    );

//====================================================================//
//-------------------------- 变量声明 --------------------------------//
//====================================================================//
    wire                              dci_sf1;
    wire                              dci_sf2; 
    wire    [BUS_W -1 : 0]            dat_sf1;
    wire    [BUS_W -1 : 0]            dat_sf2;
                      
    wire    [BUS_W -1 : 0]            tx_dout;
    wire                              tx_dci;
                      
    wire    [BUS_W -1 : 0]            tx_d1;
    wire    [BUS_W -1 : 0]            tx_d2;
    wire    [BUS_W -1 : 0]            tx_d3;
    wire    [BUS_W -1 : 0]            tx_d4;
    wire    [BUS_W -1 : 0]            tx_d5;
    wire    [BUS_W -1 : 0]            tx_d6;
    wire    [BUS_W -1 : 0]            tx_d7;
    wire    [BUS_W -1 : 0]            tx_d8; 
    wire    [BUS_W -1 : 0]            tx_d9; 
    wire    [BUS_W -1 : 0]            tx_d10;
    wire    [BUS_W -1 : 0]            tx_d11;
    wire    [BUS_W -1 : 0]            tx_d12;
    wire    [BUS_W -1 : 0]            tx_d13;
    wire    [BUS_W -1 : 0]            tx_d14;

//====================================================================//
//-------------------------   核心逻辑   -----------------------------//
//====================================================================//
    
    assign  tx_d1   = i_tx_data[   BUS_W -1 : 0       ];
    assign  tx_d2   = i_tx_data[ 2*BUS_W -1 : BUS_W   ];
    assign  tx_d3   = i_tx_data[ 3*BUS_W -1 : 2*BUS_W ];
    assign  tx_d4   = i_tx_data[ 4*BUS_W -1 : 3*BUS_W ];
    assign  tx_d5   = i_tx_data[ 5*BUS_W -1 : 4*BUS_W ];
    assign  tx_d6   = i_tx_data[ 6*BUS_W -1 : 5*BUS_W ];
    assign  tx_d7   = i_tx_data[ 7*BUS_W -1 : 6*BUS_W ];
    assign  tx_d8   = i_tx_data[ 8*BUS_W -1 : 7*BUS_W ];
    assign  tx_d9   = i_tx_data[ 9*BUS_W -1 : 8*BUS_W ];
    assign  tx_d10  = i_tx_data[10*BUS_W -1 : 9*BUS_W ];
    assign  tx_d11  = i_tx_data[11*BUS_W -1 : 10*BUS_W ];
    assign  tx_d12  = i_tx_data[12*BUS_W -1 : 11*BUS_W ];
    assign  tx_d13  = i_tx_data[13*BUS_W -1 : 12*BUS_W ];
    assign  tx_d14  = i_tx_data[14*BUS_W -1 : 13*BUS_W ];

/////////////////////////////////////
// Sync Reset to CLKDIV
    (* KEEP="TRUE" *)wire   sync_rst;
    reg  [3:0]  rst_cnt;

    always @(posedge i_tx_clkdiv or posedge i_rst)begin
        if(i_rst)
            rst_cnt     <= 0;
        else
            if(rst_cnt == 4'b1000)
                rst_cnt <= rst_cnt;
            else
                rst_cnt <= rst_cnt + 1;
    end // eng always
    
    assign  sync_rst = rst_cnt[1]; 
 
/////////////////////////////////////    
// DCI
generate
    if(SERD_W > 8)
        begin:width_expansion_mode
               OSERDESE2 #(
                  .DATA_RATE_OQ             (   SERD_MD                     ),  // DDR, SDR
                  .DATA_RATE_TQ             (   "DDR"                       ),  // DDR, BUF, SDR
                  .DATA_WIDTH               (   SERD_W                      ),  // Parallel data width (2-8,10,14)
                  .INIT_OQ                  (   DCI_SEQ[0]                  ),
                  .INIT_TQ                  (   1'b0                        ),
                  .SERDES_MODE              (   "MASTER"                    ),  // MASTER, SLAVE
                  .SRVAL_OQ                 (   1'b0                        ),
                  .SRVAL_TQ                 (   1'b0                        ),
                  .TBYTE_CTL                (   "FALSE"                     ),  // Enable tristate byte operation (FALSE, TRUE)
                  .TBYTE_SRC                (   "FALSE"                     ),  // Tristate byte source (FALSE, TRUE)
                  .TRISTATE_WIDTH           (   4                           )
               )
               u_oserdes1_dci (
                  .OFB                      (                               ),
                  .OQ                       (   tx_dci                      ),
                  // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
                  .SHIFTOUT1                (                               ),
                  .SHIFTOUT2                (                               ),
                  .TBYTEOUT                 (                               ),
                  .TFB                      (                               ),
                  .TQ                       (                               ),
                  .CLK                      (   i_tx_clk                    ),
                  .CLKDIV                   (   i_tx_clkdiv                 ),
                  // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
                  .D1                       (   DCI_SEQ[1]                  ),
                  .D2                       (   DCI_SEQ[2]                  ),
                  .D3                       (   DCI_SEQ[3]                  ),
                  .D4                       (   DCI_SEQ[4]                  ),
                  .D5                       (   DCI_SEQ[1]                  ),
                  .D6                       (   DCI_SEQ[2]                  ),
                  .D7                       (   DCI_SEQ[3]                  ),
                  .D8                       (   DCI_SEQ[4]                  ),
                  .OCE                      (   1'b1                        ),
                  .RST                      (   sync_rst                    ), 
                  // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
                  .SHIFTIN1                 (   dci_sf1                     ),
                  .SHIFTIN2                 (   dci_sf2                     ),
                  // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
                  .T1                       (   1'b0                        ),
                  .T2                       (   1'b0                        ),
                  .T3                       (   1'b0                        ),
                  .T4                       (   1'b0                        ),
                  .TBYTEIN                  (   1'b0                        ),
                  .TCE                      (   1'b0                        )
               );

               OSERDESE2 #(
                  .DATA_RATE_OQ             (   SERD_MD                     ),  // DDR, SDR
                  .DATA_RATE_TQ             (   "DDR"                       ),  // DDR, BUF, SDR
                  .DATA_WIDTH               (   SERD_W                      ),  // Parallel data width (2-8,10,14)
                  .INIT_OQ                  (   DCI_SEQ[0]                  ),
                  .INIT_TQ                  (   1'b0                        ),
                  .SERDES_MODE              (   "SLAVE"                     ),  // MASTER, SLAVE
                  .SRVAL_OQ                 (   1'b0                        ),
                  .SRVAL_TQ                 (   1'b0                        ),
                  .TBYTE_CTL                (   "FALSE"                     ),  // Enable tristate byte operation (FALSE, TRUE)
                  .TBYTE_SRC                (   "FALSE"                     ),  // Tristate byte source (FALSE, TRUE)
                  .TRISTATE_WIDTH           (   4                           )
               )
               u_oserdes2_dci (
                  .OFB                      (                               ),
                  .OQ                       (                               ),
                  // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
                  .SHIFTOUT1                (   dci_sf1                     ),
                  .SHIFTOUT2                (   dci_sf2                     ),
                  .TBYTEOUT                 (                               ),
                  .TFB                      (                               ),
                  .TQ                       (                               ),
                  .CLK                      (   i_tx_clk                    ),
                  .CLKDIV                   (   i_tx_clkdiv                 ),
                  // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
                  .D1                       (                               ),
                  .D2                       (                               ),
                  .D3                       (   DCI_SEQ[1]                  ),
                  .D4                       (   DCI_SEQ[2]                  ),
                  .D5                       (   DCI_SEQ[3]                  ),
                  .D6                       (   DCI_SEQ[4]                  ),
                  .D7                       (   DCI_SEQ[1]                  ),
                  .D8                       (   DCI_SEQ[2]                  ),
                  .OCE                      (   1'b1                        ),
                  .RST                      (   sync_rst                    ), 
                  // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
                  .SHIFTIN1                 (   1'b0                        ),
                  .SHIFTIN2                 (   1'b0                        ),
                  // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
                  .T1                       (   1'b0                        ),
                  .T2                       (   1'b0                        ),
                  .T3                       (   1'b0                        ),
                  .T4                       (   1'b0                        ),
                  .TBYTEIN                  (   1'b0                        ),
                  .TCE                      (   1'b0                        )
               );
               
                OBUFDS #(
                    .IOSTANDARD             (   "LVDS"                      ),  // Specify the output I/O standard
                    .SLEW                   (   "FAST"                      )   // "SLOW"
                )
                u_obufds_dci(
                    .I                      (   tx_dci              ), // Buffer input
                    .O                      (   o_tx_dci_p          ), // Diff_p output (connect directly to top-level port)
                    .OB                     (   o_tx_dci_n          )  // Diff_n output (connect directly to top-level port)
                );
        end // 
    else
        begin:normal_mode
               OSERDESE2 #(
                  .DATA_RATE_OQ             (   SERD_MD                     ),  // DDR, SDR
                  .DATA_RATE_TQ             (   "DDR"                       ),  // DDR, BUF, SDR
                  .DATA_WIDTH               (   SERD_W                      ),  // Parallel data width (2-8,10,14)
                  .INIT_OQ                  (   DCI_SEQ[0]                  ),
                  .INIT_TQ                  (   1'b0                        ),
                  .SERDES_MODE              (   "MASTER"                    ),  // MASTER, SLAVE
                  .SRVAL_OQ                 (   1'b0                        ),
                  .SRVAL_TQ                 (   1'b0                        ),
                  .TBYTE_CTL                (   "FALSE"                     ),  // Enable tristate byte operation (FALSE, TRUE)
                  .TBYTE_SRC                (   "FALSE"                     ),  // Tristate byte source (FALSE, TRUE)
                  .TRISTATE_WIDTH           (   1                           )
               )
               u_oserdes_dci (
                  .OFB                      (                               ),
                  .OQ                       (   tx_dci                      ),
                  // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
                  .SHIFTOUT1                (                               ),
                  .SHIFTOUT2                (                               ),
                  .TBYTEOUT                 (                               ),
                  .TFB                      (                               ),
                  .TQ                       (                               ),
                  .CLK                      (   i_tx_clk                    ),
                  .CLKDIV                   (   i_tx_clkdiv                 ),
                  // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
                  .D1                       (   DCI_SEQ[1]                  ),
                  .D2                       (   DCI_SEQ[2]                  ),
                  .D3                       (   DCI_SEQ[3]                  ),
                  .D4                       (   DCI_SEQ[4]                  ),
                  .D5                       (   DCI_SEQ[1]                  ),
                  .D6                       (   DCI_SEQ[2]                  ),
                  .D7                       (   DCI_SEQ[3]                  ),
                  .D8                       (   DCI_SEQ[4]                  ),
                  .OCE                      (   1'b1                        ),
                  .RST                      (   sync_rst                    ), 
                  // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
                  .SHIFTIN1                 (   1'b0                        ),
                  .SHIFTIN2                 (   1'b0                        ),
                  // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
                  .T1                       (   1'b0                        ),
                  .T2                       (   1'b0                        ),
                  .T3                       (   1'b0                        ),
                  .T4                       (   1'b0                        ),
                  .TBYTEIN                  (   1'b0                        ),
                  .TCE                      (   1'b0                        )
               );
             
                OBUFDS #(
                    .IOSTANDARD             (   "LVDS"                      ),  // Specify the output I/O standard
                    .SLEW                   (   "FAST"                      )   // "SLOW"
                )
                u_obufds_dci(
                    .I                      (   tx_dci              ), // Buffer input
                    .O                      (   o_tx_dci_p          ), // Diff_p output (connect directly to top-level port)
                    .OB                     (   o_tx_dci_n          )  // Diff_n output (connect directly to top-level port)
                );
        end
endgenerate
        
// DATA
genvar DAT_GEN;
generate
    if(SERD_W > 8)
        begin:width_expansion_mode
            for (DAT_GEN = 0; DAT_GEN < BUS_W; DAT_GEN = DAT_GEN + 1) 
            begin: u_dat_gen
               OSERDESE2 #(
                  .DATA_RATE_OQ             (   SERD_MD                     ),  // DDR, SDR
                  .DATA_RATE_TQ             (   "DDR"                       ),  // DDR, BUF, SDR
                  .DATA_WIDTH               (   SERD_W                      ),  // Parallel data width (2-8,10,14)
                  .INIT_OQ                  (   1'b0                        ),
                  .INIT_TQ                  (   1'b0                        ),
                  .SERDES_MODE              (   "MASTER"                    ),  // MASTER, SLAVE
                  .SRVAL_OQ                 (   1'b0                        ),
                  .SRVAL_TQ                 (   1'b0                        ),
                  .TBYTE_CTL                (   "FALSE"                     ),  // Enable tristate byte operation (FALSE, TRUE)
                  .TBYTE_SRC                (   "FALSE"                     ),  // Tristate byte source (FALSE, TRUE)
                  .TRISTATE_WIDTH           (   1                           )
               )
               u_oserdes1_dat (
                  .OFB                      (                               ),
                  .OQ                       (   tx_dout[DAT_GEN]            ),
                  // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
                  .SHIFTOUT1                (                               ),
                  .SHIFTOUT2                (                               ),
                  .TBYTEOUT                 (                               ),
                  .TFB                      (                               ),
                  .TQ                       (                               ),
                  .CLK                      (   i_tx_clk                    ),
                  .CLKDIV                   (   i_tx_clkdiv                 ),
                  // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
                  .D1                       (   tx_d1[DAT_GEN]              ),
                  .D2                       (   tx_d2[DAT_GEN]              ),
                  .D3                       (   tx_d3[DAT_GEN]              ),
                  .D4                       (   tx_d4[DAT_GEN]              ),
                  .D5                       (   tx_d5[DAT_GEN]              ),
                  .D6                       (   tx_d6[DAT_GEN]              ),
                  .D7                       (   tx_d7[DAT_GEN]              ),
                  .D8                       (   tx_d8[DAT_GEN]              ),
                  .OCE                      (   1'b1                        ),
                  .RST                      (   sync_rst                    ), 
                  // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
                  .SHIFTIN1                 (   dat_sf1[DAT_GEN]            ),
                  .SHIFTIN2                 (   dat_sf2[DAT_GEN]            ),
                  // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
                  .T1                       (   1'b0                        ),
                  .T2                       (   1'b0                        ),
                  .T3                       (   1'b0                        ),
                  .T4                       (   1'b0                        ),
                  .TBYTEIN                  (   1'b0                        ),
                  .TCE                      (   1'b0                        )
               );

               OSERDESE2 #(
                  .DATA_RATE_OQ             (   SERD_MD                     ),  // DDR, SDR
                  .DATA_RATE_TQ             (   "DDR"                       ),  // DDR, BUF, SDR
                  .DATA_WIDTH               (   SERD_W                      ),  // Parallel data width (2-8,10,14)
                  .INIT_OQ                  (   1'b0                        ),
                  .INIT_TQ                  (   1'b0                        ),
                  .SERDES_MODE              (   "SLAVE"                     ),  // MASTER, SLAVE
                  .SRVAL_OQ                 (   1'b0                        ),
                  .SRVAL_TQ                 (   1'b0                        ),
                  .TBYTE_CTL                (   "FALSE"                     ),  // Enable tristate byte operation (FALSE, TRUE)
                  .TBYTE_SRC                (   "FALSE"                     ),  // Tristate byte source (FALSE, TRUE)
                  .TRISTATE_WIDTH           (   1                           )
               )
               u_oserdes2_dat (
                  .OFB                      (                               ),
                  .OQ                       (                               ),
                  // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
                  .SHIFTOUT1                (   dat_sf1[DAT_GEN]            ),
                  .SHIFTOUT2                (   dat_sf2[DAT_GEN]            ),
                  .TBYTEOUT                 (                               ),
                  .TFB                      (                               ),
                  .TQ                       (                               ),
                  .CLK                      (   i_tx_clk                    ),
                  .CLKDIV                   (   i_tx_clkdiv                 ),
                  // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
                  .D1                       (                               ),
                  .D2                       (                               ),
                  .D3                       (   tx_d9 [DAT_GEN]             ),
                  .D4                       (   tx_d10[DAT_GEN]             ),
                  .D5                       (   tx_d11[DAT_GEN]             ),
                  .D6                       (   tx_d12[DAT_GEN]             ),
                  .D7                       (   tx_d13[DAT_GEN]             ),
                  .D8                       (   tx_d14[DAT_GEN]             ),
                  .OCE                      (   1'b1                        ),
                  .RST                      (   sync_rst                    ), 
                  // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
                  .SHIFTIN1                 (   1'b0                        ),
                  .SHIFTIN2                 (   1'b0                        ),
                  // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
                  .T1                       (   1'b0                        ),
                  .T2                       (   1'b0                        ),
                  .T3                       (   1'b0                        ),
                  .T4                       (   1'b0                        ),
                  .TBYTEIN                  (   1'b0                        ),
                  .TCE                      (   1'b0                        )
               );

                OBUFDS #(
                    .IOSTANDARD             (   "LVDS"                      ),  // Specify the output I/O standard
                    .SLEW                   (   "FAST"                      )   // "SLOW"
                )
                u_obufds_dat(
                    .I                      (   tx_dout  [DAT_GEN]      ),
                    .O                      (   o_tx_dout_p[DAT_GEN]    ),
                    .OB                     (   o_tx_dout_n[DAT_GEN]    ) 
                );
            end
        end
    else
        begin:normal_mode
            for (DAT_GEN = 0; DAT_GEN < BUS_W; DAT_GEN = DAT_GEN + 1) 
            begin: u_dat_gen
               OSERDESE2 #(
                  .DATA_RATE_OQ             (   SERD_MD                     ),  // DDR, SDR
                  .DATA_RATE_TQ             (   "DDR"                       ),  // DDR, BUF, SDR
                  .DATA_WIDTH               (   SERD_W                      ),  // Parallel data width (2-8,10,14)
                  .INIT_OQ                  (   1'b0                        ),
                  .INIT_TQ                  (   1'b0                        ),
                  .SERDES_MODE              (   "MASTER"                    ),  // MASTER, SLAVE
                  .SRVAL_OQ                 (   1'b0                        ),
                  .SRVAL_TQ                 (   1'b0                        ),
                  .TBYTE_CTL                (   "FALSE"                     ),  // Enable tristate byte operation (FALSE, TRUE)
                  .TBYTE_SRC                (   "FALSE"                     ),  // Tristate byte source (FALSE, TRUE)
                  .TRISTATE_WIDTH           (   1                           )
               )
               u_oserdes_dat (
                  .OFB                      (                               ),
                  .OQ                       (   tx_dout[DAT_GEN]            ),
                  // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
                  .SHIFTOUT1                (                               ),
                  .SHIFTOUT2                (                               ),
                  .TBYTEOUT                 (                               ),
                  .TFB                      (                               ),
                  .TQ                       (                               ),
                  .CLK                      (   i_tx_clk                    ),
                  .CLKDIV                   (   i_tx_clkdiv                 ),
                  // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
                  .D1                       (   tx_d1[DAT_GEN]              ),
                  .D2                       (   tx_d2[DAT_GEN]              ),
                  .D3                       (   tx_d3[DAT_GEN]              ),
                  .D4                       (   tx_d4[DAT_GEN]              ),
                  .D5                       (   tx_d5[DAT_GEN]              ),
                  .D6                       (   tx_d6[DAT_GEN]              ),
                  .D7                       (   tx_d7[DAT_GEN]              ),
                  .D8                       (   tx_d8[DAT_GEN]              ),
                  .OCE                      (   1'b1                        ),
                  .RST                      (   sync_rst                    ), 
                  // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
                  .SHIFTIN1                 (   1'b0                        ),
                  .SHIFTIN2                 (   1'b0                        ),
                  // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
                  .T1                       (   1'b0                        ),
                  .T2                       (   1'b0                        ),
                  .T3                       (   1'b0                        ),
                  .T4                       (   1'b0                        ),
                  .TBYTEIN                  (   1'b0                        ),
                  .TCE                      (   1'b0                        )
               );
             
                OBUFDS #(
                    .IOSTANDARD             (   "LVDS"                      ),  // Specify the output I/O standard
                    .SLEW                   (   "FAST"                      )   // "SLOW"
                )
                u_obufds_dat(
                    .I                      (   tx_dout  [DAT_GEN]      ),
                    .O                      (   o_tx_dout_p[DAT_GEN]    ),
                    .OB                     (   o_tx_dout_n[DAT_GEN]    ) 
                );
            end
        end     
endgenerate

/////////////////////////////////////    
    
endmodule


此程序实现了多DDS模块生成数据在多个通道进行的,并转串的合并输出。需要理解以下两点:

  1. 理解generate模块复用例化
  2. OSERDESE2 原语

详细的OSERDESE2 原语解释请自行查阅,如xilinx原语详解及仿真——OSERDESE2
generate的使用方法如Verilog中generate的用法

注意事项

  1. 使用OSERDESE2原语的时候,是将四个低频dds的数据合成一个,那么合成模块就是将四个dds的值一次穿插,其最终的输出频率无法降低,和使用一个dds输出波形时所用的时钟频率一致或至少其一半,但无法降低至每个小dds的低频率去运行。如果硬件如DAC无法在这么高的频率下输出,那么还是无法合成高频率的波形。也就是说此方法只是为了减轻系统计算庞大数据时候的速度压力,最终合成波形的频率上限是由硬件条件尤其是DAC决定的。
  2. OSERDESE2原语可以做到时钟上升沿和下降沿都输出数据,利用ddr模式可以生成两倍频率的数据。如10MHz的波形用一个dds实现,如果44个点为一个周期,那么时钟频率为440Mhz,而利用OSERDESE2原语只需要220MHz就可以合成。
  3. 再考虑多少个dds合成一个最终的波形时,不仅限于4个或者8,具体根据实际情况考量,可以利用OSERDESE2原语的级联做到14个DDS合成一个。
  4. 此程序使用的是8个dds的数据,但最终选出其第1、3、5、7个dds进行波形合成,第2、4、6、8个dds并未进行计算,但是在OSERDESE2模块里仍然按照8个通道去合并的。如果8个dds的数据全部并转串输出,那么最终波形一个周期就由11个点组成,而现在这种四个11/8个dds合成的波形,每个周期其实只有5或6个点。这里只是阐述D1、D2通道的数据为何一样,详细可查看此文:DDS的步进值计算。
    使用OSERDESE2原语实现多个dds合成一个波形,达到面积换速度的目的,射频低电平控制系统,fpga开发

代码要点

  1. 此代码里虽然使用了ddr模式,但是时钟上升沿和下降沿的数据是一样的,等同于仍然是每个时钟上升沿才输出一次。
  2. 虽然D1-D8通道全部使用了,但D1和D2、D3和D4、D5和D6、D7和D8的数据是一样的。
  3. 要注意并转串是倒着输出的,因此最终输出的结果等于是D7通道的第一个数据排第1输出,D5通道的第一个数据排在第2个输出,D3排第3,D1排第4;然后是D7通道的第二个数据,依次类推。
  4. 在如下图所示程序里 ,tx_d1值得不是数组,而是一个变量,这里不是利用数组的多维元素进行拼接,而是tx_d1这个变量的某一位进行generate的模块复用。要知道的是这些复用的模块是同时进行的,也就是单位时钟周期内,tx_d1这个变量的每一位都赋值成功了
                   D1                       (   tx_d1[DAT_GEN]              ),
                  .D2                       (   tx_d2[DAT_GEN]              ),
                  .D3                       (   tx_d3[DAT_GEN]              ),
                  .D4                       (   tx_d4[DAT_GEN]              ),
                  .D5                       (   tx_d5[DAT_GEN]              ),
                  .D6                       (   tx_d6[DAT_GEN]              ),
                  .D7                       (   tx_d7[DAT_GEN]              ),
                  .D8                       (   tx_d8[DAT_GEN]              ),
                  .OCE                      (   1'b1                        ),
                  .RST                      (   sync_rst                    ), 
  1. 如下表所示,复用的模块对每一位单独进行赋值,每个模块都是并行同时进行赋值的;也就是同一时间输出端tx_dout的A、B、C、D变量就已经赋值完成了,再依次按照AABBCCDD顺序输出即可。
    切勿理解为tx_dout[15:0]=0000 0000 0000 000A0

使用OSERDESE2原语实现多个dds合成一个波形,达到面积换速度的目的,射频低电平控制系统,fpga开发文章来源地址https://www.toymoban.com/news/detail-800875.html

到了这里,关于使用OSERDESE2原语实现多个dds合成一个波形,达到面积换速度的目的的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • git同一分支上多个commit合成一个的操作

    1、首先git log——查看当前分支的提交记录 ,想要把圈起来的commit合成一个, 2、开始合并,敲下面这个命令 git rebase -i commitId commitId即找出要合并的几个commit的前一个commit的ID -i 的参数是不需要合并的 commit 的 hash 值,这里指的是第一条 commit, 接着键盘摁下 i 键,我们就进

    2024年01月19日
    浏览(49)
  • linux+QT+FFmpeg 6.0,把多个QImage组合成一个视频

    我这里是专门搞了个类封装,我把这个类当成线程使用了,在启动程序的时候直接当线程启动recordInit():比如这样  然后我在需要合成视频的时候先调用初始化: 再传入QImage: 这样就不会造成卡死主线程的情况 我在使用FFmpeg的时候主要出现两个比较明显的情况: 1.pix_fmt为-1的情况

    2024年02月11日
    浏览(29)
  • 通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)

    1.简单理解文件下载 文件下载,是从服务器下载到本地电脑。 文件下载的原理,首先通过IO流将服务器的文件读取到内存里(只有将数据读到内存,电脑才可以操作数据),读取后文件数据存放在内存中,将内存中的数据通过网络发送给本地客户端的浏览器。本地客户端的浏

    2024年02月08日
    浏览(34)
  • 数字频率合成器dds的量化性能分析matlab仿真

    目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 DDS的基本原理 4.2 DDS的量化性能分析 5.完整工程文件         数字频率合成器dds的量化性能分析matlab仿真,分别定义累加器位宽,截位位宽,模拟DAC位宽等,分析不同的量化位宽对DDS信号输出频谱的影响。

    2024年01月23日
    浏览(93)
  • 多个Livox雷达点云合成及使用ROS发布

    因为单个Livox avia的FOV只有70°,无法覆盖车前方的所有范围,所以用了三个Livox avia以实现180°前方位覆盖。但由于三个雷达均是独自采集,所以需要对每个雷达采集的各帧点云进行合并,用于建图。以下工作均建立于已经知道各雷达之间的外参。 由于Fast-LIO输入的是Livox自定义

    2024年02月13日
    浏览(29)
  • Hive sql 将多个字段组合成json格式

    新的项目中,有一个需求,前端展示一个字段中要包含多个字段,讨论后决定将多个字段转成Json类型进行展示,新字段类型为 arraydict 经历了多次试验,参考多个文章版本,终于改成了符合需求的SQL版本。 SQL代码如下: 结果展示:

    2024年02月16日
    浏览(31)
  • Fast DDS入门五、在Windows平台创建一个简单的Fast DDS示例程序

    在这里,先建立一个IDL文件,然后通过使用Fast DDS-Gen生成程序生成这个简单示例程序。Fast DDS-Gen程序的编译安装请参考《Fast DDS入门二、Fast DDS在Windows平台的编译安装》,Fast DDS-Gen程序的使用请参考《Fast DDS入门四、Fast DDS-Gen使用介绍》。 (1)创建IDL文件 先建立一个单独的目

    2024年02月16日
    浏览(37)
  • java一个接口多个实现得调用

    在 Java 中,如果一个接口有多个实现类,可以通过以下几种方式来调用不同的实现类: 根据具体实现类的类型进行调用: 利用接口的引用,根据条件判断调用不同的实现类: 在集合中存储不同的实现类对象,通过循环遍历调用: 使用工厂模式或依赖注入框架来动态获取不同

    2024年02月13日
    浏览(35)
  • 端口复用·一个端口多个进程使用

            在Linux当中,我们知道,每一个进程都有自己唯一的PID。而这个唯一的PID可以标识一个主机当中的唯一一个进程,今天在用modbus写通信期间遇见一个很有意思的问题。         说是有意思讲来简单,就是简单的端口占用问题,我们知道modbus是应用层的协议,但是是基

    2024年02月12日
    浏览(30)
  • 【Git使用小技巧】一个项目使用多个远程仓库

    目录 场景一:多远程仓库的基本操作 添加远程仓库 查看远程仓库 推送到全部远程仓库 同步指定目标仓库 更改远程仓库地址 删除远程仓库 场景二:所有仓库同步拉取/推送 场景三:一个仓库只拉取,一个仓库只推送 参考资料: 前言 当我们实际开发中,可能会遇到一个项目

    2024年01月19日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包