基本时序电路一、触发器及其应用实例2-1对触发器及时钟信号的VHDL描述一、设计任务:设计一个D触发器。二、算法设计:用if语句进行描述。三、源程序dff1.vhdlibraryieee;useieee.std_logic_1164.all;entitydff1isport(d,clk:instd_logic;q:outstd_logic);end;architecturertlofdff1issignalq_temp:std_logic;beginprocess(clk)beginifclk'eventandclk='1'then--本句是对触发时钟进行描述时,用得最多的一种语句。q_temp=d;endif;q=q_temp;endprocess;endrtl;--if语句中,用信号属性even来判断时钟触发事件是否发生,用clk='1'规定触发时钟的上沿为有效触发沿。语句“ifclk'eventandclk='1'then”的含义是:若有触发时钟信号产生且当触发时钟的上沿出现时,容许触发器读入输入数据。如果上述事件没有发生,则不容许触发器读入输入数据,而读入输入数据的规则由后续语句规定。--若规定触发器是下沿触发,则触发时钟描述语句为“ifclk'eventandclk='0'then”。--图3—2是D触发器的仿真波形图。由图可以看出,触发器的默认起始状态值为'0',在第一个触发脉冲的上沿出现时刻,电路系统把数据'1'写入触发器。在第二个触发脉冲的上沿出现时刻,电路系统仍把数据'1'写入触发器,但由于触发器原状态为'1',写入数据仍为'1',所以触发器保持'1'状态不变。在第三个触发脉冲的上沿出现时刻,输入数据变为'0',电路系统把数据'0'写入触发器。以后尽管有触发脉冲的上沿出现,但是输入值为'0'不变,所以触发器保持'0'状态。图3-2D触发器的仿真波形图实例2-2锁存器一、设计任务:设计一个锁存器。二、算法设计:用条件涵盖不完整的if语句实现锁存器。三、源程序latch.vhdlibraryieee;useieee.std_logic_1164.all;entitylatchisport(kz,din:instd_logic;q:outstd_logic);end;architectureaoflatchissignalq_temp:std_logic;beginp1:process(kz,din)beginifkz='1'thenq_temp=din;endif;q=q_temp;endprocess;end;四、源程序说明1.用条件涵盖不完整的if语句可以实现锁存器。这个结果提示我们在用if条件语句进行设计时,要明确设计的任务是什么,若设计的不是锁存器,则必须使条件涵盖完整,以避免错误引入锁存器。2.若本例描述的锁存器中的控制信号kz是一个异步信号,而且输入信号较高,就有可能在输出形成冒险干扰,应注意克服。3.图3-11是锁存器正常工作时的仿真波形图。二、计数器及其应用实例2-3二进制(M=16)计数器一、设计任务:设计一个二进制(M=16)计数器。一般把计数器的模值M=2n、状态编码为自然二进制数的计数器简称为二进制计数器。二、算法设计:用if语句描述二进制(M=16)计数器。三、源程序count16.vhdlibraryieee;useieee.std_logic_1164.all;useieee.std_logic_unsigned.all;entitycount16isport(clk:inbit;oc:outbit;y:outintegerrange0to15);end;architectureaofcount16issignalq:integerrange0to15;beginprocess(clk)beginif(clk'eventandclk='1')thenq=q+1;endif;ifq=15thenoc='0';elseoc='1';endif;y=q;endprocess;end;--程序中oc是计数器进位输出端。用整数数据类型设计二进制计数器是很方便的。若要M=256,只要把整数数据范围改为:integerrange0to255。实例2-4BCD码60进同步计数器一、设计任务:设计一个BCD码60进同步计数器。个位显示0~9,十位显示0~5,均用4位二进制数表示。二、算法设计:个位计数器的模M=10,十位计数器的模M=6。用if语句描述该计数器。三、源程序count6_10tb.vhdlibraryieee;useieee.std_logic_1164.all;useieee.std_logic_unsigned.all;entitycount6_10tbisport(clk,clr:instd_logic;oc:outstd_logic;y0,y1:outstd_logic_vector(3downto0));end;architectureaofcount6_10tbissignalq:std_logic_vector(3downto0);signalk:std_logic_vector(3downto0);signalj9,j60:std_logic;beginp1:process(clk)beginifclr='0'thenq=0000;--清零。elsif(clk'eventandclk='1')thenifq=1001thenq=0000;elseq=q+1;endif;endif;y0=q;endprocess;p2:process(clk)beginifclr='0'thenk=0000;--清零。elsif(clk'eventandclk='1')thenifq=1001thenifk=0101thenk=0000;elsek=k+1;endif;elsek=k;endif;endif;y1=k;ifq=1001andk=0101thenj60='0';elsej60='1';endif;oc=j60;endprocess;end;--两级计数器的模M=M1*M0。本程序描述的计数器是一个同步计数器,由于十位计数器和个位计数器使用同一个时钟,所以程序中使用q=”1001”条件对十位计数器的时钟作用时刻进行控制。四、仿真结果实例2-5一热态位编码计数器一、设计任务:设计一个一热态位(one-hot)编码的四进计数器。该计数器类型也可称为“循环出1(或0)计数器”或“循环计数器”。其特点是对每一个计数状态采用一个触发器。二、算法设计用if语句描述一热态位编码四进计数器。三、源程序hot_count.vhdlibraryieee;useieee.std_logic_1164.all;entityhot_countisport(clk:instd_logic;y:outstd_logic_vector(3downto0));end;architectureshift_1ofhot_countissignalq:std_logic_vector(3downto0);beginprocess(clk)beginif(clk'eventandclk='1')thenif(q=1000orq=0100orq=0010orq=0001)thenq=q(0)&q(3)&q(2)&q(1);elseq=1000;endif;endif;endprocess;y=q;end;--本电路具有自启动功能。一旦电路进入非法状态之后,电路会自动恢复合法状态。--由仿真波形可以看出,开机时电路进入“0000”非法状态,之后电路会自动跳出该非法状态而恢复合法状态“1000”。四、时序仿真结果:三、移位寄存器及其应用实例2-6串入串出移存器一、设计任务:设计一个4位串入串出移存器。二、算法设计:用if语句及数组赋值语句描述4位串入串出移存器。三、源程序shift4.vhdlibraryieee;useieee.std_logic_1164.all;entityshift4isport(clk,din:instd_logic;fo:outstd_logic);end;architectureaofshift4issignald:std_logic_vector(4downto0);beginprocess(clk)beginif(clk'eventandclk='1')thend(0)=din;d(4downto1)=d(3downto0);fo=d(4);endif;endprocess;end;四、时序仿真结果实例2-7串入串出双向移存器一、设计任务:设计一个4位串入串出双向移存器。二、算法设计:用if语句及循环语句描述4位串入串出双向移存器。三、源程序:shift4_4.vhdlibraryieee;useieee.std_logic_1164.all;entityshift4_4isport(dr,dl,clk:instd_logic;kz:inbit;fr,fl:outstd_logic);end;architectureaofshift4_4issignalq:std_logic_vector(3downto0);beginprocess(clk)beginif(clk'eventandclk='1')thenifkz='1'then--kz='1'时,移存器执行右移功能,右移输入信号是drq(0)=dr;loop1:foriin0to2loopq(i+1)=q(i);endloop;else--kz='0'时,移存器执行左移功能,左移输入信号是dlq(3)=dl;loop2:foriin1to3loopq(i-1)=q(i);endloop;endif;endif;fr=q(3);fl=q(0);endprocess;end;实例2-8串入并出移存器一、设计任务设计一个5位串入并出移存器。二、算法设计用if语句描述5位串入并出移存器。三、源程序libraryieee;useieee.std_logic_1164.all;entityshift4_5isport(shift,cr,clk:instd_logic;y:outstd_logic_vector(4downto0));end;architectureaofshift4_5issignaltemp_date:std_logic_vector(5downto0);beginp1:process(clk)beginif(clk'eventandclk='1')thenifcr='0'thentemp_date=(others='0');--表示各位均赋0elsiftemp_date(0)='0'thentemp_date=shift&01111;elsetemp_date=shift&temp_date(5downto1);endif;endif;endprocess;p2:process--输出串行输入的5位数据beginiftemp_date(0)='0'theny=temp_date(5downto1);elsey=00000;endif;endprocess;end;实例2-9并入串出移存器一、设计任务设计一个4位并入串出移存器。二、算法设计用if语句描述4位并入串出移存器。三、源程序libraryieee;useieee.std_logic_1164.all;useieee.std_logic_unsigned.all;entityshift4_6isport(cr,clk:instd_logic;shift:instd_logic_vector(3downto0);y:outstd_logic);end;architectureaofshift4_6issignalk:std_logic_vector(3downto0);signalq: