FMC150配置和使用(三)ads62p49

对于芯片的配置在前两个篇章已经详细介绍过了,无非就是仔细看芯片的数据手册,然后不断试错。这一章就重点讲一讲配置ads62p49需要我们注意的地方。

SPI时序图

这里需要注意的是,对于ads62p49,输入数据是在SCLK的下降沿锁存,上升沿改变,和前两个芯片不太一样。另外,如果芯片寄存器是软复位的话,RESET得一直置零,而不是输出脉冲。
在这里插入图片描述

输出数据格式

如果是LVDS输出的话,对应如下时序图。14位的AD转换数据在时钟上升沿输出7位,在时钟下降沿输出7位(DDR),所以最后的要想得到真正的数据还得进行数据拼接。
在这里插入图片描述
如果是CMOS输出的话就不用考虑那么多了。
在这里插入图片描述
ROM中的数据:

MEMORY_INITIALIZATION_RADIX=16;
MEMORY_INITIALIZATION_VECTOR=
0080
2000
3F00
4008
4180
4400
5044
5100
5200
5340
55C0
5700
6200
6300
6640
68C0
6A00
7500
7600;

Verilog程序

目前的程序框架如下图所示,sys_top为顶层文件,对输入差分信号转单端,对输出信号转换成差分信号以满足要求。fmc150_spi_ctrl为三个芯片的SPI时序文件,并将3个ROM中的数存入相应的芯片。modulation_16QAM按照规定的时序产生了一个1MHz的正弦信号,用于测试AD/DA,之后会改成16QAM调制信号。
在这里插入图片描述

sys_top.v
module sys_top(
    input SYS_CLK_P,                  //系统200MHz差分时钟
    input SYS_CLK_N,
    input RST,                        //系统复位
    input WORK_EN,                    //SPI使能--按键
    input CLK_TO_FPGA_P,              //clock from cdce72010 to FPGA
    input CLK_TO_FPGA_N,
    output CLK_TO_FPGA_TEST,          //引到测试管脚进行观测
    output SPI_CLK,                   //common SPI clock
    output SPI_SDI,                   //common SPI data
    input SPI_SDO_CDCE72010,          //SDO from cdce72010
    input PLL_STATUS,                 //check if pll is locked
    output REF_ENA,                   //primary clock enable
    output SPI_RESET_CDCE72010,       //reset to cdce72010
    output SPI_PD_CDCE72010,          //pd to cdce72010(power down)
    output SPI_LE_CDCE72010,          //le to cdce72010
    input SPI_SDO_DAC3283,            //SDO from dac3283
    output SPI_TXENABLE_DAC3283,      //txenable to dac3283
    output SPI_LE_DAC3283,            //le to dac3283
    input SPI_SDO_ADS62P49,           //SDO from ads62p49
    output SPI_RESET_ADS62P49,        //reset to ads62p49
    output SPI_LE_ADS62P49,           //le to ads62p49
    input ADC_CLK_TO_FPGA_P,          //clock from adc to FPGA
    input ADC_CLK_TO_FPGA_N,
    input [13:0]AD_DATA_CHANNAL_A,    //adc channalA data
    input [13:0]AD_DATA_CHANNAL_B,    //adc channalB data
    output DAC_DATA_CLK_P,            //dac data clock
    output DAC_DATA_CLK_N,
    output DAC_FRAME_P,               //dac frame syn
    output DAC_FRAME_N,
    output [15:0]DA_DATA              //data to dac
    );
    
wire clk_40MHz;  //40MHz
wire clk_491MHz;  //491.52MHz
wire clk_245MHz;  //245.76MHz
wire CLK_TO_FPGA;
wire ADC_CLK_TO_FPGA;
wire conf_end;
wire [6:0]adc_data_buff;
reg [6:0]adc_data_reg_1;
reg [6:0]adc_data_reg_2;
reg [13:0]adc_data;
//*****************CDCE72010****************
reg spi_reset_cdce72010 = 1'b1;
reg spi_pd_cdce72010 = 1'b1;
reg ref_ena = 1'b1;
assign SPI_RESET_CDCE72010 = spi_reset_cdce72010;
assign SPI_PD_CDCE72010 = spi_pd_cdce72010;
assign REF_ENA = ref_ena;
assign CLK_TO_FPGA_TEST = CLK_TO_FPGA;
//*****************DAC3283****************
reg spi_txenable_dac3283 = 1'b1;
assign SPI_TXENABLE_DAC3283 = spi_txenable_dac3283;
//*****************ADS62P49****************
reg spi_reset_ads62p49 = 1'b0;
assign SPI_RESET_ADS62P49 = spi_reset_ads62p49;

