Verilog HDL笔记

这篇具有很好参考价值的文章主要介绍了Verilog HDL笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.Verilog语法基础

1. 逻辑值

        0:逻辑低电平,条件为假

        1:逻辑高电平,条件为真

        z:高阻态,无驱动

        x:未知逻辑电平

2. 归约运算符,按位运算符

        以&为例,当&作为一元运算符时表示归约与,&m是将m中所有比特位相与,最后的结果为1bit

        例如:

                &4'b1111=1&1&1&1=1'b1

                &4b'1101=1&1&0&1=1'b0

        当&作为二元运算符时表示按位与,m&n是将m的每个比特位与n的相应比特位相与,在运算时要保证m和n的比特位数相等,最后的结果与m和n的比特位数相同

        例如:

                4b'1010&4b'0101=4b'0000

                4b'1101&4b'1111=4b'1101

        其它例如'~&' , '^' , '~^' , '|', '~|' 在分别作为一元和二元运算符时也有和'&'一样的性质

3. 逻辑运算符和关系运算符

        具有'&&'形式的操作符表示逻辑与

        例如:

                a=a'ha, b=4'd0, c=a&&b  运算结果是c=0

        关系运算符(逻辑运算符)的使用方法和C语言完全类似

4. 移位运算符

        移位运算符时二元运算符,左移符号为'<<',右移符号为'>>',结果是将运算符左边的操作数左移或右移指定的位数,用0来填补空位

        b <= a<<1;   #作用是将a的每一位都向左移动1位,结果赋值给b

        b <= a>>2;   #作用是将a的每一位都向右移动1位,结果赋值给b

需要注意的是:

        1)移位运算造成的空位自动用0来填充,因此任意一个二进制数只要一直移位其值最终都会变成0。

        例如: a=4'b1000,  a>>3的结果为 4'b0001;a>>4的结果为4'b0000

        2)移位运算符在使用时可代替乘法和除法,左移一位看作是乘以2,右移移位可以看作是除以2,但是仍然要注意位宽的拓展。

5.位拼接运算符

        位拼接运算符由一对花括号加逗号组成,形式为’{  , }', 拼接的不同数据之间用','隔开。

        例如:

                将8bit的a、3bit的b、5bit的c按顺序拼接成一个16位的d,表示方法为:d={a,b,c};

6. 条件运算符

        一般格式:(逻辑判断语句)? 语句1 : 语句2

        执行过程是:当[逻辑判断语句]为真,则[语句1]作为条件表达式的值,否则将[语句2]作为表达式的值。

        例如: a=6, b=7, c=(a>b)?a:b 语句执行后c=7

7. 运算符优先级

        归约运算符 > 算术运算符 > 移位运算符 > 关系运算符 > ’==‘ 和'!='  >  按位运算符  >  '&&' 和 '||' > 条件运算符

        归纳起来就是一元运算符 > 二元运算符 > 三元运算符。

        运算符优先级往往不需要准确记忆,通过括号增加优先级是更为简单且准确的方法。

将各种常用运算操作符总结如下:

verilog拼接,笔记,fpga开发

 verilog拼接,笔记,fpga开发

8. case分支语句

        格式:

                case(<控制表达式>)

                        <分支语句1> : 语句块1;

                        <分支语句2> : 语句块2;

                         ......

                        <分支语句n> : 语句块n;

                        default : 语句块n+1;

                endcase                                #这行不要漏写

        注意:

                1)在执行了某一分支项内的语句后,跳出case语句结构,终止case语句执行。

                2)case语句中的各个<分支语句>中表达式取值必须是互不相同的。

二. 系统函数

定义:Verilog语言中预先定义了一些任务和函数,用于完成一些特殊的功能,它们被称为系统任务和系统函数。这些函数大多数都是只能在Testbench仿真中使用的,使得用户可以更方便地进行验证。

