当前位置:文档之家› 华为杯报告_匡鑫_刘洋 Verilog

华为杯报告_匡鑫_刘洋 Verilog

电光学院第六届华为杯电子设计竞赛报告题目:数字AGC的FPGA实现学院:南京理工大学电光学院姓名:匡鑫、刘洋时间:2015年5月一、题目要求1.任务用数字方法设计一个自动增益控制(AGC)电路。

2.要求1.基本要求利用EDA实验平台中的A/D、D/A扩展版设计并实现一个AGC电路,要求输入信号频率为100KHz,最大幅度为2VPP,实现方法参考下图:(1)设计接口电路,用ADC对输入信号进行采样,并用DAC恢复输入信号。

(2)实现对输入信号的手动增益控制。

2.发挥部分(1)实现对输入信号的自动增益控制,要求输出信号幅度保持2VPP,AGC的动态范围不小于20dB。

(2)进一步提高AGC电路的动态范围,优化响应时间和幅度稳定度。

(3)其他功能,自由发挥二、实现原理和结果分析1.利用按键开关实现手动控制。

原理:先将DDS源发生的信号送入AD转换,转换后的值乘以增益k,然后输出到DA转换,最后用示波器显示。

原始信号频率为100k,根据奈奎斯特采样定理fs至少为200k才能保证恢复原始信号。

当然采样频率越高越好,(频率很高时,单周期内的样点数较多,不用插值恢复即可得到完美的波形)由于AD/DA芯片支持最高20M的采样率,这里我们采用12M的采样率,直接用系统48M时钟4分频得到,免去设计复杂的非整数分频的分频器。

得到8位采样数据后,应用寄存器将其保存。

同时将8位按键开关的输入值用寄存器保存。

将二者相乘输出到10位DA转换。

这里应当注意考虑溢出和可调节范围(即动态增益)的问题。

通过推算,参考电压Vref是4v,要求输入峰峰值电压Vpp是2v代码中,如下代码较为合适,兼顾增益和调节范围。

assign da_out=ad_reg_in*reg_key/16;实验结果:成功实现256梯度调节,但是调节过程较麻烦,而且不能做到连续调节。

下面讨论改进方案。

2. 利用旋钮实现连续控制看到实验板上有个旋钮,于是考虑用旋钮实现手动调节,更加方便实用。

其实该旋钮也是8位采样的AD,所以理论上可调精度与上述方法一样,但操作方便了许多。

涉及到TLC549的控制,该芯片是8位串行的AD 转换器,要用到有限状态机的编程,所以复杂度一下提高了很多。

(还好比赛前有学习准备,不然根本不可能做出来。

)串行的要一位一位的读入,每读入一位整体要向高位进1(左移1位),8位全部读完后方可读数。

芯片手册中要求采样时钟不要超过1.1M。

下简述实现原理,将48M时钟64分频得到0.75M,并以此时钟驱动一个5位状态计数器ctrl_cnt,另其中if ( ctrl_cnt == 5'd6 || ctrl_cnt == 5'd8 || ctrl_cnt == 5'd10|| ctrl_cnt == 5'd12 || ctrl_cnt == 5'd14 || ctrl_cnt == 5'd16|| ctrl_cnt == 5'd18 || ctrl_cnt == 5'd20 )时去读入一位数,频率为1.5M,满足芯片要求。

在ctrl_cnt==23时,8位数已满,刷出全部8位数。

考虑为芯片的准备时间,在1<ctrl_cnt<25时禁止读数(指采样结果8位数),其余时间可读。

其它部分与方案一中的实现相同,详见代码。

实验结果:成功实现手动连续调节,较容易将输出值调节到规定数值。

3. 自动增益控制原理:利用简单的反馈调节机制,也叫PID调节实现。

获取输出信号(一个周期内)的最大值,将其与目标值比较,若大于目标值,则减小增益系数k;若小于目标值,则增大增益系数k。

○0获得最大值用比较法,如if(Vmax<Vin) Vmax=Vin;○1获得最大值时必须获得单周期的最大值,否则只能单向增大的时才会将其调小,反之不行。

