一周掌握 FPGA VHDL Day 3

一周掌握 FPGA VHDL Day 3

今天给大侠带来的是一周掌握 FPGA VHDL Day 3,今天开启第三天,下面咱们废话就不多说了,一起来看看吧。每日十分钟,坚持下去,量变成质变。

VHDL语言

三、VHDL语句

3.1 并行语句

在结构体中的执行是同时进行,执行顺序与书写顺序无关。

图片

 

  • 并行信号赋值语句

 

a. 简单赋值语句

目标信号名 <= 表达式(目标信号的数据类型与右边表达式一致)

ARCHITECTURE Behavior OF FreDevider IS SIGNAL Clk:Std_Logic;BEGIN  PROCESS(Clock)BEGIN  IF rising_edge(Clock) THEN    Clk<=NOT Clk;  END IF;  END PROCESS;Clkout<=Clk;

 

b. 选择信号赋值语句

WITH 选择表达式 SELECT赋值目标信号 <= 表达式1 WHEN 选择值1,               表达式2 WHEN 选择值1,               ……               表达式n WHEN OTHERS;

 

选择值要覆盖所有可能情况,若不能一一指定,用OTHERS为其他情况找个出口;

选择值必须互斥,不能出现条件重复或重叠的情况。

 

4X1多路选择器

图片

 

LIBRARY IEEE;USE IEEE.Std_Logic_1164.ALL;ENTITY MUX ISPORT( Data0,Data1,Data2,Data3:IN Std_Logic_VECTOR(7 DOWNTO 0);Sel:IN Std_Logic_Vector(1 DOWNTO 0);DOUT:OUT Std_Logic_Vector(7 DOWNTO 0));END;ARCHITECTURE DataFlow OF MUX ISBEGIN    WITH Sel SELECT        DOUT<= Data0 WHEN “00”,                Data1 WHEN “01”,                Data2 WHEN “10”,                Data3 WHEN “11”,     “00000000” WHEN OTHERS;END;

 

图片

 

c. 条件信号赋值语句

赋值目标信号 <=  表达式1 WHEN 赋值条件1 ELSE                表达式2 WHEN 赋值条件2 ELSE                 表达式n WHEN 赋值条件n ELSE                 表达式;

 

各赋值语句有优先级的差别,按书写顺序从高到低排列; 

各赋值条件可以重叠。

 

8输入优先编码器

图片

LIBRARY IEEE;USE IEEE.Std_Logic_1164.ALL;ENTITY Priority_Encoder ISPORT( I:IN Std_Logic_VECTOR(7 DOWNTO 0);  A:OUT Std_Logic_Vector(2 DOWNTO 0));END;ARCHITECTURE DataFlow OF Priority_Encoder ISBEGIN    A<= “111” WHEN I(7)=‘1’ ELSE        “110” WHEN I(6)=‘1’ ELSE        “101” WHEN I(5)=‘1’ ELSE         “100” WHEN I(4)=‘1’ ELSE        “011” WHEN I(3)=‘1’ ELSE        “010” WHEN I(2)=‘1’ ELSE        “001” WHEN I(1)=‘1’ ELSE        “000” WHEN I(0)=‘1’ ELSE        “111”;END;

 

图片

 

d. 进程语句

进程语句定义顺序语句模块,用于将从外部获得的信号值, 或内部的运算数据向其他的信号进行赋值。

  • 进程本身是并行语句,但内部是顺序语句; 

  • 进程只有在特定的时刻(敏感信号发生变化)才会被激活。

[进程标号:] PROCESS //(敏感信号参数表)一个进程可以有多个敏感信号,任 一敏感信号发生变化都会激活进程[声明区];//在进程中起作用的局部变量  BEGIN    顺序语句  END PROCESS [进程标号];

 

进程的工作原理

图片

 

进程与时钟

在每个上升沿启动一次进程(执行进程内所有的语句)。

图片

上升沿描述:Clock’ EVENT AND Clock=‘1’ 

下降沿描述:Clock’ EVENT AND Clock=‘0’

上升沿描述:rising_edge (Clock)

下降沿描述:falling_edge (Clock)

