0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

关于HDLBits的Verilog实现

OpenFPGA 来源:OpenFPGA 作者:OpenFPGA 2022-09-16 09:03 次阅读

HDLBits 是一组小型电路设计习题集,使用 Verilog/SystemVerilog 硬件描述语言 (HDL) 练习数字硬件设计~

网址如下:

https://hdlbits.01xz.net/

关于HDLBits的Verilog实现可以查看下面专栏:

https://www.zhihu.com/column/c_1131528588117385216

缩略词索引

SV:SystemVerilog

Problem 28-Alwaysblock1

从这一题开始我们将进行过程块的学习,也就是时序和组合逻辑的一些知识,下面简单介绍一下这方面知识:

由于数字电路是由用导线连接的逻辑门组成的,因此任何电路都可以表示为module和assign语句的某种组合。然而,有时这并不是描述电路的最方便的方式。过程块(比如always块)提供了一种用于替代assign语句描述电路的方法。

对于可综合硬件,有两种类型的 always :

组合逻辑:always@(*)
时序逻辑:always@(posedgeclk)

组合always块相当于assign语句,因此组合电路存在两种表达方法。选择使用哪个主要是哪个语法更方便的问题。程序块内部代码的语法与外部代码不同。程序块具有更丰富的语句集(例如,if-then、case),不能包含连续赋值,但是却引入了许多新的非直观的出错方式。 (程序连续赋值确实存在,但与连续赋值有些不同,并且不可综合。)

例如,assign和组合always块描述相同的电路。两者都创建了相同的组合逻辑块。每当任何输入(右侧)更改值时,两者都会重新计算输出。

assignout1=a&b|c^d;
always@(*)out2=a&b|c^d;
75b60436-3557-11ed-ba43-dac502259ad0.png 图片来自 HDLBits

对于组合always块,敏感变量列表总是使用(*)。如果把所有的输入都列出来也是可以的,但容易出错的(可能少列出了一个),并且在硬件综合时会忽略您少列了一个,仍按原电路综合。 但仿真器将会按少列一个来仿真,这导致了仿真与硬件不匹配。(在SystemVerilog中,使用always_comb)

关于 wire 与 reg 的注意事项:assign 语句的左侧必须是net类型(例如,wire),而过程赋值(在 always 块中)的左侧必须是变量类型(例如,reg)。这些类型(wire vs. reg)与合成的硬件无关,只是 Verilog 用作硬件模拟语言时留下的语法。

题目说明

使用 assign 语句和组合 always 块构建 AND 门。

75b60436-3557-11ed-ba43-dac502259ad0.png 图片来自 HDLBits

模块端口声明

//synthesisverilog_input_versionverilog_2001
moduletop_module(
inputa,
inputb,
outputwireout_assign,
outputregout_alwaysblock
);

题目解析

这个题目重点是使用assign和always两种方式描述一个AND门,整体难度不大。

moduletop_module(
inputlogica,
inputlogicb,
outputwirelogicout_assign,
outputvarlogicout_alwaysblock
);

assignout_assign=a&b;

always_comb
begin
out_alwaysblock=a&b;
end

endmodule

always_comb程序有很多好处,其中之一便是能自动推断出完整的敏感列表。该列表是完全完整的,避免了@*推断不完整敏感列表的极端情况。

769a6022-3557-11ed-ba43-dac502259ad0.png

点击Submit,等待一会就能看到下图结果:

76e39b84-3557-11ed-ba43-dac502259ad0.png

注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

这一题就结束了。

Problem 29-Alwaysblock2

阻塞性赋值和非阻塞性赋值

在Verilog中有以下三种赋值方法:

连续赋值(assign x=y;):不能在过程块内使用;

过程阻塞性赋值(x=y;):只能在过程块中使用;

过程费阻塞性复制(x<=y):只能在过程块内使用。

在组合always块中,使用阻塞性赋值。在时序always块中,使用非阻塞性赋值。具体为什么对设计硬件用处不大,还需要理解Verilog模拟器如何跟踪事件(的确是这样,记住组合用阻塞性,时序用非阻塞性就可以了)。不遵循此规则会导致极难发现非确定性错误,并且在仿真和综合出来的硬件之间存在差异。

题目说明

以三种方式构建异或门,使用assign语句、组合always块和时序always块。请注意,时序always块产生的电路与其他两个不同:有一个触发器,因此输出被延迟。

7727b8b4-3557-11ed-ba43-dac502259ad0.png 图片来自 HDLBits

模块端口声明

//synthesisverilog_input_versionverilog_2001
moduletop_module(
inputclk,
inputa,
inputb,
outputwireout_assign,
outputregout_always_comb,
outputregout_always_ff);

