基于VHDL语言的波形发生器的设计

基于VHDL语言的波形发生器的设计
基于VHDL语言的波形发生器的设计

基于VHDL语言的波形发生器的设计

基于VHDL语言的波形发生器的设计

利用FPGA芯片信号发生器的设计。当按下开关1时产生三角波,当按下开关2时产生正弦波,当按下开关3时产生方波。本次设计采用xilinx公司的ISE 设计工具,在zedboard开发板中的xc7z020芯片上用VHDL来实现,并且利用ISE自带的chipscop完成对FPGA内部的信号的读取。这样的设计具有体积小,修改升级容易等特点。

本设计采用自顶向下、纯文本实现数字时钟的设计、下载和调试。

1 设计原理

本设计由信号产生,信号选择,信号控制输出三大模块组合而成。其中信号产生模块有:三角波模块、方波模块、正弦波模块。本设计采用K0~K2这三个按键为信号选择开关,选择信号产生模块输出的信号。(顶层设计的例化语句见附录一)其RTL图1-1:

RTL图1-1

2主要功能模块

u1:square方波产生模块;

u2:sin正弦波产生模块;

u3:delta三角波产生模块;

u4:sig_control数据选择器模块;

u5,u6:为使用chipscope所需生成的IP核。

2.1 u1方波产生模块(程序见附录二)

产生方波,初始化为幅值225的高电平,每有一次时钟上升沿触发产生一次计数,当计数值达到128时跳到为0的低电平。利用循环语句不断的产生高低电平的方波输出。原理如图2-1:

方波模块RTL 图2-1

2.2 u1正弦波产生模块(程序见附录三)

功能是产生正弦波,产用信号抽样的原理,在一个正弦信号中等间隔的抽样64点,此64点的幅值作为一个正弦波数据表,每有一次时钟上升沿触发便赋予输出端q一个点的数据,依次赋值64个点的数据便完成一个周期的正弦波的输出。并利用循环语句不断的产生正弦波的输出。原理如图2-2:

正弦波模块RTL 图2-2

2.3 u1三角波产生模块(程序见附录四)

功能是产生三角波,初始化为幅值为0,每有一次时钟上升沿触发便进行幅值加1,当幅值达到最大255时,每有一次时钟上升沿触发便进行幅值减1,当幅值减为0时完成一个周期的输出。利用循环语句不断的产生幅值为255的波形的输出。原理图如下:

三角波模块RTL 图2-3

2.3 u4数据选择器模块(见附录五)

利用数据选择器模块可以对三角波,正弦波,方波进行三选一得输出。当开关

d0拨通,d1,d2均闭合时q端输出的是三角波;

当开关d1拨通,d0,d2均闭合时q端输出的是方波;

当开关d2拨通,d0,d1均闭合时q端输出的是正弦波;

数据选择器模块RTL 图2-4

3 硬件测试

当程序下载到硬件之后,采用chipscope实现对FPGA内部信号的在线调试。在FPGA已经下载程序的情况下,添加我们关心的信号或者接口,将选定了端口Chipscope(不妨理解为一个嵌入的系统)加入到程序后重新布局布线下载到FPGA中,此时我们就可以观察信号和接口的值了。

在对ip核的设置中设置chipscope每次对信号的抓取为2048个。

3.1 对三角波的抓取

当选择信号K0置1,K1、K2置0时,信号发生器输出波形为三角波,如图3-1-1所示:

Chipscope抓三角波波形图3-1-1

利用chipscope的导出功能,得到具体的数据表。如图3-1-2

所示:

Chipscope对三角波形的导出图3-1-2

3.2 对方波的抓取

当选择信号K1置1,K0、K2置0时,信号发生器输出波形为方波,如图3-2-1所示:

Chipscope抓方波波形图3-2-1

利用chipscope的导出功能,得到具体的数据表。如图3-2-2所示:

Chipscope对方波形的导出图3-2-2

3.3 对正弦波的抓取

当选择信号K2置1,K0、K1置0时,信号发生器输出波形为正弦波,如图3-3-1

所示:

利用chipscope的导出功能,得到具体的数据表。如图3-3-2所示:

Chipscope对正弦波形的导出图3-3-2

4 利用MATLAB实现直观的观测数据

因为利用chipscope所导出的数据是一个一个的数组,所以无法对波形实现直观的观察。为了方便观察实验数据,利用MATLAB软件实现对文本文件中的数据的读。导出的每行数据可看做一个数组,每个数组第11位是波形的数据位,因此利用MATLAB只读第11列的数据。利用MATLAB画波形时,横轴作为波形的时间轴,每间隔为1打一个点,纵轴作为波形的幅值,用polt输出将这些点链接起来,就可以直观的观测波形。

方波的MATLAB程序如下:

clc,clear

