当前课程知识点:IC设计与方法 >  3、Verilog语法 >  f)Always >  3-1-6 Always

返回《IC设计与方法》慕课在线视频课程列表

3-1-6 Always在线视频

3-1-6 Always

下一节:Video

返回《IC设计与方法》慕课在线视频列表

3-1-6 Always课程教案、知识点、字幕

刚才我们讲了连续赋值语句

用Verilog语言

进行组合逻辑电路设计的第一种手段

下面我们再来看第二种手段

过程语句

过程是用硬件描述语言来实现电路的

或者说实现组合逻辑电路的第二种手段

连续赋值语句

通常只用来实现比较简单的布尔逻辑

或者比较简单的组合逻辑电路

如果这个组合逻辑电路的功能

相对来说比较复杂

或者说不太容易用一句话

把它表述清楚的时候

这时候我们会用过程语句来实现

在过程里面通常我们会用到4种类型的操作

一种是赋值语句

分为阻塞赋值和非阻塞赋值

第二个

用if和case语句来完成一些多分支的执行情况

下面我们来详细的看一下过程

过程通常体现形式有两种

我们看一下幻灯片的右上角

和右下角的这两种形式

第一种形式

首先看过程的结构

它的关键字是always@

后面是过程所执行的条件

有点像C语言输入的变量

然后是begin跟end之间包含了一些语句块

这些语句块可以是

赋值语句、if语句、case语句等等

或者是if和case的嵌套

下面这段是过程语句的第二种形式

和上一种形式不同的是

上一种形式(过程的敏感表)是a或b或c

这些a、b、c是过程的输入信号

一个过程相当于一个小的电路模块

在这里边a、b、c是这个电路模块的输入信号

下面这种形式多了一个关键字是posedge

或者是negedge

表示在信号的上升沿或者是下降沿

这个过程才会执行

对比这两个(过程)我们可以看到

在上面这个条件

在下面这段代码里表示这些信号

任何一个信号的变化

这个过程都会执行

(这代表)什么物理意义呢

一个电路只要输入信号有变化

这个电路就需要去执行一遍

或者说电路的输出就要去改变

那这是什么电路呢

这就是组合逻辑电路

所以就是说 上面这种结构

这种方式是用来去描述一个组合逻辑电路

这里面的信号是这一小部分

这一小块组合逻辑电路的输入信号

那么下面这种形式是什么形式呢

大家再想一下

当某个信号的边沿发生变化的时候

内部才会去执行

其他时刻这个电路内部不去执行(没有任何动作)

回想一下我们在第一讲的时候讲的

一些基本设计方法

大家可以想到

是不是很像D触发器

D触发器只有在时钟沿变化的时候

D触发器的输出才有可能发生变化

其他的信号

例如输入的数据信号

或者说一些条件信号发生变化的时候

D触发器的输出并不会变化

只有当时钟沿到来的时候

输出才会变化

所以这种形式通常用来描述

基于D触发器的或者说类似D触发器

这样的时序逻辑电路

上面这种形式用来表示组合逻辑电路

在过程内部

我们常见的只有这4种方式

阻塞赋值、非阻塞赋值

(if)条件语句和case语句

通常我们设计组合逻辑电路的时候

建议大家或者说只允许大家使用阻塞赋值语句

当然不排除我们在看一些别人写的代码里

会有非阻塞赋值语句

我们后面再去讲具体是怎么回事

我们首先来看一下if语句

在这里面

我们不会对相关的语法去讲的特别细

我们只是结合具体的例子来看

因为在Verilog语言里所定义的语法知识

大多数情况下都跟C语言类似

我相信绝大多数同学

已经能够非常熟练地使用C语言了

所以我们对照着去看就可以了

if语句通常有两种形式

一个是双分支的if-else方式

第二种是多分支的if-else if-else

这种三分支的或者说更多分支的形式

我们来看一下实际的一个例子

比如说if

如果a大于b

输出结果res信号的值赋于1

否则 如果是a小于c

res是2 out是4

其他情况的时候res是3

这里面其实就是一个多分支的if语句

在这里面

我们可以注意一下

如果一个分支里边超过一条赋值语句

需要用begin和end把赋值语句包括在一起

这就是if语句的语法规则

在实际电路里面

我们可以把if语句再去嵌套if

我们在电路的内部

不一定只有赋值语句

可以把if语句和if去进行嵌套

或者说把if跟其他的

例如case语句进行嵌套

来完成比较复杂的电路

第二种比较常见的语句是case语句

刚才说了if语句比较适合设计二分支

或者说多分支的执行情况

case语句可以实现并行的多分支的情况

在if语句里面

分支的判断是根据判断条件

它的判断条件可以相对比较复杂

来实现多分支

case语句各个分支的条件是相同的

我们来看一下case的实例

我们不再结合着语法来看了

在这个例子里边

这是always语句块

在语句块里

有一个case语句

它的格式是从case到endcase

中间是一个case分支

在这个分支里

case语句块里面

判断的是信号op

根据信号op的值来决定到底执行哪一个分支

