VHDL 例程

时间:2023-03-10 07:18:12
VHDL 例程

以下程序未经仿真,仅供说明

语法

声明参考库ieee,使用ieee中的std_logic_1164包全部条目可见

library ieee;
use ieee.std_logic_1164.all;

程序框架

要点是:

  1. 实体名和构造体名允许重复,都以“end 名字; ”结尾
  2. port 括号里最后一行没有分号。目前发现只有实体里的port括号、元件申明语句里面的port括号里面各条目间以“;”分隔,其他情况的括号里面各条目间以“,”分隔。
  3. 只有端口要标明信号方向如“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;

元件申明和调用

要点:

  1. 元件属性放在实体里
  2. 元件申明component开头,不用is,以end component结尾。目前发现只有Type state_type is (S0,S1,S2);、实体和构造体和case中才有is,只有实体和构造体以end 自己定的名字;结尾
  3. 注意参数映射、端口映射间没有逗号、分号
--被调用的元件
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;

状态机

要点是:两定义三进程

  1. 状态寄存器描述:clk,rst
  2. 下一状态描述:current_state,X
  3. 输出描述: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;