数字逻辑:数字设计实践与Verilog硬件描述语言

主要是要学什么呢:

我们首先要明白数字系统是什么:

也就是:门电路,触发器等逻辑器件组成计数器,译码器等逻辑功能部件,再有逻辑功能部件组成复杂的数字系统。

我们知道,我们学的verilog语言就是一种硬件描述语言。而这种硬件描述语言其实就是EDA技术的重要工具:

就是我们在电脑上写程序表示电路的结构,电脑就会设计出对应的实际电路(PCB板,电工课诚不欺我)

接下来我们来具体地讲讲什么叫硬件描述语言:

我们平时用的C语言,python呀都是软件描述语言,和这种硬件描述语言显然不同:

软件的描述语言最终解析成0011的代码,硬件的描述语言最终解析成电路。

那么,一个HDL(硬件描述语言)设计流程是什么呢?:

现在,我们要学习我们的重头戏:verilog语言(一种硬件描述语言)了:

那就约等于哪里都能用。

可以看到模块分为声明和内容两个部分(和函数很像呀,先定义函数名,输入输出什么的在是内容)

 

行为级和结构级的具体例子:

结构级会仔细地描述各个门原件,组成一个逻辑功能部件;行为级只是像程序语言一样描述一下功能,不会涉及到各个门电路。

学习中要注意哪些?:

接下来是正式的语法学习。verilog的基本组成是模块,我们就来学习一下模块怎么写:

一个模块的开端是模块的声明:

输入肯定是连线。寄存器的话输入不就不会变了吗,那还输入个锤子。

使用前声明,有面向对象那味了。

接下来讲标识符:

也就是:正负号+位宽+进制+数字。

parameter就是个常量,可以用来表述电路,模块的性质什么的。

 assign相当于连线,一般是将一个变量的值不间断地赋值给另一个变量,就像把这两个变量连在一起,所以习惯性的当做连线用,比如把一个模块的输出给另一个模块当输入。

 

注意:wire不驱动的时候就是高阻态。

init和always就是主代码前面的那个,在里面赋值代表“大家开始做用之前就已经是这个值了”,也就是寄存器。

接下来就是运算符和表达式了:

这里先解释一下什么是位运算:

都要转化成2进制算,这样电脑就不用转化,运算超快。

还有条件运算符:

拼接运算符是verilog独有的运算符,和C没关系:

a+b+c最大有3,需要两位输出(11)来输出,所有要用cout和sum两个输出来接收。

==和===二者在正常情况下(指0,1)是一样的,但是===是更硬核的等号,x,z也会比较,一定要是同时为x或z才能是1.==就泯然众人矣,假如旁边有x或z,他就不晓得要怎么比较。

接下来就是赋值语句和块语句了:

有一个小小的问题:加了assign的赋值和不加的有什么区别?目前好像是:assign是连续赋值,右边一遍左边就变。而不加就是时序的,只有来到了自己这才会赋值。

=是普通的赋值,<=是“同时赋值”

 

接下来是过程块:

 begin和end就像是{和}一样,只是用来标记代码块的。

条件与循环语句:

 

模块的调用:

有点看不懂?其实就是这样:模块名+在我这个模块里的名字+(参数列表),这些参数可以直接写上去,也可以用.C(T3)(就是c形参的输入值是T3的意思,用字典的方法输入,前面的那个就是按照位置一个一个输入,CAB逐个对应)有没有像python里的callable的类?一边要实例化,一边可以像函数一样使用。

半加器就是模拟一位加法的过程,产生一位的结果和一个进位。全加器就更接近真实的加法,输入是一个进位,两个输入的一位数字,输出自己这一位的数和一个进位,这样我们就获得了真正的加法(半加器没有考虑上一位可能要进位的情况) 。这样的话我们要几位加法都可以了。(第一位的进位好像都是0?那第一位大概可以直接用半加器吧。)

那么我们要如何用代码表示这些电路呢?:

 这里要解释一下verilog里的向量和数组:input [7:0] a代表什么?代表这个输入a,是一个输入,但是有8个位,也就表现为要有8条线才能输入.假如是input a [7:0],就代表有八个输入,每个输入有1位。假如是input [3:0] a[7:0],就代表有8个输入,每个输入有4位。

同时,[a:b]里的a,b也有讲究。0:7代表从0到7,7:0代表从7到0.

测试模块:

用verilog制作组合运算原件:

这个之前讲过吧,窜位和并位。

如何用verilog实现呢?:

输出可能是A+B,可能是C+D,这里要少用加法模块。

这个74*381是干嘛的?:

加法器到此为止了,减法器呢?:

接下来是移位和旋转:

这种思路就是我用16个器件,每个器件在16个输入中选一个。

这个思路比较复杂:S0S1···这些代表要循环的位数(二进制输入),S0=1时会移动1位,结果向后传;S2=1时会移动两位····就是这样。这个地方可以注意一下,使用多路复用器来移位的方式就是:这个多路复用器有两个输入,两个都是16位输入,一个是原样,一个是移位后的情况(如【14:0,15】就是移动一位的)然后根据S的输入选择输出哪一个。

那如何用verilog实现呢?:

详细解释一下这个代码:开头输入数据和要移动的位数,C是模式控制(向左向右?旋转还是逻辑?上面有说)DOUT是输出。开始的时候要给Lrotate之流赋值是为了方便后面的case,使用名字作为情况更加专业,(你不赋值也是可以的,后面的case改一下就行,就是代码可读性下降了)接下来就是各个情况需要什么函数,Vrol是左移1位····接下来就是一样的操作了。

从这个代码中可以感觉到“面向对象编程”的味更重了。开局是赋初值,然后是函数,最后是callable函数(就是always那一段)

之前一直又出现一个叫多路复用器的东西(就是几个输入选一个的元件),这个东西怎么弄?:

觉得if else有点low?你也可以用?: 

当然最经典的还是case:

 三台缓冲器:

 

第二种是可以双向传输数据的。

那译码器怎么做呢?:

用verilog,可以有两种做法:

显然后面的好理解。

 现在我们可以用一个测试平台来看看:

 那么显示译码器怎么弄?:

就非常硬核地把所有情况都列一遍。测试怎么做?:

编码器怎么弄?:

简化一点写就这样:

if不想用,也可以用case:

 

奇偶校验器:

我们知道奇偶校验就是用异或门,现在就使用verilog实现这个:

前面这个是我们以前学的异或门做法,后面是行为化的做法,测的是9位的。

 复用了之前写的3位奇偶校验器。

比较器怎么做?:

这里要回忆一下:每次比较的时候会输入3个值,中间是1代表相等,左边是1代表左边大,右边是1代表右边大。所以输出也会有这3个。

阿哲···好简单呀。

想省一点硬件,可以这样:
 64位比较就可以直接用前面写好的连起来。

 最后比较之前的输出,GT大的话代表左边大(也就是P),其余同理。

组合时序电路和时序逻辑电路。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值