data=textread('F:\ISE Design\wave_generate\实验数据\DELTA.txt');%采集路径

th=data(:,11);%数组全部采集,采集第11位

a=th';%转置

t=0:2047;%点的个数

subplot(311)

plot(t,a);

利用grid on,和subplot语句可以实现把三个波形画在一起(MATLAB全部

程序见附录六),画好后波形如图4-1:

MATLAB画出波形图4-1

5有待改进

程序中的频率和幅值都是固定的,未能实现频率和幅值的可调节,因此就没

有广泛的实用性,进一步的研究应从波形发生器向信号发生器改变。

附录一

顶层设计例化语句

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

entity sig is

PORT(clk,clrn : IN STD_LOGIC;

fb,sjb,zxb:IN STD_LOGIC;

ou:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));

end sig;

architecture Behavioral of sig is

COMPONENT sin

PORT ( clk,clrn : IN STD_LOGIC;

q : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END COMPONENT;

COMPONENT square

PORT ( clk,clrn : IN STD_LOGIC;

q : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END COMPONENT;

COMPONENT delta

PORT ( clk,clrn : IN STD_LOGIC;

q : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END COMPONENT;

COMPONENT sig_control

PORT(delta,square,sin :IN STD_LOGIC;

d0,d1,d2 :IN STD_LOGIC_VECTOR(7 DOWNTO 0);

q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); END COMPONENT;

component ila

PORT (

CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0);

CLK : IN STD_LOGIC;

TRIG0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0));

end component;

component icon

PORT (

CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0));

end component;

signal CONTROL : STD_LOGIC_VECTOR(35 DOWNTO 0);

signal TRIG0 : STD_LOGIC_VECTOR(7 DOWNTO 0);

signal a:STD_LOGIC_VECTOR(7 DOWNTO 0);

signal b:STD_LOGIC_VECTOR(7 DOWNTO 0);

signal c:STD_LOGIC_VECTOR(7 DOWNTO 0);

begin

u1: square PORT MAP(clk=>clk ,clrn=>clrn,q=>a);

u2: sin PORT MAP(clk=>clk ,clrn=>clrn,q=>b);

u3: delta PORT MAP(clk=>clk ,clrn=>clrn,q=>c);

u4: sig_control PORT MAP(delta=>sjb ,square=>fb,sin=>zxb,d0=>a ,d1=>b,d2=>c,q=>ou); u5: ila PORT MAP (CONTROL,clk,ou);

u6: icon port map (CONTROL);

end Behavioral;

附录二

u1方波产生模块程序

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY square IS

PORT(clk,clrn: IN STD_LOGIC;

q: OUT STD_LOGIC_VECTOR(7 downto 0));

END square;

ARCHITECTURE a OF square IS

SIGNAL f: STD_LOGIC;

BEGIN

PROCESS(clk, clrn)

V ARIABLE tmp:STD_LOGIC_VECTOR(7 downto 0);

BEGIN

IF clrn='0' THEN tmp:="00000000";

ELSE

IF clk'event and clk='1' THEN ------------------------------上升沿触发

IF tmp="11111111" THEN tmp:="00000000"; ---计数为256时置零

ELSE tmp:=tmp+1;

END IF;

IF tmp<"10000000" THEN f<='1'; ------------------ 当计数小于128时,f为1

ELSE f<='0'; ---------------------------------------------否则f为0

END IF;

END IF;

END IF;

END PROCESS;

PROCESS(clk,f)

BEGIN

IF clk'event and clk='1' THEN

IF f='1' THEN q<="11111111"; -----------------------------------f为1时q为255

ELSE q<="00000000"; --------------------------------------------f为0时q为0

END IF;

END IF;

END PROCESS;

END a;

附录三

u2:sin正弦波产生模块程序

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY sin IS

