快速入门数字芯片设计,UCSD ECE111(二)SystemVerilog

您所在的位置:网站首页 systemverilog入门 快速入门数字芯片设计,UCSD ECE111(二)SystemVerilog

快速入门数字芯片设计,UCSD ECE111(二)SystemVerilog

2023-01-15 20:53| 来源: 网络整理| 查看: 265

这篇文章带来ECE111第二节课的Slides以及自己的一些补充。

该课程的网站如下:

第一页slide给了一个加法器的例子。该例子加法的实现方式对于初学者来说可能难以理解,实际上这是超前进位加法器。对于单比特的加法而言,使用该加法器没有意义,但是对于较高比特的加法而言,该加法器会有明显的速度优势(如果比特数过高则消耗资源过多,不太划算)。超前进位加法器主要是针对普通全加器串联时互相进位产生的延迟进行了改良,这里不详细介绍。有兴趣的朋友可以去搜索相关的资料,该课程代码写成这样只是一个引子而已,此处可暂时不掌握。

然后介绍了一个四位的加法器,该加法器就是行波进位加法器。非常的好理解,跟我们人自己算加法是差不多的,从低位算到高位,中间可能会产生进位。这页slide的重点仍然是掌握如何例化子模块,这个图使用的隐式连接,也就是没有标注出来子模块的信号名,该方法是不推荐的。因为很有可能产生连接错误。有关显示连接和隐式连接的区别可以参考显示连接与隐式连接区别的13点。

然后介绍了一下从算法层面实现两个数的加法,非常的简单。直接A+B即可。其中的assign语句是连续赋值语句,可以理解成一根线,把等号左右两侧连接起来了。该slide表明,Verilog编译器会使用默认的逻辑实现算术运算符(e.g.行波进位加法器)。大家实际做项目的时候加法直接这么写即可,目前的编译器优化一个加法还是没有问题的。当然大家可以动手,从逻辑门层面去实现自己的加法器,造个小轮子可以更加深刻的领会数字电路的神奇所在。

然后介绍了一下Verilog/SV中的数字表示方法。形式为N'Bvalue。其中的N代表有多少比特,B代表多少进制,这种写法是较为推荐的。因为可以确定用了多少比特(如果不这么写只写个数字,默认是十进制,并且多少比特是不可控的!尽管多数编译器会视作32bit,但是仍然有可能导致意想不到的错误)。所以大家一律写成标准的形式即可。如3'd6代表十进制的6,用3个比特实现。即二进制的110。

然后讲解了一下位运算的拼接操作。使用大括号实现不同信号(比特)之间的拼接。如slide所示。下划线仅仅方便阅读,没有实际意义。

然后基于位操作和实例化,将两个4位的mux拼成了一个8位的mux。

接下来讲了更多的例子。这些操作符可以参考Verilog菜鸟教程。

然后介绍了always_comb语句。该语法用于实现组合逻辑操作,代表其中间的逻辑是一段组合逻辑,如果有多条语句,需要在前后分别加上begin和end。此外这页slide还说明了一个非常重要的概念,“阻塞赋值”,也就是“=”。在组合逻辑当中,只允许使用阻塞赋值,阻塞赋值语句在赋值以后,才允许执行下面一条语句。因此表达式的先后顺序是非常重要的。通过电路图可以看出,t由a和b相与以后,和c相或得到了f。这是有先后顺序的,这里有点类似于软件思维。

然后又花了一页slide介绍always_comb语法。通过这段逻辑实现了二选一的mux。有没有发现,跟之前的三目运算符非常类似?实际上assign和always_comb都是用来实现组合逻辑的。assign一般用于实现较为简单的组合逻辑,而always_comb用于实现相对复杂的组合逻辑,如一堆if/else等。上图的mux逻辑足够简单,一句assign y=s?d1:d0;实际上就实现了,当然具体使用哪种,取决于个人习惯。

接下来讲了一下for操作,硬件设计中的for操作实际上是复制粘贴操作,跟你重复写几段是一样的。只不过是为了简化代码。同时for操作中的终止条件必须是确定的,如slide中的4。如果是不定的,是无法综合的,要时刻记住我们设计的是电路,不是顺序执行的软件代码,如果for循环次数不确定。综合工具又怎么知道应该综合多少份这样的电路呢?

至于这段代码实际上就是实现了四比特的加法器,读者可以自己把for展开思考一下。

上面的代码综合出来的电路如图所示,可以看到在n=4的时候,进位就已经很长了。所以行波进位加法器很慢很慢。

接下来介绍了case语句的使用说明。该语法实际上会生成一个多选一MUX,根据data的不同,确定segments的输出。case语句当中一定要写default。如果不写的话,编译器会认为你希望segments保持不变,但是这又是组合逻辑,所以会生成latch,写出latch的后果非常严重。借用之前微处理器老师的一句话,你如果写出这样的代码,离被开除也不远了。

这页slide也强调了default必须要写,否则会有很严重的后果。

然后介绍了一下casez的使用,casez常用于不关注某些比特,如上图所示的优先编码器,我们只关注a的某一位是不是1,当该位是1,低位的就不用看了。这种情况就可以使用casez语法。

然后介绍了一下嵌套的语句,编译器会从“最内部”向外编译。在该例子中,首先会为case语句生成多路复用逻辑,然后为if/else生成多路复用逻辑。然后根据for循环复制内部逻辑多次。

最后介绍了一下function语法,function实际上用的还是挺多的。用来替代常用的组合逻辑,用起来还是很爽的。

function不能带有时序信息,必须有至少一个输入,没有输出,但是有一个返回值。返回值就是function的函数名,该例子中为adder。可以看出,function实现本质上跟上面的always_comb没什么区别,但是优点在于可以复用。

这就是第二节课slide的全部内容了。大家加油,每天进步一点点。对文章有哪些意见或者想问的问题,欢迎在评论区指出。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3