CHANNEL-1);
35
36
37 /*********************************variables*******************************************/
38 genvar ii;
39 wire clk_out0,locked0;
40 reg locked0_r0 = 0,locked0_r1 = 0;
41 wire clk_user;
42 wire dco;
43 wire dco_bufg;
44
45 wire [DATA_W*2-1:0] data_adc;
46 wire data_adc_vld;
47 (*DONT_TOUCH = "true"*)wire [DATA_W*2-1:0] din;
48 (*DONT_TOUCH = "true"*)wire din_vld;
49 wire din_sop,din_eop;
50 reg [ (DECH_W-1):0] data_cnt =0 ;
51 wire add_data_cnt ;
52 wire end_data_cnt ;
53
54 /******************************clock generators****************************************/
55
56 //user clock generator
57 clk_wiz_0 user_clock_gen
58 (
59 // Clock out ports
60 .clk_out1(clk_out0), // output clk_out0 125MHZ
61 // Status and control signals
62 .locked(locked0), // output locked
63 // Clock in ports
64 .clk_in1(clk)); // input clk_in1 100MHZ
65
66 //pll lock信号同步
67 always@(posedge clk_out0)begin
68 locked0_r0 <= locked0;
69 locked0_r1 <= locked0_r0;
70 end
71
72 assign clk_user = clk_out0 & locked0_r1;
73
74
75 // ADC clock generator
76 IBUFDS #(
77 .DIFF_TERM("FALSE"),
78 .IBUF_LOW_PWR("FALSE"),
79 .IOSTANDARD("DEFAULT")
80 ) IBUFDS_inst (
81 .O(dco),
82 .I(dco_p),
83 .IB(dco_n)
84 );
85
86 BUFG BUFG_inst(
87 .O(dco_bufg),
88 .I(dco)
89 );
90
91 /**********************************ADC interface module***********************************/
92 adc_interface#(.WIDTH(DATA_W),
93 .FRAME_LEN(DATA_EACH_CHANNEL))
94 u_adc_interface
95 (
96 //adc -> fpga
97 . clk0 (dco_bufg) , //125MHZ 与dco_p同相
98 . clk1 (~dco_bufg), //125MHZ 与dco_n反相
99 . da (adc_p1) ,
100 . db (adc_p2) ,
101 //fpga -> adc
102 . adc_pd (adc_pd) ,//省点模式选择
103 . pll_ce (pll_ce) ,
104 . pll_rst_n (pll_rst_n) ,
105 . pen (pen),
106 //user
107 . user_clk (clk_user),//125MHZ
108 . rst_n (rst_n),
109 . dout (data_adc),//debug
110 . dout_vld (data_adc_vld),
111 . en (en)//上升沿有效
112 );
113 //data counter
114 always @(posedge clk_user or negedge rst_n) begin
115 if (rst_n==0) begin
116 data_cnt <= 0;
117 end
118 else if(add_data_cnt) begin
119 if(end_data_cnt)
120 data_cnt <= 0;
121 else
122 data_cnt <= data_cnt+1 ;
123 end
124 end
125
126 assign add_data_cnt = data_adc_vld ;
127 assign end_data_cnt = add_data_cnt && data_cnt == (DATA_EACH_CHANNEL)-1 ;
128
129 //input data to the user defined logic
130 assign din_sop = add_data_cnt && data_cnt == 0;
131 assign din_eop = end_data_cnt;
132 assign din = data_adc;
133 assign din_vld = data_adc_vld;
134
135
136 //user logic end
137
138 endmodule
top
上述代码是之前做ADC采集信号频谱分析的部分代码,因此adc_interface模块中每触发一次则连续采集一帧数据长度,用于FFT运算。用户可以根据项目需求自行改动。顶层模块中则例化IBUFDS+BUFG原语,以及后续的自定义处理模块。
五、板级调试
行为仿真是FPGA开发中必不可少的重要环节,通过充分测试可节省很多调试时间,这里仅给出板级调试结果。信号发生器产生三角波,利用ILA抓取芯片内部实时数据,并以模拟形式显示:
由于在接口模块中将两通道输入拼接为一个数据,这里拆分后观察数据数值。可见拼接后数据波形呈现三角波形状,且幅值增大过程中高字节较大,幅值降低过程中高字节较小,说明数据拼接顺序无误,高字节为当前节拍后一个采样数据。两路输出数据最高位为0,证明输出数据格式是自然二进制数。
若想细致地观察数据的模拟形状,可以通过灵活的TCL脚本将ILA抓取数据导出,并在MATLAB中查看。TCL命令为:
write_hw_ila_data E:/fpga_files/wave_file.csv [upload_hw_ila_data hw_ila_1] -csv_file –forcewave
命令格式是:write_hw_ila_data <文件路径及文件名> [upload_hw_ila_data <ILA名称