//差分转单端1
IBUFDS #(
.DIFF_TERM("TRUE"),       // Differential Termination
.IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
.IOSTANDARD("DEFAULT")     // Specify the input I/O standard
) IBUFDS_1 (
.O(CLK_TO_FPGA),     // Buffer output
.I(CLK_TO_FPGA_P),   // Diff_p buffer input (connect directly to top-level port)
.IB(CLK_TO_FPGA_N)   // Diff_n buffer input (connect directly to top-level port)
);
//差分转单端2
IBUFDS #(
.DIFF_TERM("TRUE"),       // Differential Termination
.IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
.IOSTANDARD("DEFAULT")     // Specify the input I/O standard
) IBUFDS_2 (
.O(ADC_CLK_TO_FPGA),     // Buffer output
.I(ADC_CLK_TO_FPGA_P),   // Diff_p buffer input (connect directly to top-level port)
.IB(ADC_CLK_TO_FPGA_N)   // Diff_n buffer input (connect directly to top-level port)
);
//差分转单端3
IBUFDS #(
.DIFF_TERM("TRUE"),       // Differential Termination
.IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
.IOSTANDARD("DEFAULT")     // Specify the input I/O standard
) IBUFDS_3 (
.O(adc_data_buff[0]),     // Buffer output
.I(AD_DATA_CHANNAL_A[0]),   // Diff_p buffer input (connect directly to top-level port)
.IB(AD_DATA_CHANNAL_A[1])   // Diff_n buffer input (connect directly to top-level port)
);
//差分转单端4
IBUFDS #(
.DIFF_TERM("TRUE"),       // Differential Termination
.IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
.IOSTANDARD("DEFAULT")     // Specify the input I/O standard
) IBUFDS_4 (
.O(adc_data_buff[1]),     // Buffer output
.I(AD_DATA_CHANNAL_A[2]),   // Diff_p buffer input (connect directly to top-level port)
.IB(AD_DATA_CHANNAL_A[3])   // Diff_n buffer input (connect directly to top-level port)
);
//差分转单端5
IBUFDS #(
.DIFF_TERM("TRUE"),       // Differential Termination
.IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
.IOSTANDARD("DEFAULT")     // Specify the input I/O standard
) IBUFDS_5 (
.O(adc_data_buff[2]),     // Buffer output
.I(AD_DATA_CHANNAL_A[4]),   // Diff_p buffer input (connect directly to top-level port)
.IB(AD_DATA_CHANNAL_A[5])   // Diff_n buffer input (connect directly to top-level port)
);
//差分转单端6
IBUFDS #(
.DIFF_TERM("TRUE"),       // Differential Termination
.IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
.IOSTANDARD("DEFAULT")     // Specify the input I/O standard
) IBUFDS_6 (
.O(adc_data_buff[3]),     // Buffer output
.I(AD_DATA_CHANNAL_A[6]),   // Diff_p buffer input (connect directly to top-level port)
.IB(AD_DATA_CHANNAL_A[7])   // Diff_n buffer input (connect directly to top-level port)
);
//差分转单端7
IBUFDS #(
.DIFF_TERM("TRUE"),       // Differential Termination
.IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
.IOSTANDARD("DEFAULT")     // Specify the input I/O standard
) IBUFDS_7 (
.O(adc_data_buff[4]),     // Buffer output
.I(AD_DATA_CHANNAL_A[8]),   // Diff_p buffer input (connect directly to top-level port)
.IB(AD_DATA_CHANNAL_A[9])   // Diff_n buffer input (connect directly to top-level port)
);
//差分转单端8 
IBUFDS #(
.DIFF_TERM("TRUE"),       // Differential Termination
.IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
.IOSTANDARD("DEFAULT")     // Specify the input I/O standard
) IBUFDS_8 (
.O(adc_data_buff[5]),     // Buffer output
.I(AD_DATA_CHANNAL_A[10]),   // Diff_p buffer input (connect directly to top-level port)
.IB(AD_DATA_CHANNAL_A[11])   // Diff_n buffer input (connect directly to top-level port)
);
//差分转单端9
IBUFDS #(
.DIFF_TERM("TRUE"),       // Differential Termination
.IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
.IOSTANDARD("DEFAULT")     // Specify the input I/O standard
) IBUFDS_9 (
.O(adc_data_buff[6]),     // Buffer output
.I(AD_DATA_CHANNAL_A[12]),   // Diff_p buffer input (connect directly to top-level port)
.IB(AD_DATA_CHANNAL_A[13])   // Diff_n buffer input (connect directly to top-level port)
);