PORT (clk,clrn:IN STD_LOGIC;

q:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END sin;

ARCHITECTURE A OF sin IS

BEGIN

PROCESS(clk,clrn)

V ARIABLE tmp:INTEGER RANGE 63 DOWNTO 0; -------------------------对一个周期的正弦波采用64个点

BEGIN

IF clrn='0' THEN q<="00000000" ; tmp:=0;

ELSE

IF clk'EVENT AND clk='1' THEN -----------------------------------------------上升沿触发IF tmp=63 THEN tmp:=0;

ELSE tmp:=tmp+1;

END IF;

CASE tmp IS

WHEN 00=>q<="11111111"; WHEN 01=>q<="11111110"; WHEN 02=>q<="11111100";

WHEN 03=>q<="11111001"; WHEN 04=>q<="11110101"; WHEN 05=>q<="11101111";

WHEN 06=>q<="11101001"; WHEN 07=>q<="11100001"; WHEN 08=>q<="11011001";

WHEN 09=>q<="11001111"; WHEN 10=>q<="11000101"; WHEN 11=>q<="10111010";

WHEN 12=>q<="10101110"; WHEN 13=>q<="10100010"; WHEN 14=>q<="10010110";

WHEN 15=>q<="10001001"; WHEN 16=>q<="01111100"; WHEN 17=>q<="01110000";

WHEN 18=>q<="01100011"; WHEN 19=>q<="01010111"; WHEN 20=>q<="01001011";

WHEN 21=>q<="01000000"; WHEN 22=>q<="00110101"; WHEN 23=>q<="00101011";

WHEN 24=>q<="00100010"; WHEN 25=>q<="00011010"; WHEN 26=>q<="00010011";

WHEN 27=>q<="00001101"; WHEN 28=>q<="00001000"; WHEN 29=>q<="00000100";

WHEN 30=>q<="00000001"; WHEN 31=>q<="00000000"; WHEN 32=>q<="00000000";

WHEN 33=>q<="00000001"; WHEN 34=>q<="00000100"; WHEN 35=>q<="00001000";

WHEN 36=>q<="00001101"; WHEN 37=>q<="00010011"; WHEN 38=>q<="00011010";

WHEN 39=>q<="00100010"; WHEN 40=>q<="00101011"; WHEN 41=>q<="00110101";

WHEN 42=>q<="01000000"; WHEN 43=>q<="01001011"; WHEN 44=>q<="01010111";

WHEN 45=>q<="01100011"; WHEN 46=>q<="01110000"; WHEN 47=>q<="01111100";

WHEN 48=>q<="10001001"; WHEN 49=>q<="10010110"; WHEN 50=>q<="10100010";

WHEN 51=>q<="10101110"; WHEN 52=>q<="10111010"; WHEN 53=>q<="11000101";

WHEN 54=>q<="11001111"; WHEN 55=>q<="11011001"; WHEN 56=>q<="11100001";

WHEN 57=>q<="11101001"; WHEN 58=>q<="11101111"; WHEN 59=>q<="11110101";

WHEN 60=>q<="11111001"; WHEN 61=>q<="11111100"; WHEN 62=>q<="11111110";

WHEN 63=>q<="11111111"; WHEN OTHERS=>NULL;

END CASE;

END IF;

END IF;

END PROCESS;

END A;

附录四

u3:三角波产生模块程序

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL; -------------------预先定义的操作符可以进行重载ENTITY delta IS

port(clk,clrn:IN STD_LOGIC;

q:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END delta;

ARCHITECTURE a OF delta IS

BEGIN

PROCESS(clk,clrn)

V ARIABLE tmp:STD_LOGIC_VECTOR(7 DOWNTO 0);

V ARIABLE f:STD_LOGIC; BEGIN

IF clrn='0' THEN tmp:="00000000";

ELSIF clk'EVENT AND clk='1' THEN

IF f='0' THEN --------------- 三角波的上升,到255时跳到f1 IF tmp="11111110" THEN tmp:="11111111"; f:='1';

ELSE tmp:=tmp+1;

END IF;

ELSE -----------------三角波的下降,到0时跳到f0 IF tmp ="00000001" THEN tmp:="00000000"; f:='0';

ELSE tmp:=tmp-1;

END IF;

END IF;

END IF;

q<=tmp;

END PROCESS;

END a;

附录五

u4:数据选择器模块程序

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY sig_control IS

PORT( delta,square,sin :IN STD_LOGIC;

d0,d1,d2:IN STD_LOGIC_VECTOR(7 DOWNTO 0);

q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END sig_control;

ARCHITECTURE behave OF sig_control IS

SIGNAL sel:STD_LOGIC_VECTOR(2 DOWNTO 0);

BEGIN

sel<=delta&square&sin; ---------------------------并置

PROCESS(sel)

BEGIN

CASE sel IS

WHEN"100"=>q<=d0;

WHEN"010"=>q<=d1;

WHEN"001"=>q<=d2;

WHEN OTHERS=>NULL;

END CASE;

END PROCESS;

END behave;

附录六

利用MATLAB画波形的程序

clc,clear

data=textread('F:\ISE Design\wave_generate\实验数据\DELTA.txt');%采集路径

th=data(:,11);%数组全部采集,采集第11位

a=th';%转置

t=0:2047;%点的个数

subplot(311)

plot(t,a);

grid on

data=textread('F:\ISE Design\wave_generate\实验数据\SIN.txt');%采集路径th=data(:,11);%数组全部采集,采集第11位

b=th';%转置

t=0:2047;%点的个数

subplot(312)

plot(t,b);

grid on

data=textread('F:\ISE Design\wave_generate\实验数据\SQUARE.txt');%采集路径

th=data(:,11);%数组全部采集,采集第11位

c=th';%转置

t=0:2047;%点的个数

subplot(313)

plot(t,c);

grid on

相关主题
相关文档
最新文档