精华内容
下载资源
问答
  • 【FPGA学习笔记】VHDL:GENERATE语句

    千次阅读 2020-03-23 18:12:06
    generate 是一种可以**建立重复结构**或者是**在多个模块的表示形式之间进行选择**的语句。由于生成语句**可以用来产生多个相同的结构**,因此使用生成语句就可以**避免多段相同结构的VHDL程序的重复书写。**

    generate语句

    是一种可以建立重复结构或者是在多个模块的表示形式之间进行选择的语句。由于生成语句可以用来产生多个相同的结构,因此使用生成语句就可以避免多段相同结构的VHDL程序的重复书写。
    有两种用途:
    1、生成相同的元件,多次例化

    --异步加法计数器
    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    
    ENTITY DFFR IS                       --定义一个D触发器DFFR
    	PORT(clk , clr, d : IN STD_LOGIC;
    		Q ,BQ : OUT STD_LOGIC);
    END DFFR;
    ARCHITECTURE art OF DFFR IS
    	SIGNAL Q_IN :STD_LOGIC;
    BEGIN
    	Q <= Q_IN;
    	BQ <= NOT Q_IN;
    	PROCESS(clk,clr)
    	BEGIN
    		IF (clr = '1')THEN
    			Q_IN <= '0';
    		ELSIF (clk'EVENT AND clK = '1')
    			Q_IN <= d;
    		END IF;
    	END PROCESS;
    END art;
    
    ENTITY rplcounter IS
    	PORT(clK,clr : IN STD_LOGIC;
    		count :OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
    END rplcounter;
    ARCHITECTURE art1 OF DFFR IS
    	SIGNAL COUNT_IN : STD_LOGIC_VECTOR(7 DOWNTO 0);
    	COMPONENT DFFR                        --说明元件
    		PORT(clk , clr, d : IN STD_LOGIC;
    		Q ,BQ : OUT STD_LOGIC);
    	END COMPONENT;
    BEGIN
    	COUNT_IN(0) <= clK;
    	GEN1: FOR i IN 0 TO 3 GENERATE--元件例化并定义引脚连接:低位触发器的输出作为下一级的时钟信号
    		U:DFFR PORT MAP
    		(clK => COUNT_IN(i);
    		 clr => clr;
    		 d => COUNT_IN(i+1);
    		 Q => COUNT_IN(i);
    		 BQ => COUNT_IN(i+1));
    	END GENERATE;
    END art1;
    

    2、生成结构相同的多次赋值、组合逻辑;

    FOR i IN 0 TO 99 GENERATE
    
    a(i)<=b(i)+c(i);
    
    END GENERATE;
    
    展开全文
  • 更加详细抽象的例子就不加赘述,总之,模块的实例化无论是在verilog还是在vhdl中都是一种相当高效的电路描述方式。 例化的操作方法在实际电路中又是什么样的呢? 在第一段中我们通过一种比较通俗的方法来理解例化的...

    一:模块的组成和例化

    • 在了解模块的例化这一操作前,我们先需要理解硬件描述语言中模块到底是什么。硬件描述语言的宗旨是用代码去描述电路的功能,而再复杂的电路都是由一块一块简单的电路组成的,硬件描述过程也是如此。程序员通常先从最底层的基础模块开始书写代码,然后逐层地在更高地层级中对低一层级的模块进行调用(可以想象一下把已经封装好的已知内部逻辑和输入输出端口的芯片一片一片地插在电路板上,这些芯片也就是“模块”)。当然,在更高一级的电路中,不仅包含有低层级的模块(即实例化建模),还会有当下电路中的数据流建模(多以assign连续赋值语句出现)和行为级建模(以always语句等形式出现)。

    • 模块的实例化是一种非常高效的电路调用方法。如:
      (1)描述一个4位相加的加法器,就可以用4个一位全加器进行实例化来实现;
      (2)描述一个16位BCD加法器,就可以用四个四位BCD全加器实例化来实现;
      更加详细抽象的例子就不加赘述,总之,模块的实例化无论是在verilog还是在vhdl中都是一种相当高效的电路描述方式。

    • 例化的操作方法在实际电路中又是什么样的呢?
      在第一段中我们通过一种比较通俗的方法来理解例化的过程。实际上,例化是指通过硬件描述语言来实现模块端口或者是线网间的映射关系。

    实例化的两种方法

    以以下一段已经給出模块的代码作为引例:

    /*四位加法器模块*/
    module BCD_4bit(A,B,cin,cout,sum);
    
    input   [3:0]A,B;
    input   cin;
    output  cout;
    output  [3:0]sum;
        
    reg [4:0]middle;//用于存放中间计算结果
    reg cout;
    reg [3:0]sum;
        always @(A,B,cin) begin
        	middle=A+B+cin;
            if (middle>9)
            	{cout,sum}=middle+6;
            else
            	{cout,sum}=middle;
        end
    endmodule
    

    观察上面这段代码可以发现,在不具体了解代码功能(也就是内特性)的时候,我们依旧可以通过观察知道其外特性(也就是端口特性),可以发现:这个电路模块有三个输入端口和两个输出端口,并且其各自的端口名已经在模块内部定义(关于BCD四位加法器的代码原理不再详述,笔者会在文末附件中作简单的解释),那么在使用到这个模块的电路时就需要为这些内部端口与外部进行列连接,以笔者这次碰到的题目(题目传送门:HDLBits中16位BCD加法器)为例。题目:使用已写好的四位BCD加法器来实现16位加法器。

    • 分析:整个16位BCD加法器的外特性为:
    input [15:0] a, b,
    input cin,
    output cout,
    output [15:0] sum );
    

    先看最低的四位BCD加法器输入,它们的组成除了两个被加数的低四位A[3:0]和B[3:0]以外,还有一个一位的进位输入cin,而它们的加法结果输出经过要调用的***第一个4位BCD加法器(也就是第一个BCD_4bit)*** 的逻辑运算后,输出构成了sum[3:0]的结果,同时还有一个一位进位输出"cout"(此处加双引号的目的是cout此时作为内部端口名出现)。根据我们对加法器的理解,低位的进位输出就是高位的进位输入(也就是下一个4位BCD加法器的进位输入端)。但这时我们还需要申请线网变量矢量reg来存放进位输入和输出进位位的中间变量,此时观察可以发现,由于只需要四个四位BCD加法器模块就可以构成16位BCD加法器,装载输入输出进位位的 中间变量矢量宽度为3 即可,因为最后一位的内部端口(“cout”)就是整个16位加法器电路模块的进位输出cout。

    • 现在我们可以以解决问题为导向正式进入实例化的过程。模块的例化有两种方法,一种是名字映射,一种是位置映射
      (1)名称映射
      名称映射就是把实例外部的信号(signal)直接对应到要例化的 模块的各个端口上,这种端口对应的顺序的方式是任意的,其格式如下:
    模块名称 实例名称(
    	.模块内部端口名称a (实例外部信号a),
    	.模块内部端口名称b (实例外部信号b),
    	...;
    

    在本题中,顶层模块根据前文分析后代码如下(本段代码原理比较简单,因此直接参考了解析 传送门☞4-digit BCD adder):

    module top_module( 
        input [15:0] a, b,
        input cin,
        output cout,
        output [15:0] sum );
    
        wire [3:0] cout_temp;
    
        //例化4次,注意前一次计算的cout为后一次计算的cin
        BCD_4bit inst1_bcd_fadd(
            .a(a[3:0]),
            .b(b[3:0]),
            .cin(cin),
            .cout(cout_temp[0]),
            .sum(sum[3:0])
        );
    
        BCD_4bit inst2_bcd_fadd(
            .a(a[7:4]),
            .b(b[7:4]),
            .cin(cout_temp[0]),
            .cout(cout_temp[1]),
            .sum(sum[7:4])
        );
    
        BCD_4bit inst3_bcd_fadd(
            .a(a[11:8]),
            .b(b[11:8]),
            .cin(cout_temp[1]),
            .cout(cout_temp[2]),
            .sum(sum[11:8])
        );
    
        BCD_4bit inst4_bcd_fadd(
            .a(a[15:12]),
            .b(b[15:12]),
            .cin(cout_temp[2]),
            .cout(cout_temp[3]),
            .sum(sum[15:12])
        );
        assign cout = cout_temp[3];
    endmodule
    
    (2)位置映射

    位置对应方式就是在模块实例化的时候外部信号或者说外部线网需要按照该模块端口声明时的顺序一一对应。如此次4位BCD加法器的底层模块其声明的端口顺序为:

    module BCD_4bit(A,B,cin,cout,sum);
    

    因此在进行顶层模块书写时,代码如下:

    module top_module( 
        input [15:0] a, b,
        input cin,
        output cout,
        output [15:0] sum );
        reg [2:0]m_cout;//m_cout就是用来装载进位位的中间矢量
        BCD_4bit BCDa(a[3:0],b[3:0],cin,m_cout[0],sum[3:0]);
        BCD_4bit BCDb(a[7:4],b[7:4],m_cout[0],m_cout[1],sum[7:4]);
        BCD_4bit BCDc(a[11:8],b[11:8],m_cout[1],m_cout[2],sum[11:8]);
        BCD_4bit BCDd(a[15:12],b[15:12],m_cout[2],cout,sum[15:12]);
    endmodule
    
    • 两种方法的总结:
      名称映射 能够更加清晰的显示端口的输入输出关系,但是所占篇幅较大,在例化对象规模较大时更加不适合使用;
      位置映射 需要操作者能够熟悉各个端口的输入输出关系,但是节省空间使用高效简洁。

    • 在这个部分的最后我们可以看一下Quartus給出的RTL仿真结果:

    基于4个四位BCD加法器的十六位BCD加法器
    图中的绿框就是封装好的只显示输入输出端口的加法器模块,在RTL仿真图中点击➕号可以进入查看其内特性(见下图)
    RTLviewer of 4Bit_BCD

    二:生成块语句(generate)的简单应用和使用规范

    • 本部分前言: 试想以上的内容仅仅是基于16位的BCD加法器,如果要实现100位,200位甚至400位呢,明显一行一行地例化这一操作就会非常耗时且麻烦,这时我们就会用到新的语句------ 生成块语句(generate)

    • 本次程序使用了generate(生成块)语句,其主要功能是对已经写好的module\reg\assign\task等语句进行复制。如果需要实现的是400位的BCD加法器,那么其代码如下(总体设计思路其实与16位的并无分别):

    module   BCD_addtop(a,b,cin,cout,sum);
    input    [399:0] a, b;
    input    cin;
    output   cout;
    output   [399:0] sum;
    wire     [98:0]r_cout;//作为模块例化使用的中间变量,r_cout一定要定义为wire类型否则会报错
    genvar i;
    	BCD_4bit bcd_fadd_0(a[3:0],b[3:0],cin,r_cout[0],sum[3:0]);
    	BCD_4bit bcd_fadd_99(a[399:396],b[399:396],r_cout[98],cout,sum[399:396]);
    generate for(i=1;i<99;i=i+1)
    	begin:bcd_1
    		BCD_4bit bcd_fadd_i(a[4*i+3:4*i],b[4*i+3:4*i],r_cout[i-1],r_cout[i],sum[4*i+3:4*i]);
       end
    endgenerate
    endmodule
    
    • generate语句使用最多的是generate for,其中还有generate_if和generate_case。现在此详细介绍一下generate语句尤其是应用最为广泛的generate for语句的使用规范:
      1)for循环中的 循环变量(i为例)需要在生成块以外声明(如genvar i)。(genvar是generate语句中的一种变量类型,用在generate_for中声明正整数变量。
    1. 需要复制的语句必须写到begin_end语句里面(就算只有一句!!!)
      3)begin_end需要有一个类似于模块名的名字(如本例中的begin:addbit)

    本次博客基于自己在写HDLBits题库时遇到的一些问题和思考,关于generate语句的使用细节借鉴了csdn上其它优秀答主的回答verilog语法之generate语句的基本认识 By小蒋啊 。读者在阅读时如果碰到什么问题或者发现什么笔误都欢迎在评论区指正,也希望这篇博客能够給在学习fpga的小伙伴带来一些帮助!!!
    (另:答主有时间会附上BCD加法器的详解还有例化过程中常见的几种报错提示和解决办法)

    展开全文
  • VHDLGENERATE语句实现四位全加器

    千次阅读 2020-05-24 00:27:34
    1位全加器接口有:A被加数输入端,为加数输入端,C进位输入端,CO进位输出端,S和数输出端。1位全加器表达式如下:S=A xor B xor C, CO=(AB)+(AC)...本文用VHDL语言的GENERATE语句用四个一位全加器实现一个四位全加器。

    1位全加器

    在这里插入图片描述  1位全加器接口如上图所示,A为被加数输入端,B为加数输入端,C为进位输入端,CO为进位输出端,S为和数输出端。1位全加器表达式如下: S = A ⨁ B ⨁ C S =A \bigoplus B\bigoplus C S=ABC C O = ( A ⋅ B ) + ( A ⋅ C ) + ( B ⋅ C ) CO =(A \cdot B)+(A \cdot C)+(B \cdot C) CO=(AB)+(AC)+(BC)
    1位全加器VHDL代码:

    --ADD1.vhd
    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    ENTITY ADD1 IS
    	PORT(
    		A,B,C: IN STD_LOGIC;
    		S: OUT STD_LOGIC;
    		CO:OUT STD_LOGIC
    	);
    END ADD1;
    ARCHITECTURE BHV OF ADD1 IS
    BEGIN
    	S <= A XOR B XOR C;
    	CO <= (A AND C)OR(B AND C)OR(A AND B);
    END BHV;
    

    4位全加器

      4位全加器是将低位的1位全加器的CO端接高位的1位全加器的C端,最低位的1位全加器的C端作为4位全加器的进位输入端,最高位的1位全加器的CO端作为1位全加器的进位输出端,4个1位全加器的A端和B端分别作为4位被加数和4位加数的输入端。4位全加器的RTL图如下图所示:
    在这里插入图片描述
    4位全加器VHDL代码:

    --ADD_N.vhd
    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    ENTITY ADD_N IS
    	GENERIC(N : INTEGER:=4);--改这个N的值可以实现其他位数的全加器
    	PORT(
    		A,B: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);
    		CI: IN STD_LOGIC;
    		S: OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0);
    		CO: OUT STD_LOGIC
    	);
    END ADD_N;
    ARCHITECTURE RTL OF ADD_N IS
    	COMPONENT ADD1
    	PORT(
    		A,B,C: IN STD_LOGIC;
    		S: OUT STD_LOGIC;
    		CO:OUT STD_LOGIC
    	);
    	END COMPONENT;
    	SIGNAL TEMP: STD_LOGIC_VECTOR(N DOWNTO 0);
    BEGIN
    	TEMP(0) <= CI;
    	CO <= TEMP(N);
    	G: FOR I IN 0 TO N-1 GENERATE
    			U: ADD1 PORT MAP(A=>A(I),B=>B(I),C=>TEMP(I),S=>S(I),CO=>TEMP(I+1));
    		END GENERATE;
    END RTL;
    

    功能仿真波形:
    在这里插入图片描述

    展开全文
  • 雷达信号产生4PSK简单脉冲信号很好用信号产生
  • VHDL.............................................................................................................................................................7 1.5 Synthesis.........................
  • VHDL基础

    千次阅读 2020-05-14 00:30:45
    二、VHDL的基本结构 一、运算符 1.算数运算符 +,-,*,/ MOD: 取模,取模运算(a MOD b)的符号与b相同,其绝对值小于b的绝对值。如:-5 MOD 2 = 1,5 MOD -2 = -1。 REM: 取余,取余运算...

    目录

     

    一、VHDL简介

    1.历史

    2.产生原因

    二、VHDL的基本结构

    1.库和程序包

    1.1 库

    1.2 程序包

    2.实体(Entity)

    2.1 类属:

    2.2 端口

    3.结构体

    3.1 结构体的作用和特点

    3.2 结构体的格式:

    3.3 结构体的四种描述方式:

    3.4 块语句结构:

    3.5 进程语句结构:

    4.配置(Configuration)

    4.1 配置的作用

    4.2 配置的格式

    4.3 配置举例

    5.子程序模块

    5.1 过程语句(Procedure)

    5.2 函数(Functure)

    三、VHDL基本语法

    1.标识符

    1.1 标识符规则:

    1.2 关键字 (保留字)

    2.数据对象

    2.1 信号(SIGNAL)

    2.2 变量(VARIABLE)

    2.3 常量(CONSTAT)

    2.4 信号与变量的区别

    3.数据类型

    3.1 标准定义的数据类型

    3.2 IEEE预定义的标准逻辑位与矢量

    3.3 用户自定义的数据类型

    4.运算符

    4.1 算术运算符

    4.2 关系运算符

    4.3 逻辑运算符

    4.4 赋值运算符

    4.5 关联运算符

    4.6 其他运算符

    4.7 运算符优先级

    4.8 运算符表格一览

    四、VHDL语句

    1. 并行语句

    1.1 并行语句的特点

    1.2 并行语句的格式

    1.3 并行语句的种类

    下面介绍八种并行语句

    1.4 并行信号赋值语句

    1.5 条件信号赋值语句

    1.6 

    2. 顺序语句


    一、VHDL简介

    VHDL的全称为VHSIC硬件描述语言(VHSIC Hardware Description Language),VHSIC: Very High Speed Integrated Circuit

    1.历史

    1980 – 美国国防部设立一个基金,在VHSIC项目之下开设了一个子课题,研究标准的硬件描述语言,1982诞生VHDL。
    1987 – IEEE 将其修正为 IEEE 标准:1076
    1993 – 修正了VHDL语言,升级至IEEE 1076-1993

    2.产生原因

    为什么使用VHDL ?原理图图形化设计缺点?
    答:
    大型设计,原理图连接太复杂,检查错误太困难
    通过使用高级语言对你的设计做描述,可以分析语法错误,综合后效率可能更高,时间成本更好。
     

    二、VHDL的基本结构

    VHDL的基本设计单元结构:程序包说明、实体说明、结构体说明三部分。

    -- 库、程序包的说明调用
    Library IEEE;
    use IEEE.Std_Logic_1164.ALL;
    -- 实体声明
    Entity FreDevider is
    port
    (
        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;    
            END IF;
        END process;
        Clkout <= Clk;
    END

    1.库和程序包

    1.1 库

    库是专门用于存放预先编译好的程序包的地方,对应一个文件目录,程序包的文件就放在此目录中,其功能相当于共享资源的仓库,所有已完成的设计资源只有存入某个“库”内才可以被其他实体共享。库的说明总是放在设计单元的最前面,表示该库资源对以下的设计单元开放。库语句格式如下:

    LIBRARY 库名;

    常用的库有IEEE库、STD库和WORK库:

    • IEEE库:是VHDL设计中最常用的资源库,包含IEEE标准的STD_LOGIC_1164、NUMERIC_BIT、NUMERIC_STD以及其他一些支持工业标准的程序包。其中最重要和最常用的是STD_LOGIC_1164程序包,大部分程序都是以此程序包中设定的标准为设计基础。
    • STD库:是VHDL的标准库,VHDL在编译过程中会自动调用这个库,所以使用时不需要用语句另外说明。
    • WORK库:是用户在进行VHDL设计时的现行工作库,用户的设计成果将自动保存在这个库中,是用户自己的仓库,同STD库一样,使用该库不需要任何说明。

    库的作用范围:

    库说明语句的作用范围从一个实体说明开始到它所属的构造体、配置为止。当一个源程序中出现两个以上的实体时,两条作为使用库的说明语句应在每个实体说明语句前重复书写。
     

    1.2 程序包

    程序包是用VHDL语言编写的一段程序,可以供其他设计单元调用和共享,相当于公用的“工具箱”,各种数据类型、子程序等一旦放入了程序包,就成为共享的“工具”,类似于C语言的头文件,使用它可以减少代码的输入量,使程序结构清晰。在一个设计中,实体部分所定义的数据类型、常量和子程序可以在相应的结构体中使用,但在一个实体的声明部分和结构体部分中定义的数据类型、常量及子程序却不能被其他设计单元使用。因此,程序包的作用是可以使一组数据类型、常量和子程序能够被多个设计单元使用。
    程序包分为包头和包体两部分。包头(也称程序包说明)是对包中使用的数据类型、元件、函数和子程序进行定义,其形式与实体定义类似。包体规定了程序包的实际功能,存放函数和过程的程序体,而且还允许建立内部的子程序、内部变量和数据类型。包头、包体均以关键字PACKAGE开头。程序包格式如下:

    --包头格式:
    PACKAGE 程序包名 IS
    [包头说明语句]
    END 程序包名;
    
    --包体格式:
    PACKAGE BODY 程序包名 IS
    [包体说明语句]
    END 程序包名;

    调用程序包的通用模式为:

    USE 库名.程序包名.ALL;

    常用预定义程序包有以下四个:

    • 1.STD_LOGIC_1164程序包
      STD_LOGIC_1164程序包定义了一些数据类型、子类型和函数。数据类型包括:STD_ULOGIC、STD_ULOGIC _VECTOR、STD_LOGIC和STD_LOGIC _VECTOR,用的最多最广的是STD_LOGIC和STD_LOGIC_VECTOR数据类型。调用STD_LOGIC_1164程序包中的项目需要使用以下语句:
      LIBRARY IEEE;
      USE IEEE.STD_LOGIC_1164.ALL;
      该程序包预先在IEEE库中编译,是IEEE库中最常用的标准程序包,其数据类型能够满足工业标准,非常适合CPLD(或FPGA)器件的多值逻辑设计结构。
    • 2.STD_LOGIC_ARITH程序包
      该程序包是美国Synopsys公司的程序包,预先编译在IEEE库中。主要是在STD_LOGIC_1164程序包的基础上扩展了UNSIGNED(无符号)、SIGNED(符号)和SMALL_INT(短整型)三个数据类型,并定义了相关的算术运算符和转换函数。
    • 3.STD_LOGIC_SIGNED程序包
      该程序包预先编译在IEEE库中,也是Synopsys公司的程序包。主要定义有符号数的运算,重载后可用于INTEGER(整数)、STD_LOGIC(标准逻辑位)和STD_LOGIC _VECTOR(标准逻辑位向量)之间的混合运算,并且定义了STD_LOGIC _VECTOR到INTEGER的转换函数。还定义了STD_LOGIC _VECTOR类型的符号数算数运算子程序。
    • 4.STD_LOGIC_UNSIGNED程序包
      该程序包用来定义无符号数的运算,其他功能与STD_LOGIC_SIGNED相似。



     

    2.实体(Entity)

    实体描述了设计单元的输入输出接口信号或引脚,是设计实体经封装后对外的一个通信界面。

    ENTITY 实体名 IS -- 引导语句
    [GENERIC (常数名: 数据类型: 设定值)] -- 类属表
    PORT -- 端口表
    (
        端口名1: 端口方向 端口类型;
        端口名2: 端口方向 端口类型;
        端口名3: 端口方向 端口类型;
        ......
        端口名n: 端口方向 端口类型 -- 最后一个一定不能加";",不然会报next process的")" expect ";" or ","
    );
    END [实体名]; -- 结束语句

     注意:

    1. 端口n的声明最后一定不能加";",不然会报next process的")" expect ";"
    2. port中端口默认类型为signal

    2.1 类属:

    • 类属说明的书写格式是:

    GENERIC(常数名:数据类型:设定值);
    • 其他
      类属 GENERIC 参量是一种端口界面常数,常以一种说明的形式放在实体或块结构体前的说明部分。比较常见的情况是利用类属来动态规定一个实体的端口的大小,或设计实体的物理特性,或结构体中的总线宽度,或设计实体中底层中同种元件的例化数量等等。一般在结构体中,类属的应用与常数是一样的,其中的常数名是由设计者确定的类属常数名,数据类型通常取 INTEGER 或TIME 等类型,设定值即为常数名所代表的数值,但需注意 VHDL 综合器仅支持数据类型为整数的类属值。例如:

    ENTITY mcu1 IS
    GENERIC (addrwidth : INTEGER := 16);
    PORT(
        add_bus : OUT STD_LOGIC_VECTOR(addrwidth-1 DOWNTO 0) );
        ...

    在这里 GENERIC 语句对实体 mcu1 作为地址总线的端口 add_bus 的数据类型和宽度作了定义 即定义 add_bus 为一个 16 位的标准位矢量 定义 addrwidth 的数据类型是整数INTEGER 其中 常数名addrwidth减 1 即为 15 所以这类似于将上例端口表写成PORT (add_bus : OUT STD_LOGIC_VECTOR (15 DOWNTO 0));

    2.2 端口

    • 端口语句的格式:
    PORT(端口信号名:端口模式 数据类型;
    端口信号名:端口模式 数据类型);
    
    • 端口模式有:
      • IN : 在实体中只读,接受外来数据. 只能出现在赋值语句的右侧。
      • OUT: 在实体中只能更新,不可读。只能出现在赋值语句的左侧。
      • INOUT: 在实体内部可更新、可读,可出现在赋值语句的两侧。 
      • BUFFER: 可用作内部赋值,可出现在赋值语句的两侧。在可综合代码中不推荐使用。

    3.结构体

    3.1 结构体的作用和特点

    3.1.1 作用

    结构体的任务是:定义结构体中的各项内部使用元素,如数据类型(TYPE),常数(CONSTAND),信号(SIGNAL),元件(COMPONENT),过程(POCEDURE),变量(VARIABLE)和进程(PROCESS)等。通过VHDL语句描述实体所要求的具体行为和逻辑功能。描述各元件之间的连接。

    3.1.2 特点

    1. 用于描述模型的功能
    2. 必须和一个 Entity相关联
    3. 一个Entity可有多个 Architectures
    4. Architecture 语句并发执行.

    3.2 结构体的格式:

    Architecture 结构体名 OF 实体名 IS
    定义语句法;
    BEGIN
    功能描述语句法;
    END 结构体名称;
    

    3.3 结构体的四种描述方式:

    结构化描述、数据流描述、行为描述、混合。

    3.3.1 结构描述

    原件和内联,通过低级器件的内联实现。

    特点:

    1. 描述电路的功能和结构。
    2. 可调用专用硬件。
    3. 可综合。
    4. 结构化、模块化。
    5. 结构化描述易于理解,接近于原理图,使用简单的模块组成逻辑电路,实现逻辑功能。
    6. 组件以层次化相连接。
    7. 结构化描述可以将简单门、甚至更复杂的逻辑门连接在一起。
    8. 结构化描述在团队协作时非常有用。

    3.3.2 RTL(寄存器传输级)描述, 又称数据流描述

    描述数据在系统中的流动过程,数据流使用一系列的并发语句实现逻辑,数据流的描述是在控制逻辑函数已经获得的条件下实现,数据流代码亦称为并发代码。
    注意:并发语句在编译中被同时评估,因此语句的顺序无关紧要。

    特点:

    1. 直接使用基本门和扩展门实现,没有结构化。
    2. 逻辑表达式在编码之前需要写好。
    3. 没有特定的硬件约束。
    4. 可以综合。
    5. 数据流使用一系列的并发语句实现逻辑. 。
    6. 数据流的描述是在控制逻辑函数已经获得的条件下实现。
    7. 数据流代码亦称为并发代码。
       

    举例:

    • input: x1, x2, x3, ... , xn;
    • output: y1, y2, y3, ..., yn;
    • 数据流描述:
    y1 <= x1 AND x2; y2 = NOT x1; y3 <= x3 OR x2;

    3.3.3 行为描述

    顺序和并发语句,通过输入输出响应描述。

    特点:

    1. 电路的功能,无关结构(用于数学模型或系统工作原理的仿真)。
    2. 不面向特定硬件。
    3. 不一定可综合。
    4. 易于理解,因为行为描述更像人类的语言。
    5. 它精确地表示了在“黑盒子”内部发生的输入-输出之间的关系。
    6. 在VHDL中,通常使用PROCESS(进程)实现。

    举例:

    • input: x1, x2, x3, ... , xn;
    • output: y1, y2, y3, ..., yn;
    • 行为描述:
    if x1 = '0' then
    y1 <= x2 and x3; 
    elsif ... 
    esle ... 
    end if;

    3.3.4 举例说明,下面是一个两位相等比较器的例子:

    entity equ2 is
    port(a,b:in std_logic_vector(1 downto 0);
    equ:out std_logic);
    end equ2;
    --结构体结构描述:用元件例化,即网表形式来实现;
    architecture netlist of equ2 is
    component nor2
    port(a,b :in std_logic;
    c :out std_logic);
    end component;
    component xor2
    port(a,b :in std_logic;
    c :out std_logic);
    end component;
    signal x: std_logic_vector(1 downto 0);
    begin
    U1:xor2 port map(a(0),b(0),x(0));
    U2:xor2 port map(a(1),b(1),x(1));
    U3:nor2 port map(a(0),b(1),equ);
    end netlist;
    --结构体数据流描述:用布尔方程来实现:
    architecture equation of equ2 is
    begin
    equ<=(a(0) xor b(0)) nor(a(1) xor b(1));
    end equation;
    --结构体行为描述:用顺序语句来实现:
    architecture con_behave of equ2 is
    begin
    process(a,b)
    begin
    if a=b then
    equ<='1';
    else
    equ<='0';
    end if;
    end procerss;
    end con_behave;
    --结构体行为描述:用并行语句来实现:
    architecture seq_behave of equ2 is
    begin
    equ<='1' when a=b else '0';
    end sqq_behave;

    用行为描述方式设计的全加器 

    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    
    ENTITY onebitadder IS
    PORT(a,b,cin:IN BIT;
    Sum,count:OUT BIT);
    END onebitadder;
    
    ARCHITECTURE behavior OF onebitadder IS
    BEGIN
    PROCESS(a,b,cin)
    BEGIN
    Sum<= a XOR b XOR cin;
    Count<=(a AND b) OR ((a XOR b) AND cin);
    END PROCESS;
    END behavior;
    

    3.4 块语句结构:

    块结构名:
    BLOCK 
    端口说明 类属说明
    BEGIN
    并行语句
    END BLOCK 块结构名;
    

    3.5 进程语句结构:

    进程名:
    PROCESS(敏感信号表) IS
    进程说明
    BEGIN
    顺序描述语句
    END PROCESS 进程名;

    4.配置(Configuration)

    4.1 配置的作用

    • 用于实现模型的关联,可将一个 Entity 和一个Architecture关联起来,也可将一个 component 和一个 entity-architecture关联起来。
    • 目的是为了在一个实体中灵活的使用不同的Architecture。可以在仿真环境中大量使用,但是在综合环境中限制使用。

    4.2 配置的格式

    Configuration 配置名 of 实体名 IS
        for 结构体名
        end for;
    end;-- 1076-1987 version
    end;Configuration;-- 1076-1993 version
    
    Configuration <identifier> of <entity_name> IS
        for <architecture_name>
        end for;
    end;-- 1076-1987 version
    end;Configuration;-- 1076-1993 version

    4.3 配置举例

    5.子程序模块

    能被主程序反复调用并能将处理结果传送到主程序的程序模块,子程序分为过程语句(Procedure)和函数(Functure)两种。子程序中的参数说明是局部的,只能在子程序体内起作用。

    5.1 过程语句(Procedure)

    PROCEDURE 过程名(参数1;参数2;----) IS
    定义语句;
    BEGIN
    顺序处理语句;
    END 过程名;
    

    5.2 函数(Functure)

    FUNCTION 函数名(参数1;参数2;----)
    RETURN 数据类型 IS
    定义语句;
    BEGIN
    顺序处理语句;
    RETURN 返回变量名;

    三、VHDL基本语法

    1.标识符

    标识符用来定义常数、变量、信号、端口、子程序或者参数的名字。由字母(A~Z, a~z)、数组(0~9)和下划线(_)字符组成。

    1.1 标识符规则:

    1. 首字符必须是字母
    2. 末字符不能为下划线
    3. 不允许出现两个连续的下划线
    4. 不区分大小写
    5. VHDL定义的保留字(关键字),不能用作标识符
    6. 标识符字符最长可以是32个字符
    7. 注释由两个连续的下划线(--)引导

    1.2 关键字 (保留字)

    关键字(keyboard)是VHDL中具有特别含义的单词,只能作为固定的用途,用户不能用其做为标识符。

    2.数据对象

    2.1 信号(SIGNAL)

    为全局变量,在程序包说明、实体说明、结构体描述中使用,用于声明内部信号,而非外部信号(外部信号为IN、OUT、INOUT、BUFFER),其在元件之间起互联作用,可以赋值给外部信号。
    定义格式:

    SIGNAL 信号名: 数据类型[:= 初始值];
    
    举例:
    SIGANL brdy: BIT;
    SIGANL output: INTEGER:= 2;

    赋值格式:

    目标信号名<=表达式

    常在结构体中用赋值语句完成对信号赋初值的任务,因为综合器往往忽略信号声名时所赋的值。

    2.2 变量(VARIABLE)

    只在给定的进程(process)中用于声明局部值或用于子程序中,变量的赋值符号为“:=”,和信号不同,信号是实际的,是内部的一个存储元件(SIGNAL)或者是外部输入(IN、OUT、INOUT、BUFFER),而变量是虚的,仅是为了书写方便而引入的一个名称,常用在实现某种算法的赋值语句当中。
    定义格式:

    VARIABLE 变量名: 数据类型[:= 初始值];
    
    举例:
    VARIABLE opcode: BIT_VECTOR(3 downto 0):= "0000";
    VARIABLE freq: INTEGER;

    变量赋值符号":=",变量赋值立刻更新。 

    2.3 常量(CONSTAT)

    在结构体描述、程序包说明、实体说明、过程说明、函数调用说明和进程说明中使用,在设计中描述某一规定类型的特定值不变,如利用它可设计不同模值的计数器,模值存于一常量中,对不同的设计,改变模值仅需改变此常量即可,就如上一章所说的参数化元件。
    定义格式:

    CONSTANT 常数名:数据类型:= 初始值;
    
    举例:
    CONSTANT rise_fall_time: TIME:= 2ns;
    CONSTANT data_bus: INTEGER:= 16;
    

    2.4 信号与变量的区别

    信号与变量最大的不同在于,如果在一个进程中多次为一个信号赋值,只有最后一个值会起作用,而当为变量赋值时,变量的值改变是立即发生的。

    3.数据类型

    VHDL是一种强类型语言,对于每一个常数、变量、信号、函数及设定的各种参量的数据类型(DATA TYPES)都有严格要求,相同数据类型的变量才能互相传递和作用,标准定义的数据类型都在VHDL标准程序表STD中定义,实际使用中,不需要用USE语句以显式调用。

    VHDL常用的数据类型有三种:

    1. 标准定义的数据类型
    2. IEEE预定义标准逻辑位
    3. 矢量及用户自定义的数据类型。

    3.1 标准定义的数据类型

    • 布尔:(Boolean)

    Type BOOLEAN IS (FALSE, TRUE);

    取值为FALSE和TRUE,不是数值,不能运算,一般用于关系运算符

    • 位:(Bit)

    TYPE BIT IS ('0', '1');

    取值为0和1,用于逻辑运算

    • 位矢量:(Bit_Vector)

    TYPE BIT_VECTOR IS ARRAY(Natural range<>) OF BIT;

    基于Bit类型的数组,用于逻辑运算

    SIGNAL a: Bit_Vector (0 to 7); Signal a: Bit_Vector (7 to 0);

    • 字符:(character)

    TYPE CHARACTER IS (NUL, SOH, STX, ..., '', '!', ...);

    通常用''引号引起来,区分大小写

    • 字符串:(String)

    通常用""双引号引起来,区分大小写

    VARIABLE string_var: STING (1 to 7);

    string_var := "ABCD"

    • 整数:(Integer)

    取值范围-(2^{31}-1) to (2^{31}-1),可用32位的有符号的二进制数表示

    VARIABLE a: INTEGER -63 to 63

    在实际应用中,VHDL仿真器将ITEGER作为有符号数处理,而VHDL综合器将Integer作为无符号数处理

    要求用range子句为所定义的数限定范围,以便根据范围来决定表示此信号或变量的二进制的位数。

    • 实数:(real)

    实数类型仅能在VHDL仿真器中使用,综合器不支持

    取值范围 -1.0E38 to +1.0E38

    • 时间:(Time)

    物理量数据,包括整数和单位两个部分

    时间类型仅能在VHDL仿真器中使用,综合器不支持

    范围从-(2^{31} -1)to (2^{31}-1)

    表达方法包含数字、(空格)单位两部分,如(10 PS)

    常用单位:fs,ps,ns,us,ms,sec,min,hr

    • 错误等级:(severity level)

    表示系统状态

    该类型仅能在VHDL仿真器中使用,综合器不支持

    TYPE severity_lever IS (NOTE, WARNING, ERROR, FAILURE)

    3.2 IEEE预定义的标准逻辑位与矢量

    • STD_LOGIC:工业标准的逻辑类型,取值为‘0’(强制为高)、‘1’(强制为低)、‘Z’(高阻态)、‘X’(强未知)、‘W’(弱未知;弱信号不定)、‘L’(弱0;弱低)、‘H’(弱1;若高)、‘-’(忽略;不关心)、‘U’(未初始化),只有前四种具有实际物理意义,其他的是为了与模拟环境相容才保留的。
    • STD_LOGIC_VECTOR:工业标准的逻辑类型集,STD_LOGIC的组合。

    3.3 用户自定义的数据类型

    • 枚举类型
      • 格式:TYPE 数据类型名 IS (枚举文字,枚举文字,. . . .)
    • 整数类型和实数类型
      • 整数类型与实数类型是标准包中预定义的整数类型的子集,由于综合器无法综合未限定范围的整数类型的信号或变量,故一定要用RANGE子句为所定义整数范围限定范围以使综合器能决定信号或变量的二进制的位数。
      • 格式:TYPE 数据类型名 IS RANGE 约束范围;(如-10到+10)
    • 数组类型
      • 格式:TYPE 数据类型名 IS ARRAY(下限 TO 上限) OF 类型名称
    • 记录类型
      • 格式:
    TYPE 记录类型名 IS RECODE
    元素名: 数据类型名;
    元素名: 数据类型名;
    END RECODE

    4.运算符

    4.1 算术运算符

    1. +, -, *, /
    2. MOD: 取模,取模运算(a MOD b)的符号与b相同,其绝对值小于b的绝对值。如:-5 MOD 2 = 1,5 MOD -2 = -1。
    3. REM: 取余,取余运算(a REM b)的符号与a相同,其绝对值小于b的绝对值。如:-5 REW 2 = -1,5 MOD -2 = 1。
    4. 多数语言对取余和取整不区分,比如python都是用%符号。详情见https://blog.csdn.net/origin_lee/article/details/40541053
    5. SLL(Shift Left Logical): 逻辑左移,将位向量左移,右边移空位补零。
    6. SRL(Shift Right Logical): 逻辑右移,将位向量右移,左边移空位补零。
    7. SLA(Shift Left Arithmetic): 算数左移,将位向量左移,右边第一位数值保持不变。
    8. SRA(Shift Right Arithmetic): 算数右移,将位向量右移,左边第一位数值保持不变。
    9. ROL(rotate left): 循环左移。
    10. ROR(rotate right): 循环右移。
    11. **: 乘方。
    12. ABS(absolute): 取绝对值。

    4.2 关系运算符

    1. =,/=,<,>,<=,>=

    4.3 逻辑运算符

    1. AND, OR
    2. NAND, NOR, NOT
    3. XNOR: 同或, XOR: 异或

    4.4 赋值运算符

    1. <=: 信号赋值,最后赋值。
    2. :=:逻辑赋值,即时赋值。

    4.5 关联运算符

    1. =>

    4.6 其他运算符

    1. +,-
    2. &:并置操作符

    4.7 运算符优先级

    4.8 运算符表格一览

    关于运算符的分类暂不详究。。。

    四、VHDL语句

    顺序语句和并行语句是VHDL程序设计中两大基本描述语句系列。顺序语句(Sequential Statements)用来实现模型的算法描述;并行语句(Concurrent Statements)用来表示各模型算法描述之间的连接关系,这些语句从多侧面完整地描述数字系统的硬件结构和基本逻辑功能,其中包括通信的方式、信号的赋值、多层次的元件例化以及系统行为等。

    1. 并行语句

    1.1 并行语句的特点

    • 相对于传统的软件描述语言,并行语句结构是最具VHDL特色的:并行运行。 
    • 物理意义:硬件连接关系
    • 每一并行语句内部的语句运行方式可以有两种不同的方式,即并行执行方式(如块语句)和顺序执行方式(如进程语句)。因此,VHDL并行语句勾画出了一幅充分表达硬件电路的真实的运行图景。

    1.2 并行语句的格式

    Architecture <architecture_name> of <entity_name> is
    说明语句;
    begin
        并行语句;
    end architecture 结构体名;

    1.3 并行语句的种类

    1. 并行信号赋值语句(CONCURRENT SIGNAL  ASSIGNMENTS)
    2. 条件/选择信号赋值语句(CONDITIONAL/SELECTED SIGNAL  ASSIGNMENTS)
    3. 进程语句(PROCESS STATEMENTS)
    4. 块语句(BLOCK STATEMENTS)
    5. 元件例化语句(COMPONENT INSTANTIATIONS)
    6. 生成语句(GENERATE STATEMENTS)
    7. 并行过程调用语句(CONCURRENT PROCEDURE CALLS)

    下面介绍八种并行语句

    1.4 并行信号赋值语句

    <signal_name> <= <expression>;
    
    Example:
    q <= input1 or input2;
    q <= input1 and input2;
    -- 最终执行 q <= input1 and input2; 

    1.5 条件信号赋值语句

     

    1.6 

    2. 顺序语句
     

     

     

     

     

     

     

     

     

     

     


    参考文献:

    https://wenku.baidu.com/view/52d350b509a1284ac850ad02de80d4d8d15a0127.html

    https://www.jianshu.com/p/73b2bd91407f

     

     

    展开全文
  • VHDL的语法

    2021-10-27 11:08:17
    9、属性 S'EVENT,如果当前的△时间期间发生了事件返回真,否则返回假(信号是否有值的变化) VHDL语法学习笔记:一文掌握VHDL语法 - 云+社区 - 腾讯云 FPGA学习笔记06-VHDL语法基础-生成语句(generate) - 伊可的...
  • vhdl入门8位全减器

    千次阅读 2019-09-24 23:08:33
    课上写全减器,题看错了,...代码:课上我是用两个with——select写的,忘记了vhdl也可以用数组的方式,注意with——select是直接放在结构体下的! 如果是给高阻态,一定大写的Z。 --ujs-lili library IEEE; use IEE...
  • VHDL中具有属性的项目有:类型、子类型、过程、函数、信号、变量、常量、实体、结构体、配置、程序包、元件和语句标号 8.1、信号类属性 用于信号,包括: EVENT :如果当前的δ期间内发生了事件,则返回TRUE,...
  • VHDL实现计数器

    万次阅读 多人点赞 2019-04-17 11:37:40
    10进制同步计数器 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL;... G1:FOR i IN 0 TO 3 GENERATE dtriggerx:dtrigger PORT MAP(temp(i+1),temp(i),r,q(i),temp(i+1)); END GENERATE G1; END count16_behavior;
  • generate块应用的场合通常是对模块进行批量例化,或者有条件的例化,使用参数进行控制对哪些模块进行例化,或者例化多少。 不仅限于模块例化,当同一个操作或模块实例需要多次重复,或者某些代码需要根据给定的...
  • VHDL 入门 01编程步骤

    2020-09-26 22:40:49
    VHDL Language Structural Modeling Step1 Generate top-level entity declaration entity my_compare is port( A_IN : in std_logic_vector(2 downto 0) ; B_IN : in std_logic_vector(2 downto 0) ; EQ_OUT : ...
  • QUARTUS II 编译报错Error: Run Generate Functional Simulation Netlist (...) to generate functional simulation netlist for top level entity bmg_control before running the Simulator (quartus_sim)的解决...
  • VHDL的元件例化

    千次阅读 2020-12-06 21:36:11
    VHDL的元件例化元件声明元件例化三种关联方式两种调用方式生成语句 元件声明 COMPONENT 元件名 [GENERIC<参数说明>;] PORT<端口说明>; END COMPONENT; 元件例化 三种关联方式 1.位置关联 这种方式中...
  • VHDL 疑难解答

    千次阅读 2017-10-31 08:29:35
    VHDL的并行语句用来描述一组并发行为,它是并发执行的,与程序的书写顺序无关。进程语句 begin 进程语句包含在结构体中,一个结构体可以有多个进程语句,多个进程语句间是并行的,并可访问结构体或实体中定义的...
  • vhdl按键消抖

    2013-05-10 19:35:15
    关于vhdl的消抖程序, library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity shift is port(sin,cp:in std_logic;f:out std_logic); end shift; ...
  • EDA与VHDL题库

    千次阅读 多人点赞 2020-07-04 22:53:25
    EDA与VHDL题库分享
  • VHDL N位 除法器

    2011-09-21 00:20:34
    已调试通过 修改GENERATE 就可以实现N位除法
  • This file consists of a design with doc file description to generate sin-cos
  • VHDL的并行语句

    千次阅读 2021-05-28 12:06:30
    generate语句 进程语句 过程调用语句 块语句 并行语句在VHDL程序中的位置 并行语句可以是结构体的begin与end之间的任何位置,举例如下: architecture <arch_name> of <entity_name> is -- Declarat
  • VHDL中的简单UART实现 描述 非常简单,无缓冲的8位数据位,0位奇偶校验,1位停止位串行通信通道的实现。 通过分别设置I_clk_baud_count,应该能够在任何波特率下(有一定程度的错误): For a 50MHz I_clk: I_clk_...
  • VHDL保留关键字

    2021-09-06 19:19:55
    From VHDL 87: abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant disconnect downto else elsif end entity exit file ...
  • 基于VHDL移位寄存器程序设计

    千次阅读 2020-04-23 17:43:36
    下面全加器的设计采用层次结构的VHDL程序设计方法,采用元件例化语句。 工程文件名与顶层文件(全加器)文件名一样; 把全加器、半加器、或门的vhdl文件都要包含到工程中; 在全加器文件中声明半加器、或门为元件;...
  • VHDL——4位移位寄存器

    千次阅读 2021-04-17 14:23:40
    2.VHDL语言 2.1 D触发器 library ieee; use ieee.std_logic_1164.all; entity dff1 is port( clk,d:in std_logic; q:out std_logic ); end dff1; architecture behavior of dff1 is begin process(c
  • Verilog中生成语句(generate)的用法

    万次阅读 2016-12-18 23:36:50
    一:generate Verilog-2001添加了generate循环,允许产生module和primitive的多个实例化,同时也可以产生多个variable,net,task,function,continous assignment,initial和always。在generate语句中可以引入if-...
  • VHDLVHDL设计n的全加器

    千次阅读 2017-02-28 07:41:46
     其中的两输入或门可以调用系统元件库也可以自己设计和封装,或者通过画图的方式来实现,本人是通过编程的方式来实现的,即在相同的文件夹下,新建VHDL文件,然后编写或门。 --两输入或门 library ieee; use...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 878
精华内容 351
关键字:

generatevhdl