LIBRARY IEEE; USE IEEE.Std_Logic_1164.ALL;ENTITY FreDevider ISPORT( Clock: IN Std_logic;  Clkout: OUT Std_logic);END;ARCHITECTURE Behavior OF FreDevider IS SIGNAL Clk: Std_Logic;BEGIN  PROCESS (Clock) --将时钟作为进程的敏感信号BEGIN  IF rising_edge (Clock) THEN    Clk<=NOT Clk; --在时钟上升沿执行Clk<=NOT Clk  END IF;END PROCESS;Clkout<=Clk;END;

 

仿真波形:

图片

 

LIBRARY IEEE; USE IEEE.Std_Logic_1164.ALL;ENTITY Counter ISPORT( RESET:IN Std_Logic; --异步复位信号  Clock: IN Std_logic; --时钟信号  NUM: BUFFER Integer RANGE 0 TO 3); --计数器输出值 END;ARCHITECTURE Behavior OF Counter IS BEGIN  PROCESS (RESET, Clock) --将复位、时钟作为进程的敏感信号BEGIN  IF RESET=‘1’ THEN    Num<=0; --复位时Num清0 ELSIF rising_edge (Clock) THEN      IF Num=3 THEN        Num<=0; --如果Num=3就清0      ELSE        Num<=Num+1; -- 否则自加1 END IF;      END IF;END PROCESS;END;

仿真波形:

图片

 

 

图片

LIBRARY IEEE; USE IEEE.Std_Logic_1164.ALL;USE IEEE.Std_Logic_unsigned.ALL;ENTITY Counter ISPORT( clr :IN Std_Logic; inl: in std_logic_vector(3 downto 0); outl: out std_logic_vector(3 downto 0) --计数器输出值);END;  ARCHITECTURE Behavior OF Counter IS   BEGIN    PROCESS (clr, inl) --进程的敏感信号  BEGIN    IF (clr=‘1’ or inl=“1001”) THEN      outl<=“0000”;     ELSE      outl<=inl+1; //重载符号,在库IEEE.Std_Logic_unsigned中预先声明  END IF;END PROCESS;END;

 

图片

LIBRARY IEEE; USE IEEE.Std_Logic_1164.ALL;USE IEEE.Std_Logic_unsigned.ALL;ENTITY Counter ISPORT( clr,clk:IN Std_Logic; cnt: buffer std_logic_vector(3 downto 0) --计数器输出值);END;    ARCHITECTURE Behavior OF Counter IS   BEGIN    PROCESS   BEGIN    Wait until clk’event and clk=‘1’; //Wait语句,信号赋值有寄存功能,引入时序器件  IF (clr=‘1’ or cnt=9) THEN    cnt<=“0000”;   ELSE    cnt<=cnt+1;   END IF;END PROCESS;END;

 

进程的启动

当process的敏感信号参数表重没有列出任何敏感信号时,进程通过wait语句启动。

ARCHITECTURE Behavior OF state IS BEGIN  PROCESS --敏感信号列表为空 BEGIN  wait until Clock; --等待clock激活进程    IF ( drive=‘1’) THEN      CASE output IS          WHEN s1 => output <= s2;           WHEN s2 => output <= s3;           WHEN s3 => output <= s4;           WHEN s4 => output <= s1;       END CASE;    END IF;END PROCESS;END;

 

进程注意事项:

  • 进程本身是并行语句,但内部为顺序语句; 

  • 进程在敏感信号发生变化时被激活,在使用了敏感表的进程中不能含wait语句; 

  • 在同一进程中对同一信号多次赋值,只有最后一次生效; 

  • 在不同进程中,不可对同一信号进行赋值;

  • 一个进程不可同时对时钟上、下沿敏感。 

  • 进程中的信号赋值是在进程挂起时生效的,而变量赋值是即时生效。

  • 相对于结构体而言,信号具有全局性,是进程间进行并行联系的重要途径。 

  • 进程为综合器支持,且其建模方式直接影响仿真和综合结果,综合后对应于进程的硬件结构对进程中所有可读入信号都是敏感的。

 

  • 元件例化语句