1.timescale函数

        格式: 'timescale   1ns/1ns   #时间尺度预编辑指令  参数对应  时间单位/时间精度

        其中时间单位和时间精度由值为1、10、100以及单位s, ms, us, ns, ps, fs 组成。

        时间单位:定义仿真过程所有与时间相关量的单位。

        仿真中使用"#数字"格式表示延时相应时间单位的时间,例如在前面设定的时间单位和精度前提下"#10"表示延时10个时间单位,也就是10ns

        时间精度:决定时间相关量的精度以及仿真显示的最小刻度。

        例如:

                `timescale 1ns/10ps   表示的精度为0.01ns, #10.11表示延迟10110ps

                很重要的一点:timescale前面的符号是键盘左上角的,千万不要写成单引号!

        注意:在使用timescale函数时要保证时间单位大于时间精度

                'timescale  100ps/1ns 这样的写法就是错误的

2.display函数

        功能:用来输出、打印信息

        格式:$display("%b+%b=%d",a,b,c);        #"%b+%b=%d"用于输出格式控制,未指定时默认为十进制

        %h或%H    以十六进制格式输出

        %d或%D    以十进制格式输出

        %o或%O    以八进制格式输出

        %b或%B    以二进制格式输出

        注意:每次输出结束后自动换行

3.write函数

        功能:用于输出、打印信息

        格式:$write("%b+%b=%d\n",a,b,c);        #其中控制参数的用法同display函数

        注意: $write函数每次输出结束后不会自动换行,换行需要搭配"\n"实现。

4.strobe函数

        功能和用法与display和write相同,区别在于$strobe函数不论被置于程序中什么位置都是固定放在最后执行,其中变量参数也都是程序执行到最后的值。并且会自动换行。

5.monitor函数

        功能和用法与display和write相同,区别在于每改变$monitor中参数的值时就会打印一次。自动换行。

6.stop和finish函数

        $stop用于暂停仿真,$finish用于结束仿真

7. time和random函数

        功能:$time为时间函数,返回64位当前仿真时间;$random用于产生随机函数,返回随机数

8.readmemb/readmemh函数

        功能:$readmemb和$readmemh分别用于读取二进制和十六进制文件

        格式: $readmemb("<数据文件名>",<存储器名>);

                例如:$readmemb("test.txt",a);

三. 关键字

1. module(模块开始)---endmodule(模块结束) 

       格式: module exmaple

2. input(输入)/input(输出)

        input   wire    sys_cik,               #这里注意每一个参数定义要加‘,’而定义语句结尾没有

        input   wire    sys_rst_n,

        inout   wire    sda,                     #inout定义的信号可同时用于输入或输出

        output  wire    po_flag

3. 变量类型

        1)线网型变量: wire                #在系统中会被直接认为具有一条物理连线

        2)寄存器型变量: reg        #对某一时间点的状态进行保存,在系统中会被认为是寄存器

              格式: reg [7:0] a [20:0];   #表示定义一个名为a,位宽为8bit,深度为21的寄存器变量

        两种变量类型的使用场景:

                1. 当使用always语句给变量赋值时,要用reg型

                2. 当使用assign语句给变量赋值时,用wire型。assign可以视为在电路中添加一条连线。

4.参数

        1)parameter

               格式: parameter   CNT_MAX = 100;

                特性:实例化时参数可修改

        2)localparam

                格式:localparam   CNT_MAX = 100;

                特性:只能在模块内部使用,不能实例化

5.常量(基数表示法)

        格式:[换算为二进制后位宽的总长度]['][数值进制符号][与数值进制符号相对应的应的数值]

        其中:[数值进制符号]:[h]表示十六进制,[o]表示八进制,[b]表示二进制

        例如: 8'd171 : 位宽是8bit,十进制的171

                    8'hab : 8bit的十六进制数ab

                    8'o253 : 8bit的八进制数253

                    8‘b1010_1011 : 8bit的二进制数1010_1011   #二进制数可以用下划线分割增强可读性 

        [换算为二进制后位宽的总长度]这一项可有可无,verilog会自动为常量匹配合适的位宽。 当总位宽大于实际位宽,则自动在左边补0,总位宽小于实际位宽则自动截断左边超出的位数

        例如:'d7与8'd7表示相同数值,8'd7换算为二进制是8'b0000_0111,前五位补0

                   2'd7换算为二进制是2'b11,超过2位宽的部分被截断   #这里的截断是从右往左进行的

        注意:如果直接写参数,例如100,表示位宽为32bit的十进制数100        

6.赋值

        1)阻塞赋值(“=”)

                内部语句同时并行执行

        2)非阻塞赋值(“<=")

               程序从上到下顺序执行赋值语句

注意一些问题:

        1.阻塞赋值电路结构与时钟触发沿没有关系,只与输入电平的变化有关。阻塞赋值语句是顺序执行的,先计算赋值符号右边的语句并更新赋值号左边的语句,此时不允许有来自其他任何语句的干扰,直到现行的赋值完成,才允许下一条赋值语句的执行。

        2.非阻塞赋值的电路结构与时钟触发沿有关系,只有触发沿时刻才进行相应的非阻塞赋值。非阻塞赋值语句是并行执行的,先计算所有非阻塞赋值号右边的语句再同时进行向左赋值,这期间允许其他语句进行操作。

        3.非阻塞赋值只能用于对寄存器变量进行赋值,因此只能能用于‘inital’和‘always’块中(敏感列表要采用电平触发方式/敏感列表就是always@(这里)的语句),不允许用于连续赋值‘assign’中。

        4.时序逻辑电路中推荐使用非阻塞赋值,方便实现时钟边沿触发。

        5.一个语句块中不要同时用阻塞和非阻塞赋值。同时推荐一个always语句块只对一个变量进行赋值。

        6.使用锁存器(latch)要采用非阻塞赋值。

        

实例:DDS信号发生器设计

verilog拼接,笔记,fpga开发

 图中:频率字输入F_WORD和相位字输入P_WORD共同调节输出信号的频率,有如下关系:

        k=2^N*Fout/Fclk (k为频率字输入F_WORD)

        Fout=k*Fclk/2^N     

        P=θ*(2*pi/2^M)  (P位相位字输入P_WORD)

其中累加寄存器的作用是将频率字输入与相位累加器的输入隔离开,防止频率字输入的不规则性相位累加器造成影响,相位字输入的累加寄存器则同理。

注意到累加寄存器输入位宽N和相位调制器输入位宽M往往并不相同,因此这里需要考虑到位宽转换的问题,这里简单地取N的高M位作为M的输入,这样做导致的问题是计数周期会变成原来的2^(N-M)倍,也就是频率会变成原来的1/2^(N+M)倍,相当于降低了输出频率。

而频率字累加寄存器和相位字累加寄存器的值需要在相位调制器处求和并作为波形数据表寻址来在已经储存有波形幅值数据的波形数据表中取出需要的波形成分,完成DDS信号发生器的制作。 

四. 一些Verilog开发中需要注意的问题汇总

 1. 使用always@(*)进行组合逻辑设计时要注意敏感变量的情况,此时Verilog默认对于always语句块内所有变量敏感,也就是说当在同一个always语句块内对同一变量多次赋值时将导致always块被循环触发,因此会陷入死循环。

错误形式:在仿真时会出现collapse,如modelsim报错如下:Error:(vsim-3601) Iteration limit reached at time 55445 ns.

解决方法:在每个always@(*)语句块内只对同一变量进行一次赋值,如果单次赋值无法满足需求则需额外增加temp变量。

2. 在Verilog语法中,如果没有使用变量承接运算的中间变量,则中间变量的位宽默认为1,例如:

verilog拼接,笔记,fpga开发

 上面语句的预期功能是判断补码运算的溢出问题,在实际运行中发现参与异或运算的两个数据移位后结果恒为0,其原因时Verilog默认中间变量位宽为1。当为中间变量提前指定位宽后运行正常:

verilog拼接,笔记,fpga开发

 verilog拼接,笔记,fpga开发

 3.关于Modelsim仿真的一点提示:

        如果Modelsim报错error loading design 则最常用的解决办法是返回检查tb文件中的文件名是否与仿真项目名一致。

 文章来源地址https://www.toymoban.com/news/detail-775256.html

到了这里,关于Verilog HDL笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【FPGA】组合逻辑电路三种建模方式(Verilog HDL 门级建模、Verilog HDL 数据流建模、组合电路行为级建模)

    【FPGA】组合逻辑电路三种建模方式(Verilog HDL 门级建模、Verilog HDL 数据流建模、组合电路行为级建模)

    目录   Verilog HDL 门级建模 各种逻辑门的表示和使用 门级建模书写实例 Verilog HDL 数据流建模 数据流建模 数据流建模书写实例 组合电路行为级建模 always语句 条件语句 多路分支语句 循环语句 for while repeat forever 行为级建模示例   可以理解为对逻辑电路中各个门依次进行描述

    2024年04月13日
    浏览(26)
  • 【Verilog HDL】FPGA-testbench基础知识

    【Verilog HDL】FPGA-testbench基础知识

    🎉欢迎来到FPGA专栏~testbench基础知识 ☆* o(≧▽≦)o *☆ 嗨 ~我是 小夏与酒 🍹 ✨ 博客主页: 小夏与酒的博客 🎈该系列 文章专栏: FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 📜 欢迎大家关注! ❤️ 📜在开发FPGA的过程中,需要掌握V

    2024年02月12日
    浏览(15)
  • Verilog HDL笔记

    Verilog HDL笔记

    1. 逻辑值         0:逻辑低电平,条件为假         1:逻辑高电平,条件为真         z:高阻态,无驱动         x:未知逻辑电平 2. 归约运算符,按位运算符         以为例,当作为一元运算符时表示归约与,m是将m中所有比特位相与,最后的结果为1bit         例如

    2024年02月03日
    浏览(9)
  • FPGA实验报告 Verilog HDL:7人表决器 巴克码信号发生器 FPGA数字时钟

    写在前面:本文提供以下三个任务的思路讲解和代码实现, 如需参考引脚配置说明,可以点击下方链接跳转查看完整实验报告 ;本实验使用的是Altera公司的cycloneⅢ类型的芯片。 Verilog HDL实现:7人表决器 信号发生器 多功能数字时钟 实验目标:实现7人投票表决电路,支持人

    2024年02月05日
    浏览(18)
  • FPGA/Verilog HDL/AC620零基础入门学习——第一个项目按键控制LED

    FPGA/Verilog HDL/AC620零基础入门学习——第一个项目按键控制LED

    最近要考试了,所以我赶紧补习FPGA,我们用的是小梅哥的AC620开发板,软件是Quartus。推荐看这个视频教程:零基础轻松学习FPGA,小梅哥FPGA设计思想与验证方法视频教程 用按键控制LED灯的亮灭就是一个二选一多路器,两个IO,a、b,可以是高电平,也可以是低电平。 输入按键

    2024年02月05日
    浏览(20)
  • 基于FPGA的DDS原理信号发生器设计 quartusII 9.1平台 Verilog HDL语言编程 可产生正弦波

    基于FPGA的DDS原理信号发生器设计 quartusII 9.1平台 Verilog HDL语言编程 可产生正弦波

    基于FPGA的DDS原理信号发生器设计 quartusII 9.1平台 Verilog HDL语言编程  可产生正弦波、方波、锯齿波以及三角波   频率幅度可调节   代码+原理图 在现代电子技术领域,针对各种应用的信号发生器是一种非常核心的设备,而基于现场可编程逻辑门阵列(FPGA)的直接数字合成(

    2024年04月27日
    浏览(11)
  • FPGA纯verilog实现8路视频拼接显示,提供工程源码和技术支持

    FPGA纯verilog实现8路视频拼接显示,提供工程源码和技术支持

    没玩过图像拼接都不好意思说自己玩儿过FPGA,这是CSDN某大佬说过的一句话,鄙人深信不疑。。。 图像拼接在实际项目中应用广泛,特别是在医疗和军工行业,目前市面上的图像拼接方案主要有Xilinx官方推出的Video Mixer方案和自己手撕代码的自定义方案;Xilinx官方推出的Vide

    2024年02月08日
    浏览(9)
  • FPGA实现的多波形信号发生器,支持正弦、方波、锯齿波、三角波及调制,配备仿真和实物制作功能,使用Verilog HDL编写

    FPGA实现的多波形信号发生器,支持正弦、方波、锯齿波、三角波及调制,配备仿真和实物制作功能,使用Verilog HDL编写

    基于FPGA的DDS多波形信号发生器,可以产生正弦波,方波,锯齿波三角波,调制波形2psk.2askAM调制,可以仿真,可以制作实物,可以进行讲解! 使用可以使用Quarter9.0自带仿真软件进行仿真波形。 也可以使用quarter13.1与modesim进行联合仿真进行仿真波形! 使用verilog HDL语言进行编

    2024年04月12日
    浏览(15)
  • 紫光同创FPGA纯verilog代码实现视频拼接,提供PDS工程源码和技术支持

    紫光同创FPGA纯verilog代码实现视频拼接,提供PDS工程源码和技术支持

    紫光同创FPGA纯verilog代码实现视频拼接,提供PDS工程源码和技术支持 “苟利国家生死以,岂因祸福避趋之!”大洋彼岸的我优秀地下档员,敏锐地洞察到祖国的短板在于高精尖半导体的制造领域,于是本着为中华民族伟大复兴的中国梦贡献绵薄之力的初心,懂先生站在高略高

    2024年02月07日
    浏览(16)
  • FPGA纯verilog实现4路视频拼接,纯逻辑资源搭建,提供4套工程源码和技术支持

    FPGA纯verilog实现4路视频拼接,纯逻辑资源搭建,提供4套工程源码和技术支持

    FPGA高端项目:Xilinx Kintex7系列FPGA多路视频拼接 工程解决方案 提供6套工程源码和技术支持 没玩过图像拼接都不好意思说自己玩儿过FPGA,这是CSDN某大佬说过的一句话,鄙人深信不疑。。。 图像拼接在实际项目中应用广泛,特别是在医疗和军工行业,目前市面上的图像拼接方

    2024年02月08日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包