考虑采样频率12M和信号频率100k,可用7位计数器count,在1-120间累加,当值为120时计数器count置1同时根据Vmax与目标值的大小调节增益K,同时将Vmax置为中值(否则下一周期比较时当最大值小于当前值时将不会改变)。

置为中值的原因是,可以置为零值,但响应会变慢,由于半偏置电压的存在,在极端情况下(零输入)的值恰好为中值。

○3下面讨论溢出和偏置的影响:输入中值在128,输出中值在512,原始解决方法assign da_out=512+((ad_reg_in-128))*k;//当k值为4时恰好匹配到输出,这样随着k值得波动输出波形的波动很大,不稳定。

assign da_out=512+((ad_reg_in-128))*k/10; 当k值为40时恰好匹配到输出,这样随着k值得波动输出波形的波动不会很大,改善输出波形稳定度。

三、实验总结1.比赛的题目基本完成,并且利用了旋钮手动调节增益和功能自动增益控制,动态调节范围达到30dB。

经过本次比赛,我们充分熟悉了利用Verilog在FPGA开发的基本使用方法。

这更激励我们在将来的生活学习中,多动脑多动手,收获更多的知识果实。

2.在比赛过程中通过在线调试工具Signaltap查看各总线信号的值,为比赛的分析和参数选择提供了理论依据,这是个对信号进行捕捉观察的有力工具,无疑是顺利完成比赛的有力保证。

3.由于系统自学过Verilog语言,所以在比赛中利用语言实现要求有很大的优势,很轻松的完成一些比如乘法器,比较器,有限状态机等利用传统逻辑器件很难搭建的RTL。

但是语言利用不当也会造成致命的错误,很难发现,比如有符号数,无符号数,没有小数,溢出等问题,必须根据器件的特性来编写代码。

最后,感谢大赛的举办方和承办方,是你们的辛勤付出才给了我们这次体验学习的机会。