元件例化引入一种连接关系,将预先设计好的实体定义为元件,并将此元件(要插在电路系统板上的芯片)与当前设计实体中的端口(电路板上准备接受芯片的插座 )相连接,从而为当前设计(较大的电路系统)实体引入一个新的低一级的设计层次。

Component 元件名   port (端口名表);//列出对外通信的各端口名End component 元件名;例化名:元件名 port map ( [元件端口名=>]连接端口名 , …);

解析:

名字关联方式:port map语句中位置可以任意;

位置关联方式:端口名和关联连接符号可省去, 连接端口名的排列方式与所需例化的元件端口定义中的端口名相对应。

当前系统与准备接 入的元件对应端口相连 的通信端口。

 

元件例化:

LIBRARY IEEE; USE IEEE.Std_Logic_1164.ALL;ENTITY ord41 ISPORT( a1, b1,c1, d1:IN Std_Logic;       z1: out std_logic);END;ARCHITECTURE ord41behv OF ord41 IS BEGINCOMPONENT nd2PORT( a, b: IN Std_Logic;      c: out std_logic);End COMPONENT;SIGNAL x, y: STD_LOGIC; BEGINu1:nd2 PORT MAP( a1, b1, x); --位置关联方式 u2:nd2 PORT MAP( a=>c1, c=>y, b=>d1); --名字关联方式 u3:nd2 PORT MAP( x, y, c=>z1); --混和关联方式 END;

 

设计2输入与非门:

图片

LIBRARY IEEE; USE IEEE.Std_Logic_1164.ALL;ENTITY nd2 ISPORT( a, b:IN Std_Logic;   c: out std_logic);END;ARCHITECTURE nd2behv OF nd2 IS BEGIN  y<=a NAND b;END;

 

3.2 顺序语句

顺序语句仅出现在进程和子程序中。

顺序语句综合后,映射为实际的门电路,系统一上电,门电路开始工作。电路可实现逻辑上的顺序执行,实际上所有门电路是并行工作的。

  • 赋值语句

  • 流程控制语句

  • 空操作语句

  • 等待语句

  • 子程序调用语句

  • 返回语句

 

  • 赋值语句

ENTITY TEST_Signal ISPORT( Reset, Clock: IN Std_logic;NumA, NumB: OUT Integer RANGE 0 TO 255);END;ARCHITECTURE TEST OF TEST_Signal IS SIGNAL A, B: Integer RANGE 0 TO 255;BEGINPROCESS (RESET,Clock) VARIABLE C: Integer RANGE 0 TO 255;BEGIN    IF RESET=‘1’ THEN      A<=0; B<=2;C:=0;    ELSEIF rising_edge(Clock) THEN    C:=C+1;A<=C+1;B<=A+2;  END IF;END PROCESS;Num A<=A; NumB<=B;END;

图片

 

  • 流程控制语句

  • IF语句:

IF 条件式 THEN  顺序语句END IF;
IF 条件式 THEN  顺序语句ELSE  顺序语句END IF;
IF 条件式 THEN //有优先级  顺序语句ELSEIF 条件式2 THEN  顺序语句ELSE  顺序语句END IF;

 

用IF语句描述组合逻辑电路时,务必涵盖所有的情况,否则综合后将引入锁存器!

ENTITY Encoder ISPORT( En: IN Std_logic;    I: IN Std_logic_Vetor(7 DOWNTO 0);    A: OUT Std_logic_Vetor(2 DOWNTO 0);    Idle: OUT Std_logic);END;ARCHITECTURE Behavior OF Encoder IS BEGIN  PROCESS (En, I)BEGIN  IF En=‘1’ THEN    IF  I(7)=‘1’ THEN        A<=“111”; Idle<=‘0’;         ELSIF IF I(6)=‘1’ THEN        A<=“110”; Idle<=‘0’; ELSIF IF I(5)=‘1’ THEN        A<=“101”; Idle<=‘0’;         ELSIF IF I(4)=‘1’ THEN        A<=“100”; Idle<=‘0’;         ELSIF IF I(3)=‘1’ THEN        A<=“011”; Idle<=‘0’;         ELSIF IF I(2)=‘1’ THEN        A<=“010”; Idle<=‘0’;         ELSIF IF I(1)=‘1’ THEN        A<=“001”; Idle<=‘0’;         ELSIF IF I(0)=‘1’ THEN        A<=“000”; Idle<=‘0’;         ELSE //引入ELSE, 否则综合器 将引入锁存        A<=“000”; Idle<=‘1’; END IF;END PROCESS;END;

 