clk_wiz_0 clk_wiz_0_i(
    // Clock out ports
    .clk_out1(clk_40MHz),     // output clk_out1
    .clk_out2(clk_491MHz),     // output clk_out2
    .clk_out3(clk_245MHz),     // output clk_out3
    // Clock in ports
    .clk_in1_p(SYS_CLK_P),    // input clk_in1_p
    .clk_in1_n(SYS_CLK_N)     // input clk_in1_n
    );
    
fmc150_spi_ctrl fmc150_spi_ctrl_i(
    .SYS_CLK(clk_40MHz),                      //40MHz
    .RST(RST),
    .WORK_EN(WORK_EN),                        //SPI使能--按键
    .CONF_END(conf_end),
    .SPI_CLK(SPI_CLK),                        //SPI时钟,最大不能超过20MHz
    .SPI_SDI(SPI_SDI),                        //主机向cdce72010传输数据
    .SPI_LE_CDCE72010(SPI_LE_CDCE72010),      //cdce72010片选端
    .SPI_LE_DAC3283(SPI_LE_DAC3283),          //dac3283片选端
    .SPI_LE_ADS62P49(SPI_LE_ADS62P49)          //ads62p49片选端
        );

wire data_clk;
wire [7:0]dac_data;
wire frame;
modulation_16QAM modulation_16QAM_i(
    .SYS_CLK(clk_491MHz),
    .RST(RST),
    .DATA_CLK(data_clk),
    .DATA(dac_data),
    .FRAME(frame)
            );

//单端转差分1
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_1 (
.O(DAC_DATA_CLK_P),     // Diff_p output (connect directly to top-level port)
.OB(DAC_DATA_CLK_N),   // Diff_n output (connect directly to top-level port)
.I(data_clk)      // Buffer input 
);
//单端转差分2
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_2 (
.O(DAC_FRAME_P),     // Diff_p output (connect directly to top-level port)
.OB(DAC_FRAME_N),   // Diff_n output (connect directly to top-level port)
.I(frame)      // Buffer input 
);
//单端转差分3
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_3 (
.O(DA_DATA[0]),     // Diff_p output (connect directly to top-level port)
.OB(DA_DATA[1]),   // Diff_n output (connect directly to top-level port)
.I(dac_data[0])      // Buffer input 
);
//单端转差分4
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_4 (
.O(DA_DATA[2]),     // Diff_p output (connect directly to top-level port)
.OB(DA_DATA[3]),   // Diff_n output (connect directly to top-level port)
.I(dac_data[1])      // Buffer input 
);
//单端转差分5
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_5 (
.O(DA_DATA[4]),     // Diff_p output (connect directly to top-level port)
.OB(DA_DATA[5]),   // Diff_n output (connect directly to top-level port)
.I(dac_data[2])      // Buffer input 
);
//单端转差分6
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_6 (
.O(DA_DATA[6]),     // Diff_p output (connect directly to top-level port)
.OB(DA_DATA[7]),   // Diff_n output (connect directly to top-level port)
.I(dac_data[3])      // Buffer input 
);
//单端转差分7
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_7 (
.O(DA_DATA[8]),     // Diff_p output (connect directly to top-level port)
.OB(DA_DATA[9]),   // Diff_n output (connect directly to top-level port)
.I(dac_data[4])      // Buffer input 
);
//单端转差分8
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_8 (
.O(DA_DATA[10]),     // Diff_p output (connect directly to top-level port)
.OB(DA_DATA[11]),   // Diff_n output (connect directly to top-level port)
.I(dac_data[5])      // Buffer input 
);
//单端转差分9
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_9 (
.O(DA_DATA[12]),     // Diff_p output (connect directly to top-level port)
.OB(DA_DATA[13]),   // Diff_n output (connect directly to top-level port)
.I(dac_data[6])      // Buffer input 
);
//单端转差分10
OBUFDS #(
.IOSTANDARD("DEFAULT"), // Specify the output I/O standard
.SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_10 (
.O(DA_DATA[14]),     // Diff_p output (connect directly to top-level port)
.OB(DA_DATA[15]),   // Diff_n output (connect directly to top-level port)
.I(dac_data[7])      // Buffer input 
);