题目解析

这道题难度不大,主要时区分三种方式。

moduletop_module(
inputlogicclk,
inputlogica,
inputlogicb,
outputwirelogicout_assign,
outputlogicout_always_comb,
outputlogicout_always_ff);

assignout_assign=a^b;

always_combbegin
out_always_comb=a^b;
end

always_ff@(posedgeclk)begin
out_always_ff<= a ^ b;
    end

endmodule



775f175a-3557-11ed-ba43-dac502259ad0.png

点击Submit,等待一会就能看到下图结果:

778b72be-3557-11ed-ba43-dac502259ad0.png

从仿真的波形图可以看出,out_always_ff比其他两个输出延迟了一个时钟周期,这就是非阻塞性赋值带来的。

注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

这一题就结束了。

Problem 30-Always if

if语句通常创建一个2 对 1 多路复用器,如果条件为真则选择一个输入,如果条件为假则选择另一个输入。

下面给出了一个基本的if语句和其综合出来的电路。

always@(*)begin
if(condition)begin
out=x;
end
elsebegin
out=y;
end
end

这与下面使用条件运算符连续赋值的语句是等价的:

assignout=(condition)?x:y;

但是,过程if语句使用不当可能会引入新的错误,只有out在所有的条件下都被赋值才会生成正确的组合电路。

题目说明

构建一个在a和b之间进行选择的 2 对 1 多路复用器。如果sel_b1和sel_b2都为真,则选择b 。其他情况输出a。请使用两种方法作答,一次使用assign赋值,一次使用if语句。

79ce78aa-3557-11ed-ba43-dac502259ad0.png

模块端口声明

moduletop_module(
inputa,
inputb,
inputsel_b1,
inputsel_b2,
outputwireout_assign,
outputregout_always);

题目解析

本题考查的是if语句的简单用法,使用条件运算符作为对比,入门练习题。

moduletop_module(
inputlogica,b,
inputsel_b1,sel_b2,
outputwirelogicout_assign,
outputlogicout_always);

assignout_assign=(sel_b1&sel_b2)?b:a;

always_comb
begin
if(sel_b1&sel_b2)
out_always=b;
else
out_always=a;
end

endmodule

7a00b9fa-3557-11ed-ba43-dac502259ad0.png

点击Submit,等待一会就能看到下图结果:

7a81dcf6-3557-11ed-ba43-dac502259ad0.png

注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

这一题就结束了。

Problem 31-Always_if2

常见的错误来源:如何避免引入锁存器

在设计电路时,必须首先具体考虑电路:

1、我想实现一个逻辑门;

2、我想实现一个具有输入并产生输出的组合逻辑块;

3、我想实现一组组合逻辑,紧接着一组触发器。

不要上来就写代码,这样往往与你想象的电路相差很远。

7aea6636-3557-11ed-ba43-dac502259ad0.png

if(cpu_overheated)thenshut_off_computer=1;
if(~arrived)thenkeep_driving=~gas_tank_empty;

除了你指定的情况以外,会发生些什么,答案是什么也不会发生,输出保持不变。而这往往就导致了电路的错误,所以说语法正确的代码不一定能产生合理的电路(组合逻辑+触发器)。

输出保持不变,这就意味着电路需要记住当前状态,从而产生锁存器。组合逻辑(比如逻辑门)不能记住任何状态。

题目说明

以下代码包含创建锁存器的不正确行为。修复错误~

always@(*)begin
if(cpu_overheated)
shut_off_computer=1;
end

always@(*)begin
if(~arrived)
keep_driving=~gas_tank_empty;
end
7aea6636-3557-11ed-ba43-dac502259ad0.png 图片来自 HDLBits

模块端口声明

moduletop_module(
inputcpu_overheated,
outputregshut_off_computer,
inputarrived,
inputgas_tank_empty,
outputregkeep_driving);

题目解析

这个题目的核心是修复由于各种原因在组合电路中引入的锁存器代码,理解了前面说的产生锁存器的原因,看这个代码还是比较好找出问题的,尽量补全if语句的条件。

moduletop_module(
inputlogiccpu_overheated,
outputlogicshut_off_computer,
inputlogicarrived,
inputlogicgas_tank_empty,
outputlogickeep_driving
);

always_combbegin
if(cpu_overheated)
shut_off_computer=1;
else
shut_off_computer=0;
end

always_combbegin
if(~arrived)
keep_driving=~gas_tank_empty;
else
keep_driving=0;
end

endmodule


7b597b98-3557-11ed-ba43-dac502259ad0.png

点击Submit,等待一会就能看到下图结果:

7b8f3aa8-3557-11ed-ba43-dac502259ad0.png