不完整条件语句与时序电路:

ENTITY COMP_BAD IS   PORT( a1 : IN BIT;        b1 : IN BIT;        q1 : OUT BIT ); END ; ARCHITECTURE one OF COMP_BAD ISBEGIN   PROCESS (a1,b1) BEGIN     IF a1 > b1 THEN q1 <= '1' ;     ELSIF a1 < b1 THEN q1 <= ‘0’ ; -- 未提及当a1=b1时,q1作何操作 END IF;     END PROCESS ;END ;

 

综合结果:

图片

 

 

完整条件语句:

ENTITY COMP_GOOD IS   PORT( a1 : IN BIT;        b1 : IN BIT;        q1 : OUT BIT ); END ; ARCHITECTURE one OF COMP_GOOD ISBEGIN   PROCESS (a1,b1)     BEGIN       IF a1 > b1 THEN q1 <= '1' ;       ELSE q1 <= '0' ;      END IF;   END PROCESS ;END ;

 

图片

 

CASE语句:

CASE 表达式 IS  WHEN 选择值[|选择值 ]=>顺序语句;   WHEN 选择值[|选择值 ]=>顺序语句;    ……  WHEN OTHERS=>顺序语句; END CASE;
  • 选择值不可重复或重叠;

  • 当CASE语句的选择值无法覆盖所有的情况时,要用OTHERS指定未能列出的其他所有情况的输出值;

LIBRARY IEEE;USE IEEE.Std_Logic_1164.ALL;ENTITY MUX ISPORT( Data0,Data1,Data2,Data3:IN Std_Logic_VECTOR(7 DOWNTO 0);Sel:IN Std_Logic_Vector(1 DOWNTO 0);DOUT:OUT Std_Logic_Vector(7 DOWNTO 0));END;ARCHITECTURE DataFlow OF MUX IS    BEGIN      CASE Sel IS        WHEN “00”=> DOUT<= Data0;         WHEN “01”=> DOUT<= Data1;         WHEN “10”=> DOUT<= Data2;         WHEN “11”=> DOUT<= Data3;         WHEN OTHERS => DOUT<=“00000000” ;      END CASE;    END PROCESS; END;

 

LOOP语句:

​​​​​​​

[LOOP 标号:] FOR 循环变量 IN 循环次数范围 LOOP                                    顺序语句临时变量仅在此END LOOPLOOP [LOOP 标号];

循环变量:临时变量,仅在此END LOOPLOOP [LOOP 标号];中有效,无需事先定义。

循环次数范围:….TO…. ….DOWNTO…..从初值开始,每执行完一次后递增(递减),直到终值 为止。

​​​​​​​

Sum:=0;FOR i IN 0 TO 9 LOOP    Sum:=Sum+i;END LOOP;

 

循环次数只能用具体数值表达,否则不可综合。

​​

VARIABLE Length:Integer RANGE 0 TO 15;……FOR i IN 0 TO Length LOOP……END LOOP;

NEXT语句:

NEXT语句主要用在LOOP语句执行中有条件或无条件转向控制,跳向LOOP语句的起点。

NEXT [循环标号] [WHEN 条件];

① NEXT ;--无条件终止当前循环,跳回到本次循环LOOP语句处,开始下一次循环。 

② NEXT LOOP 标号;--当有多重LOOP语句嵌套时,跳转到指定标号LOOP语句处,重新开始执行循环操作。 

③ NEXT LOOP 标号 WHEN 条件表达式;--条件表达式为TRUE, 执行NEXT语句,进入跳转操作,否则向下执行。

 

EXIT语句:

EXIT语句主要用在LOOP语句执行中有条件或无条件内部 转向控制,跳向LOOP语句的终点,用于退出循环。当程序需要处理保护、出错和警告状态时,语句能提供一个快捷、简便的方法。

