對于晶片的配置在前兩個篇章已經詳細介紹過了,無非就是仔細看晶片的資料手冊,然後不斷試錯。這一章就重點講一講配置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
);
[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