天天看點

FMC150配置和使用(三)ads62p49

對于晶片的配置在前兩個篇章已經詳細介紹過了,無非就是仔細看晶片的資料手冊,然後不斷試錯。這一章就重點講一講配置ads62p49需要我們注意的地方。

SPI時序圖

這裡需要注意的是,對于ads62p49,輸入資料是在SCLK的下降沿鎖存,上升沿改變,和前兩個晶片不太一樣。另外,如果晶片寄存器是軟複位的話,RESET得一直置零,而不是輸出脈沖。

FMC150配置和使用(三)ads62p49

輸出資料格式

如果是LVDS輸出的話,對應如下時序圖。14位的AD轉換資料在時鐘上升沿輸出7位,在時鐘下降沿輸出7位(DDR),是以最後的要想得到真正的資料還得進行資料拼接。

FMC150配置和使用(三)ads62p49

如果是CMOS輸出的話就不用考慮那麼多了。

FMC150配置和使用(三)ads62p49

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調制信号。

FMC150配置和使用(三)ads62p49

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 
);

[email protected](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

[email protected](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
[email protected](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
[email protected](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
//産生一個标志信号
[email protected](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
[email protected](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
[email protected](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
[email protected](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
//狀态機
[email protected](posedge SYS_CLK or posedge RST)
begin
    if(RST)
        current_state <= IDLE;
    else
        current_state <= next_state;
end
[email protected](*)
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位)
[email protected](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位)
[email protected](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位)
[email protected](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位址産生
[email protected](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位址産生
[email protected](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位址産生
[email protected](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完成标志
[email protected](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完成标志
[email protected](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完成标志
[email protected](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資料,并做移位寄存器
[email protected](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資料,并做移位寄存器
[email protected](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資料,并做移位寄存器
[email protected](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
//資料輸出
[email protected](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片選信号産生
[email protected](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片選信号産生
[email protected](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片選信号産生
[email protected](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時鐘信号産生
[email protected](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
//配置結束信号
[email protected](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];

[email protected](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
[email protected](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
[email protected](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
[email protected](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
[email protected](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