当前位置:文档之家› 实验三序列发生器与序列检测器实验报告

实验三序列发生器与序列检测器实验报告

南昌大学实验报告姓名: 学号:6100210173 专业班级:中兴通信101实验类型:验证□综合■设计□创新□实验日期:2012、11、16实验四序列信号发生器与检测器设计一、实验目的1、.学习VHDL文本输入法2、学习有限状态机的设计3、设计序列信号发生器和检测器二.实验内容与要求1. 设计序列发生器,完成序列为0111010011011010的序列生成器2.用有限状态机设计序列检测器,实现串行序列11010的检测器3. 若检测到符合要求的序列,则输出显示位为“1”,否则为“0”4. 对检测到的次数计数三.设计思路1.设计分频器因为最终要把待检测序列的检测次数在数码管上显示出,所以必须设计一个分频器,将起始频率作为数码管的扫描频率,而将分频后的频率作为序列发生器的移位频率,所以在程序中设置10KHZ进行分频分成1HZ脉冲(10KHZ的扫描频率是为了让数码管的动态显示更加清晰)2.设计序列发生器在这次的设计序列发生器时没有用状态转移的方法来来形成一个16位的序列,而是通过直接设计一串16位的序列,通过对最高位的输出与并置来形成一串循环的16位序列,这样设计简单方便,易于操作与控制,也减少了在状态转移产生的误差,其主要的核心程序为:architecture bhv of p2 issignal bs: std_logic_vector(15 downto 0):="0111010011011010";beginxlout<=bs(15);process (clk1hz)beginif (clk1hz'event and clk1hz='1') thenbs<= bs(14 downto 0)&bs(15);先将序列最高位输出至序列检测器中,然后在一个脉冲作用下,将此时最高位变成最低位,其余14位不变,使序列循环移动,最终形成一个16位循环序列。

3.设计序列检测器基本思想是采用有限状态机设计,通过状态的转移来实现被检测序列的的检测,首先设定6个状态S0 S1 S2 S3 S4 S5 通过这6个状态的转移情况来检测出11010这个序列。

但因为序列发生器发生的序列不断循环过程中也会出现一些类似11010的特殊序列,则在状态转移中则需要通过一些状态的变换来检测出里面包含的11010序列,如下文所讲的两种特殊情形便是我们序列发生器产生序列中出现的特殊序列:(1)在序列发生器产生序列不断循环过程中出现该序列1110100,此序列中也有一个要检测到的序列但在状态转移过程需要注意:1 1 1 0 1 0 0 S0 S1 S2 S2 S3 S4 S5 S0即当S2状态转移到S3状态时,如果此时序列值为1,则只需转移到状态本身S2而不需要转移至S0,这样即可节约转移时间也可提高检测效率,之后的状态按正常转移并且最后从状态S5回到S0。

(2)在序列发生器产生序列不断循环过程中出现该序列110110100,此序列中也有一个要检测到的序列但是在状态团转移时同样需要注意:1 1 0 1 1 0 1 0 0 S0 S1 S2 S3 S4 S2 S3 S4 S5 S0 即当状态S4转移到S5状态时,如果此时序列值为1,则需要将状态转移至S2状态,从S2状态重新开始检测,而不需要转移至S0,之后其它状态正常转移并且最后由S5状态转移至S0状态。

从上面的流程图可以看出所有的回路在检测完一次序列后在下一次没有该序列时会流向初始状态S0,而当两个或多个被检测序列连续在一起时,状态S5会跳过状态S0直接转移至状态S1完成序列的的检测,直到检测完后再次回到初始状态S0,并且为了避免上面所讲的两种特殊序列在状态转移都进行了改进,在状态S2至状态S3时若序列值为1则返回自身,消除第一种特殊情况下序列的检测问题,在状态S4至状态S5时若序列值为1返回到状态S2,消除第二种特殊情况对1101016序列的检测。

3、此外在设计序列检测器时,为了使实验现象更明显,更好的观测序列的的移动与检测情况我使用了5个LED 分别来显示最新产生的五个序列位,分别输出到端口ledag(4),ledag(3),ledag(2),ledag(1),ledag(0)实现程序语句如下if(clk1hz'event and clk1hz='1') thenledag(4)<=ledag(3);---移位输出显示在led 上以便观看S1S0S4S3S20 110 111S5ledag(3)<=ledag(2); ledag(2)<=ledag(1); ledag(1)<=ledag(0);ledag(0)<=xlout;--将最近生产的序列赋给最前端的ledge(0)位 end if; 4、设计计数器模块因为序列发生器产生的序列不断地循环,待检测序列11010的个数很多,则在程序中设计计数模块,当序列检测器模块检测完一次待检测序列11010时产生一次下降沿,而计数器模块通过该下降沿进行计数自动加一,因为用两个数码管来表示待检测序列的个数,所以计数模块取上限为99即用数码管译码模块将计数值在数码管表示出来时最多能计99检测序列之后清零重新计数,这样设计之后比通过LED 的亮灭来统计被检测序列的个数更加具体直观。

四、实验程序(程序来源于自己编写) --总的设计模块如图所示:--分频器模块library ieee;use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity p1 isrt(clk:in std_logic;clk1hz:out std_logic --分频的频率1HZ 的输出端口 ); end p1;architecture behave of p1 isSignal Clk_Count1 : std_logic_vector(13 downto 0); beginprocess(clk) --将10KHZ 的频率分频成1HZ beginif(Clk'event and Clk='1') then if(Clk_Count1<10000) thenClk_Count1<=Clk_Count1+1; --在小于10000时,自动加1 elseClk_Count1<="00000000000001"; --超过10000后返回1分频模块序列产生模块序列检测模块100计数模块扫描译码模块流水灯(显示序列移动)模块end if;end if;end process;Clk1Hz<=Clk_Count1(13); --将Clk_Count1的第14位赋给Clk1Hzend behave;--序列发生器模块library ieee;use ieee.std_logic_1164.all;entity p2 isport(clk1hz : in std_logic; --定义输入端口此时频率为1HZxlout : out std_logic --输出序列发生器产生的序列端口);end entity;architecture bhv of p2 issignal bs: std_logic_vector(15 downto 0):="0111010011011010";beginxlout<=bs(15); --将bs的第16位值赋给xloutprocess (clk1hz)beginif (clk1hz'event and clk1hz='1') thenbs<= bs(14 downto 0)&bs(15); --前15位保持不变,将bs的第16位并到最前来形成序列的循环end if;end process;end bhv;--序列检测器模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity p3 isport( clr :in std_logic; --清零端口clk1hz:in std_logic; --输入信号频率xlout : in std_logic; --输入序列result: out std_logic);end entity;architecture bhv of p3 istype state_value is(s0,s1,s2,s3,s4,s5); --定义6个状态signal state: state_value;signal dclk: std_logic;beginresult<=dclk;process (clr,clk1hz)beginif (clr='0') then state<=s0; dclk<='0'; --检测输入序列“11010”由左开始elsif(clk1hz'event and clk1hz='0') thencase state iswhen s0=> if xlout='1' then --序列值为1S0转态S1,若序列值为0,返回自身state<=s1;else state<=s0;end if;when s1=> if xlout='1' thenstate<=s2;else state<=s0;end if;when s2=> if xlout='0' then --序列值为1,S2转向自身,序列值为0,转向S3 state<=s3;else state<=s2;end if;when s3=> if xlout='1' thenstate<=s4;else state<=s0;end if;when s4=> if xlout='0' then --序列值为0,S4转向S5,输出端为1state<=s5; dclk<='1';else state<=s2; --若此时序列值为1,S4转向S2end if;when s5=> if xlout='0' then --序列值1,S5转移至S1,若为0,转向S0state<=s0;else state<=s1;end if;dclk<='0';when others => state<=s0; --其它状态都将返回初始状态end case;end if;end process;end bhv;--100计数模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity p5 isport( result:in std_logic; --前面序列检测模块中检测到序列后产生的跳变信号d6,d7: out std_logic_vector(3 downto 0) --定义十位个位数值);end entity;architecture behave of p5 issignal cnt0,cnt1:std_logic_vector(3 downto 0):="0000"; --初始化beginprocess (result)beginif (result'event and result='0') thenif (cnt0="1001" and cnt1="1001") then --设置计数上限为99cnt0<="0000"; cnt1<="0000";elsif (cnt0="1001") then --BCD码的调整cnt0<="0000";cnt1<=cnt1+1; --接受跳变信号后自动加1计数else cnt0<=cnt0+1;end if;end if;end process;d6<=cnt1;d7<=cnt0;end behave;--数码管译码模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity p6 isport(clk:in std_logic; --扫描频率10KHZ的输入端口sel0,sel1,sel2:buffer std_logic; --数码管的位选信号sg:out std_logic_vector(6 downto 0); --数码管的段选sel:out std_logic_vector(7 downto 0);d6,d7:in std_logic_vector(3 downto 0) --计数模块中个位十位的数值);end p6;architecture behave of p6 issignal cnt:std_logic_vector(1 downto 0);signal A:std_logic_vector(3 downto 0);beginprocess(clk)beginif clk'event and clk='1' thenif cnt<"01" then cnt<=cnt+1;else cnt<=(others=>'0');end if;end if;sel(0)<=sel0;sel(1)<=sel1;sel(2)<=sel2;case cnt iswhen "00"=>sel2<='1';sel1<='1';sel0<='1';A<=d7; --选择数码管的位置when "01"=>sel2<='1';sel1<='1';sel0<='0';A<=d6;when others=>null;end case;end process;process(A)begincase A iswhen "0000" =>sg<="0111111"; --数码管显示值为0时的译码值when "0001" =>sg<="0000110";when "0010"=>sg<="1011011";when "0011"=>sg<="1001111";when "0100"=>sg<="1100110";when "0101"=>sg<="1101101";when "0110"=>sg<="1111101";when "0111"=>sg<="0000111";when "1000"=>sg<="1111111";when "1001"=>sg<="1101111";when others=>null;end case;end process;end behave;--显示序列移动模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity p4 isport(clk1hz:in std_logic; --分频后的频率输入端口xlout:in std_logic; --序列发生器产生的序列ledag :buffer std_logic_vector(4 downto 0) --5位序列值的输出口);end p4;architecture behave of p4 isbeginprocess(clk1hz)beginif(clk1hz'event and clk1hz='1') thenledag(4)<=ledag(3); --序列值向左移动 ledag(3)<=ledag(2); ledag(2)<=ledag(1); ledag(1)<=ledag(0);ledag(0)<=xlout; --将最近生产的序列赋给最前端的ledge(0)位 end if;end process; end behave;四. 实验步骤 1. 建立工程项目2. 在VHDL 编辑窗口下写好程序,并保存3、进行全编译,没有错误。

相关主题