Verilog HDL 快速入门

VerilogHDL快速入门VerilogHDL是一种硬件描述语言(HDL:HardwareDescriptionLanguage),它是以文本形式来描述数字系统硬件的结构和行为的语言。世界上最流行的两种硬件描述语言是VerilogHDL和VHDL。注意,VerilogHDL是一种描述语言,它和常见的编程语言C有根本的不同。C语言,让计算机的CPU从上往下按顺序执行每一条指令,执行完…

大家好,又见面了,我是你们的朋友全栈君。

Verilog HDL 快速入门

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

注意,VerilogHDL是一种描述语言,它和常见的编程语言C有根本的不同。C语言,让计算机的CPU从上往下按顺序执行每一条指令,执行完程序就结束了。

而,VerilogHDL主要是描述了一个数字模块的结构,或者行为。有点像商业合同,合同里面也会描述产品的结构,产品的功能等等。合同的每一个条款,并不需要严格的先后顺序,只要把项目的方方面面都考虑完整,写下来就OK了。VerilogHDL也是这样。

我们用VerilogHDL描述数字模块的功能,剩下的交给编译器(如,Quartus),编译器会根据我们的要求设计重构FPGA内部硬件。对于大批懒人来说,这技术简直碉堡了。这就是EDA(Electronic Design Automation,电子设计自动化)。


好,下面就来认识一下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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

每个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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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


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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这里reg表示寄存器(存储器),需要提醒一下的是,assign后面只能接wire型,不能接reg型。(当然output从物理上也是wire) 
为什么不能?因为寄存器的赋值除了需要输入信号,还需要触发信号(例如D触发器寄存器),assign?sorry,he can’t。

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中,和它对应的还有一个“非阻塞赋值”,表示方法是 <=,我把这种赋值称为“并行赋值”。具体区别,请参考另一篇短文阻塞赋值和非阻塞赋值

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/124574.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • java异常处理(较详细)「建议收藏」

    java异常处理(较详细)「建议收藏」java异常处理(较详细)在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的。比如:客户输入数据的格式,读取文件是否存在,网络是否始终保持通畅等等。异常:在Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)Java程序在执行过程中所发生的异常…

  • Python字符串操作之字符串分割与组合「建议收藏」

    Python字符串操作之字符串分割与组合「建议收藏」12、字符串的分割和组合str.split():字符串分割函数通过指定分隔符对字符串进行切片,并返回分割后的字符串列表。语法:os.path.split():路径文件分割函数join(seq):将序列组合成字符串函数

  • 什么是DDR3_DDR3 SDRAM

    什么是DDR3_DDR3 SDRAMODT是什么鬼?为什么要用ODT?在很多关于DDR3的博文和介绍中都没有将清楚。在查阅了很多资料并仔细阅读DDR3的官方标准(JESD79-3A)之后,总算有点了头绪,下面来整理整理。1、首先ODT是什么?ODT(On-DieTermination),是从DDR2SDRAM时代开始新增的功能。其允许用户通过读写MR1寄存器,来控制DDR3SDRAM中内部的终端电阻的连接或者断开。在DDR3…

  • QT中this指针

    QT中this指针一:this指针只能在一个类的成员函数中调用,它表示当前对象的地址。下面是一个例子: void Date::setMonth( int mn) { month=mn; // 这三句是等价的 this->month=mn; (*this).month=mn; }1.this只能在成员函数中使用。全局函数,静态函数都不能使用th

  • exe免杀c语言,CobaltStrike shellcode免杀捆绑exe思路[通俗易懂]

    exe免杀c语言,CobaltStrike shellcode免杀捆绑exe思路[通俗易懂]这里演示的方式为shellcode框架加载自解压1.生成shellcode2.c加载(随便拉的加载器)#include#include#pragmacomment(linker,”/subsystem:\”windows\”/entry:\”mainCRTStartup\””)unsignedcharshellcode[]=”\xfc\xe8\x89\x00\x00\x00\x60\…

  • linux中ll命令用法_linux命令ll与ls的区别

    linux中ll命令用法_linux命令ll与ls的区别ll并不是linux下一个基本的命令,它实际上是ls-l的一个别名。一些Linux系统默认不支持命令ll,必须用ls-l,这样使用起来不是很方便。如果要使用此命令,可以作如下修改:打开~/.bashrc增加aliasll=‘ls-l’aliasll=’ls-l’(关闭原来的终端才能使命令生效)这样个人用户可以使用ll命令,当切换成超级用户后,使用ll命令时提示找不到命令,那是因为你只是修改了个人用户的配置,所以,切换成root后做相同的操作即可解决问题。启示:我们可以通

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号