实验六计数器与序列检测器的仿真
一、实验内容
1.用VHDL语言设计一个按余3码顺序计数的计数器,并进行仿真与分析;
2.用VHDL语言设计一个“1101001”位串的序列检测器,并仿真与分析。
二、实验要求
1.进实验室前,请写一份预习报告;进实验室时经指导老师检查后,才可上机操作。
2.预习报告内容有:
用VHDL语言编写余3码计数器程序;
用VHDL语言编写“1101001”序列检测器程序。
3.在文本编辑区使用VHDL硬件描述语言设计逻辑电路,再利用波形编辑区进行逻辑功能仿真,以此验证电路的逻辑功能是否正确,最后在实验箱上进行下载验证。
4.实验结束前,由指导老师检查了仿真波形和实验箱上的实验结果后方可离开。
三、电路功能介绍
1、计数器
计数器: 一般来说,在状态图中包含有一个循环(见下图)的任何时钟时序电路都可称为计数器。
计数器的模是指在循环中的状态个数。
一个有m个状态的计数器称为模m计数器,有时也称为m分频计数器。如果一个计数器的模不是2的幂,就会有多余状态,在正常工作时是不用这些状态的。
最常用的计数器可能就是n位二进制计数器。这样的计数器有n个触发器及2n种状态,这些状态的循环顺序是0, 1, 2, ..., 2n-1, 0, 1, ...。其中,每一种状态都被编码成对应的n位二进制整数。
行波计数器:当某一位由1变到0,这一位就会向高位产生一个进位,由低位到高位,每次传送一位,如T触发器。
同步计数器: 所有的触发器都共用一个CLK信号,在经过仅仅tTQ纳秒的延迟后,所有的触发器的输出都同时变化,它包括两种结构:同步串行计数器和同步并行计数器。
1.同步串行计数器:采用一个主计数使能信号CNTEN来实现控制。每一个T触发器要发生翻转的充要条件是CNTEN信号有效且所有的低阶计数位都为1,同步n位二进制计数器的每一位都可以用一定数量的逻辑元件来实现,它的缺点是组合型的使能信号由最低位到最高位串行传送,如果时钟周期太短的话,计数器LSB(最低位)的变化可能来不及传送到MSB(最高位)。
2.同步并行计数器:每一个EN输入都用一个专门的与门来驱动,这样,CNTEN信号到达各个触发器的EN输入端只需要经过一级逻辑电路,它是最快的二进制计数器的结构形式。
2.序列检测器
应用状态机的概念设计一个序列检测器,以“1110010”序列检测器的设计为例。该序列检测器收到一组串行码(1110010)后输出检测标志为‘1’,否则为‘0’。
一、计数器
1. VHDL语言实现
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity count is
port(clk,clr,en:in std_logic;
a:out std_logic_vector(3 downto 0);
cout:out std_logic);
end count;
architecture bhv of count is
signal b:std_logic_vector(3 downto 0);
begin
process(clk,clr,en,b)
begin
if(clr='1') then b<="0011";
elsif(clk'event and clk='1') then
if(en='1') then
if(b<"1100") then b<=b+1;
else b<="0011";
end if;
end if;
end if;
if(b="1100") then cout<='1';
else cout<='0';
end if;
a<=b;
end process;
end bhv;
2. 波形仿真
3. 逻辑图
二、序列检测器
1.VHDL实现
library ieee;
use ieee.std_logic_1164.all;
entity xulie is
port(clk,rst,d:in std_logic;
z: out std_logic);
end xulie;
architecture bhv of xulie is
type state_type is(s0,s1,s2,s3,s4,s5,s6); --状态定义
signal state: state_type; --状态寄存器
begin
process(clk,rst) --次态设置
begin
if rst= '1' then state<=s0; --异步重启
elsif (clk'event and clk ='1') then
case state is --根据d判断状态转移
when s0 =>
if d='1' then state<=s1;
else state<=s0;
end if;
when s1=>
if d='1' then state<=s2;
else state<=s0;
end if;
when s2=>
if d='0' then state<=s3;
else state<=s2;
end if;
when s3=>
if d='1' then state<=s4;
else state<=s0;
end if;
when s4=>
if d='0' then state<=s5;
else state<=s2;
end if;
when s5=>
if d='0' then state<=s6;
else state<=s1;
end if;
when s6=>
if d='1' then state<=s0;
else state<=s0;
end if;
end case;
end if;
end process; --输出设置
process(state,d)
begin
case state is
when s6=>
if d='1' then z<='1'; --1101001检测成功
else z<='0';
end if;
when others=>z<='0';
end case;
end process;
end bhv;
2.仿真
3.逻辑图
4. 序列检测器的Mealy机状态表:
第二篇:序列信号检测器的设计与实现 实验报告
数字电路与逻辑设计实验
实验名称:序列信号检测器的设计与实现
学院: 信息与通信工程学院
班级: xxxxxxxxxx
学号: xxxxxxxxxx
班内序号: xx
姓名 大学霸
一、实验课题
序列信号检测器的设计与实现
二、实验任务及设计要求
(1) 熟悉用VHDL语言设计时序逻辑电路的方法。
(2) 熟悉序列信号检测器的设计方法
(3) 了解状态机的设计方法
用VHDL语言设计实现一个序列信号检测器,当检测到“101”时,输出为“1”;其他情况时,输出为“0”,仿真验证其功能,并下载到实验板测试。
三、设计思路与过程
实验需要4个端口,时钟输入clk,数据输入d_in,输出f。根据老师的要求后面还加入了时钟显示clk_out来保证数据输入在时钟上升沿之前
1、设计思路
序列检测器有输入信号d_in和输出信号f。输入输出的的逻辑关系为:当外部输入x第一个为“1”,外部输出Z为“0”;当外部输入x第二个为“0”,外部输出Z为“0”;当外部输入x第三个为“1”,外部输出Z才为“1”。要判断输入序列中的一段是否为“101”,电路需要用不同的状态来标记。
假设电路的初始状态A,d_in输入第一个“1”,检测器状态由A转换到B,B代表101序列中的第一个“1”,输出为f=0,如果之后继续输入“1”还会保持在这个状态;d_in输入“0”,检测器由B转换到C,C代表101序列中的“0”,输出f=0;d_in输入第三个值“1”时检测到完整的101序列,输出f=1,同时因为输入为“1”,状态由C又转换回B;如果d_in输入第三个值为“0”,状态由C退回到初始状态A,输出f=0。以上为序列检测器的功能分析。由此可以画出序列检测器的状态图
状态表如下:
2、实验过程
(1) 用计算机QuartusII 9.0软件新建工程,新建VHDL,写入程序代码,运行调试直至编译成功。
(2) 新建波形仿真软件,设置endtime,输入输出信号,运行,观察仿真结果确认无误。
(3) 将实验板与计算机相连,设置管脚后再次编译工程。
(4) 下载至实验板,检查其功能准确无误。
四、VHDL代码
单进程状态机
P1:process(clk_tmp)—分频过后的时钟信号
begin
if (clk_tmp'event and clk_tmp='1')then
case state is
when A=>if(d_in='1')then state<=B;--A状态
else state<=A;
end if;
f<='0';
when B=>if(d_in='1')then state<=B;--B状态
else state<=C;
end if;
f<='0';
when C=>if(d_in='1')then state<=B;f<='1';--C状态
else state<=A;f<='0';
end if;
end case;
end if;
end process;
分频器: 实验板提供的2Hz低频信号感觉还是有点快,所以自己加入了上节课用到的50M分频器,将时钟信号调整成1Hz,同时将时钟信号显示在实验板上,方便观测
p2:process(clk)
begin
if (clk'event and clk='1') then
if cnt=24999999 then
cnt<=0;
clk_tmp<= not clk_tmp;
else
cnt<=cnt+1;
end if;
end if;
end process;
clk_out<=clk_tmp;
完整的结构体定义
architecture mealy of d_101 is
type state_type is(A,B,C);
signal state:state_type;
signal cnt : integer range 0 to 24999999;
signal clk_tmp : std_logic;
begin
P1:process(clk_tmp)
begin
if (clk_tmp'event and clk_tmp='1')then
case state is
when A=>if(d_in='1')then state<=B;
else state<=A;
end if;
f<='0';
when B=>if(d_in='1')then state<=B;
else state<=C;
end if;
f<='0';
when C=>if(d_in='1')then state<=B;f<='1';
else state<=A;f<='0';
end if;
end case;
end if;
end process;
p2:process(clk)
begin
if (clk'event and clk='1') then
if cnt=24999999 then
cnt<=0;
clk_tmp<= not clk_tmp;
else
cnt<=cnt+1;
end if;
end if;
end process;
clk_out<=clk_tmp;
end mealy;
五、仿真波形图及其分析
分析如下
如图所示,当输入信号序列d_in为010101101001010时,能检测到101的有010101101001010,其中第四个值“1”,为两个“101”信号所共用。此时输出信号检测的结果f为000101001000010,在第4,6,9,14个时钟周期检测到目标信号,仿真结果准确无误,说明实现了题目的要求,完成对101信号的检测。由于时钟是上升沿触发,检测器的状态不受干扰,工作稳定。
六、故障及问题分析
故障1、波形仿真的输出波形全是0
原因:输入信号与时钟信号之间没有匹配
解决方法:
要想让输入信号与时钟信号对应,适当的修改设定周期,使其满足一定的关系。把输入信号d_in周期设置成时钟信号clk周期的两倍,但发现输入信号为0101010……,不满足随机序列的形式,需要自己手动将d_in的一些部分单独置1或0,这样能更全面直观地检测其功能。
故障2、下载到实验板后出错
原因:设置管脚后没有编译
解决方法:在QuartusII9.0软件中设置管脚之后,再次编译工程无误后,下载到实验开发板上。
故障3、拨码输入信号跟不上时钟信号
原因:实验板提供的2Hz信号翻转太快
解决方法: 我在原来设计的VHDL程序里加入50M分频器,让实际的时钟信号变为1Hz,这样拨动拨码开关的速度就能跟得上时钟改变了。实验中还用了发光二极管来显示当前时钟的状态,亮灭分别表示高低电平,可以根据二极管状态来判定时钟的上升沿,输入信号d_in仅在上升沿有效
七、总结和结论
总结了之前的两次VHDL实验得到的经验,这次小的综合实验感觉还挺顺利的。这次的实验需要我们了解有限状态机的相关知识,在实验之前我预习了实验教程P72~80关于状态机的设计步骤与实例,然后按照步骤完成实验的设计,掌握了这部分的知识,了解到状态机包括时序逻辑电路(存储部分)以及组合逻辑电路(控制部分)
进行VHDL实验,理论分析是十分重要的一环,只有逻辑分析透彻无误,才能用语言进行描述,进而用硬件实现。比如这个实验中,三个状态与转换关系的设计是实验的关键,用到了在数电理论课上学到的一般时序电路的设计知识,只有明白了实验背后的逻辑思想,才进行VHDL语言编写,仿真等等
在这次实验中,我也发现了一些我的缺点,比如不够细心,VHDL代码调试中出现些小错误,自己发现不了,如果下次能细心点,就完全可以避免,在以后的实验中,我会尽量减少实验中的错误,顺利完成实验任务。同时我也发现了每学一门新知识的重要性,只有当所学的知识可以用来解决实际问题的时候,才是学到精处。通过不断的练习与应用,加深自己的理解,提高能力,学为所用
八、对本课程的建议
完成了本学期四次数电基础实验课程之后,学到了很多知识,掌握了Quartus II软件的使用,完成了一些简单的实验,感觉每节课自己都有一些收获。同时为下学期的数电综合实验及以后一些硬件设计打下了基础。在实验课结束之际有一些自己的建议。
1、希望这门课能像电子电路实验那样进行周末实验预约,对一些想要在课后单独练习的同学提供机会。
2、实验的进度要与理论课的进度一致,记得做第三次实验时序逻辑电路设计时,我们才正学习这部分知识,虽然实验完成了,但对其中的原理还不是非常的了解。
3、我发现每节课都有部分剩余的时间,如果有可能的话,可以利用这些时间讲一些这个学科前沿的内容,丰富我们的视野