always@(posedge ADC_CLK_TO_FPGA or negedge RST)
begin
    if(RST)
    begin
        adc_data <= 14'b00_0000_0000_0000;
        adc_data_reg_1 <= 7'b000_0000;
    end
    else
    begin
        adc_data <= {adc_data_reg_2[6],adc_data_reg_1[6],adc_data_reg_2[5],adc_data_reg_1[5],adc_data_reg_2[4],adc_data_reg_1[4],adc_data_reg_2[3],adc_data_reg_1[3],adc_data_reg_2[2],adc_data_reg_1[2],adc_data_reg_2[1],adc_data_reg_1[1],adc_data_reg_2[0],adc_data_reg_1[0]};
        adc_data_reg_1 <= adc_data_buff;
    end
end

always@(negedge ADC_CLK_TO_FPGA or negedge RST)
begin
    if(RST)
    begin
        adc_data_reg_2 <= 7'b000_0000;
    end
    else
    begin
        adc_data_reg_2 <= adc_data_buff;
    end
end

ila_0 ila_0_i (
            .clk(clk_491MHz), // input wire clk
            .probe0(WORK_EN), // input wire [0:0]  probe0  
            .probe1(CLK_TO_FPGA), // input wire [0:0]  probe1 
            .probe2(SPI_CLK), // input wire [0:0]  probe2 
            .probe3(SPI_SDI), // input wire [0:0]  probe3 
            .probe4(SPI_LE_CDCE72010), // input wire [0:0]  probe4 
            .probe5(SPI_SDO_CDCE72010), // input wire [0:0]  probe5 
            .probe6(SPI_LE_DAC3283), // input wire [0:0]  probe6 
            .probe7(SPI_SDO_DAC3283), // input wire [0:0]  probe7 
            .probe8(SPI_LE_ADS62P49), // input wire [0:0]  probe8 
            .probe9(SPI_SDO_ADS62P49), // input wire [0:0]  probe9 
            .probe10(ADC_CLK_TO_FPGA), // input wire [0:0]  probe10 
            .probe11(adc_data), // input wire [13:0]  probe11
            .probe12(PLL_STATUS), // input wire [0:0]  probe12
            .probe13(adc_data_buff), // input wire [6:0]  probe13 
            .probe14(adc_data_reg_1), // input wire [6:0]  probe14 
            .probe15(adc_data_reg_2) // input wire [6:0]  probe15
        );

    
endmodule
fmc150_spi_ctrl.v
module fmc150_spi_ctrl(
    input SYS_CLK,                    //40MHz
    input RST,
    input WORK_EN,                    //SPI使能--按键
    output reg CONF_END,
    output SPI_CLK,                   //SPI时钟,最大不能超过20MHz
    output SPI_SDI,                   //主机向cdce72010传输数据
    output SPI_LE_CDCE72010,          //cdce72010片选端
    output SPI_LE_DAC3283,            //dac3283片选端
    output SPI_LE_ADS62P49            //ads62p49片选端
    );
    
