Verilog HDL入门

Verilog HDL是一种硬件描述语言(HDL:Hardware Description Language),它是以文本形式来描述数字系统硬件的结构和行为的语言。世界上最流行的两种硬件描述语言是Verilog HDL和VHDL。

Verilog HDL是一种描述语言,和常见的编程语言C有根本的不同。C语言让计算机的CPU从上往下按顺序执行每一条指令,执行完程序就结束了。而Verilog HDL主要是描述一个数字模块的结构,或者行为。有点像商业合同,合同里面也会描述产品的结构,产品的功能等等。合同的每一个条款,并不需要严格的先后顺序,只要把项目的方方面面都考虑完整,写下来就OK了。VerilogHDL也是这样。

我们用户Verilog HDL描述数字模块的功能,剩下的交给编译器(如Quartus),编译器会根据我们的要求设计重构FPGA内部硬件。

下面来认识一下VerilogHDL:

我们先选择一个“数据选择器”:s是数据选择控制端;a,b是输入信号,y是输出信号

module mux2_1(a, b, s, y); //模块名、模块接口名
    input a, b, s;        // 定义输入端口
    output y;              // 定义输出端口
 
    /* s为0时,选择a输出;
        s为1时,选择b输出。*/  
    assign y = (s == 0) ? a : b;  //输出信号
endmodule

每个Verilog文件中都有一个module开始,endmodule结束的代码块。

这个代码块定义了一个名字叫mux2_1的模块,模块名后面紧跟的括号内写明了该模块的接口信号,相当于数字器件的引脚。但是括号内没有说明接口的信号方向,所以紧跟着另起一行用input和output再说明一下。注释和C语法一样,可以用//或/* */。

assign是Verilog的关键字,书上为连续赋值,assign后面紧跟的y在硬件上是一根导线(或输出引脚)。

assign y = (s == 0)?a:b;这句话的意思是:如果s为0,那么等号左边为a;否则就是b。将这个表达式的输出结果接在输出引脚y上。

这就是一个简单的Verilog程序,不需要我们设计与非门,直接表达想要的功能就好了。然后,编译下载到FPGA,功能就实现了。需要注意的是assign后边永远跟着一个=,它们是一起使用的。即assign xx = zz。

上面的2选1数据选择器,内部实现结构如下:

这里写图片描述

所以assign语句还可以这样写,直接使用逻辑表达式:

assign y =(a&(~s)) | (b&s); 

这个是在门级对逻辑关系进行描述,所以不属于行为描述,算是结构描述吧。下面这种描述方式,叫做门原语,算结构描述。这里的关键词wire表示电路中的导线(信号线)。

module mux2_1(a, b, s, y);
    input a, b, s;
    output y;
    wire ns, as, bs;
 
    not(ns, s);//这里使用了一个非门,输出是ns,输入是s
    and(as, a, ns);//使用一个与门,输出as,输入a和ns
    and(bs, b, s);//使用与门,输出bs,输入b和s
    or(y, as, bs);//使用或门,输出y,输入as和bs
endmodule

这是告诉我们电路中有什么元器件,又是怎么连接的,所以这个属于结构描述。很明显,有时候结构描述比行为描述要费力的多,而且不太容易理解程序功能。另外,上面的这个程序中,4个逻辑门的顺序可以随便写,不用管先后顺序。

通过计算机上运行的工具进行图1模块到图2模块形式的转化,就称之为综合。

这个数据选择器,还可以使用如下行为描述方法:

module mux2_1(a, b, s, y);
    input a, b, s; 
    output y; 
    reg  y; //reg 表示寄存器
 
    always @(a, b, s)
    begin
        if(!s) y = a;
        else y = b;
    end
endmodule

这里reg表示寄存器(存储器),需要提醒一下的是,assign后面只能接wire型,不能接reg型。(当然output从物理上也是wire)。因为寄存器的赋值处理需要输入信号,还需要触发信号。

always @(a, b, s)中,括号里的输入信号a,b,s表示敏感信号。always @( )是连在一起的使用的,意思是,敏感信号列表中的任何一个信号发生变化,将会引起begin ...... end之间的行为。

Verilog用begin和end包围代码段,相当于c语言中的大括号{ }的功能。

if(!s) y  = a; 这里的 “=” 单独使用,叫做“阻塞赋值”,比如有这么一段代码:

b = a;

c = b;

那么最后,c的值就等于a,这个行为在描述的时候,语句的先后顺序,决定了赋值的先后。

在Verilog中,和它对应的还有一个“非阻塞赋值”,表示方法是<=,也可以称之为“并行赋值”。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值