FPGA中用定制ROM产生正弦信号
- 格式:pdf
- 大小:1.60 MB
- 文档页数:8
基于LPM_ROM 的正弦信号发生器如图1所示的正弦信号发生器的结构由4部分组成。
1、计数器或地址发生器(6位)2、正弦信号ROM (6位地址线,8为数据线),含64个8位数据(一个周期)。
3、VHDL 顶层设计。
4、8位D/A 。
顶层文件singt.vhd 在FPGA 中实现,包含两个部分:ROM 的地址信号发生器,由6位计数器担任;一个正弦数据ROM ,由LPM_ROM 模块构成。
地址发生器的时钟CLK 的输入频率f 0与每周期的波形数据点数(在此选择64点),以及D/A 输出的频率f 的关系是:f=f 0/64图1. 正弦信号发生器结构框图内容步骤1、定制LPM_ROM 初始化数据文件(建立.mif 格式文件)首先确定图1中ROM 内的波形数据文件。
Quartus II 可接受memory initialization file (.mif)格式的LPM_ROM 初始化数据文件。
选择菜单file —>new 命令,单击other files 标签,选择memory initialization file 项,产生ROM 数据文件大小选择窗。
根据64点8位正弦数据的情况,选择ROM 的数据数为64,数据宽取8位。
单击OK 出现空的mif 数据表格,然后将波形数据填入表格中(如图2)。
完成后,以romd.mif 文件名保存。
图2. 波形数据填入mif 文件表中2、定制LPM_ROM 文件在设计正弦信号发生器前,必须首先完成存放波形数据ROM 的设计。
利用megawizard plug-in manager 定制正弦信号数据ROM 宏功能块,并将上面的波形数据加载于此ROM 中。
波形输出选择菜单tools—>megawizard plug-in manager命令,在出现的对话框中选择create a new custom,单击next,产生图3所示对话框,如图设置图3. LPM宏功能模块设定在左栏选择memory compiler项下的ROM:1-PORT,再选择器件和VHDL语言方式,输入ROM文件存放的路径和文件名。
使用FPGA产生正弦波看不懂可以加QQ1371947821 使用matlab产生正弦波的.mif的rom表工程中,经常要用到正弦表数据。
把正弦表数据存入mif文件中,供LPM_ROM初始化用,那么如何得到正弦表数据呢?可以用matlab 实现这里介绍两种方式:(一)这个方法只在matlab中生成数据表,需要自己手动的往mif文件中添加数据1.假设用到的DA芯片为14为,则2^14=163842.一个完整的正弦波为0-2pi3.正弦波ROM的深度为4096(地址总数)4.由于FPGA中不识别负数,加入一个直流分量,加8192则用matlab产生正弦表的函数为:Y=ceil((16384/2-1)*sin(0:pi*2/4096:2*pi)+8192)其中ceil函数描述如下:ceil(x) : 大于x 的最小整数>> ceil( [3.12 -3.12])ans =4 -3(二)可以直接生成mif文件直接生成mif文件depth = 4096;width =14;x=ceil(16384/2*sin(0:pi*2/4096:2*pi)+8192)fid = fopen('d:\romdata1.mif','w');%路径fprintf(fid,'depth= %d ;\n',depth);fprintf(fid,'width= %d ;\n',width);fprintf(fid,'address_radix=uns;\n');fprintf(fid,'data_radix = uns;\n');fprintf(fid,'Content Begin \n');for(k=1:depth)fprintf(fid,'%d: %d ;\n',k-1,x(k));endfprintf(fid,'end;');用上面这段程序最大值会出现16384,在Quartus II中会认为是超出数据范围,所以需要手动的改写为16383把x=ceil(16384/2*sin(0:pi*2/4096:2*pi)+8192)改写为下面语句x=ceil((16384/2-1)*sin(0:pi*2/4096:2*pi)+8192) 就不存在上述问题了数据量小的话,可以用第一种方法,要是数据量大的话,介意用第二种方法。
定制LPM_ROM设计简单的正弦信号发生器
实验名称:利用定制好的LPM_ROM设计简单的正弦信号发生器。
实验过程:
1:LPM_ROM的定制
图1 调用LPM_ROM
图2 LPM_ROM的参数设置
图3 加入初始化文件配置
2:LPM_ROM的仿真测试
图4 LPM_ROM仿真测试
3:波形分析
由图4可以看出,随着CLK的上升沿的出现,对应地址A的数据输出与初始化文件的数据完全吻合,实验得证。
再利用次模块完成一个简单的正弦信号发生器设计,该模块可以用来作为地址信号发生器(7位输出)和数据存储器(7位地址线,8位数据线),含有128个8位波形数据(一个正弦波形周期)。
4:正弦信号发生器的VHDL顶层设计
包括了对定制LPM_ROM时文件模块ROM78的例化调用。
图5 正弦信号发生器的VHDL描述
图6正弦信号发生器的仿真波形输出
5:波形分析
随着每个时钟上升沿的到来,输出端口将正弦波数据依次输出。
输出的数据与初始化配置文件相符。
6:观察RTL图
图7 正弦信号发生器的RTL电路图
分析:其中左边三个元件:加法器,寄存器构成7位计数器:其输出接右边ROM的地址输入端。
输出可接FPGA外的DAC,完成正弦波形输出。
实验结论:作为数据和程序的存储单位,ROM还有很多其他用处,如数字信号发生器的波形数据存储器,正弦信号发生器等。
现代电子设计实验报告实验名称:正弦波信号发生器设计系(科):信息科学与技术系班级:180932学号:姓名:完成时间:2012年5月6日一、实验内容设计要求1.设计一正弦信号发生器,采用ROM进行一个周期数据存储,并通过地址发生器产生正弦信号。
2.正弦信号六位地址数据128,140,153,165,177,188,199,209,219,227,235,241,246,250,253,255,255,254,252,248,244,238,231,223,214,204,194,183,171,159,147,134,121,109,96,84,72,61,51,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,46,56,67,78,0,102,115,1273.说明:——地址6位;——ROM:6位地址8位数据;要求使用两种方法:VHDL编程和LPM。
——原理图完成顶层设计;——仿真;——下载到FPGA实验箱中,用示波器观察产生的波形;二、实验原理通过计数器设置地址发生器产生正弦波信号并用ROM进行一个周期数据存储。
三、设计方案地址发生器正弦波数据存储ROM8位D/AFPGA 四、原理图五、模块设计(一)地址发生器1.设计原理设计原理同计数器,(时钟信号为上升沿且为有效的计数状态时,加一循环计数。
)把计数器的计数范围设置为0-63即可。
2.VHDL程序代码library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity count isport(clk1000: in std_logic;q: out integer range 0 to 63);end count;architecture a of count isbeginprocess (clk1000)variable temp:integer range 0 to 63;beginif(clk1000'event and clk1000 = '1') thenif(temp=63) thentemp := 0;elsetemp := temp + 1;end if;end if;q <= temp;end process;end a;(二)只读存储器ROM1.设计原理为每一个存储单元编写一个地址,只有地址指定的存储单元才能与公共的I/O相连,然后进行存储数据的读写操作。
题目名称:基于FPGA的正弦信号发生器班级:姓名:学号:日期:2012/07/06基于FPGA 的正弦信号发生器设计1.1 引言直接数字频率合成(Digital Direct Frequency Synthesis)是一种比较新颖的频率合成方法。
这个理论早在20世纪70年代就被提出,它的基本原理就是利用采样定理,通过查表法产生波形。
1.2 方案比较与确定设计要求:利用EDA 技术,建立正弦信号DDS 产生模型,编写源程序,达到频率输出范围1KHz-10MHz 、频率步进100Hz 、频率稳定度优于104-、带50Ω负载输出电压峰峰值大于1V 等要求,完成硬件实现与测试。
【方案一】 采用分立元件模拟直接合成法。
这种方法转换速度快,频率分辨率高,但其转换量程靠手动来实现,不仅体积大难以集成,而且可靠性和准确度很难进一步提高。
【方案二】 采用MAX038芯片来产生正弦波信号。
该集成块的输出波形种类多,频率覆盖范围广。
它采用的是RC 充放电振荡结构。
第一,由于模拟器件元件分散性太大,外接的电阻、电容对参数的影响很大,因而产生的频率稳定度差,只能达到431010---。
第二,它的频率控制是通过充放电流的大小来实现。
因而要达到步进100HZ ,所需的电流变化量非常小,精度要求很高。
所以采用MAX038芯片难以实现设计要求。
【方案三】 采用锁相环合成方法。
采用该方案设计输出信号的频率可达到超高频甚至微波段,且输出信号频谱纯度较高。
由于锁相环技术是一个不间断的负反馈控制过程,所以该系统输出的正弦信号频率可以维持在一个稳定状态,频率稳定度高。
但由于它是采取闭环控制的,系统的输出频率改变后,重新达到稳定的时间也比较长。
所以锁相环频率合成器要想同时得到较高的频率分辨率和转换率非常困难,频率转换一般要几毫秒的时间[1],同时频率间隔也不可能做得很小。
【方案四】 采用直接数字合成器(DDS ),可用硬件或软件实现。
即用累加器按频率要求对相应的相位增量进行累加,再以累加相位值作为地址码,取存放于ROM 中的波形数据,经D/A 转换,滤波即得到所需波形。
用FPGA产生正弦信号上一篇/ 下一篇2013-12-23 23:45:42 / 个人分类:设计心得查看( 2015 ) / 评论( 0 ) / 评分( 0 / 0 )正弦信号,是一个模拟信号。
而FPGA只能产生数字信号。
因此需要用DA将数字量转化为模拟量。
这里采用modelsim的模拟波形显示,就不需要DA模块了。
产生正弦信号的方法有很多,这里用的是查找rom的方法,产生正弦信号。
正弦信号,是一个介于-1和1之间的模拟量。
而正弦信号是周期变化的,因此这里只需要将半个正弦信号周期的值存进rom里,其余周期可以根据这个半个周期的值变化可得到。
用matlab产生正弦信号的值。
以0.01为步长,从0采集到pi/2。
共158个点。
因此sin的值是小数,而FPGA是不能表示小数的,因此需要将小数扩大,以整数来表示。
此次是以12位二进制来显示这整数。
扩大的方法就是乘以2^12即可了。
12位二进制数最大能表示2^12-1的值。
这里用0表示最小值0,2^12-1表示最大值1.则0到1中间的数,就可以扩大到用0到2^12-1中间的数来表示了。
例如,0.3,就可用整数0.3*2^12=1228.8,在向上取整,为1228.当然这样表示会有误差。
这里rom用的是ISE的IP rom。
将matlab生成的数据放进rom里面。
然后依次读取rom的值,即可生成正弦信号了。
首先是生成rom的初始化文件。
Xilinx的rom的初始化文件的后缀为.coe。
而这个特殊文件有固定的格式。
第一行的10表示下面的数字是10进制的。
后面的数据是依次存入rom的值,以逗号分开,最后一个以分号结束。
前面两行的内容是固定的。
生成初始化文件的matlab如下所示:fid = fopen('sin_rom.txt','w');fprintf(fid,'MEMORY_INITIALIZATION_RADIX = 10;\n');fprintf(fid,'MEMORY_INITIALIZATION_VECTOR =\n');for i = 0:1:pi/2*100y = sin(i/100);rom =floor( y * 2^12);if i == 157fprintf(fid,'%d;',rom);elsefprintf(fid,'%d,',rom);endif mod(i,10)==0 && i ~= 0fprintf(fid,'\n');endendfclose(fid);生成的文件是.txt文件。
基于ROM的正弦波发生器的设计设计基于ROM的正弦波发生器,对其编译,仿真。
具体要求:1.正弦发生器由波形数据存储模块(ROM),波形发生器控制模块及锁存模块组成2.波形数据存储模块(ROM)定制数据宽度为8,地址宽度为6,可存储 64点正弦波形数据,用MATLAB求出波形数据。
3.将50MHz作为输入时钟。
1.设计的框图如下所示:图1.设计框图2.简述设计步骤和调试过程首先是实验matlab获得需要的数据,代码如下:y=zeros(65,1);step=(2*pi/64);for n=0:64y(n+1)=(255/2)*(1+sin(step*n));end设计的VHDL代码如下:---------------------------------------------------------LIBRARY ieee;USE ieee.std_logic_1164.all;USE ieee.std_logic_arith.all;---------------------------------------------------------entity rom isgeneric ( counter:integer:=16777216);port(clk:in std_logic;data:out std_logic_vector(15 downto 0));end rom;---------------------------------------------------------architecture sinrom of rom istype vector_array is array(0 to 63)ofstd_logic_vector(7 downto 0);signal COUNT : INTEGER RANGE 0 TO counter;-- 16777216 signal data0:std_logic_vector(7 downto 0);signal data1:std_logic_vector(7 downto 0);signal addr0:integer range 0 to 63:=0;-------------------------------------------------------------Constant memory: vector_array:=(conv_std_logic_vector(128,8),conv_std_logic_vector(140,8),conv_std_logic_vector(152,8), conv_std_logic_vector(165,8),conv_std_logic_vector(176,8), conv_std_logic_vector(188,8),conv_std_logic_vector(198,8), conv_std_logic_vector(208,8),conv_std_logic_vector(218,8), conv_std_logic_vector(226,8),conv_std_logic_vector(234,8), conv_std_logic_vector(240,8),conv_std_logic_vector(245,8), conv_std_logic_vector(250,8),conv_std_logic_vector(253,8), conv_std_logic_vector(254,8),conv_std_logic_vector(255,8), conv_std_logic_vector(254,8),conv_std_logic_vector(253,8), conv_std_logic_vector(250,8),conv_std_logic_vector(245,8), conv_std_logic_vector(240,8),conv_std_logic_vector(234,8), conv_std_logic_vector(226,8),conv_std_logic_vector(218,8), conv_std_logic_vector(208,8),conv_std_logic_vector(198,8), conv_std_logic_vector(188,8),conv_std_logic_vector(176,8), conv_std_logic_vector(165,8),conv_std_logic_vector(152,8), conv_std_logic_vector(140,8),conv_std_logic_vector(128,8), conv_std_logic_vector(115,8),conv_std_logic_vector(103,8), conv_std_logic_vector(90,8), conv_std_logic_vector(79,8), conv_std_logic_vector(67,8), conv_std_logic_vector(57,8), conv_std_logic_vector(47,8),conv_std_logic_vector(37,8),conv_std_logic_vector(29,8), conv_std_logic_vector(21,8), conv_std_logic_vector(15,8), conv_std_logic_vector(10,8), conv_std_logic_vector(5,8), conv_std_logic_vector(2,8),conv_std_logic_vector(1,8),conv_std_logic_vector(0,8),conv_std_logic_vector(1,8), conv_std_logic_vector(2,8),conv_std_logic_vector(5,8), conv_std_logic_vector(10,8),conv_std_logic_vector(15,8), conv_std_logic_vector(21,8), conv_std_logic_vector(29,8),conv_std_logic_vector(37,8),conv_std_logic_vector(47,8), conv_std_logic_vector(57,8), conv_std_logic_vector(67,8), conv_std_logic_vector(79,8), conv_std_logic_vector(90,8), conv_std_logic_vector(103,8), conv_std_logic_vector(115,8));BEGINdata0<=memory(addr0);data1<="0000"&data0(7 downto 4);------------------------------------------------------------- PROCESS (clk)BEGINIF(clk'EVENT AND clk='1')THENCOUNT<=COUNT+1;if(COUNT=counter)thenaddr0<=addr0+1;end if;END IF;END PROCESS;------------------------------------------------------------ PROCESS (clk)BEGINcase data1(7 downto 0)iswhen"00000000"=>data<="0000000000000001";when"00000001"=>data<="0000000000000011";when"00000010"=>data<="0000000000000111";when"00000011"=>data<="0000000000001111";when"00000100"=>data<="0000000000011111";when"00000101"=>data<="0000000000111111";when"00000110"=>data<="0000000001111111";when"00000111"=>data<="0000000011111111";when"00001000"=>data<="0000000111111111";when"00001001"=>data<="0000001111111111";when"00001010"=>data<="0000011111111111";when"00001011"=>data<="0000111111111111";when"00001100"=>data<="0001111111111111";when"00001101"=>data<="0011111111111111";when"00001110"=>data<="0111111111111111";when"00001111"=>data<="1111111111111111";when others=>data<="0000000000000000"; end case;END PROCESS;-------------------------------------------------------------end sinrom;---------------------------------------------------------引脚功能定义文件:图2.引脚定义文件仿真图如下:(为了便于仿真,时钟的累加次数为counter= 4,不是16777216)图3.仿真图。
FPGA实现基于ROM的正弦波发生器软件环境:QuartusII 11.0操作系统:win7芯片型号:CycloneII EP2C5Q208C81.总体框图:1.波形数据第一步,是获得含有正弦波的数据的ROM初始化文件.mif,方法见《如何生成mif文件》;此处生成的波形数据为8bit宽度,128字节深度的数据。
2.利用Quartus的LPM功能,定制一个8bit数据宽度,128字节深度的ROM:详细步骤说明可以参考《FPGA实现RAM--LPM_RAM》,此处只给出具体配置,为避免冗余,不再详细说明各项含义。
3.顶层模块的verilog描述复制代码moduleSinGen(inputclk, /*clock input*/inputrst_n, /*async reset ,active low*/input en, /*enable control,active high*/output [7:0] q /*data output from ROM*/);/***********ROM instance**********************/wire [6:0] addr;ROM1P ROM1P_inst (.address ( addr ),.clock ( clk),.q ( q));/***************address generate***************/reg [6:0] cnt;always@(posedgeclk or negedgerst_n)beginif(!rst_n)cnt<= 7'd0;else if(en)cnt<= cnt+7'd1;elsecnt<=cnt;endassignaddr = cnt;endmodule复制代码4.波形仿真:分析:当使能端有效(en==1)时,在每个时钟的上升沿,输出ROM中的正弦波数据;5.波形实测将数据输出端接入到DAC后,可以接入示波器来观察波形;也可以使用QuartusII自带的SignalTap对数据输出端对Q进行采样,来查看波形;这里使用SignalTap捕获的波形如下:可以看到,数据的确是正弦波吧?使用同样的道理,只要有相应波形的数据,也就是存储器的初始化文件.mif,就可以发生三角波、方波、甚至任意波形!如果您感兴趣,可以添加按键扫描模块,来控制发生想要的波形,制作一台简易波形发生器。
定制ROM元件(DATAROM.VHD)利用MegaWizard Plug-In Manager定制正弦信号数据ROM步骤如下:1、设置MegaWizard Plug-In Manager初始对话框。
在Tools菜单中选择“MegaWizard Plug-In Manager”,产生图1-14的界面,选择“Create a new custom…”项,即定制一个新的模块。
点击“Next”后,产生图1-15对话框,在左栏选择“Storage”项下的LPM_ROM,再选“Cyclone”器件和VHDL语言方式,最后键入ROM文件存放的路径和文件名:e:\sin_gnt\asm\datarom.vhd,点击“Next”。
2、选择ROM控制线和地址、数据线。
在图1-16,17所示的对话框中选择地址与数据的位宽分别为6和8,选择地址所存控制信号inclock,并选择数据文件sind1.hex(图1-18,19)。
最后完成ROM文件DA TAROM.vhd的生成。
然后打开此文件DA TAROM.vhd,可以看到其中调用初始化数据的语句(图1-20):init_file => "SIND1.HEX" ,由于QartusII的原因,必须修改此路径为:init_file => "./asm/SIND1.hex" 如图1-20所示。
注意,与mif文件不同,hex文件必须放在当前工程的子目录中(这里的子目录是asm),而DA TAROM.vhd与顶层工程文件SINGT.VHD在同一文件夹中!且后缀hex必须小写!图1-16 选择DA TAROM模块数据线和地址线宽度图1-17选择地址所存信号inclock图1-18选择数据文件图1-19 调入ROM初始化数据文件图1-20 修改数据路径和后缀3、测试ROM模块。
由于此时QuartusII的工程设置在顶层文件(图1-3),现在启动全程编译:选择Processing菜单的“Start Compilation”项。
基于FPGA的正弦波信号发生器的设计题目名称:基于FPGA的正弦信号发生器班级:姓名:学号:日期:2012/07/06基于FPGA的正弦信号发生器设计1.1 引言直接数字频率合成(Digital Direct Frequency Synthesis)是一种比较新颖的频率合成方法。
这个理论早在20世纪70年代就被提出,它的基本原理就是利用采样定理,通过查表法产生波形。
1.2 方案比较与确定设计要求:利用EDA技术,建立正弦信号DDS 产生模型,编写源程序,达到频率输出范围1KHz-10MHz、频率步进100Hz、频率稳定度优于104-、带50Ω负载输出电压峰峰值大于1V等要求,完成硬件实现与测试。
【方案一】采用分立元件模拟直接合成法。
这种方法转换速度快,频率分辨率高,但其转换量程靠手动来实现,不仅体积大难以集成,而且可靠性和准确度很难进一步提高。
【方案二】采用MAX038芯片来产生正弦波信号。
该集成块的输出波形种类多,频率覆盖范围广。
它采用的是RC充放电振荡结构。
第一,由于模拟器件元件分散性太大,外接的电阻、电容对参数的影响很大,因而产生的频率稳定度差,只能达到4--。
第二,它的频率控制是通过充31010-放电流的大小来实现。
因而要达到步进100HZ,所需的电流变化量非常小,精度要求很高。
所以采用MAX038芯片难以实现设计要求。
【方案三】采用锁相环合成方法。
采用该方案设计输出信号的频率可达到超高频甚至微波段,且输出信号频谱纯度较高。
由于锁相环技术是一个不间断的负反馈控制过程,所以该系统输出的正弦信号频率可以维持在一个稳定状态,频率稳定度高。
但由于它是采取闭环控制的,系统的输出频率改变后,重新达到稳定的时间也比较长。
所以锁相环频率合成器要想同时得到较高的频率分辨率和转换率非常困难,频率转换一般要几毫秒的时间[1],同时频率间隔也不可能做得很小。
【方案四】采用直接数字合成器(DDS),可用硬件或软件实现。
FPGA中用定制ROM产生正弦信号
简介:
本文详细介绍了在fpga中定制ROM,以及用查表法产生正弦波的方法,并借助matlab加以验证。
编译软件用xilinx13.1.
1.借助matlab生成ISE中ROM的.coe文件。
在matlab工作区中输入以下代码。
fid = fopen('sin.txt','a');
str1='MEMORY_INITIALIZATION_RADIX=10;';
str2='MEMORY_INITIALIZATION_VECTOR=';
fprintf(fid,'\t%s\n\t%s\n',str1,str2);
for k=1:256;
y(k)=sin(2*pi*k/256);
y(k)=int8(y(k)*100);
fprintf(fid,'\t%4.0f\t%c\n',y(k),',');
end
fclose(fid);
在work文件夹下回生成一个sin.txt的文件,将其后缀改为coe,保存。
打开ISE。
2.在ISE中建立new project
添加新的verilog module文件,直接点next直到finish,verilog代码将在后面添加。
3.选中新添加的mysinrom.v点右键添加ip core。
点击next->finish
在弹出的窗口中选择ROM的属性:
选择sin.coe存放的路径,一直点next到finish。
在hierachy窗口可以看到新添加的sinrom。
双击view HDL Functional…可查看接口代码。
4.在mysinrom.v中输入如下代码:
5.双击Synthesize综合,在View RTL …中可查看综合后的结果。
顶层示意图以及内部模块连接
6.添加仿真文件: 选中simulation
右键点击sinrom 添加test.v
添加代码:
7.双击simulate behavioral model仿真
在弹出的isim窗口中点击restart->runall,一段时间后点击break
得到仿真结果,注意将douta的属性改为有符号数更方便观察。
在下方的console窗口可查看输出的结果:
这些值便是rom中的值,负数是以补码的形式存储的。
8.在matlab中验证:
将console窗口中的值复制出一个周期(256个值)。
粘贴到matlab工作区,当然要赋给某
个变量,设为x,只需在前后加中括号即可:
再输入:
for i=1:256
x(i)=compl_neg(x(i));
end
plot(x)
得到x曲线。
其中compl_neg(x)是将补码表示的数x转化成有符号数,其M函数的matlab代码:
function f=compl_neg(x);
if(x>32768)
y=de2bi(x,16);
k=1;
while y(k)==0
k=k+1;
end
n=k;
for k=1:16
if(k<=n)y(k)=y(k);
else y(k)=~y(k);
end
end
f=bi2de(y);
f=-f;
else f=x;
end%end if(x>32768)。