赞
踩
基本的D触发器分为三个端口:信号输入端D、信号输出端Q、以及时钟信号输入CLK。
其工作特性:在时钟上升沿到来的瞬间,从输入端Q获取信号来更新输出端口D的信号,其余时刻输出信号D保持不变。
以下是实现代码:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY DFF1 IS PORT( CLK,D : IN STD_LOGIC; Q : OUT STD_LOGIC ); END DFF1; ARCHITECTURE BHV OF DFF1 IS SIGNAL Q1 : STD_LOGIC; BEGIN PROCESS(CLK,D) BEGIN IF CLK'EVENT AND CLK='1' THEN Q1<=D; END IF; END PROCESS; Q<=Q1; END BHV;
最终仿真效果如下图所示
CLK'EVENT AND CLK='1'
CLK'EVENT AND (CLK='1') AND (CLK'LAST_VALUE='0')
CLK='1' AND CLK'LAST_VALUE='0'
IF RISING_EDGE(CLK)
顾名思义,就是比基本的D触发器多了两个输入端:异步复位端RST和时钟使能端EN。对于异步复位端RST,只要其输入为“1”,D触发器输出端立即清零;对于时钟使能端EN,只有其为“1”时,D触发器才能接受时钟上升沿的信号,对输出端口产生信号更新。实现代码如下:
library ieee; use ieee.STD_logic_1164.all; entity dff2 is port ( D,CLK,EN,RST : IN std_logic;-- EN时钟使能 RST异步清零 Q : OUT std_logic ) ; end dff2; architecture behav of dff2 is signal Q1 : std_logic; begin reg : process( RST,EN,CLK,D ) begin if RST='1' then --触发器被清零 Q1<='0'; elsif EN='1' then if (CLK'EVENT AND CLK='1') then Q1 <= D; end if ; end if ; end process ; -- reg Q <= Q1; end behav ; -- behav
这部分存在有两个疑问,留待后续解决:
顾名思义,该触发器含有四个输入端口,信号输入端D、时钟信号CLK,时钟使能信号EN以及同步复位端RST,“RST=1”只有在等到信号上升沿到达时才能起到清零作用。
这里需要注意两个重点:
以下是实现代码:
library IEEE; use IEEE.std_logic_1164.all; entity dff3 is port( RST,EN,CLK,D : in std_logic; Q : out std_logic ); end dff3; architecture behav of dff3 is signal Q1 : std_logic; begin ---千万不要忘记architecture里的begin! reg:process (CLK,EN) begin if (CLK'event and CLK='1' and EN='1') then --外部的if语句是不完整的,构成了时序逻辑器件 if RST = '1' then --内部的if是完整的,构成了一个多路选择器 Q1<='0'; else --加上了else肯定是完整的判断语句 Q1 <=D; end if; end if; end process; Q <= Q1; end behav;
仿真效果图如下:
基本锁存器端口组成:
基本锁存器工作特性:当CLK=‘1’时,输出信号Q时刻等于输入信号D,当CLK=‘0’时,输出信号Q保持。
实现代码如下:
library IEEE; use IEEE.std_logic_1164.all; entity LTCH1 is port( CLK,D : in std_logic; Q : out std_logic ); end LTCH1; architecture bhv of LTCH1 is signal Q1 : std_logic; begin reg:process(CLK,D) begin if CLK='1' then Q1 <= D; end if; end process; Q <= Q1; end; --bhv
仿真波形如下:
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity CNT20 is port ( CLK,RST,EN,LOAD : in std_logic;-- 时钟信号、同步清零信号、计数使能信号、预置数信号 DATA : in std_logic_vector(4 downto 0);--预置数信号 DOUT : out std_logic_vector(4 downto 0);--计数输出 COUT : out std_logic--进位输出 ) ; end CNT20; architecture bhv of CNT20 is signal Q : std_logic_vector(4 downto 0); begin REG : process( CLK,RST,EN,LOAD ) begin if CLK'EVENT and CLK='1' then if RST='0' then Q <= (others=>'0');-- 同步清零 elsif EN='1' then if LOAD='0' then Q <= DATA;--采用低电平进行预置数 elsif Q<19 then Q <= Q + 1;--未达到进位条件则进位 else Q <= (others=>'0');--手动清零 end if ; end if ; end if ; end process ; -- REG COM : process( Q ) begin if Q="10011" then --20进制计数到19 COUT <= '1'; else COUT <= '0'; end if ; end process ; -- COM DOUT <= Q; end bhv ; -- bhv
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity CNT_8 is port ( CLK,RST,EN,LOAD : in std_logic;-- 时钟信号、异步清零信号、计数使能信号、预置数信号 DATA : in std_logic_vector(7 downto 0);--预置数信号 DOUT : out std_logic_vector(7 downto 0);--计数输出 COUT : out std_logic--进位输出 ) ; end CNT_8; architecture bhv of CNT_8 is signal Q : std_logic_vector(7 downto 0); begin REG : process( CLK,RST,EN,LOAD ) begin if RST='0' then Q <= (others=>'0'); elsif CLK'EVENT and CLK='1' then if EN='1' then if LOAD='0' then Q <= DATA; else Q <= Q + 1; end if ; end if ; end if ; end process ; -- REG COM : process( Q ) begin if Q="11111111" then -- COUT <= '1'; else COUT <= '0'; end if ; end process ; -- COM DOUT <= Q; end bhv ; -- bhv
注意,由于这个8位计数器是计满全部位,所以不需手动设置计数最高位的清零跳转。
--串行输入并行输出 library IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; entity SHIFT6_LEFT is port ( CR,CLK,SHIFT : IN STD_LOGIC; --清零信号、时钟信号、串行输入信号 Y : OUT STD_LOGIC_VECTOR(5 DOwNTO 0) --并行四位输出 ) ; end SHIFT6_LEFT; architecture A of SHIFT6_LEFT is signal TEMP_DATA : STD_LOGIC_VECTOR(6 DOWNTO 0); --共计7位,增加一位作为状态位 begin REG1:process( CLK ) --状态位"011111"工作特性的设定 begin if CLK'EVENT AND CLK='1' then if CR='0' then--信号清零 TEMP_DATA<="0000000"; elsif TEMP_DATA(6)='0' then--状态位重载 --此句更改了TEMP_DATA --默认信号初始值都为0 (一般会先存在CR信号对TEMP_DATA进行清零) TEMP_DATA<="111110" & SHIFT ; else TEMP_DATA <= TEMP_DATA(5 DOWNTO 0) & SHIFT ;--信号左移:串行输入一位 & 高四位右移 end if ; end if ; end process ; REG2:process( TEMP_DATA ) --并行输出时刻的设定 --每 移动一位\状态位重载 检测一次 begin if CLK'event and CLK='1' then if TEMP_DATA(6)='0' then --输出状态位到达 Y <= TEMP_DATA(5 DOWNTO 0); --else --Y<="0000"; end if ; end if ; end process ; end A ;
library IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; entity SHIFT6_RIGHT is port ( CR,CLK : IN STD_LOGIC; SHIFT : IN STD_LOGIC_VECTOR(5 DOwNTO 0); Y : OUT STD_LOGIC ) ; end SHIFT6_RIGHT; architecture A of SHIFT6_RIGHT is signal TEMP_DATA : STD_LOGIC_VECTOR(11 DOWNTO 0); begin REG1:process( CLK ) begin if CLK'EVENT AND CLK='1' then if CR='0' then TEMP_DATA<=(others=>'0'); elsif TEMP_DATA(0)='0' then TEMP_DATA<=SHIFT & "011111"; else TEMP_DATA(10 DOWNTO 0) <= TEMP_DATA(11 DOWNTO 1); end if ; end if ; end process ; Y <= TEMP_DATA(6); end A ;
摘录了几个我目前需要改进的、可以理解的VHDL书写习惯:
(完整版参考:VHDL书写规范)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。