parameter IDLE            = 11'b000_0000_0001;            //空闲状态,等待触发
parameter WAIT_1          = 11'b000_0000_0010;            //写各个寄存器之间的等待状态
parameter R_MEM_CDCE72010 = 11'b000_0000_0100;            //读ROM(cdce72010部分)
parameter W_REG_CDCE72010 = 11'b000_0000_1000;            //写寄存器(cdce72010部分)
parameter WAIT_2          = 11'b000_0001_0000;            //写各个寄存器之间的等待状态
parameter R_MEM_DAC3283   = 11'b000_0010_0000;            //读ROM(dac3283部分)
parameter W_REG_DAC3283   = 11'b000_0100_0000;            //写寄存器(dac3283部分)
parameter WAIT_3          = 11'b000_1000_0000;            //写各个寄存器之间的等待状态
parameter R_MEM_ADS62P49  = 11'b001_0000_0000;            //读ROM(ads62p49部分)
parameter W_REG_ADS62P49  = 11'b010_0000_0000;            //写寄存器(ads62p49部分)
parameter STOP            = 11'b100_0000_0000;            //配置完成

reg [10:0]current_state = IDLE;
reg [10:0]next_state = IDLE;
reg [2:0]div_cnt;
reg spi_clk;
reg pose_flag;
reg [3:0]wait_cnt_1;
reg [3:0]wait_cnt_2;
reg [3:0]wait_cnt_3;
reg [5:0]shift_cnt_1;
reg [5:0]shift_cnt_2;
reg [5:0]shift_cnt_3;
reg data_end_1;
reg data_end_2;
reg data_end_3;
reg [4:0]r_addr_1;
reg [4:0]r_addr_2;
reg [4:0]r_addr_3;
reg [31:0]shift_buf_1; //存储从cdce72010_ROM读出来的32位数据
wire [31:0]r_data_1;
reg [15:0]shift_buf_2; //存储从dac3283_ROM读出来的16位数据
wire [15:0]r_data_2;
reg [15:0]shift_buf_3; //存储从ads62p49_ROM读出来的16位数据
wire [15:0]r_data_3;
wire spi_clk_reverse;

reg clk; //spi时钟
reg sdi; //主机向从机输出
reg le_cdce72010;       //cdce72010片选端
reg le_dac3283;         //dac3283片选端
reg le_ads62p49;        //ads62p49片选端

assign SPI_CLK = clk;
assign SPI_SDI = sdi;
assign spi_clk_reverse = ~spi_clk;
assign SPI_LE_CDCE72010 = le_cdce72010;
assign SPI_LE_DAC3283 = le_dac3283;
assign SPI_LE_ADS62P49 = le_ads62p49;