注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

这一题就结束了。

总结

今天的几道题就结束了,整体难度不大,逐渐的在学习新知识~

最后我这边做题的代码也是个人理解使用,有错误欢迎大家批评指正,祝大家学习愉快~

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1626

    文章

    21671

    浏览量

    601888
  • 硬件
    +关注

    关注

    11

    文章

    3255

    浏览量

    66122
  • Verilog
    +关注

    关注

    28

    文章

    1345

    浏览量

    109986
  • HDL
    HDL
    +关注

    关注

    8

    文章

    327

    浏览量

    47340

原文标题:HDLBits: 在线学习 SystemVerilog(七)-Problem 28-31

文章出处:【微信号:Open_FPGA,微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    HDLBits: 65.mux256to1v

    /*HDLBits: 65.mux256to1v要点://in[4*sel + : 4] 不允许两边都是变量 //in[4*sel+ : 4] sel和+间要有空格*/module
    发表于 03-17 17:16

    Verilog实现8255芯片功能

    Verilog实现8255芯片功能
    发表于 11-03 17:06 144次下载

    夏宇闻老师优秀的verilog教程课件

    本资料是关于夏宇闻老师优秀的verilog教程课件,其中包括verilog讲稿PPT、verilog课件、verilog例题等。
    发表于 09-27 15:00 473次下载
    夏宇闻老师优秀的<b class='flag-5'>verilog</b>教程课件

    基本组合逻辑功能双向管脚的Verilog HDL源代码

    电子发烧友网核心提示: 本例程是Verilog HDL源代码:关于基本组合逻辑功能中双向管脚的功能实现源代码。 Verilog HDL: Bidirectional Pin This
    发表于 10-15 11:28 1605次阅读

    数字系统设计:VERILOG实现

    数字系统设计:VERILOG实现 (第2版)
    发表于 11-30 10:21 0次下载

    verilog实现的RS204—188编码

    这是verilog实现的RS204—188编码,附带测试文件
    发表于 01-20 18:24 28次下载

    verilog_实现_LCD显示

    关于fpga和LCD方面的知识,verilog实现的LCD显示的设计
    发表于 05-16 18:04 47次下载

    Verilog实现74LS194芯片设计程序

    Verilog作为一种种硬件描述语言目前已经得到了普遍运用。本文主要介绍了Verilog特点、Verilog用途以及Verilog实现74L
    发表于 12-22 17:26 6687次阅读

    关于Verilog语言标准层次问题

    关于Verilog语言的官方标准全称是《IEEE Std 1364-2001:IEEE Standard Verilog® Hardware Description Language》。其中包括27章以及8个附录,真正对于电路设
    发表于 07-06 09:59 4985次阅读
    <b class='flag-5'>关于</b><b class='flag-5'>Verilog</b>语言标准层次问题

    关于verilog的学习经验简单分享

    学习verilog最重要的不是语法,“因为10%的语法就能完成90%的工作”,verilog语言常用语言就是always@(),if~else,case,assign这几个了。
    发表于 03-26 14:06 2865次阅读
    <b class='flag-5'>关于</b><b class='flag-5'>verilog</b>的学习经验简单分享

    FPGA设计中DAC控制的Verilog实现

    FPGA设计中DAC控制的Verilog实现(单片机电源维修)-该文档为FPGA设计中DAC控制的Verilog实现资料,讲解的还不错,感兴趣的可以下载看看…………………………
    发表于 07-26 12:18 18次下载
    FPGA设计中DAC控制的<b class='flag-5'>Verilog</b><b class='flag-5'>实现</b>

    HDLBits:在线学习 Verilog (二十八 · Problem 135-139)

    HDLBits:在线学习 Verilog (二十八 · Problem 135-139)
    发表于 11-24 14:06 41次下载
    <b class='flag-5'>HDLBits</b>:在线学习 <b class='flag-5'>Verilog</b> (二十八 · Problem 135-139)

    使用Verilog/SystemVerilog硬件描述语言练习数字硬件设计

    HDLBits 是一组小型电路设计习题集,使用 Verilog/SystemVerilog 硬件描述语言 (HDL) 练习数字硬件设计~
    的头像 发表于 08-31 09:06 1659次阅读

    卡诺图如何化简

    .01xz.net/ 关于HDLBitsVerilog实现可以查看下面专栏: https://www.zhihu.com/column/c_1131528588117385216 缩
    的头像 发表于 11-01 09:02 4054次阅读

    Vivado:ROM和RAM的verilog代码实现

    本文主要介绍ROM和RAM实现verilog代码版本,可以借鉴参考下。
    的头像 发表于 05-16 16:57 1606次阅读