时序电路的ⅤHDL设计 Mealy状态机设计要点 设定若干状态; 用输入和状态控制进程 用case语句分别选择每一个状态; 用if语句确定输入条件,指定相应的下一状态和输出值 输出立即赋值(使用一个进程); 状态等待时钟条件满足再进行赋值(使用另一个进程) 例 Mealy状态机设计 该状态机具有4个状态,输入x,输出z;状态转换图如下所 /z 1/0 0/0 1/0 library ieee use ieee std logic 1164 all ity mealy is port(x,clk: in std le z: out std logic) end mealy architecture beh of mealy is type state is(sO, Sl, S2, $3); signal current state, next state: state
时序电路的 VHDL 设计 Mealy 状态机设计要点: 设定若干状态; 用输入和状态控制进程; 用 case 语句分别选择每一个状态; 用 if 语句确定输入条件,指定相应的下一状态和输出值; 输出立即赋值(使用一个进程); 状态等待时钟条件满足再进行赋值(使用另一个进程); 例 Mealy 状态机设计 该状态机具有 4 个状态,输入 x,输出 z;状态转换图如下所 示; library ieee; use ieee.std_logic_1164.all; entity mealy is port(x,clk: in std_logic; z: out std_logic); end mealy; architecture beh of mealy is type state is (s0,s1,s2,s3); signal current_state,next_state: state; begin
aaa process( current state, X case current state Is when s0=> if x=o' then z<=o' next state<=s0 else z<='l. next state<=s2: end if when sl=> if xo' then z<=0, next state<=sO else z<=0, next state<=s2: end if when s2=> if xeo then z<='I next state<=s2 else z<=o'- next state<=s3: end if when s3=> if x=o' then z<=o'. next state<=s3 else z<='l next state<=sl: end end process aaa sync process be wait until clk'event and clkel current state<=next state end process sync, end beh counter计数器 计数器通常以ck信号为基本输入,对输入信号进行计数: 在clk每个周期中改变一次计数器状态,状态可以输出; 经过n次计数后,计数器将回到初始状态,并给出进位输 出信号 计数器的ⅤHDL设计的要点在于正确安排状态的变化次 序,以及满足类型及运算的相容性; 例1p708表8-14
aaa:process(current_state,x) begin case current_state is when s0=> if x='0' then z<='0';next_state<=s0; else z<='1';next_state<=s2; end if; when s1=> if x='0' then z<='0';next_state<=s0; else z<='0';next_state<=s2; end if; when s2=> if x='0' then z<='1';next_state<=s2; else z<='0';next_state<=s3; end if; when s3=> if x='0' then z<='0';next_state<=s3; else z<='1';next_state<=s1; end if; end case; end process aaa; sync:process begin wait until clk'event and clk='1'; current_state<=next_state; end process sync; end beh; counter 计数器 计数器通常以 clk 信号为基本输入,对输入信号进行计数: 在 clk 每个周期中改变一次计数器状态,状态可以输出; 经过 n 次计数后,计数器将回到初始状态,并给出进位输 出信号; 计数器的 VHDL 设计的要点在于正确安排状态的变化次 序,以及满足类型及运算的相容性; 例 1 p.708 表 8-14
4位二进制加法计数器74163 具有同步复位,同步置数和进位控制功能 library ieee, use ieee std logic arith. all entity k74163 is port( clk, clrl, ldl, enp, ent: in std logic: d in unsigned (3 downto 0); g out unsigned (3 downto 0); rco: out std logic) end K74163 architecture beh of k74 163 is signal iq: unsigned (3 downto 0) process(clk, ent, iq) if clk'event and clk='l'then if clrl=o then iq<=(others=>0) elsif (ent and enp)='I then iq<=iq d if if(iq=15)and(ent=I")then rco<=l else rco<=O nd if end process end beh 将上述程序中的iq=iq-1,就构成减法计数器
4 位二进制加法计数器 74163 具有同步复位,同步置数和进位控制功能; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity k74163 is port ( clk,clrl,ldl,enp,ent: in std_logic; d: in unsigned (3 downto 0); q: out unsigned (3 downto 0); rco:out std_logic); end k74163; architecture beh of k74163 is signal iq: unsigned (3 downto 0); begin process (clk,ent,iq) begin if clk'event and clk='1' then if clrl='0' then iq<= (others=>'0'); elsif ldl='0' then iq<=d; elsif (ent and enp)='1' then iq<=iq+1; end if; end if; if (iq=15) and (ent='1') then rco<='1'; else rco<='0'; end if; q<=iq; end process; end beh; 将上述程序中的 iq<=iq-1,就构成减法计数器;
注意:对于 signed类型,在位数固定的条件下,加/减1的运 算可以自动产生循环,不会有进位或借位问题发生 若希望输入和输出都是 std logic类型,则可在程序中进 行如下变化 library ieee use ieee std logic 1164. all; use ieee std logic arith entity k74163 is port( clk, clrl,ldl, enp, ent: in std logic, d: in std logic vector(3 downto 0); g: out std logic vector (3 downto 0); rco: out std logic) end K74163 architecture beh of k74 163 is signal iq: unsigned (3 downto 0) process(clk, ent, ig) if clk'event and clke'I then if clrl=o' then iq<=(others=>0); elsif ldl=O' then iq<=unsigned(d) Isif(ent and enp)I' then iq<=iq+I end if end if if (iq=15)and(ent=I')then rco<='l else rco<=0 end process
注意:对于 usigned 类型,在位数固定的条件下,加/减 1 的运 算可以自动产生循环,不会有进位或借位问题发生; 若希望输入和输出都是 std_logic 类型,则可在程序中进 行如下变化: library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity k74163 is port ( clk,clrl,ldl,enp,ent: in std_logic; d: in std_logic_vector (3 downto 0); q: out std_logic_vector (3 downto 0); rco:out std_logic); end k74163; architecture beh of k74163 is signal iq: unsigned (3 downto 0); begin process (clk,ent,iq) begin if clk'event and clk='1' then if clrl='0' then iq<= (others=>'0'); elsif ldl='0' then iq<=unsigned(d); elsif (ent and enp)='1' then iq<=iq+1; end if; end if; if (iq=15) and (ent='1') then rco<='1'; else rco<='0'; end if; q<=iq+0; end process; end beh;
在p709表8-15中显示了余3码计数器,与74163相比,变 化为:只有10个状态(从3到12) 在状态12时输出进位信号 程序的改变只有两句: elseif (ent and enp)'I and (iq=12)then iq<=0011 if (iq=12)and(ent='I")then rco<=I 前一句指定加法循环的起点和终点;后一句指定进位信号 采用类似方案很容易构成任意进制的计数器: 计数器设计的一个关键问题在于电路综合的效果,很多 综合工具会将计数器的每一步(加1)作为一个加法器进行综 合,导致庞大的组合电路;为了避免出现这种情况,通常只 用上述方式构成小规模计数器,而对大规模计数器则采用结 构设计方式,由小规模计数器级连构成 例:16位加法二进制计数器的结构设计(模65536) 采用4个74163级连构成 library iee use ieee std logic 1164. all use ieee std logic arith. all entity kcount16 port( clk, clrl, ldl, en: in std log d: in unsigned (15 downto 0) q: out unsigned (15 downto 0) rco: out std logic)
在 p.709 表 8-15 中显示了余 3 码计数器,与 74163 相比,变 化为:只有 10 个状态(从 3 到 12) 在状态 12 时输出进位信号; 程序的改变只有两句: elseif (ent and enp)='1' and (iq=12) then iq<="0011"; if (iq=12) and (ent='1') then rco<='1'; 前一句指定加法循环的起点和终点;后一句指定进位信号; 采用类似方案很容易构成任意进制的计数器; 计数器设计的一个关键问题在于电路综合的效果,很多 综合工具会将计数器的每一步(加 1)作为一个加法器进行综 合,导致庞大的组合电路;为了避免出现这种情况,通常只 用上述方式构成小规模计数器,而对大规模计数器则采用结 构设计方式,由小规模计数器级连构成; 例: 16 位加法二进制计数器的结构设计(模 65536) 采用 4 个 74163 级连构成 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity kcount16 is port ( clk,clrl,ldl,en: in std_logic; d: in unsigned (15 downto 0); q: out unsigned (15 downto 0); rco:out std_logic);