对于芯片的配置在前两个篇章已经详细介绍过了,无非就是仔细看芯片的数据手册,然后不断试错。这一章就重点讲一讲配置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