匡鑫2015年5月17日星期日五、实验源码1.按键调节module AGC1(input clk,input[7:0] ad_in,input[7:0] key_in,output ad_en,output ad_clk,output da_clk,output da_mode,output[9:0] da_out);/////////////////////////////////////////////////reg[7:0]ad_reg_in;reg clk_12M;reg[1:0] count4;reg[7:0] reg_key;////////////////////////////////////////////////assign ad_en=1'b0;assign da_out=ad_reg_in*reg_key/16;assign ad_clk=clk_12M;assign da_clk=clk_12M;assign da_mode=0;always@(key_in)beginreg_key<=key_in;endalways@(posedge clk)beginclk_1M<=(count4<4/2)?1'b1:1'b0;if(count4==4-1)//clock 12Mcount4<=0;elsecount4<=count4+1;endalways@(posedge clk_12M)beginad_reg_in<=ad_in;endendmodule2.旋钮调节module AGC(input clk,input [7:0] ad_in,input ad_ctl_in,output ad_en,output ad_clk,output da_clk,output da_mode,output[9:0] da_out,output ad_ctl_cs,output ad_ctl_clk,output[7:0] ad_ctl_out);/////////////////////////////////////////////////////// reg[7:0]ad_reg_in;reg clk_1M;reg[5:0] count4;///////////////////////////////////////////////////////assign ad_en=1'b0;assign da_out=ad_reg_in*ad_ctl_out/32;assign ad_clk=clk_1M;assign da_clk=clk_1M;assign da_mode=0;/////////////////////////////////////////////////////////调用旋钮AD输入模块ad_ctl ad(//input.sys_clk(clk), //system clock;系统时钟.sys_rst_n(1), //system reset, low is active;复位.AD_IO_DATA(ad_ctl_in), //输入的串行信号//output.AD_IO_CLK(ad_ctl_clk), //采样时钟.AD_CS(ad_ctl_cs), //ad片选.AD_out(ad_ctl_out) //ad采样输出);//4分频always@(posedge clk)beginclk_12M<=(count48<4/2)?1'b1:1'b0;if(count4==4-1)count4<=0;elsecount4<=count4+1;endalways@(posedge clk_12M)beginad_reg_in<=ad_in;endendmodule3. 旋钮AD采样模块module ad_ctl (//inputinput sys_clk , //system clock;系统时钟input sys_rst_n , //system reset, low is active;复位input AD_IO_DATA , //输入的串行信号//outputoutput reg AD_IO_CLK , //采样时钟output reg AD_CS , //ad片选output reg [7:0] AD_out);//Reg definereg [6:0] div_cnt ;//分频计数reg ad_clk ;reg [4:0] ctrl_cnt ;reg [7:0] ad_data_shift ;// counter used for div osc clk to ad ctrl clk 50M/64 = 0.78Mhzalways @(posedge sys_clk or negedge sys_rst_n) beginif (sys_rst_n ==1'b0)div_cnt <= 6'b0;elsediv_cnt <= div_cnt + 6'b1;end//gen ad_clkalways @(posedge sys_clk or negedge sys_rst_n) beginif (sys_rst_n ==1'b0)ad_clk <= 1'b0 ;else if ( div_cnt <= 6'd31 )ad_clk <= 1'b1 ;elsead_clk <= 1'b0 ;end// ad ctrl signal gen// ctrl_cnt 0 - 32is for ad ctrlalways @(posedge ad_clk or negedge sys_rst_n) beginif (sys_rst_n ==1'b0)ctrl_cnt <= 5'b0;elsectrl_cnt <= ctrl_cnt + 5'b1;endalways @(posedge ad_clk or negedge sys_rst_n) beginif (sys_rst_n ==1'b0)AD_IO_CLK <= 1'b0;else if ( ctrl_cnt == 5'd6 || ctrl_cnt == 5'd8 || ctrl_cnt == 5'd10 || ctrl_cnt == 5'd12 || ctrl_cnt == 5'd14 || ctrl_cnt == 5'd16|| ctrl_cnt == 5'd18 || ctrl_cnt == 5'd20 ) // ad clk low AD_IO_CLK <= 1'b1;elseAD_IO_CLK <= 1'b0;endalways @(posedge ad_clk or negedge sys_rst_n) beginif (sys_rst_n ==1'b0)AD_CS <= 1'b1;else if ( ctrl_cnt >= 5'd1 && ctrl_cnt <= 5'd25 ) // ad output csAD_CS <= 1'b0;elseAD_CS <= 1'b1;end// shift AD return analog DATA to ad_data_shift reg use AD_IO_CLK rising edge always @(posedge ad_clk or negedge sys_rst_n) beginif (sys_rst_n ==1'b0)ad_data_shift <= 8'b0;else if ( AD_CS == 1'b1 )ad_data_shift <= 8'b0;else if ( AD_IO_CLK == 1'b1 )ad_data_shift <= { ad_data_shift[6:0], AD_IO_DATA } ;else ;end//display AD sample data to AD_out when ad_data_shift is constanctalways @(posedge ad_clk or negedge sys_rst_n) beginif (sys_rst_n ==1'b0)AD_out <= 8'b0;else if ( ctrl_cnt == 5'd23 )AD_out <= ad_data_shift ;else ;endendmodule4.自动增益控制module AGC2(input clk,input[7:0] ad_in,output ad_en,output ad_clk,output da_clk,output da_mode,output[9:0] da_out);///////////////////////////////////////////////// reg[7:0]ad_reg_in;reg clk_1M;reg[5:0] count48;reg[9:0] reg_vmax;reg[8:0] k=100;reg[7:0] count;wire[9:0] ccc;//////////////////////////////////////////////// //assign k=16;assign ad_en=1'b0;assign da_out=512+((ad_reg_in-128))*k;//assign da_out=512+((ad_reg_in-128))*k;assign ad_clk=clk_1M;assign da_clk=clk_1M;assign da_mode=0;always@(posedge clk)beginclk_1M<=(count48<4/2)?1'b1:1'b0;if(count48==4-1)//clock 12Mcount48<=0;elsecount48<=count48+1;endalways@(posedge clk_1M)beginad_reg_in<=ad_in;endalways@(posedge clk_1M)begincount<=count+1'b1;if(reg_vmax<da_out)reg_vmax<=da_out;if(count>=120)begincount<=8'h00;if(reg_vmax<540)k<=k+1;if(reg_vmax>540)k<=k-1;reg_vmax<=512;endendendmodule。

相关主题