EDA 第五章 VHDL设计进阶

时间:2021-03-01 20:32:27

第五章   VHDL设计进阶
1,数据对象有三类,变量,常量,信号
2,常量定义:
   constant  常数名:数据类型  :=表达式
   constant fat:  STD_LOGIC_VECTOR    :="1011"
   STD_LOGIC_VECTOR标准位矢类型
   INTEGER整数类型
常数在程序包,设计实体,具有全局化特征,如果常数在设计实体的某一结构体中,则只能用于此结构体中
3,变量
  变量是一个局部量,只能在进程和子程序中使用。变量的赋值,是一中理想化的输入,不存在任何延时行为
  定义    variable  变量名 :  数据类型 :=初始化
     variable  a:  integer  range  0  to 15;变量a定义为常数,取值范围0——15
     variable  d:  std_logic  :='1'  变量d定义为标准逻辑位类型                                                                                         

                                                                            
 
  变量的赋值语句:=‘表达式’
  variable  x,y :   integer range 15 dowmto   0;取值范围为0——15
  variable  a,b  :   std_logic_vector( 7 dowmto  0);表示有8位
  x:= 11;
  y:=2 + x;
  a:=b;
  a(0 to 5):=b(2 to 7);
4,信号  
  信号具有记忆和延时 行为
  signal 信号名: 数据类型 :=初始化
  与变量相比,信号的硬件特征更为明显,它具有全局性特征                                                       
  信号和实体的端口概念是一致的,对于端口来说只是输出端口不能输入数据,输入端口不能被赋值。信号可看成实体内部的端口。
  信号的使用和定义范围是  实体,结构体和程序包。在进程和子程序的顺序语句中不允许定义信号
  赋值:
   目标信号名  <= 表达式
  信号的赋值可以在进程中,也可以在结构体的并行语句中,在进程中信号可以被多次赋值,但是有效的是最后一个,并行语句中信号不允许被多次赋值
   signal a,b,c,y,z: integer;
.....
   process(a,b,c)
   begin
   y<=a+b;
   z<=c-b;
   y<=b;
   end process;
 5.进程中信号赋值和变量赋值
   变量和信号相当于逻辑电路系统中的连线和连线上的信号值;常量相当于恒电平;
   信号可以设置传输延迟量,而变量则不能,变量只能作为局部的信息载体,信号可以作为信息传输和界面间的通信。
  信号用作为电路中的信号连线,变量用于进程中局部数据存储单元。

 使用变量赋值的d触发器
 architcture  bhv  of  dff3  is        ;结构体
 begin
 process(clk)
    variable qq : std_logic;
 begin
   if clk'event  and clk='1'
   then qq: =d1;
   end if;
   q1<=qq;
 end process;
 end;
 使用信号赋值的d触发器
 architctrue  bhv of dff3 is
   signal qq : std_logic;
 begin
 process(clk)
 begin
 if clk'event and clk ='1';
 then qq<=d1;
 end if;
 end process;
 q1<=qq;
 end;
变量的赋值只能放在进程中,信号中同一语句放在进程内外都可以、

再看下面两个程序:
 使用信号赋值:
 library ieee;
 use ieee.std_logic_1164.all;
 entity dff3 is
 port( clk,d1: in std_logic;
       q1:     out std_logic);
 end;
 architcture bhv of dff3 is
   signal a,b : logic;
 begin
 process(clk)
 begin
 if clk'event and clk='1'
 then
 a<=d1;
 b<=a;
 q1<=b;
 end if;
 end process;
 end;
使用变量赋值:
 library ieee;
 use ieee.std_logic_1164.all;
 entity dff3 is
 port(clk,d1 : in std_logic ;
          q1:   out std_logic);
 end;
 architecture bhv of dff3 is
 begin
 process(clk)
 variable a,b :std_logic;
 begin
 if clk'event and clk='1'
 then
  a:=d1;
  b:=a;
  q1<=b;
 end if ;
 end process;
 end;
这两个例子,不同: 使用信号的是三个d触发器的连接,使用变量的是仍然一个触发器。
一个进程的赋值特点,所有赋值语句(变量和信号)都必须在一个&延时内完成,即,一个进程的
运行时间固定为一个&延时。执行赋值和完成赋值是两个不同的概念。
6,信号被多次赋值时候,只有最后一个才有效。。。
  看一个使用变量的4选1多路选择器。
 library ieee;
 use ieee.std_logic_1164.all;
 entity mux4 is
 port( i0,i1,i2,i3,a,b: in std_logic;
       q: out std_logic);
 end mux4;
 architecture body_mux4 of mux4 is
 begin
 process(i0,i1,i2,i3,a,b)
 variable  muxval : integer range 7 downto 0;
 begin
 muxval :=0;
 if(a='1') then muxval :=muxval+1; end if;
 if(b='1') then muxval :=muxval+2; end if;
 case muxval is
     when 0 => q<=i0;
     when 1 => q<=i1;
     when 2 => q<=i2;
     when 3 => q<=i3;
     when other =>null;
 end case;
 end process;
 end  body_mux4;