或者说根据信号op的值来决定

到底把哪些信号赋给out

为了让代码具备更强的可读性

我们这里面定义了几个助记符

用define来定义的

我们把2'b00、2'b01和2'b10分别定义给这三个操作符

也就是说

当op的值等于LOAD的时候

我们把输入的数据din送给out

如果操作是一个SUB减法操作的时候

我们把a减b送给out

我们也可以在写成

当加法操作的时候执行a加b操作

在做电路设计的时候有一条规则

通常这个规则的意思

是要求在写case语句的时候

通常最后一条语句必须是default语句

表示当op的值不是前面的这些情况的时候

其他情况

我们执行最后一条分支

也就是说

当op的值不是LOAD

不是SUB的时候

把a加b的值送给out

对照着刚才的if语句

case语句相当于

是一个具有多分支的多路选择器

说到多路选择器

我们来看一下

我们实际上在设计物理上的

多路选择器的时候都有哪些手段

第一种特别简单的多路选择器

我们看一下左边这段代码

这是我们前面在讲assign语句的时候

讲过assign语句有一种特别简单的形式

这种形式可以实现一个2选1的多路选择器

相当于是什么呢

相当于是一个条件判断语句

这是用always语句

大家从这个always开始看

一直到end的地方

这是一个always语句块

我们说了always语句用来实现一个

比较简单的组合逻辑电路

这块组合逻辑电路的信号是什么

它的输入信号是什么

是a、b和sel信号

内部的功能是什么

内部功能是根据sel的值来判断

当sel等于0的时候

把a送给out

else也就是sel是1的时候

把b给送out

所以这块语句块的功能

跟assign语句的功能是完全一样的

根据这个大家又可以得到一个结论

前面我们说过

assign语句是用来实现

组合逻辑电路的第一个手段

assign语句可以用来实现

比较简单的组合逻辑电路

always语句是用来实现

组合逻辑电路的第二个手段

可以用来实现比较复杂的组合逻辑电路

在这里我们说

它们之间是一一对应的

其实也就是说

assign语句是always的一个特例

它看起来(以及)写起来会比较简洁一点

在有些工程项目里面

大家会要求代码书写是完全同一个风格

这就是在某些工程项目里面的推荐写法

当然

如果电路特别简单

用这种方式可能代码看起来更简洁一点

刚才是一个2选1的多路选择器

我们再来看一下稍微复杂一点的

更多的多路选择器

假设我们设计的是一个多路选择器

它一共有4个输入端

然后根据选择端产生一个输出信号

所以

输入信号我们看输入有一个EN信号

有输入的4个信号

这4个信号都是8位的信号

要从4个信号里面选择一路输出

所以这个SEL信号

就不是1位的信号了

SEL信号是一个2位信号

输出信号是一个8位的信号

这个8位信号到底应该是wire类型

还是reg类型呢

要看这个信号到底是由谁来产生的

在我们这段代码里面

这个out信号是由一个always块来产生的

所以在前面定义的时候

就要把它定义成是reg类型

所以大家可以看

我们设计的是一个组合逻辑电路

组合逻辑电路的输出

根据需要

根据代码书写风格的需要

纯粹是因为根据它的风格需要

需要把它定义成是reg类型

这就是我们前面说的reg类型

跟register没有任何关系

纯粹是由于这种代码书写的风格

导致我们的out信号必须定义成是reg类型

下面我们再来看一下这个电路的功能

这个多路选择器的核心部分是一个case语句

根据SEL信号到底00/ 01/ 10

还是11来决定把输入的四个信号之一送给out

这里面还加了一个default

如果SEL信号是2位信号

只可能出现这4种情况

根本就不可能出现default这个情况了

实际上 我们在写代码的时候

从RTL级代码要求

要求大家必须写default分支

所以这段代码

实际工程里面会有两种书写风格

一种是我们幻灯片上所看到的这种方式

另一种方式就把第三种情况

直接用default替换掉

这样代码看起来会更规整一点

这是在EN信号有效的时候

电路输出是把输入的四者之一送给输出

这个多路选择器定义的比较复杂

当EN信号无效的时候

直接就把8位的全0送给输出了

大家可以关注一下这个8位的全0是怎么描述的

描述了8个1比特的0合成一个矢量

用这样的方式表述

当然大家也可以写成8个0

二进制的8个0

那这也是一种方式

用这种方式

我们电路的可改性

或者可读性就比较强了

将来大家如果想把位宽从8位变成16位的时候

只要在这里直接改了

就可以实现更多位宽的多路选择器了

再来看第三个例子

3-8译码器

3-8译码器的功能

我想大家都应该非常清楚

在大学本科的数字电路里面都应该讲过

根据输入的3位信号产生8个输出

从8根输出线中的某一位

输出一个有效电平

我们看这是一个译码器

输入的是一个3位的数据信号in

输出的是8位信号

由于我们的8位信号out是由always块产生的

所以我们需要把它定义成是reg类型

always块的@后面写的是输入信号

