基于fpga的脉冲信号发生器设计
1、脉冲信号产生原理:输入量周期和脉宽,结合时钟频率,转换成两个计数器的容量,用来对周期和高电平的计时,输出即可产生脉冲信号。
2、脉冲信号的精度保证:时间分辨率0.1us,周期精度:+0.1%+0.05us,宽度精度:+0.1%+0.05us,为满足精度要求,所以所选时钟频率至少1/0.05us=20MHZ,由于试验箱上大于10MHZ只有50MHZ,故选时钟信号50MHZ,此时精度1/50MHZ=0.02us<0.05us,满足精度要求。
3、正弦信号产生原理:正弦信号的产生由DDS原理实现,频率由频率控制字M和时钟周期Fc决定,M=Fout*2^N/Fc,Fout=1/T,N即为相位累加器的位数,化简锝M=2^N/(5*T),即说明可以通过输入量周期控制正弦的频率,与脉冲达到同周期。
1、系统流程框图如图

2、按键输入模块:通过不同的按键切换周期和脉宽、高低位输入数据。
按键输入模块代码:
library ieee;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
entity xianshi is
port(cp,change,clr,hl,aj1,aj2,aj3:in std_logic;
zq,mk:out std_logic_vector(16 downto 0));
end xianshi;
architecture one of xianshi is
signal m:std_logic_vector(16 downto 0);
signal n:std_logic_vector(16 downto 0);
begin
process(cp,change,clr,hl,aj1,aj2,aj3)
begin
if clr='1'then
m<="00000000000000000"; n<="00000000000000000";
elsif cp'event and cp='1' then
if change='0'and hl='0'then
if aj1='1'then m<=m+1;end if;
if aj2='1'then m<=m+10;end if;
if aj3='1'then m<=m+100;end if;
end if;
if change='0'and hl='1'then
if aj1='1'then m<=m+1000;end if;
if aj2='1'then m<=m+10000;end if;
if aj3='1'then m<=m+100000;end if;
end if;
if change='1'and hl='0'then
if aj1='1'then n<=n+1;end if;
if aj2='1'then n<=n+10;end if;
if aj3='1'then n<=n+100;end if;
end if;
if change='1'and hl='1'then
if aj1='1'then n<=n+1000;end if;
if aj2='1'then n<=n+10000;end if;
if aj3='1'then n<=n+100000;end if;
end if;
end if;
zq<=m;
mk<=n;
end process;
end one;

3、显示模块:采用查询ROM表的方法,二进制数值通过一个ROM表显示为十进制数值,在数码管上显示。(代码分为两个模块,rom表见图示)
library ieee;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
entity chg is
port(change:in std_logic;
zq,mk:in std_logic_vector(16 downto 0);
xs:out std_logic_vector(16 downto 0));
end chg;
architecture one of chg is
begin
process(change)
begin
if change='0'then
xs<=zq;
else
xs<=mk;
end if;
end process;
end one;
library ieee;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
entity hhll is
port(hl:in std_logic;
h:in std_logic_vector(16 downto 0);
l:in std_logic_vector(9 downto 0);
xxss:out std_logic_vector(9 downto 0));
end hhll;
architecture one of hhll is
begin
process(hl)
begin
if hl='0'then
xxss<=l;
else
xxss<=h(9 downto 0);
end if;
end process;
end one;


4、高低电平计数模块:计数器接时钟脉冲50MHZ,即每次计数0.02us,5次计数为0.1us,即为实验要求的时间精度0.1us,通过置入周期和脉宽放大5倍(周期和脉宽均以0.1us为单位)便可产生高低脉冲信号。
library ieee;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
entity mk is
port(clk:in std_logic;
t,k:std_logic_vector(19 downto 0);
f:out std_logic);
end mk;
architecture one of mk is
signal m:std_logic_vector(19 downto 0);
begin
process(clk,t,m)
begin
if clk'event and clk='1'then
m<=m+1;
if m>=t then
m<="00000000000000000001";f<='0';
elsif m<=k then
f<='1';
else f<='0';
end if;
end if;end process;
end one;

5、正弦信号产生模块:由DDS原理产生,频率控制字M=Fout*2^N/Fc,Fout=1/T,N即为相位累加器的位数,化简得M=2^N/(5*T),再通过相位累加器查找正弦ROM表,便可产生正弦信号,正弦信号的周期即为T,与脉冲信号同周期。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity reg29 is
port(d:in std_logic_vector(31 downto 0);
clk:in std_logic;
q:out std_logic_vector(31 downto 0));
end reg29;
architecture one of reg29 is
begin
process(clk,d)
begin
if clk'event and clk='1' then
q<=d;
end if;
end process;
end one;
dm1
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity dm1 is
port(q:in std_logic_vector(9 downto 0);
si:in std_logic_vector(16 downto 0);
f:out std_logic_vector(9 downto 0));
end dm1;
architecture one of dm1 is
begin
process(si,q)
begin
if si="00000000000000000" then f<="0000000000";
else f<=q;
end if;
end process;
end one;


1、控制时钟:50MHz
按键操作:Key1:十分位、百位计数使能;Key2:个位、千位计数使能;key3:十位、万位计数使能;key4:高三位低三位切换;key5:脉宽、周期切换;key6:脉宽周期输入脉冲;Key7:猝发脉冲计数按键;key8:系统清零键;key3与key2同时按下切换至单猝发方式;key3、2、1同时按下但猝发脉冲发射。
测试方法:按键输入脉宽和周期,经过示波器观察测量正弦和脉冲周期以及脉宽,记录数据制4.3表格,切换猝发方式后继续用示波器进行单猝发计数测试。
