5.程序源代码
A/D转换模块:
library
ieee;
--标准函数库
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;
entity adcc is
port(clk,status:in
std_logic;
--状态机时钟CLK,AD574状态信号
d : in std_logic_vector(7 downto 0);
--数据输入
q : out std_logic_vector(7 downto
0));
--锁存数据输出
end adcc;
architecture behav of adcc is
type states is
(s0,s1,s2,s3,s4);
--定义状态信号
signal current_state,next_state:states:=s0;
signal regl:std_logic_vector(7 downto 0);
signal lock:std_logic;
begin
com1:process(current_state,status)
--决定转换状态的进程
begin
case current_state
is
--状态转换
when
s0=>next_state<=s1;
when
s1=>next_state<=s2;
when
s2=>if(status='1')then
next_state<=s2;
else next_state<=s3;
end if;
when s3=>next_state<=s4;
when s4=>next_state<=s0;
end case;
end process com1;
com2:process(current_state)
--输出控制信号的进程
begin
case current_state is
when
s0=>lock<='0';
--初始化
when
s1=>lock<='0';
--启动转换
when
s2=>lock<='0';
--等待转换
when
s3=>lock<='0';
--输出有效
when
s4=>lock<='1';
--锁存数据
when
others=>lock<='0';
--其他情况返回初始态
end case;
end process com2;
reg:process(clk)
--时序进程
begin
if(clk'event and clk='1')then
current_state<=next_state;
end if;
end process reg;
latch1:process(lock)
--数据锁存进程
begin
if lock='1' and lock'event then
regl<=d;
end if;
end process;
q<=regl;
end behav;
MAX+PLUSΠ波形仿真如下:
A/D模块仿真分析:
仿真输入是从0开始递增的自然数,状态信号status等于‘1’时等待转换current_state等于2时与其对应,status等于‘0’时转换结束,current_state等于3时数据输出,current_state从0到4为一个转换周期。上图中q的输出7对应第一个周期中clk上升沿和current_state等于4的前沿。完成A/D采样。
(2)FIR滤波器模块:
package fir_int is --user defined types
subtype byte is integer range -128 to
127;
--定义byte为-128到127整型
type array_byte is array(0 to 3)of
byte;
--定义array_byte为4位byte
end fir_int;
library work;
use work.fir_int.all;
library
ieee;
--标准库函数
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity fir_srg is
--定义fir_srg实体
port (clk : in std_logic;
x : in
byte;
--数字信号输入
y : out
byte);
--滤波输出
end fir_srg;
architecture flex of fir_srg is
signal tap :array_byte;
--定义延迟抽头线
begin
process(clk)
begin
if clk'event and clk='1'
then
--用滤波器系数计算输出Y
-- 滤波器系数[-1 3.75 3.75 -1].
--在ALTERA的VHDL中乘法和除法
--只容许是2 的权
y<=2*tap(1)+tap(1)+tap(1)/2+tap(1)/4
+2*tap(2)+tap(2)+tap(2)/2+tap(2)/4
-tap(3)-tap(0);
--低通滤波器系数[-1 3.75 3.75 -1]
--3阶滤波器,4抽头
--系数h(n)满足偶对称,长度N=4
for i in 3 downto 1 loop
tap(i)<=tap(i-1);
--抽头延迟线赋值
end loop;
tap(0)<=x;
end if;
end process;
end flex;
MAX+PLUSΠ波形仿真比较如下图:
:
FIR滤波模块仿真分析:
滤波输入x分别是1,10,100,255时对应的仿真波形,tap为抽头延迟线信号,当输入x等于10时,tap的延时信号分别是0A000000,0A0A0000,0A0A0A00,0A0A0A0A。延迟系数[-1,3.75,3.75,,-1],此时经滤波器输出y等于246,246是-1*10=-10的无符号数表示10的补码是B00001010经过取反加1得到的即B11110110即246。由于是FIR数字低通滤波器和模拟滤波器的输出相似,刚开幅度比较大,随后数变小形成过度带,最后延时相乘完毕输出为零。实现FIR低通滤波。
(3)D/A转换模块:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity dacc is
port(clk:in std_logic;
data : in std_logic_vector(7 downto 0);
dd : out
integer range 255 downto
0);
--dd波形数据输出端口
end dacc;
architecture dacc of dacc is
signal
q
: integer range 127 downto 0;
signal
d
: integer range 255 downto 0;
signal
fss
: std_logic;
signal
count
: std_logic_vector(9 downto 0);
signal
data1
: std_logic_vector(7 downto 0);
begin
data1<=data;
process(fss)
--产生波形数据地址
begin
if (fss'event and fss='0')then
q<=q+1;
end if;
end process;
process(q)
begin
case q
is
--D/A转换的波形数据
when
00=>d<=128;when
01=>d<=134;when
02=>d<=140;
when
03=>d<=147;when
04=>d<=153;when
05=>d<=159;
when
06=>d<=165;when
07=>d<=171;when
08=>d<=177;
when
09=>d<=183;when
10=>d<=188;when
11=>d<=194;
when
12=>d<=199;when
13=>d<=204;when
14=>d<=209;
when
15=>d<=214;when
16=>d<=219;when
17=>d<=223;
when
18=>d<=227;when
19=>d<=231;when
20=>d<=234;
when
21=>d<=238;when
22=>d<=241;when
23=>d<=244;
when
24=>d<=246;when
25=>d<=249;when
26=>d<=250;
when
27=>d<=251;when
28=>d<=253;when
29=>d<=254;
when
30=>d<=254;when
31=>d<=255;when
32=>d<=255;
when
33=>d<=255;when
34=>d<=254;when
35=>d<=254;
when
36=>d<=253;when
37=>d<=251;when
38=>d<=250;
when
39=>d<=249;when
40=>d<=246;when
41=>d<=244;
when
42=>d<=241;when
43=>d<=238;when
44=>d<=234;
when
45=>d<=231;when
46=>d<=227;when
47=>d<=223;
when
48=>d<=219;when
49=>d<=214;when
50=>d<=209;
when
51=>d<=204;when
52=>d<=199;when
53=>d<=194;
when
54=>d<=188;when
55=>d<=183;when
56=>d<=177;
when
57=>d<=171;when
58=>d<=165;when
59=>d<=159;
when
60=>d<=153;when
61=>d<=147;when
62=>d<=141;
when
63=>d<=134;when
64=>d<=128;when
65=>d<=122;
when
66=>d<=115;when
67=>d<=109;when
68=>d<=103;
when
69=>d<=97;when
70=>d<=91;when
71=>d<=85;
when
72=>d<=79;when
73=>d<=73;when
74=>d<=68;
when
75=>d<=62;when
76=>d<=57;when
77=>d<=52;
when
78=>d<=47;when
79=>d<=42;when
80=>d<=37;
when
81=>d<=33;when
82=>d<=29;when
83=>d<=25;
when
84=>d<=22;when
85=>d<=18;when
86=>d<=15;
when
87=>d<=12;when
88=>d<=10;when
89=>d<=7;
when
90=>d<=6;when
91=>d<=4;when
92=>d<=2;
when
93=>d<=1;when
94=>d<=1;when
95=>d<=0;
when
96=>d<=0;when
97=>d<=0;when
98=>d<=1;
when
99=>d<=1;when
100=>d<=2;when
101=>d<=4;
when
102=>d<=6;when
103=>d<=7;when
104=>d<=10;
when
105=>d<=12;when
106=>d<=15;when
107=>d<=18;
when
108=>d<=22;when
109=>d<=25;when
110=>d<=29;
when
111=>d<=33;when
112=>d<=37;when
113=>d<=42;
when
114=>d<=47;when
115=>d<=52;when
116=>d<=57;
when
117=>d<=62;when
118=>d<=68;when
119=>d<=73;
when
120=>d<=79;when
121=>d<=85;when
122=>d<=91;
when
123=>d<=97;when
124=>d<=103;when
125=>d<=109;
when
126=>d<=115;when
127=>d<=122;
when
others=>null;
end case;
end process;
dd<=d;
process(clk,data)
--产生扫描时钟
begin
if(clk'event and clk='0')then
if count>="1000000000"then
count<="0000000000";
fss<='1';
else count<=count+data1+121;
fss<='0';
end if;
end if;
end process;
end;