VHDL 例程
以下程序未经仿真,仅供说明
语法
声明参考库ieee,使用ieee中的std_logic_1164包全部条目可见
library ieee;
use ieee.std_logic_1164.all;
程序框架
要点是:
- 实体名和构造体名允许重复,都以“end 名字; ”结尾
- port 括号里最后一行没有分号。目前发现只有实体里的port括号、元件申明语句里面的port括号里面各条目间以“;”分隔,其他情况的括号里面各条目间以“,”分隔。
- 只有端口要标明信号方向如“in、out”,如实体里、元件声明里的port
library ieee;
use ieee.std_logic_1164.all;
entity mux is
port(d0,d1,sel:in std_logic;
q:out std_logic);
end mux;
architecture rtl of mux is
begin
process(d0,d1,sel)
begin
if(sel='0')then
q<=d0;
elsif(sel='1')then
q<=d1;
else
q<='Z';
end if;
end process;
end rtl;
元件申明和调用
要点:
- 元件属性放在实体里
- 元件申明component开头,不用is,以end component结尾。目前发现只有
Type state_type is (S0,S1,S2);
、实体和构造体和case中才有is,只有实体和构造体以end 自己定的名字;
结尾 - 注意参数映射、端口映射间没有逗号、分号
--被调用的元件
library ieee;
use ieee.std_logic_1164.all;
entity and2_gate is
generic(delay:time);
port (
in1,in2:in std_logic;
out1:out std_logic);
end and2_gate;
architecture beh of and2_gate is
begin
out1<=in1 and in2 after delay;
end beh;
--当前设计
library ieee;
use ieee.std_logic_1164.all;
entity nand2 is
port(a,b:in std_logic;
q:out std_logic);
end nand2;
architecture structure of nand2 is
component and2_gate
generic(delay:time);
port (
in1,in2:in std_logic;
out1:out std_logic);
end component;
signal pass_state:std_logic;
begin
q<=not pass_state;
u1: and2_gate
generic map(5 ns)
port map( a,b,pass_state);
end structure;
并行语句
所谓并行是:本语句和其他语句并发执行没有先后
并行赋值语句:条件信号赋值、选择信号赋值。process中只能有简单赋值和顺序描述语句
只有条件信号赋值和if语句才有else
-----------条件信号赋值,有优先级
t<=a when sel='0' else
b when sel='1' else
'X';
-----------选择信号赋值,有优先级
with sel select
v<=a when '0',
b when '1',
'X' when others;
顺序语句
顺序语句可以放在process里面,并行语句放在process外面
if是顺序语句,可以用来实现有优先级的分支
case 是顺序描述语句,各个分支没有优先级,各分支条件需穷举且不重复。
case sel is
when "00"=>q<=a;
when "01"=>q<=b;
when "10"=>q<=c;
when others=>q<=d;
end case;
组合电路
基本逻辑门
门名称 | 符号 |
---|---|
与门 | and |
或门 | or |
非门 | not |
与非 | nand |
或非 | nor |
异或 | xor |
编程方法一
library ieee;
use ieee.std_logic_1164.all;
entity and2 is
port(
a,b:in std_logic;
y :out std_logic
);
end and2;
architecture rtl of and2 is
begin
y<=a and b;
end rtl;
编程方法二
library ieee;
use ieee.std_logic_1164.all;
entity and2 is
port(a,b:in std_logic;
y:out std_logic);
end and2;
architecture rtl of and2 is
begin
process(a,b)
variable comb:std_logic_vector(1 downto 0);
begin
comb:=a&b;
case comb is
when "00"|"01"|"10"=>y<='0';
when "11"=>y<='1';
when others=>y<='X';
end case;
end process;
end rtl;
38译码器
library ieee;
use ieee.std_logic_1164.all;
entity decoder38 is
port(a,b,c,g1,g2a,g2b:in std_logic;
y:out std_logic_vector(7 downto 0));
end decoder38;
architecture rtl of decoder38 is
signal indata:std_logic_vector(2 downto 0);
begin
indata<=a&b&c;
process(indata,g1,g2a,g2b)
begin
if(g1='1' and g2a='0' and g2b='0')then
case indata is
when "000"=>y<=B"1111_1110";
when "001"=>y<=B"1111_1101";
when "010"=>y<=B"1111_1011";
when "011"=>y<=B"1111_0111";
when "100"=>y<=B"1110_1111";
when "101"=>y<=B"1101_1111";
when "110"=>y<=B"1011_1111";
when "111"=>y<=B"0111_1111";
when others=>y<=B"1111_1111";
end case;
else
y<="11111111";
end if;
end process;
end rtl;
83优先级编码器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity priorityencoder is
port(input:in std_logic_vector(7 downto 0);
y:out std_logic_vector(2 downto 0));
end priorityencoder;
architecture rtl of priorityencoder is
begin
process(input)
begin
if(input(0)='0')then
y<="111";
elsif(input(1)='0')then
y<="110";
elsif(input(2)='0')then
y<="101";
elsif(input(3)='0')then
y<="100";
elsif(input(4)='0')then
y<="011";
elsif(input(5)='0')then
y<="010";
elsif(input(6)='0')then
y<="001";
else
y<="000";
end if;
end process;
end rtl;
选择器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity mux4 is
port(input:in std_logic_vector(3 downto 0);
a,b:in std_logic;
y:out std_logic);
end mux4;
architecture rtl of mux4 is
signal sel:std_logic_vector(1 downto 0);
begin
sel<=a&b;
process(sel,input)
begin
if(sel="00")then
y<=input(0) ;
elsif(sel="01")then
y<=input(1) ;
elsif(sel="10")then
y<=input(2) ;
elsif(sel="11")then
y<=input(3);
else
y<='Z';
end if;
end process;
end rtl;
比较器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity comp4 is
port(a,b:in std_logic;
GT:out std_logic;
EQ:out std_logic;
LT:out std_logic);
end comp4;
architecture rtl of comp4 is
begin
process(a,b)
begin
if(a>b)then
GT<='1';EQ<='0';LT<='0';
elsif(a=b)then
GT<='0';EQ<='1';LT<='0';
else
GT<='0';EQ<='0';LT<='1';
end if;
end process;
end rtl;
减法器
library ieee;
use ieee.std_logic_1164.all;
entity subtracter is
port(x,y,cin:in std_logic;
sub,cout:out std_logic);
end subtracter;
architecture rtl of subtracter is
begin
sub<=x xor y xor cin;
cout<=(not x and y)or (not x and cin)or (y and not cin);
end rtl;
时序电路
异步D触发器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity dffAsync is
port(clk,d,clr_n:in std_logic;
q:out std_logic);
end dffAsync;
architecture rtl of dffAsync is
begin
process(clk,clr_n)
begin
if(clr_n='0')then
q<='0';
elsif (clk'EVENT and clk='1')then
q<=d;
end if;
end process;
end rtl;
同步D触发器
library ieee;
use ieee.std_logic_1164.all;
entity dffSync is
port(d,clk,clr_n:in std_logic;
q:out std_logic);
end dffSync;
architecture rtl of dffSync is
begin
process(clk) --同步复位敏感信号表不需要复位信号
begin
if(clk'EVENT and clk='1')then
if (clr_n='0')then
q<='0';
else
q<=d;
end if;
end if;
end process;
end rtl;
T触发器
library ieee;
use ieee.std_logic_1164.all;
entity tff is
port(clk:in std_logic;
q:out std_logic);
end tff;
architecture rtl of tff is
signal temp:std_logic:='0';
begin
process(clk)
begin
if(clk'EVENT and clk='1')then
temp<=not temp;
end if;
end process;
q<=temp;
end rtl;
RS触发器
--rs触发器
library ieee;
use ieee.std_logic_1164.all;
entity rsff is
port(r,s:in std_logic;
q,qn:out std_logic);
end rsff;
architecture rtl of rsff is
signal qtemp,qntemp:std_logic;
begin
qtemp<=r nor qntemp;
qntemp<=qtemp nor s;
q<=qtemp;
qn<=qntemp;
end rtl;
八位寄存器
--8位锁存寄存器
library ieee;
use ieee.std_logic_1164.all;
entity register8 is
port(clk,reset_n:in std_logic;
d:in std_logic_vector(7 downto 0);
q:out std_logic_vector(7 downto 0));
end register8;
architecture rtl of register8 is
signal qtemp:std_logic_vector(7 downto 0);
begin
process(clk,reset_n)
begin
if(reset_n='0')then
qtemp<="00000000";
elsif (clk'EVENT and clk='1')then
q<=qtemp;
end if;
end process;
q<=qtemp;
end rtl;
6位串入串出移位寄存器
library ieee;
use ieee.std_logic_1164.all;
entity siso6 is
port(d,clk:in std_logic;
q:out std_logic);
end siso6;
architecture rtl of siso6 is
component dff
port(d,clk:in std_logic;
q:out std_logic);
end component;
signal z:std_logic_vector(0 to 6);
begin
z(0)<=d;
g:for i in 0 to 5 generate
dff_map: dff
port map(
d=>z(i),
clk=>clk,
q=>z(i+1)
);
end generate;
q<=z(6);
end rtl;
上面的程序调用的D触发器写在下面
library ieee;
use ieee.std_logic_1164.all;
entity dff is
port(d,clk:in std_logic;
q:out std_logic);
end dff;
architecture rtl of dff is
begin
process(clk)
begin
if clk'EVENT and clk='1' then
q<=d;
end if;
end process;
end rtl;
另一种行为级写法
library ieee;
use ieee.std_logic_1164.all;
entity siso6_v2 is
port(d,clk:in std_logic;
q,qn:out std_logic);
end siso6_v2;
architecture rtl of siso6_v2 is
signal temp:std_logic_vector(5 downto 0);
signal temp1:std_logic_vector(5 downto 0);
begin
--这一段是为了比较
process(clk)
begin
if clk'EVENT and clk='1' then
temp(4 downto 0)<=temp(5 downto 1);
temp(5)<=d;
end if;
end process;
--保留下面这段即可
process(clk)
begin
if clk'EVENT and clk='1' then
temp1(5)<=d;
temp1(4 downto 0)<=temp1(5 downto 1);
end if;
end process;
qn<=temp1(0);
q<=temp(0);
end rtl;
十进制计数器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity count10en is
port(clk,clr,en:in std_logic;
qa,qb,qc,qd:out std_logic);
end count10en;
architecture rtl of count10en is
signal count:std_logic_vector(3 downto 0) ;
begin
process(clk,clr)
begin
if(clr='1')then
count<="0000";
elsif clk'EVENT and clk='1' then
if en='1' then
if(count="1001")then
count<="0000";
else
count<=count+1;
end if;
end if;
end if;
end process;
qa<=count(0);
qb<=count(1);
qc<=count(2);
qd<=count(3);
end rtl;
可逆计数器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity countReversible is
port(clk,clr,updown:in std_logic;
qa,qb,qc,qd:out std_logic);
end countReversible;
architecture rtl of countReversible is
signal count:std_logic_vector(3 downto 0);
begin
process(clk)
begin
if(clr='1')then
count<="0000";
elsif(clk'EVENT and clk='1')then
if(updown='1')then
count<=count+1;
else
count<=count-1;
end if;
end if;
end process;
qa<=count(0);
qb<=count(1);
qc<=count(2);
qd<=count(3);
end rtl;
6分频器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity clk_div6 is
port(clk,clr:in std_logic;
clk_div6:out std_logic);
end clk_div6;
architecture rtl of clk_div6 is
signal count:std_logic_vector(1downto 0);
signal clk_temp:std_logic;
begin
process(clk,clr)
begin
if(clr='1')then
count<="00";
clk_temp<='0';
elsif clk'EVENT and clk='1' then
if count="10" then
count<="00";
clk_temp<=not clk_temp;
else
count<=count+1;
end if;
end if;
end process;
clk_div6<=clk_temp;
end rtl;
数控N分频
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity ClkDiv is
port(
clk_i:IN STD_LOGIC;
N_i: IN STD_LOGIC_VECTOR(9 DOWNTO 0);
clk_o:OUT STD_LOGIC);
end ClkDiv;
architecture behavior of ClkDiv is
signal count:STD_LOGIC_VECTOR(9 DOWNTO 0):="0000000001";
signal clk_temp:STD_LOGIC:='0';
begin
process(clk_i)
begin
if(clk_i'EVENT and clk_i='1')then
if (count=N_i)then
count<="0000000001";
clk_temp<='1';
else
count<=count+1;
clk_temp<='0';
end if;
end if;
end process;
clk_o<=clk_temp;
end behavior;
状态机
要点是:两定义三进程
- 状态寄存器描述:clk,rst
- 下一状态描述:current_state,X
- 输出描述:current_state
--引入状态编码的两定义
constant s0:std_logic_vector(1 downto 0):="00";
constant s1:std_logic_vector(1 downto 0):="01";
constant s2:std_logic_vector(1 downto 0):="11";
signal current_state:std_logic_vector(1 downto 0);
signal next_state:std_logic_vector(1 downto 0);
--一般的两定义
type state_type is (S0,S1,S2,S3,S4);
signal current_state,next_state:state_type;
moore机
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity moore is
port(clk,rst,X:in std_logic;
Z:out std_logic);
end moore;
architecture behavior of moore is
type state_type is (S0,S1,S2,S3);
signal current_state,next_state:state_type;
begin
--状态寄存器描述
sync:process(clk,rst)
begin
if clk'EVENT and clk='1' then
if rst='1' then
current_state<=S1;
else
current_state<=next_state;
end if;
end if ;
end process;
--下一转态描述
state_trans:process(current_state,X)
begin
case current_state is
when S0=>
if X='0' then
next_state<=S0;
else
next_state<=S2;
end if;
when S1=>
if X='0' then
next_state<=S0;
else
next_state<=S2;
end if;
when others=>
next_state<=S1;
end case;
end process;
--输出描述
output:process(current_state)
begin
case current_state is
when S0=>Z<='0';
when S1=>Z<='1';
when others=>Z<='0';
end case;
end process;
end behavior ;
mealy机
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity mealy is
port(clk,clr,X:in std_logic;
Z:out std_logic);
end mealy;
architecture rtl of mealy is
type state_type is (S0,S1,S2,S3);
signal current_state,next_state:state_type;
begin
--寄存器描述
sync:process(clk,clr,next_state)
begin
if clk'EVENT and clk='1' then
if clr='1' then
current_state<=S0;
else
current_state<=next_state;
end if;
end if;
end process;
--下一状态描述、输出描述
combin:process(current_state,X)
begin
case current_state is
when S0=>
if X='0'then
next_state<=S0;
Z<='1';
else
next_state<=S1;
Z<='0';
end if;
when others=>
next_state<=S0;
Z<='0';
end case;
end process;
end rtl;
testbench
library ieee;
use ieee.std_logic_1164.all;
entity siso6_v2_tb is
end siso6_v2_tb;
architecture TB_ARCHITECTURE of siso6_v2_tb is
component siso6_v2
port(
d : in STD_LOGIC;
clk : in STD_LOGIC;
q,qn : out STD_LOGIC );
end component;
signal d : STD_LOGIC;
signal clk : STD_LOGIC;
signal q ,qn: STD_LOGIC;
begin
UUT : siso6_v2
port map (
d => d,
clk => clk,
q => q ,
qn => qn
);
--时钟
process
begin
clk<='1';
wait for 50ns;
clk<='0';
wait for 50ns ;
end process ;
d<='1',
'0' after 1000ns,
'1' after 1200ns,
'0' after 1300ns,
'1' after 1500ns;
end TB_ARCHITECTURE;