7,VHDL设计实例及语法内涵
含有同步并行预置功能的8位移位寄存器设计
电路的工作原理: 当clk上升沿到来时,进程被启动,如果这时候预置使能load为高电平,则将输入端口的8位二进制数
并行置入移位寄存器中,作为串行右移输出的初始值,如果预置使能load为低电平,则执行:
reg8(6 downto 0)<= reg8(7 downto 1);

串行移空的最高位始终由最初并行预置数的最高位填补。
library ieee;
use ieee.std_logic1164.all;
entity shft is
 port(clk,load:in std_logic;
      din : in std_logic_vector(7 downto 0);
      dout : out std_logic_vector(7 downto 0);
      qb:   out std_logic);
end shft;
architecture behav of shft is
signal  reg8 : std_logic_vector(7 downto 0);
begin
process(clk,load)
begin
if clk'event and clk='1' then
  if  load='1' then reg8<=din;
     else   reg8(6 downto 0)<= reg8(7 downto 1);  
   end if;
end if;
end process;
qb<=reg8(0);
dout=reg8;
end behav;
8,移位可控的8位移位寄存器设计
library ieee;
use ieee.std_logic_1164.all;
entity shft is
  port( clk,co : in std_logic;     co是进位输入
        md  : in std_logic_vector(2 downto 0);
        d:  in std_logic_vector(7 downto 0);
        qb: out std_logic_vector(7 downto 0);
        cn: out std_logic);   cn是进位输出
end entity;
architecture behav of shft is
  signal reg : std_logic_vector(7 downto 0);
  signal cy: std_logic;
begin
process(clk,md,co)
begin
if clk'event and clk='1' then
  case md is
    when "001" =>  reg(0)<=c0;
reg( 7 downto 1)<= reg(6 downto 0); cy<=reg(7); 带进位循环左移
    when "010" =>  reg(0)<=reg(7);              自循环左移
reg(7 downto 1)<= reg(6 downto 0);   
    when "011"=> reg(7)<=reg(0);                自循环右移
reg(6 downto 0)<=reg(7 downto 1);
    when "100"=> reg(7)<=c0;
reg(6 downto 0)<=reg(7 downto 1);cy<=reg(0);    带进位循环右移
    when "101"=>reg(7 downto 0)<= d( 7 downto 0);加载待移数
    when others =>  reg<=reg; cy<=cy;
end case;
end if;
end process;
qb(7 downto 0)<=reg(7 downto 0); cn<=cy; 移位后输出
end behav;

9,JK触发器的设计

 library ieee;

use ieee.std_logic_1164.all;

entity  jkffl is

port(j,k: in std_logic;

       clk: in std_logic;

       q,qn: out  std_logic);

endtity jkffl ;

architecture bhv of jkffl is

signal q1:std_logic;

begin

process(clk)

begin

if  clk'event and  clk='1' then

if j='1' and k='0' then q1<='0';

elsif j='0' and k='1' then q1='1';

elsif j='1' and k='1' then q1<=not q1;

else q1<=q1;

end if;

end if;

end process;

q<=q1;

qn<=not q1;

end architecture;

10,4位十进制计数器的设计

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

 

entity couter1 is

port(enb: in std_logic;

     clr: in std_logic;

     clk: in std_logic;

    cout: out std_logic;

q: out std_logic_vector(15 downto 0));

    end entity couter1;


architecture bhv of couter1 is

signal q1,q2,q3,q4: std_logic_vector(3 downto 0);

 begin

process(clk,enb,clr)

begin

if clr='1' then q1<="0000";q2<="0000";q3<="0000";q4<="0000";

  elsif clk'event and clk='1' then

     if enb='1' then

       if q1<"1001" then q1<=q1+1; cout<='0';

       elsif  q2<"1001" then q1<="0000";q2<=q2+1;

       elsif  q3<"1001" then q1<="0000";q2<="0000";q3<=q3+1;

       elsif q4<"1001" then q1<="0000";q2<="0000";q3<="0000";q4<=q4+1;

       else q1<="0000";q2<="0000";q3<="0000";q4<="0000"; cout<='1';

       end if;

     end if;

  end if;

 end process;

q<=q4&q3&q2&q1;

11,位矢中‘1’数码个数的统计电路设计

注意:这里是只能使用变量不能使用使用信号

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity cntc is

port( din: in std_logic_vector(7 downto 0;

          cnth: out std_logic_vector(3 downto 0);

 end entity cntc;

architecture bhv of cntc is

begin 

process(din)

variable q:  std_logic_vector(3 downto 0);

begin 

q="0000";

for(n in 0 to 7) loop     ;;;;;;;n是loop 的循环变量  

  if ( din(n)='1')  then q:=q+1;

 end  loop;

cnth<=q;

end process;

end;

这里注意的是loop循环的使用

12,三态门的设计

如果用std_logic数据类型的'z'对一个变量赋值,就会引入一个三态门

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。


。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

13,顺序语句归纳

在一个结构体中,允许放置任意多个进程语句结构,而每一个进程的内部是由一系列顺序语句构成的,

在进程中的顺序语句并不意味着硬件的实现也顺序

下面详细了解一下process进程语句

一个结构体中可以包含多个进程process,但是所有被激活的的进程都是并行运行的

process结构由三部分组成:进程说明,顺序描述,敏感参数表