//8分频计数器,分出5MHz
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        div_cnt <= 3'd0;
    else if(div_cnt == 3'd3)
        div_cnt <= 3'd0;
    else
        div_cnt <= div_cnt + 3'd1;
end
//spi_clk : 5MHz
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        spi_clk <= 1'b0;
    else if(div_cnt == 3'd3)
        spi_clk <= ~spi_clk;
    else
        spi_clk <= spi_clk;
end
//产生一个标志信号
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        pose_flag <= 1'b0;
    else if(spi_clk == 1'b0 && div_cnt == 3'd3)
        pose_flag <= 1'b1;
    else
        pose_flag <= 1'b0;
end
//等待计数器1
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        wait_cnt_1 <= 4'd0;
    else if(current_state == WAIT_1 && pose_flag == 1'b1)
        wait_cnt_1 <= wait_cnt_1 + 4'd1;
    else if(current_state != WAIT_1)
        wait_cnt_1 <= 4'd0;
    else
        wait_cnt_1 <= wait_cnt_1;
end
//等待计数器2
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        wait_cnt_2 <= 4'd0;
    else if(current_state == WAIT_2 && pose_flag == 1'b1)
        wait_cnt_2 <= wait_cnt_2 + 4'd1;
    else if(current_state != WAIT_2)
        wait_cnt_2 <= 4'd0;
    else
        wait_cnt_2 <= wait_cnt_2;
end
//等待计数器3
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        wait_cnt_3 <= 4'd0;
    else if(current_state == WAIT_3 && pose_flag == 1'b1)
        wait_cnt_3 <= wait_cnt_3 + 4'd1;
    else if(current_state != WAIT_3)
        wait_cnt_3 <= 4'd0;
    else
        wait_cnt_3 <= wait_cnt_3;
end
//状态机
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        current_state <= IDLE;
    else
        current_state <= next_state;
end
always@(*)
begin
    case(current_state)
    IDLE : begin
               if(WORK_EN == 1'b1)
                   next_state <= WAIT_1;
               else
                   next_state <= IDLE;
    end
    WAIT_1 : begin
                 if(wait_cnt_1[3] == 1'b1)
                     next_state <= R_MEM_CDCE72010;
                 else
                     next_state <= WAIT_1;
    end
    R_MEM_CDCE72010 : begin
                          next_state <= W_REG_CDCE72010;
    end
    W_REG_CDCE72010 : begin
                          if(shift_cnt_1 == 6'd32 && pose_flag == 1'b1 && data_end_1 != 1'b1)
                              next_state <= WAIT_1;
                          else if(shift_cnt_1 == 6'd32 && pose_flag == 1'b1 && data_end_1 == 1'b1)
                              next_state <= WAIT_2;
                          else
                              next_state <= W_REG_CDCE72010;
    end
    WAIT_2 : begin
                 if(wait_cnt_2[3] == 1'b1)
                     next_state <= R_MEM_DAC3283;
                 else
                     next_state <= WAIT_2;
    end
    R_MEM_DAC3283 : begin
                        next_state <= W_REG_DAC3283;
    end
    W_REG_DAC3283 : begin
                        if(shift_cnt_2 == 6'd16 && pose_flag == 1'b1 && data_end_2 != 1'b1)
                            next_state <= WAIT_2;
                        else if(shift_cnt_2 == 6'd16 && pose_flag == 1'b1 && data_end_2 == 1'b1)
                            next_state <= WAIT_3;
                        else
                            next_state <= W_REG_DAC3283;
    end
    WAIT_3 : begin
                 if(wait_cnt_3[3] == 1'b1)
                     next_state <= R_MEM_ADS62P49;
                 else
                     next_state <= WAIT_3;
    end
    R_MEM_ADS62P49 : begin
                         next_state <= W_REG_ADS62P49;
    end
    W_REG_ADS62P49 : begin
                         if(shift_cnt_3 == 6'd16 && pose_flag == 1'b1 && data_end_3 != 1'b1)
                             next_state <= WAIT_3;
                         else if(shift_cnt_3 == 6'd16 && pose_flag == 1'b1 && data_end_3 == 1'b1)
                             next_state <= STOP;
                         else
                             next_state <= W_REG_ADS62P49;
    end
    STOP : begin
               next_state <= STOP;
    end
    default : begin
                  next_state <= IDLE;
    end
    endcase
end
//cdce72010寄存器位数的计数(32位)
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        shift_cnt_1 <= 6'd0;
    else if(current_state == W_REG_CDCE72010 && pose_flag == 1'b1)
        shift_cnt_1 <= shift_cnt_1 + 6'd1;
    else if(current_state != W_REG_CDCE72010)
        shift_cnt_1 <= 6'd0;
    else
        shift_cnt_1 <= shift_cnt_1;
end
//dac3283寄存器位数的计数(16位)
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        shift_cnt_2 <= 6'd0;
    else if(current_state == W_REG_DAC3283 && pose_flag == 1'b1)
        shift_cnt_2 <= shift_cnt_2 + 6'd1;
    else if(current_state != W_REG_DAC3283)
        shift_cnt_2 <= 6'd0;
    else
        shift_cnt_2 <= shift_cnt_2;
end
//ads62p49寄存器位数的计数(16位)
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        shift_cnt_3 <= 6'd0;
    else if(current_state == W_REG_ADS62P49 && pose_flag == 1'b1)
        shift_cnt_3 <= shift_cnt_3 + 6'd1;
    else if(current_state != W_REG_ADS62P49)
        shift_cnt_3 <= 6'd0;
    else
        shift_cnt_3 <= shift_cnt_3;
end
//读cdce72010_ROM地址产生
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        r_addr_1 <= 5'd0;
    else if(current_state == R_MEM_CDCE72010)
        r_addr_1 <= r_addr_1 + 5'd1;
    else
        r_addr_1 <= r_addr_1;
end
//读dac3283_ROM地址产生
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        r_addr_2 <= 5'd0;
    else if(current_state == R_MEM_DAC3283)
        r_addr_2 <= r_addr_2 + 5'd1;
    else
        r_addr_2 <= r_addr_2;
end
//读ads62p49_ROM地址产生
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        r_addr_3 <= 5'd0;
    else if(current_state == R_MEM_ADS62P49)
        r_addr_3 <= r_addr_3 + 5'd1;
    else
        r_addr_3 <= r_addr_3;
end
//读cdce72010_ROM完成标志
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        data_end_1 <= 1'b0;
    else if(current_state == R_MEM_CDCE72010 && r_addr_1 == 5'd12)
        data_end_1 <= 1'b1;
    else
        data_end_1 <= data_end_1;
end
//读dac3283_ROM完成标志
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        data_end_2 <= 1'b0;
    else if(current_state == R_MEM_DAC3283 && r_addr_2 == 5'd31)
        data_end_2 <= 1'b1;
    else
        data_end_2 <= data_end_2;
end
//读ads62p49_ROM完成标志
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        data_end_3 <= 1'b0;
    else if(current_state == R_MEM_ADS62P49 && r_addr_3 == 5'd18)
        data_end_3 <= 1'b1;
    else
        data_end_3 <= data_end_3;
end
//读cdce72010_ROM数据,并做移位寄存器
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        shift_buf_1 <= 32'h0000_0000;
    else if(current_state == R_MEM_CDCE72010)
        shift_buf_1 <= r_data_1;
    else if(current_state == W_REG_CDCE72010 && pose_flag == 1'b1)
        shift_buf_1 <= {1'b1,shift_buf_1[31:1]};
    else
        shift_buf_1 <= shift_buf_1;
end
//读dac3283_ROM数据,并做移位寄存器
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        shift_buf_2 <= 16'h0000;
    else if(current_state == R_MEM_DAC3283)
        shift_buf_2 <= r_data_2;
    else if(current_state == W_REG_DAC3283 && pose_flag == 1'b1)
        shift_buf_2 <= {shift_buf_2[14:0],1'b1};
    else
        shift_buf_2 <= shift_buf_2;
end
//读ads62p49_ROM数据,并做移位寄存器
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        shift_buf_3 <= 16'h0000;
    else if(current_state == R_MEM_ADS62P49)
        shift_buf_3 <= r_data_3;
    else if(current_state == W_REG_ADS62P49 && pose_flag == 1'b1)
        shift_buf_3 <= {shift_buf_3[14:0],1'b1};
    else
        shift_buf_3 <= shift_buf_3;
end
//数据输出
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        sdi <= 1'b0;
    else if(next_state == W_REG_CDCE72010 && pose_flag == 1'b1)
        sdi <= shift_buf_1[0];
    else if(next_state == W_REG_DAC3283 && pose_flag == 1'b1)
        sdi <= shift_buf_2[15];
    else if(next_state == W_REG_ADS62P49 && pose_flag == 1'b1)
        sdi <= shift_buf_3[15];
    else if(next_state != W_REG_CDCE72010 && next_state != W_REG_DAC3283 && next_state != W_REG_ADS62P49)
        sdi <= 1'b0;
    else
        sdi <= sdi;
end
//cdce72010片选信号产生
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        le_cdce72010 <= 1'b1;
    else if(current_state == W_REG_CDCE72010)
        begin
        if(shift_cnt_1 > 6'd0)
            le_cdce72010 <= 1'b0;
        else
            le_cdce72010 <= le_cdce72010;
        end
    else
        le_cdce72010 <= 1'b1;
end
//dac3283片选信号产生
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        le_dac3283 <= 1'b1;
    else if(current_state == W_REG_DAC3283)
        begin
        if(shift_cnt_2 > 6'd0)
            le_dac3283 <= 1'b0;
        else
            le_dac3283 <= le_dac3283;
        end
    else
        le_dac3283 <= 1'b1;
end
//ads62p49片选信号产生
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        le_ads62p49 <= 1'b1;
    else if(current_state == W_REG_ADS62P49)
        begin
        if(shift_cnt_3 > 6'd0)
            le_ads62p49 <= 1'b0;
        else
            le_ads62p49 <= le_ads62p49;
        end
    else
        le_ads62p49 <= 1'b1;
end
//spi时钟信号产生
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        clk <= 1'b0;
    else if(current_state == W_REG_CDCE72010)
    begin
        if(shift_cnt_1 > 6'd0)
            clk <= spi_clk_reverse;
        else
            clk <= clk;
    end
    else if(current_state == W_REG_DAC3283)
    begin
        if(shift_cnt_2 > 6'd0)
            clk <= spi_clk_reverse;
        else
            clk <= clk;
    end
    else if(current_state == W_REG_ADS62P49)
    begin
        if(shift_cnt_3 > 6'd0)
            clk <= spi_clk;
        else
            clk <= clk;
    end
    else
    begin
        if(current_state < WAIT_3)
            clk <= 1'b0;
        else if(current_state >= R_MEM_ADS62P49 )
            clk <= 1'b1;
        else
            clk <= clk;
    end
end
//配置结束信号
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        CONF_END <= 1'b0;
    else if(current_state == STOP)
        CONF_END <= 1'b1;
    else
        CONF_END <= CONF_END;
end

rom_cdce72010 rom_cdce72010_i (
  .a(r_addr_1),        // input wire [4 : 0] a
  .clk(SYS_CLK),    // input wire clk
  .qspo(r_data_1)  // output wire [31 : 0] qspo
);

rom_dac3283 rom_dac3283_i (
  .a(r_addr_2),        // input wire [4 : 0] a
  .clk(SYS_CLK),    // input wire clk
  .qspo(r_data_2)  // output wire [15 : 0] qspo
);

rom_ads62p49 rom_ads62p49_i (
  .a(r_addr_3),        // input wire [4 : 0] a
  .clk(SYS_CLK),    // input wire clk
  .qspo(r_data_3)  // output wire [15 : 0] qspo
);

endmodule
modulation_16QAM.v
module modulation_16QAM(
    input SYS_CLK,
    input RST,
    output DATA_CLK,
    output [7:0]DATA,
    output FRAME
    );

reg data_clk = 1'b0;
reg m_axis_data_tvalid_delay;
reg frame;
reg [4:0]frame_cnt;
reg frame_flag;
wire clk_122MHz;  //122.88MHz
clk_wiz_1 clk_wiz_1_i
(
// Clock out ports
.clk_out1(clk_122MHz),     // output clk_out1
// Clock in ports
.clk_in1(SYS_CLK));      // input clk_in1

wire m_axis_data_tvalid;
wire [15:0]m_axis_data_tdata;
wire m_axis_phase_tvalid;
wire [31:0]m_axis_phase_tdata;
sin_test sin_test_i (
      .aclk(SYS_CLK),                                // input wire aclk
      .m_axis_data_tvalid(m_axis_data_tvalid),    // output wire m_axis_data_tvalid
      .m_axis_data_tdata(m_axis_data_tdata),      // output wire [15 : 0] m_axis_data_tdata
      .m_axis_phase_tvalid(m_axis_phase_tvalid),  // output wire m_axis_phase_tvalid
      .m_axis_phase_tdata(m_axis_phase_tdata)    // output wire [31 : 0] m_axis_phase_tdata
    );

assign FRAME = frame;
assign DATA_CLK = data_clk;
assign DATA = m_axis_data_tdata[7:0];

always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        m_axis_data_tvalid_delay <= 1'b0;
    else
        m_axis_data_tvalid_delay <= m_axis_data_tvalid;
end
always@(negedge SYS_CLK or posedge RST)
begin
    if(RST)
        data_clk <= 1'b0;
    else if(frame_flag == 1'b1)
        data_clk <= ~data_clk;
    else
        data_clk <= data_clk;
end
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        frame <= 1'b0;
    else if(m_axis_data_tvalid_delay == 1'b0 && m_axis_data_tvalid == 1'b1)
        frame <= 1'b1;
    else if(frame_cnt == 5'd31)
        frame <= 1'b1;
    else if(frame_cnt == 5'd3)
        frame <= 1'b0;
    else
        frame <= frame;
end
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        frame_flag <= 1'b0;
    else if(m_axis_data_tvalid_delay == 1'b0 && m_axis_data_tvalid == 1'b1)
        frame_flag <= 1'b1;
    else
        frame_flag <= frame_flag;
end
always@(posedge SYS_CLK or posedge RST)
begin
    if(RST)
        frame_cnt <= 5'd0;
    else if(frame_flag == 1'b1)
        frame_cnt <= frame_cnt + 5'd1;
    else
        frame_cnt <= frame_cnt;
end

endmodule
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值