530 likes | 700 Views
基本逻辑电路设计. 组合逻辑电路 时序电路设计 存储器. 组合逻辑电路设计. 简单门电路 编、译码器与选择器 加法器、求补器 三态门及总线缓冲器. a. y. &. b. 简单门电路. library IEEE; use IEEE.STD_LOGIC_1164.all; entity nand2 is port( a : in STD_LOGIC; b : in STD_LOGIC; y : out STD_LOGIC ); end nand2; architecture nand2 of nand2 is
E N D
基本逻辑电路设计 • 组合逻辑电路 • 时序电路设计 • 存储器
组合逻辑电路设计 • 简单门电路 • 编、译码器与选择器 • 加法器、求补器 • 三态门及总线缓冲器
a y & b 简单门电路 library IEEE; use IEEE.STD_LOGIC_1164.all; entity nand2 is port( a : in STD_LOGIC; b : in STD_LOGIC; y : out STD_LOGIC ); end nand2; architecture nand2 of nand2 is begin y<=a nand b; end nand2;
architecture nand2 of nand2 is begin process(a,b) variable comb:std_logic_vector(1 downto 0); comb:=a&b; case comb is when "00"=>y<='1'; when "01"=>y<='1'; when “10"=>y<='1'; when “11"=>y<='0'; when others=>y<='Z'; end case; end process; end nand2;
a y + b 或非门 y<= a nor b; case comb is when "00"=>y<='1'; when "01"=>y<='1'; when “10"=>y<='1'; when “11"=>y<='0'; when others=>y<='Z'; end case;
a y 反相器 y<=not a; if a='1' then y<='0'; else y<='1'; end if;
a y + b 异或门 y<=a xor b; case comb is when "00"=>y<=‘0'; when "01"=>y<='1'; when “10"=>y<='1'; when “11"=>y<='0'; when others=>y<='Z'; end case;
d0 y1 d1 y0 d2 d3 编码器 IF (d(0) = ‘0’)THEN q <= “11”; ELSIF (d(1)=‘0’) THEN q <= “10”; ELSIF(d(2)=‘0’) THEN q<=“01”; ELSE q <= “00”; END IF;
译码器 Case a is When “000”=>q<=“11111110”; When “001” =>q<=“11111101”; ….. When “111” =>q<=“01111111”; When orthers =>q<=“ZZZZZZZZ”; End case; Else Q<=“ZZZZZZZZ”; End if;
a b y1 c d y0 Sel[1..0] 选择器 if sel="00" then y<=a; elsif sel="01" then y<=b; elsif sel="10" then y<=c; else y<=d; end if;
s a 半加器 co b 半加器 半加器真值表
library IEEE; use IEEE.STD_LOGIC_1164.all; entity half_adder is port( a : in STD_LOGIC; b : in STD_LOGIC; s : out STD_LOGIC; co : out STD_LOGIC ); end half_adder; architecture half_adder of half_adder is signal c,d:std_logic; begin c<=a or b; d<=a nand b; co<=not d; s<=c and d; end half_adder;
u1 u2 U0_s a s 半加器 半加器 U0_co b co + cin 全加器
library IEEE; use IEEE.STD_LOGIC_1164.all; entity full_adder is port( a,b,cin : in STD_LOGIC; co,s : out STD_LOGIC); end full_adder; architecture full_adder of full_adder is component half_adder port( a,b : in STD_LOGIC; s,co : out STD_LOGIC ); end component ; signal u0_co,u0_s,u1_co:std_logic; begin u0:half_adder port map(a,b,u0_s,u0_co); u1:half_adder port map(u0_s,b,cin,s,u1_co); co<=u0_co or u1_co; end full_adder;
三态门 if en='1' then dout<=din; else dout<='Z'; end if;
单向总线缓冲器 if en='1' then dout<=din; else dout<=“ZZZZZZZZ”; end if;
b a 缓冲器 dr en 双向缓冲器 双向总线缓冲器真值表
process(a,dr,en) begin if en='0' and dr='1' then bout<=a; else bout<="ZZZZZZZZ"; end if; b<=bout; end process; process(a,dr,en) begin if en='0' and dr='0' then aout<=b; else aout<="ZZZZZZZZ"; end if; a<=aout; end process;
时序电路的设计 • 时钟信号和复位信号 • 触发器 • 寄存器 • 计数器
时钟信号 • 上升沿 clk’event and clk = ‘1’ rising_edge(clk) • 下降沿 clk’event and clk = ‘0’ falling_edge(clk)
普通d触发器 if clk'event and clk='1' then q<=d; end if;
非同步D触发器 process(clk,rst) begin if rst='1' then q<='0'; elsif clk'event and clk='1' then q<=d; end if; end process;
非同步复位/置位触发器 process(clk,rst,pset) begin if rst='1' then q<='0'; elsif pset='0' then q<='1'; elsif clk'event and clk='1' then q<=d; end if; end process;
同步复位的d触发器 process(clk,rst,pset) begin if clk'event and clk='1' then if rst='1' then q<='0'; else q<=d; end if; end if; end process;
dffx(1) dffx(2) dffx(3) dffx(0) b a q q q q d d d d clk clk clk clk clk 寄存器
architecture shift of shift is begin component dff port (d,clk: in std_logic; q: out std_logic); end component ; signal z:std_logic_vector(0 to 4); begin z(0)<=a; g1:for i in 0 to 3 generate dffx:dff port map (z(i),clk,z(i+1)); end generate; b<=z(4); end shift;
同步计数器 所谓同步计数器,就是在时钟脉冲的控制下,构成计数器的各触发器状态同时发生变化的那一类计数器 可逆计数器 process(clk,rst) begin if rst='1' then count<=(others=>'0'); elsif clk'event and clk='1' then if updn='1' then count<=count+1; else count<=count-1; end if; end if; end process;
q q q q q d d d d d clk clk clk clk clk count0 count1 count2 count3 qn qn qn qn 异步计数器 • 异步计数器又称行波计数器,它的下一位计数器的输出作为上一位计数器的始终信号。 clk
library IEEE; use IEEE.STD_LOGIC_1164.all; entity rplcont is port( clk : in STD_LOGIC; count : out STD_LOGIC_VECTOR(7 downto 0)); end rplcont; architecture rplcont of rplcont is signal count_in_bar:std_logic_vector(7 downto 0); component dff port (clk,d:in std_logic; q,qb:out std_logic); end component ; begin count_in_bar(0)<=clk; gen1:for i in 0 to 7 generate U:dff port map (clk=>count_in_bar(i), d=>count_in_bar(i+1), q=>count(i),qb=>count_in_bar(i+1)); end generate; end rplcont;
存储器 • 建议使用宏功能模块
组合逻辑 输出译码器 输出 输入 状态 状态译码器 状态寄存器 反馈 状态机的VHDL设计 扩展内容 状态机的结构示意图
状态机的基本操作 • 状态机内部状态转换。状态机的下一个状态由译码器根据当前状态和输入条件决定。 • 产生输出信号序列。输出信号由输出译码器根据当前状态和输入条件决定。
状态机的分类 • 一般状态机 • MOORE状态机 • MEALY状态机
一般状态机的设计 • 为了能获得可综合的,高效的vhdl状态描述,建议使用枚举数据类型来定义状态机的状态,并使用多进程方式来描述状态机的内部逻辑。 • 一般情况下,一个进程描述时序逻辑,包括状态寄存器的工作和寄存器状态的输出。另一个进程描述组合逻辑,包括进程间状态值的传递逻辑以及状态以及状态转换值的输出。必要时还可以引入第三个进程完成其他的逻辑功能。
一般状态机实例 library IEEE; use IEEE.STD_LOGIC_1164.all; entity s_machine is port( clk : in STD_LOGIC; rst : in STD_LOGIC; state_input : in STD_LOGIC_VECTOR(1 downto 0); comb_output : out STD_LOGIC_VECTOR(1 downto 0) ); end s_machine; architecture s_machine of s_machine is type states is (st0,st1,st2,st3); signal cur_state,next_state : states;
begin process(clk,rst) begin if rst='1' then cur_state<=st0; elsif clk'event and clk='1' then cur_state<=next_state; end if; end process; process(cur_state,next_state) begin case cur_state is when st0=>comb_output<="00"; if state_input="00" then next_state<=st0; else next_state<=st1; end if; when st1=>comb_output<="01"; if state_input="00" then
next_state<=st1; else next_state<=st2; end if; when st2=>comb_output<="10"; if state_input="11" then next_state<=st2; else next_state<=st3; end if; when st3=>comb_output<="11"; if state_input="11" then next_state<=st3; else next_state<=st0; end if; end case; end process; end s_machine;
0/0 1/0 s0 s1 0/0 1/0 0/0 0/0 1/1 s3 s2 1/1 111序列检测器 • 例:111序列检测器的功能是连续输入三个或三个以上的1时,电路输出为1,其余情况下输出为0。 s0:初始状态,电路还未收到一个有效1 s1:收到一个1后的状态 S2:连续收到两个1后的状态 s3:连续收到三个1个后的状态
111序列检测器程序 library IEEE; use IEEE.STD_LOGIC_1164.all; entity s_machine is port( clk : in STD_LOGIC; rst : in STD_LOGIC; din : in STD_LOGIC; comb_output : out STD_LOGIC ); end s_machine; architecture s_machine of s_machine is type states is (st0,st1,st2,st3); signal cur_state,next_state : states;
begin process(clk,rst) begin if rst='1' then cur_state<=st0; elsif clk'event and clk='1' then cur_state<=next_state; end if; end process; process(cur_state,next_state) begin case cur_state is when st0=>comb_output<=‘0’; if din=‘1’ then next_state<=st1; else next_state<=st0; end if; when st1=>comb_output<=‘0’; if din=‘1’ then
next_state<=st2; else next_state<=st0; end if; when st2=> if din=‘1’ then next_state<=st3; comb_output<=‘1’; else next_state<=st0; comb_output<=‘0’; end if; when st3=> if state_input=‘1’ then next_state<=st3; comb_output<=‘1’; else next_state<=st0; comb_output<=‘0’; end if; end case; end process; end s_machine;
思考题 • 设计任务:设计一个自动售货机控制程序,它的投币口每次可以投入1元、2元、5元,且规定投入1元或2元后不得再投入5元。当投入总值等于或超过设定值(4元),售货机就自动送出货物并找回多余的钱。 • 基本要求:按照上面要求,编写程序,实现售单一商品的功能。(10分) • 扩展要求:在基本要求的基础上,完善电路,实现售多个商品的功能(设定值应该相应增加)。(5分) 撰写完整的设计报告于13周上课时上交。 报告内容要求:详细的设计方案,设计程序(关键部分应该有注释),仿真波形,设计中存在的问题及改进措施。 报告形式:打印稿
提示 信号输入: din=00 未投币 din=01 投入1元 din=10 投入2元 din=11 投入5元 状态:s0 初始状态,还没有收到投币; s1 收到1元; s2 收到2元; s3 收到3元; 输出:commodity 控制送出商品,1为送出; give_change控制找钱,分析题目要求,找钱只有两种情况(不找或找1元钱)。
Moore状态机 • Moore状态机的输出只与有限状态自动机的当前状态有关,与输入信号的当前值无关。 Moore有限状态机在时钟CLOCK脉冲的有效边沿后的有限个门延后,输出达到稳定值。即使在一个时钟周期内输入信号发生变化,输出也会在一个完整的时钟周期内保持稳定值而不变。输入对输出的影响要到下一个时钟周期才能反映出来。 • Moore有限状态机最重要的特点就是将输入与输出信号隔离开来。
Mealy状态机 • Mealy状态机与Moore有限状态机不同,Mealy有限状态机的输出不单与当前状态有关,而且与输入信号的当前值有关。 • Mealy有限状态机的输出直接受输入信号的当前值影响,而输入信号可能在一个时钟周期内任意时刻变化,这使得Mealy有限状态机对输入的响应发生在当前时钟周期,比Moore有限状态机对输入信号的响应要早一个周期。因此,输入信号的噪声可能影响在输出的信号。
OE CLK START ALE OE START RST ALE CS CS DIN[7..0] RD DIN[7..0] RD 控制器 6264 WR ADC0809 WR EOC RAM_DIN[7..0] EOC RAM_DIN[7..0] ADDRESS[12..0] ADDA ADDRESS[12..0] ADDA 状态机实例
控制器程序 library IEEE; use IEEE.STD_LOGIC_1164.all; use ieee.std_logic_unsigned.all; entity adtosram is port( clk : in STD_LOGIC; --工作时钟 rst : in STD_LOGIC; --复位 eoc : in STD_LOGIC; --转换结束标志 din : in STD_LOGIC_VECTOR(7 downto 0); oe : out STD_LOGIC; start : out STD_LOGIC; ale : out STD_LOGIC;--地址锁存允许 cs : out STD_LOGIC; rd : out STD_LOGIC; wr : out STD_LOGIC; adda : out STD_LOGIC; --AD地址线最低位 ram_din : out STD_LOGIC_VECTOR(7 downto 0); address : out STD_LOGIC_VECTOR(12 downto 0) ); end adtosram;
architecture adtosram of adtosram is type ad_states is (st0,st1,st2,st3,st4,st5,st6,st7); type writ_states is (start_write,write1,write2,write3,write_end); signal ram_current_state,ram_next_state:writ_states; signal adc_current_state,adc_next_state:ad_states; signal adc_end:std_logic; signal lock: std_logic; --转换后数据输出锁存信号 signal enable:std_logic; --ad转换允许信号,高电平有效 signal addres_plus:std_logic;--sram地址加1时钟信号 signal adc_data:std_logic_vector(7 downto 0); signal addres_cnt:std_logic_vector(12 downto 0); begin adda<=‘1’; --选择通道1 rd<=‘1’; -- 禁止写sram adc:process(adc_current_state,eoc,enable) –ad转换组合电路进程 begin if rst='1' then adc_next_state<=st0; else case adc_current_state is
when st0=>ale<='0';start<='0'; oe<='0'; lock<=‘0’; adc_end<=‘0’; --ad转换初始化 if enable=‘1’ then adc_next_state<=st1;--允许转换,转下一状态 else adc_next_state<=st0; --禁止转换,仍停留在本状态 end if; when st1=>ale<='1';start<='0'; oe<='0'; lock<='0'; adc_end<='0'; adc_next_state<=st2; --通道选择地址锁存,并转下一状态 when st2=>ale<='1';start<='1'; oe<='0'; lock<='0'; adc_end<='0'; adc_next_state<=st3; --启动ad转换信号start when st3=>ale<='1';start<='1'; oe<='0'; lock<=‘0’; adc_end<=‘0’; --延迟一个脉冲周期 if eoc='1' then adc_next_state<=st4; else adc_next_state<=st3; end if; when st4=>ale<='0';start<='0'; oe<='0'; lock<='0'; adc_end<='0'; if eoc=‘1’ then adc_next_state<=st5; --转化结束,转下一状态
else adc_next_state<=st4; end if; when st5=>ale<='0';start<='0'; oe<='1'; lock<=‘1’; adc_end<=‘1’; --开启数据输出使能信号oe adc_next_state<=st6; --开启数据锁存信号 when st6=>ale<='0';start<='0'; oe<='1'; lock<='1'; adc_end<='1'; adc_next_state<=st7; when st7=>ale<='0';start<='0'; oe<='1'; lock<='1'; adc_end<='1'; adc_next_state<=st0; when others=>adc_next_state<=st0; end case; end if; end process adc;