6
``///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2012/5/24 今天完成ad转换verilog程序编写。选用的ad利器是tlc549。 8bit串行ad转换器,最大转换时间17us。 除了写ad的读写控制程序,还写了tlc549的简化虚拟模型,modelsim下仿真无误。
仿真结果
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/5/25
今天完成ad读入的数据转换为电压值。
Vo=Vref * data/255, 这是计算ad转换电压公式,Vref取5v。
本打算用除法器ip实现计算的,仔细一想,其实用移位运算就可以了,"/255" 约等于 ">>8",这个误差很小,可以忽略,结算结果取一位小数,由于移位运算只能取整,所以将计算结果x10,得到小数后一位。综上,计算公式为 V =data*50/256。
再将乘除运算变换为移位运算即可。
temp = (temp <<5) + (temp <<4) + (temp<<1); //dividend *5*10
quo
tient = temp >>8; // dividend *5*10 / 256, 计算ad转换电压,x10得到小数点后一位
仿真结果
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/5/30
今天完成LCD显示模块程序编写。
LCD采用1602,双行显示,第一行是功率密度,单位uw/cm2,显示宽度4位;第二行是场强,单位v/m,显示宽度3位。
开发板上测试通过,数据是自定义的。原理和verilog程序见附件。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/6/19
终于考完试了,得赶紧做完了,还有很多事没完成。
今天完成功率密度的计算程序。s = E^2 /3.77。
其中E^2的计算采用乘法器IP。
1.设置A,B端口属性。
2.选择使用专用乘法器实现该乘法器。
FPGA内嵌了18x18的专用乘法器,使用它可以节约LUT资源的使用。
3.设置输出端,流水线级数,和控制信号等属性。
4.该乘法器端口说明,其中的CE,SCLR可选。
5.在程序中调用乘法器实例。
multiply YourInstanceName (
.clk(clk),
.a(a), // Bus [7 : 0]
.b(b), // Bus [7 : 0]
.p(p)); // Bus [15 : 0]
这是配置好IP后自动生成的乘法器实例,只需要在程序中调用即可。
/3.77的计算
常数除法似乎不太好实现,当然可以用除法器IP来做,但是感觉有点浪费和麻烦,找了一下ip只发现乘法器有常数乘法的,没找到常数除法ip,考虑到这个辐射测量仪并不需高精度,一定的误差是容许的。所以采用近似计算实现/3.77.
1/32 - 1/256 - 1/1024 = 0.0263
1/37.7 = 0.0265
故 E^2/3.77 = E^2 *10 /37.7 ≈ E^2 *10 *(1/32 - 1/256 - 1/1024),这样就可以用移位运算来实现了。
/////////////////////////////verilog //////////////////////////
module calculate(
input clk,
input [7:0] e,
output reg[11:0] s
);
wire [15:0] p;
reg [15:0] temp;
multiply mul( //调用乘法器
.clk(clk),
.a(e),
.b(e),
.p(p));
always @(p)
begin
temp = (p<<3) + (p<<1); //E^2 * 10
temp = (temp>>5) - (temp>>8) - (temp >>10); //E^2 *10*(1/32 - 1/256 - 1/1024)
s = temp[11:0];
end
endmodule
仿真结果
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/6/22
xilinx fpga全局时钟的使用
时钟是系统的动力源,时钟偏移、抖动等问题都会影响时钟质量,对系统造成影响。全局时钟是解决时钟问题的最好方案。
xilinx fpga全局时钟采用全铜工艺,并设计了专用时钟缓冲与驱动结构,可到达芯片内部任何一个逻辑单元,且延时和抖动最小。最好的时钟方案是由专用时钟输入管脚驱动单个全局时钟,并用后者去控制设计中的每个触发器。
全局时钟的使用需要调用原语。具体可查看ise帮助文档。本设计中用到了IBUFG和BUFG。IBUFG是输入全局缓冲,是与专用全局时钟输入管脚相连接的首级全局缓冲。BUFG是全局缓冲,他的输入可以是IBUFG的输出,也可以是内部的逻辑信号。BUFG的输出到达fpga内部CLB、IOB、BRAM的抖动和延时最小,而且其扇出大,可用于驱动大扇出的信号。
1、IBUFG+BUFG的使用
IBUFG clk_ibufg(
.I(clk),
.O(clk_ibuf)
);
BUFG clk_bufg(
.I(clk_ibuf),
.O(clk_buf)
);
//外部时钟—>IBUFG—>BUFG
2、LOGIC+BUFG的使用
BUFG clk2m(
.I(clk_2m),
.O(clk_2m_buf)
);
//内部2m时钟—>BUFG
BUFG clk100(
.I(clk_100hz),
.O(clk_100hz_buf)
);
//内部100hz时钟—>BUFG
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/6/24
二进制转BCD码
上述的计算得到场强E和功率密度S都是二进制的,为了能让LCD显示,需要转换成BCD码。原理和代码请看附件。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/6/25
开始做硬件部分了,fpga使用的一个s3c500e的开发板,还需要几个外围模块。
电源模块:利用两个稳压管产生±5V的电压。
AD转换模块:TLC549串行adc。
滤波模块:有源低通滤波。
放大模块:第一级采用共模抑制比高、线性度好、低功耗运算放大器AD620,第二级采用高精度、低失调电压型的运放OP07。这两级的放大能满足低噪放大器的噪声系数要求,频带要宽的要求。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/6/30
异步FIFO
AD转换模块的速度远大于LCD显示模块,两者的速度不匹配,不能将AD转换后的数据直接送到LCD模块显示,可以在两者之间加入FIFO模块,起到缓冲的作用。异步FIFO是一种先进先出
电路,使用在需要产生数据接口的部分,用来存储、缓冲在两个异步时钟之间的数据传输。FIFO是常用模块,所以ise中有对应ip可以调用。
1.
2.选择读写独立时钟
3.设置读写数据宽度和深度
4.标志位选择
5.复位方式选择
6.读写数据计数器选择
7.完成
fifo YourInstanceName (
.rst(rst), //复位
.wr_clk(wr_clk), //写时钟
.rd_clk(rd_clk), //读时钟
.din(din), // Bus [27 : 0],要写入的数据
.wr_en(wr_en), //写使能
.rd_en(rd_en), //读使能
.dout(dout), // Bus [27 : 0],读出的数据
.full(full), //满标志
.empty(empty)); //空标志
配置完后生成如上的模板,调用即可。以下是我调用的实例。
fifo fifo_inst(
.rst(~rst_n),
.wr_clk(~cs_n), //观察tlc549的仿真模型可以发现,cs_n的上升沿时输出并行数据 ,故选择cs_n的下降沿作为写时钟
.rd_clk(clk_10hz_buf),
.din({E,S}), // Bus [27 : 0] ,将场强和功率密度数据合并
.wr_en(~full), //以满标志作为写使能信号,满时~full = 0,禁止写
.rd_en(~empty), //以读标志作为读使能信号,空时~empty = 0,禁止读
.dout({E_buf,S_buf}), // Bus [27 : 0]
.full(full),
.empty(empty)
);
//////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/7/2
天线的选择
刚开始时,打算用收音机上的那种拉杆天线。后来想起曾在网上看到高频二极管也有类似的功能,电磁场能在二极管中产生电压。于是用面包板,若干1N60二极管,万用表来测试。将二极管串联,然后万用表接两端,调到直流20v档。将拨号中的
手机靠近二极管,万用表示数开始不断变化,最大时能达到3、4V,能点亮一个led了。然后在笔记本上试了试,发现触控板上方的辐射最强,能产生大约200mv。等焊接好了再上图。
利用9只1N60串联,代替天线。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/7/7
时钟生成模块
整个系统中会用到多个时钟,故在一个模块中生成这些时钟。
clk_gen clock( //时钟生成模块
.clk(clk_buf), //生成ad和lcd所需时钟
.rst_n(rst_n),
.clk_2m(clk_2m),
.clk_100hz(clk_100hz),
.clk_10hz(clk_10hz)
);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/7/9
modelsim调试之do文件
用modelsim做仿真,每次修改代码后都需要重新添加信号,并设置信号数据格式,如果信号比较多,工作量很大,很麻烦。do文件很好的解决了这个问题,一个do文件其实是一个tcl脚本,相当于把命令都集合到一块了,只要输入命令do do文件即可执行。具体可参考这个链接。
vsim -voptargs=+acc work.test
add wave -dec sim:/test/data1
add wave -dec sim:/test/data2
add wave -dec sim:/test/dataout
add wave -bin sim:/test/clk
add wave -bin sim:/test/clr
run 1us
这是我的一个do文件,第一行是对test.v执行仿真,下面是添加模块中的信号,-dec -bin表示十进制,二进制。具体语法可查阅help文件。如果对do文件不太熟悉,可以在gui模式下运行仿真,添加信号,在transcript中会生成对应的命令,把这些命令都包装到一个do文件中,运行do就行。这样,修改源程序后,只有运行一个do文件就可以了,很方便。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/7/10
滤波放大部分的电路
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/7/11
以上分别是顶层模块和内部结构图。各个子模块在上面已经介绍过了。
现在的工作就是调试。fifo的读写时钟很关键,直接决定数据的正确写入和lcd显示的效果。写时钟采用tlc549的cs信号,fpga每次从tlc549读入采样数据都要拉低cs,读完之后释放cs,所以可以使用cs的下降沿来当做fifo写时钟。lcd的时钟为100hz,根据lcd的状态转移可以推算fifo的读时钟约为lcd时钟的1/20,可以选用5hz作为读时钟。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2012/7/14
视频:
http://v.youku.com/v_show/id_XNDI3NDI3NTE2.html
源码及文档:
总结一下吧,总的来说整个过程还是比较顺利的,就是硬件部分调试的时候出现了问题,好几天都找不到原因,最后通过修改电路解决问题。这次比赛的方案选的不太好,fpga用来做计算处理实在没有用
单片机来的方便。回过头来想想,其实自己从接触fpga开始到现在学的做的一些东西都可以用单片机、arm来实现。一次在qq群里和高人交流时知道fpga还有高速数据传输的功能。才发现自己学到的实在太少太少了。那时连LVDS是什么都不知道。一开始学fpga,主要是看书上的一些实例,然后用开发板自己动手实践。现在更关注fpga的内部结构,硬着头皮看上百页的英文收据手册。虽然有很多不懂,但还是看下去。总有一天会搞明白的。不看就永远都不会明白。
``
|
评分
-
查看全部评分
|