EXIT [循环标号] [WHEN 条件];

① EXIT ;--无条件从当前循环中退出。 

② EXIT LOOP 标号;--程序执行退出动作无条件从循环标号所标明 的循环中退出。 

③ EXIT LOOP 标号 WHEN 条件表达式;--条件表达式为TRUE,程序从当前循环中退出。

 

NULL语句:

NULL为空操作语句,一般用于CASE中,表示在某些情况下对 输出不作任何改变,隐含锁存信号。不能用于纯组合逻辑电路。

PROCESS (Clock)BEGIN    IF rising_edge (Clock) THEN    ……        CASE Sel IS          WHEN…           WHEN OTHERS=>NULL;        END CASE;    ……    END IF;END PROCESS;

WAIT语句:

在进程或过程中执行到WAIT语句时,程序将被挂起,并设 置好再次执行的条件。 

WAIT [ON 信号表][UNTIL 条件表达式][FOR 时间表达式]; 

① WAIT ;--未设置停止挂起的条件,表示永远挂起。 

② WAIT ON 信号表;--敏感信号等待语句,敏感信号的变化将结束 挂起,再次启动进程。

③ WAIT UNTIL 条件表达式;--条件表达式为中所含的信号发生变 化,且满足WAIT语句所设条件,则结束挂起,再次启动进程。

④ WAIT FOR 时间表达式;--超时等待语句,从执行当前的WAIT语 句开始,在此时间段内,进程处于挂起状态,超过这一时间段后,程序自动恢复执行。

 

3.3 配置语句

配置主要为顶层设计实体指定结构体,或为参与例化的元 件实体指定所希望的结构体 ,以层次方式来对元件例化做结构配置。​​​​​​​

Configuration 配置名 of 实体名 is配置说明End 配置名;
  • 为顶层设计实体指定结构体

Entity nand is   port (  a, b: in std_logic;          c: out std_logic );End entity nand;Architecture one of nand is       begin        c<=not (a and b);      End architecture one;    Architecture two of nand is       begin      c<=‘1’ when (a=‘0’) and (b=‘0’) else      ‘1’ when (a=‘0’) and (b=‘1’) else      ‘1’ when (a=‘1’) and (b=‘0’) else      ‘0’ when (a=‘1’) and (b=‘1’) else      ‘0’; End architecture two;​​​​​​​
Configuration second of nand is  for two  end for;End second; Configuration first of nand is  for one  end for;End first;
  • 为参与例化的元件实体指定所希望的结构体 ,以层次方式来对元件例化做结构配置。

LIBRARY IEEE; USE IEEE.Std_Logic_1164.ALL; Entity rs is     port ( r, s: in std_logic;           q,qf: out std_logic );End entity rs;Architecture rsf of rs is Component nandPORT( a, b: IN Std_Logic;      c: out std_logic);End Component;BEGIN  u1:nand PORT MAP (a=>s, b=>qf, c=>q);   u2:nand PORT MAP ( a=>q, b=>r, c=>qf); END rsf;

用实体nand构成更高层次设计实体中的元件,由配置语 句指定元件实体nand使用哪个结构体。​​​​​​​

Configuration sel of rs is  for rsf    for u1,u2:nand    use entity work.nand (two);end for;end for;End sel;

Day 3 就到这里,Day 4 继续开始状态机在VHDL中的实现。

 

【QQ交流群】

群号:173560979,进群暗语:FPGA技术江湖粉丝。

多年的FPGA企业开发经验,各种通俗易懂的学习资料以及学习方法,浓厚的交流学习氛围,QQ群目前已有1000多名志同道合的小伙伴,无广告纯净模式,给技术交流一片净土,从初学小白到行业精英业界大佬等,从军工领域到民用企业等,从通信、图像处理到人工智能等各个方向应有尽有。

 

【微信交流群】

现微信交流群已建立08群,人数已达数千人,欢迎关注“FPGA技术江湖”微信公众号,可获取进群方式。

后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。

江湖偌大,继续闯荡,愿大侠一切安好,有缘再见!

06-10 243
02-09 489
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值