FPGA学习:Verilog基本语法

    前言

    这学期的数电课进行了很大的改革,要求学生使用FPGA开发板进行课内实验,还有专门的数电实验课,课程结束后还有为期两周的课程设计,近几年,由于深度学习、异构计算等的兴起,FPGA的地位也是显著上升,FPGA强大的并行计算能力决定了它极高的上限,当然对设计人员的要求也是很高的。本来我是不怎么想学FPGA的,但是学校这么安排,而且自己看了看也觉得有点意思,所以学一学也是挺不错的,说不定会有什么用处呢。

基本语法

    与C的区别

        Verilog是硬件描述语言,在编译下载到FPGA后会生成电路,是并行运行的

        C的软件编程语言,编译下载到单片机后是存储器中的一组指令,串行执行

    逻辑值:0,1,x,z

    b,o,d,h 二 八 十 十六

    4'd2表示二进制数2(4位宽)

    注意:位宽为2进制的位宽,不指定的话为32位位宽,直接写数默认是32位十进制数

    可以加下划线提高可读性16'b1001_1010_1010_1001=16'h9AA9

    标识符

        定义变量、模块名、信号名

        字母、数字、$、_组合而成 首字母是数字或_   区分大小写

        推荐写法:大小写不混写、普通内部信号小写、命名体现含义

    数据类型

        三大类:寄存器、线网、参数

        前两者在数字电路中真正起作用

        寄存器类型

            抽象的数据存储单元,可以通过赋值语句改变寄存器存储的值,关键字reg,reg类型的默认初始值x

            reg类型只能在always和initial语句中被赋值

            如果该过程语句描述的是时序逻辑,即always语句带有时钟信号,则该寄存器变量对应为触发器

            如果是组合逻辑,即不带时钟信号,则该寄存器变量对应为硬件连线

            不给位宽默认为1

            注意:定义时不能赋值

            reg[31:0] delay_cnt;//32位

            reg    key_reg;//1位

        线网类型

            结构实体(例如门)之间的物理连线

            wire和tri类型,常用wire

            不能存储值,值是由驱动它的值决定的

            驱动元件:门、连续赋值语句、assign赋值语句

            没有接驱动元件是高阻

            wire key_flag;//一位,指定位数同上

        参数类型

            常量

            parameter定义常量

           parameter   H_SYNC   =   11'd41;

             采用标识符代表一个常量可以提高程序可读性和可维护性

            用于表示状态机状态、表示位宽、延迟大小

            在模块调用中通过参数的传递改变调用模块汇总已定义的参数

运算符

    1、算术运算符

        同C

    2、关系运算符

       同C

    3、逻辑运算符

        同C

    4、条件运算符

        同C三目运算符

    5、位运算符

        ^按位异或

        ~取反

        &按位与

        |按位或

        位数小的前面补零补到位数相同进行操作

    6、移位运算符

        同C

        不同点:左移时位宽增加,右移位宽不变

    7、拼接运算符

        {}    {a,b}   将a,b拼接起来作为一个新信号

       例:c={a,b[3:0]};

     优先级排序和C类似单目到多目递增

程序框架

    Verilog注释

        两种,同C

    Verilog关键字

        

    常用关键字

       

    Verilog程序框架

        基本的设计单元是模块block(类似C的函数)

        模块由两个部分组成,一部分描述接口,一部分描述逻辑功能

        

        可综合模块:能对应的实际电路

       四个主要的部分:端口定义、IO说明、内部信号说明、功能定义

        功能定义部分有三种方法:

        1、assign语句

            描述组合逻辑

        2、always语句

            描述组合/时序逻辑

        3、例化实例元件

            如:and #2 u1(q,a,b);

        上述三种逻辑功能是并行的

        在always块中,逻辑是顺序执行的,而多个always块之间是并行的

        模块的调用

            在模块调用时,信号通过模块端口在模块之间传递

           

            

           以上为例化端口和端口连接的实例

          注意输出daunt必须连接到一个wire类型的变量上去,变量传递时位宽要一致

          另一种端口连接方式(不推荐,对顺序要求严格)

            

高级知识点

    结构语句

        initial和always

        initial

          只执行一次,常用于测试文件的编写,用来产生仿真测试信号(激励信号),或者用于对存储器变量赋初值

        always

          语句一直在不断地重复活动,但是只有和一定的时间控制结合在一起才有作用

          

            

            always的时间控制可以是沿触发也可以是电平触发,可以是单个信号也可以是多个信号,多个信号用or连接(敏感列表)

          posedge上升沿 negedge下降沿

           

           顺序块又叫过程块

          沿触发的always块常用来描述时序逻辑

           电平触发的always块常用来描述组合逻辑

           

            

        如果组合逻辑块语句输入变量多,可以用*表示对后面语句块中所有的输入变量的变化都是敏感的

        组合逻辑和时序逻辑是逻辑功能的不同

        组合逻辑中,任意时刻的输出仅仅取决于该时刻的输入,与电路原来的状态无关

        时序逻辑中,任意时刻的输出不仅取决于当时的输入信号而且还取决于电路原来的状态,或者说还与以前的输入有关,因此时序逻辑必须具备记忆功能

    

    赋值语句

        阻塞赋值 如b=a

           阻塞幅值可以认为只有一个操作:计算RHS并更新LHS

           所谓阻塞的概念是指在同一个always块中,后面的赋值语句是在前一句赋值语句结束后才开始赋值的

       非阻塞赋值 如b <= a;

            可以看成两个操作:赋值开始时计算RHS;赋值结束时更新LHS

            概念是指在计算非阻塞赋值的RHS以及更新LHS期间,允许其他的非阻塞赋值语句同时计算RHS和更新LHS

            只能用于对寄存器类型的变量进行赋值,因此只能用于initial块和always块等过程块中

        在描述组合逻辑的always块中用阻塞幅值,这种电路结构只与输入电平的变化有关系

        在描述时序逻辑的always块中用非阻塞赋值,这种电路结构往往与触发沿有关系,只有在触发沿时才可能发生赋值变化

        注意:在同一个always块中不要即用非阻塞幅值又用阻塞幅值

            不允许在多个块中对一个变量进行赋值

    条件语句

       if-else语句(与C类似)

        case语句

            没有switch

           

          分支表达式的值需要互不相同

          所有表达式的位宽必须完全相等(不能用'bx等写法)

          casez比较时不考虑表达式中的高阻态

          casex不考虑高阻态和不定值

  • 12
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值