里面我们用了一个case语句产生8位输出(信号)

我们可以看一下

当输入的信号是3位的000的时候

它对应的是十进制的0

输出的是什么呢

是一个8位的高位全1

最低位是0

如果输入的是1的时候

第二位是零

也就是说

根据输入的8种不同情况

输出是在相应的有效位

输出一个低电平输出的3-8译码器

这也是一种典型的组合逻辑电路

那么我们可以做一个小结

怎么设计组合逻辑电路

怎么用条件判断语句if语句

以及case语句设计组合逻辑电路

大家看一下这些always块

一个是always后面的@

一定是信号原始的(输入数据)

把这个组合电路的所有输入信号

都要放在always块的(敏感表)里

这样才表示的是一个组合逻辑电路

第二个

如果我们用case语句或者if语句的时候

因为我们设计的是组合逻辑电路

所以我们需要把case语句的所有分支

或者if语句的所有分支全部要列出来

不能有漏的分支

一旦有漏的分支

这个电路就会产生其他的效果

全部列出来以后

要对输出信号赋值

在每一个分支里面

都要对这个输出信号赋值

什么意思呢

总结一下就是说

在case语句或者if语句里边的每一个分支

都要为输出信号产生一个确定的固定的值

否则

如果比如说我们中间有一行没有写

Verilog语言定义了

当这行没有写(的时候),表示这个语句保持原来的值不变

比如说这一行

3’d1这一行没有写

表示在这种情况out值要保持刚才的值不变

这样

这个电路就具备保持功能了

具备保持功能了就不是一个组合逻辑电路了

所以我们说在用always语句块

来实现组合逻辑电路(的时候)

内部可以是if case

以及if case的各种复杂的嵌套结构

我们作为设计人员

一定要保证每一个分支都会被写到

并且不能有漏写的地方

并且在每个分支里面

都要对输出信号或者

涉及到有多位输出信号的时候

它对所有的输入信号都产生固定的输出

后面我们有机会

还会给出具体的一些例子

IC设计与方法课程列表:

课程准备:Quartus II软件的下载

-软件下载说明

--Quartus II软件下载教程

1、集成电路的发展

-a) 集成电路的应用及市场

--1-1集成电路应用及市场

-a) 集成电路的应用及市场--作业

-b)集成电路的制造过程

--1-2 集成电路的制造过程

-b)集成电路的制造过程--作业

-c)从CPU的发展看IC的进展

--1-3从CPU的发展看IC的进展

-c)从CPU的发展看IC的进展--作业

-d)从行业的发展看IC的进展

--Video

-d)从行业的发展看IC的进展--作业

-e)从ISSCC看IC的发展方向

--讲课视频

-e)从ISSCC看IC的发展方向--作业

2、数字集成电路设计方法

-a)数字系统的实现方法 (ASSP/FPGA/ASIC的对比)

--讲课视频

-a)数字系统的实现方法 (ASSP/FPGA/ASIC的对比)

-b)组合逻辑电路

--Video

-2、数字集成电路设计方法--b)组合逻辑电路

-c)时序逻辑电路(1)

--2-3时序逻辑电路的设计方法 (一)

-d)时序逻辑电路(2)

--2-3时序逻辑电路的设计方法 (二)

-2、数字集成电路设计方法--d)时序逻辑电路(2)

3、Verilog语法

-a)Verilog的历史和学习要点

--讲课视频

-b)端口、信号及数据类型

--讲课视频

-b)端口、信号及数据类型--作业

-c)逻辑电平及数据操作

--讲课视频

-3、Verilog语法--c)逻辑电平及数据操作

-d)Assign 语句

--3-1-4assign语句

-e)Assign 举例

--3-1-5 Assign 举例

-f)Always

--3-1-6 Always

-f)Always--作业

-g)阻塞与非阻塞赋值

--Video

-3、Verilog语法--g)阻塞与非阻塞赋值

-h)D触发器的描述

--Video

-i)时序电路的设计

--Video

-i)时序电路的设计--作业

-j) 面向测试的Verilog语法(1)

--3-3-1面向测试的Verilog语法(1)

-k) 面向测试的Verilog语法(2)

--3-3-2 面向测试的Verilog语法(2)

-k) 面向测试的Verilog语法(2)--作业

4、电路设计实例

-a)电路设计实例1

--Video

-b)电路设计实例2

--讲课视频

-b)电路设计实例2--作业

-c)电路设计实例3

--讲课视频

5、Modelsim仿真工具

-Modelsim仿真

--Modelsim仿真

6、Quartus工具

-a)综合及相关基本概念

--Video

-a)综合及相关基本概念--作业

-b)综合及优化

--Video

-c)门级仿真

--门级仿真

-d)Quartus综合及分析(1)

--讲课视频

-e)Quartus综合及分析(2)

--讲课视频

-e)Quartus综合及分析(2)--作业

-f)Quartus综合及分析(3)

--Video

-g)Quartus综合及分析(4)

--Video

-g)Quartus综合及分析(4)--作业

3-1-6 Always笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。