当前课程知识点:IC设计与方法 >  3、Verilog语法 >  i)时序电路的设计 >  Video

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

Video在线视频

Video

下一节:3-3-1面向测试的Verilog语法(1)

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

Video课程教案、知识点、字幕

下面我们再来看一下非阻塞赋值语句

实现时序逻辑电路的时候的一些特点

这些幻灯片

我们前面已经看到过了

那这再强调一次

在非阻塞赋值语句实现时序逻辑电路的时候

在这里面

我们用的是时钟有效沿

所谓这是时序逻辑电路

我们要求用非阻塞赋值语句

对应实现是每一条语句对应了一个D触发器

每一条语句对应了一个D触发器

或者说每一个对不同信号赋值的语句

对应了一个D触发器

所以上面这段代码产生了3个级联的D触发器

这是正确的

如果再时序逻辑电路设计

因为这条语句决定了

我们设计的是一个时序逻辑电路

如果用到了阻塞赋值语句的话

得到的结果可能并不是你所预期的一个结果

我们说刚才这些幻灯片

产生的是一个移位寄存器

或者说若干个D触发器级联在一起

就在实际工程电路里面

是有具体的用处的

我们通常把这种形式的电路

称之为叫移位寄存器

移位寄存器的写法

我们可以看一下下面这段代码

用一个always块

对若干个信号Q信号去进行赋值

这是一种常见的写法

把输入的信号给D0

把输入的信号给Q0

Q0再给Q1 Q1给Q2 Q2给Q3

所以这四句话的话呢

分别产生4个不同的D触发器

它们之间的关系是级联的

会把输入的信号经过4排以后

从Q0一直移到Q3

我们称之为叫移位寄存器

这种方式对应的

通常用在什么串并转化电路

或者是并串转换电路

这些电路里边

根据非阻塞赋值语句定义

我们可以想象

这四条语句相当于是在同时执行

我们放在一个always块里面

同样

我们说每一个always块

相当于是一个独立的小电路 对吧

所以对于移位寄存器的话

我们还有另一种写法

就是把这4个电路再分开

我们可以把它分解成4个always块

每一个always块里边只写其中的一句话

这也都是完全等效的

只是两种不同的代码书写风格

移位寄存器的话

还有另一种写法

通常移位寄存器

是对有一定位宽的信号去进行移位的

比如说我们输入的这个信号

要变成一个8位的信号

把输入的一个串行的一个信号

串行输入信号并行着变成8位输出

我们可以用这么一个方式来看

前面是信号的整个电路模块的D1

我们有输入的1bit的数据信号

时钟信号和复位信号

然后并行转换成8位数据进行输出

怎么做呢

我们在复位信号有效的时候

就是在时钟上升沿

如果复位信号有效的时候

把数据先清零

我们用的是

因为复位信号clr信号

没有放到敏感表里面去

所以我们知道这用的是同步清零的方式

并且用的是信号的高电频

然后当清零信号无效的时候

这时候我们要做移位操作

我们把dout

我们定义的是一个8位的dout

每次让它左移一位

用这种方式左移一位

表示把dout的0位给1

dout1给第dout2

一直到dout6给dout7 对吧

这样的一个移位操作送给dout

移位完了以后的话

最后一句话我们是把下一句话

我们是把din信号送到dout零端

也就是送到dout的最低端

用这种方式完成了一个数据从低位进入

从低位进入高位移出的过程

在这里面

其实我们可以看到有一个小问题

对dout0

我们在上面这句话

这句话里面dout是一个矢量 是吧

所以实际上是对8位

dout的8位同时进行操作

所以在上面这句话

对第dout0其实也赋了一个值

在下面这句话又得dout0进行赋值

在Verilog里面规定

如果有连续多条语句

对一个信号进行赋值的话

最后一条语句是有效的

对一个变量连续赋值多次

只有最后一次值有效

结合前面几个例子

不管是组合逻辑电路也好

还是时序逻辑电路也好

我们下面来仔细的分析一下

Verilog代码里面的每一句话

跟电路之间的一个映射关系

我会不断的去强调这个概念

因为我们讲过

在电路设计过程中

我们虽然写的是代码

实际上涉及的是上面这样的电路图

我们脑子里要有

在写代码的时候

就要想着我这个代码最终出来的电路

是一个什么样子

在时序逻辑电路设计的时候

我们所有电路设计的模型

都是一个基于D触发器设计的电路

所以我们写完代码

最终分析出来的话

也都是一个D触发器类型的电路

以这个例子为例

以这段标准的代码为例

我们来看具体是一个什么样的分析过程

我们首先从第一句话来看

碰到一个always块

always at clock有效沿的块

我们就知道

这段代码描述的是一个带有D触发器的进程

对应的也就是说

这段电路的最右端是一个D触发器

D触发器的时钟信号叫clock

D触发器的时钟信号

是一个上升沿的一个什么信号

这是描述这个D触发器的这部分时钟部分

然后再看代码内部

赋值语句左边的信号叫Q

也就是说

这个电路的输出信号叫Q

也就是说D触发器的输出信号叫Q

我们就画完了这一部分

D触发器的时钟信号和输出信号

D触发器的输入信号是什么呢

要看电路的内部的语句了

条件判断语句

从进程分析的时候

从代码分析的时候

从代码的条件判断的

最外层往里面一层层分析进去

我们电路的话

就顺着D触发器

然后从右往左画

碰到一个条件判断语句

我们就知道

这是一个2选1的多路选择器

判断条件是漏的

多路选择器的选择信号是漏的

条件满足的时候

Q被清零

也就是说条件满足 这可以写个1

条件满足的时候 Q被清零

条件不满足的时候

Q是零的时候

要做什么事呢

Q加1赋给Q

也就是说有一个加法器

加法器的一端是1

加法器另一端是Q 是吧

那Q的话呢

就是指的D触发器输出会反馈过来

作为输入端的Q

所以这样的话

我们就能够根据代码

一步一步的把所对应的电路给它画出来了

我们总结一下

刚才的分析过程

我们碰到的赋值语句

碰到的赋值语句

对应的就是逻辑函数 对吧

对应的就是一小块一小块的子电路

对应的就是一小块小块子电路

比如说加法器

比如说一个值

或者说一些逻辑函数

或者一些简单的门

碰到边沿性的条件分支

边沿性的条件分支

就是类似这样

我这写的变异性条件分支

是针对这个VHDL而言

在Verilog里面就是说碰到这种沿的判断

那就表示我们电路一定是有D触发器

碰到这种条件分支 if-else条件分支

或者是case语句这样的语句话

我们就知道出来的就是2选1的多数选择器

或者是更多的四选一 八选一

或者十六选一的多路选择器

这就是我们对于代码

和具体电路之间的一个对应关系

或者说进程语句的物理含义

刚才我们讲完了

时序逻辑电路设计的一些Verilog的要素

下面我们来看一个比较小的实际的例子

我们来看一个8位计数器的设计例子

在具体做这个例子之前的话

我们先简单的回顾一下

这个时序逻辑电路设计的一个过程

第一步 我们是分析需求

第二步的话

其实是画出电路的一个大致的一个结构图

结构图应该都映射在每个人的脑子里边了

是吧

也就是说

我们用硬件描述语言来设计电路的时候

它的固有的电路模型

或者电路结构应该是什么样子

第三步

根据这样的一个结构写出电路代码

然后第四步

再检查一下代码有没有错误

然后再根据代码反过来

再把电路结构在回画一遍

确定有没有错误

最后是软件仿真及真正的电路实现

大致是这么一个过程

不管多小的电路

其实我们都是这么一个过程

在这里面

怎么画这个电路图

我们就跳过去了

待会会有单独的章节来讲这份工作

首先

我们举个例子

是一个8位的计数器

这个计数器我想在很多本科的课程里边

或者大家做的习题里面都做过

通常计数器的话

我们称之为叫有多功能的

包括它可以清零

它可以这个装载数据

清零或是装在一个计数数值

从某个计数值开始

可以加计数

可以减计数等等等等这样的功能

我们来看一下

我们做这个计数器

它有8位的这个数据

可以装载一个8位数据

我们计数的过程中的话

计数值也是一个8位的

可以清零

然后可以加计数 可以减计数

有相应的信号来支持族不同的工作

这么一个计数器做完以后的代码

或者设计完了电路是一个什么样子

这种代码的写法其实

并没有完全按照我们刚才说的过程来写

因为计数器是一个比较特殊的一个电路

所以的话可以用这样一种方式做的话更简单

实际上标准的计数器的话

如果是按照标准流程设计出来的计数器

长的是另外一个样子

代码看起来是跟这个有点不一样的

在每个时钟沿

我们判断那些输入信号

如果是有清零信号的话

如果是由低电频的清零信号的话

计数器的值要清零

没有清零信号的话

我们判断一下

如果有装载信号的话

直接把输入的数据D装载到这个计数器里面来

然后如果有这个加信号

如果是这个加信号

加减计数信号是1的话

计数器是加1

如果是加减信号是零的话

那计数器的值被减1

就是说这个信号是高电频的话

就加计数

是低电频的话就是减计数

这样一段代码就描述了一个刚才我们所说的

具有多个功能的这样一个8位计数器

大家看一下这段代码

看起来是不是非常的直观

有没有什么问题

仔细看一下

在这里面我们要设计的是一个持续逻辑电路

赋值语句应该用什么

应该用这个非阻塞赋值语句

对吧

那实际上的话

这里面我们用的是阻塞赋值语句

是不符合代码设计规范的要求

当然没有语法错误

实际上的话在这样一个情况

用阻塞赋值语句也没有什么错误

电路功能也是正确的

也是正确的

这只是一个特例

为什么说是一个特例呢

正好是我们所有的条件分支全部是分散的

全部是并排的并列的

应该说所有条件都是并列的

然后每个分支里面

又只对一个信号进行了赋值

所以的话

用哪种赋值语句没有什么本质差异

但是从工程的角度来说

一般来说我们要养成一个习惯

只要是碰到这样的情况

我们这都是应该是小于等于直接来用

我们再来回顾一下时序逻辑电路的设计方法

第一步确定电路的外特性

它的输入和输出都是什么东西

第二步

确定电路的内部的状态的个数转移的条件

画出电路的状态转移图

电路的状态转移表等等等等

从某个角度来说

到第二步做完

我们的设计人员的设计工作已经完成了

或者说一个项目组的

项目经理的事情已经做完了

下面是下面的这个工作人员

具体的工程师开始干下面的活了

按照传统设计方法

下面就是简化状态图

然后这个指定触发器类型

然后进行状态化简等等等等这些工作

剩下琐碎的工作

现在都可以由计算机来帮助完成

用EDA软件来帮助完成

所以作为设计人员

我们现在要做的事情是什么

画出电路的结构图

这个结构图其实就是说

我们的电路的模型是一个什么形

所有电路的结构图都是一样的

如果说你已经非常熟练的话

第三步就已经跳过去了

我们可以直接进入到第四步

写出电路的对应的代码

然后由EDA软件把最终的电路图产生出来

用软件去仿真代码的功能是不是正确

基于这样的一个设计方法的设计模型

就是这么一个模型

我们的电路核心是一个D触发器 是吧

这个模型在我们第一讲里面讲过了

核心是一个D触发器

然后有两块组合逻辑电路

一块是状态计算逻辑

用来计算根据当前的状态

根据电路的当前状态计算电路的下一个状态

next-stage是什么

然后另外一块是电路的输出逻辑

输出逻辑也是一块组合逻辑电路

它根据电路的当前状态

以及输入的信号来判断电路的输出是什么

如果是摩尔状态机虚线就不存在 对吧

只是根据电路的当前状态判断出

当前状态的输出

如果是Mily状态机

那这根虚线就存在了

在每一个当前状态下

电路的输出还会跟输入有一定的关系

这就是我们的电路的模型

所以我们的VHDL代码也是参考这个模型来设计

在这个模型里边

有几部分赋值语句

一个是D触发器

D触发器是一个时序逻辑电路 对吧

如果让大家

我们前面已经举了好多

关于D触发器的process怎么写

D触发器的这个always块怎么写

在这个always块的话里边

我们是把next-state相当于D触发器D端的型号

赋给current-state

写法的话时序逻辑电路

所以是next-state是个小于等于

赋给current-state

对于组合逻辑电路1和组合逻辑电路2而言

它们是组合逻辑电路

所以在这两个电路里边

我们是应该用作阻塞赋值语句去完成

这两块电路的设计

当然当你对代码描写熟练以后

可以把组合逻辑电路1

跟组合逻辑电路2合并在一起

合并在一起以后表示

从意义上来说

从对照这张图的意义上来说

表示在时钟的有效沿到来的时候

有效沿的时候

是把这个组合逻辑计算的结果

直接送到current-state 对吧

所以从某个角度说

next-state的这个信号都可以不用写了

对应的话在这个always块里边

这个always时序逻辑电路里边写的话

只要写成是关于in和cs

关于输入信号和CS计算的结果

直接复制给CS

我们在这条语句里边

这个cs表示的是当前的状态

其实表示这个状态 赋给CS

为什么又赋给cs

在这边的这个赋值号左边的cs呢

已经是电路的下一个状态了

这也就是说赋值号的这的CS

表示是current-state

在这儿的这个CS

表示的是next-state

在使用上升沿之后

这个操作完成

刚才讲的是比较简单的

时序逻辑电路的设计方法

如果时序逻辑电路更复杂

我们是一个什么模型

从物理上来说

持续逻辑电路

在实现的时候

实现完了以后都是一堆寄存器

一堆D触发器

加上一堆组合逻辑电路 对吧

如果我们把这些D触发器

它可能是一堆D触发器

我们把它展开以后变成一个一个D触发器

两个D触发器之间是夹杂了一些组合逻辑电路

电路的行为的话

或者电路功能的话

我们可以看成是从一个D触发器的输出

经过一堆组合逻辑的传递计算以后

传递到另一个D触发器的输入

从英语上来说

就是register

或者叫寄存器传输级 是吧

寄存器传输级

顾名思义就是这么过来的

对应这样的一个电路模型

我们用Verilog语言描述的时候

这个代码是一个什么样子

就always块的条件

如果有reset时候赋一个值

reset条件不存在的时候

是有一大堆语句

语句可能只有一句话

可能有1000句话描述的

是两个D触发器之间的组合逻辑电路

有时候这个东西我们也把它称之为叫做云图

对于复杂的时序逻辑电路

我们就不能只用一个简单的有限状态机来表示了

复杂的时序逻辑电路通常除了有状态转移部分

另外还要完成更复杂的计算操作

不仅仅是指输出一两个控制信号

所以的话

我们通常要用右边这样一个幻灯片

右边这样Data Path部分

它完成电路的动作

比如说要计算数据

这个数据的话

可能要受到有限状态机的控制

决定有限状态机产生一个控制信号

控制Data Path在每一个节拍完成不同的操作

Data Path又把当前的操作结果

反馈给有限状态机

让它决定下面到底应该相应的去对动作

或者计算做什么样的调整

这样的话

我们电路就分成这么两部分

对于这样一个模型里边有限状态机

还是用我们传统的有限状态机的设计方法

来进行设计

Data Path的话是独立的分离出来的电路

我们作为设计人员的话

通常是先设计Data Path

先确定我们这个电路计算的时候

都有哪些计算部件

比如说加法器 减法器 乘法器等等

然后确定它们的数据是怎么传递的

以及这些计算部件都需要哪些控制信号

然后用一个有限状态机来协调

或者说控制这个Data Path

来完成预定的这个目标

我们下面举一个简单的例子

一个非常简单的例子

在这个例子里面

其实

Data Path部分可以省略掉了

只用简单的有限状态机就可以做

假设我们的电路要循环的输出1935

1935这四个数

循环输出

根据这个电路的需求

我们可以确定

或者我们可以看出来电路每四拍循环一遍

每四拍循环一遍 对吧

所以大致可以觉得

这个电路可以用一个

具有4个状态的状态机来实现

在每一个状态输出一个值

分别输出1935

按照传统的设计方法

或者说按照现在我们所要求的设计方法

我们首先应该把这个状态机给它画出来

画出状态转移图

画出电路的模型

然后去写代码

在这我们就先把它省略掉了

我们看一下一个初学者经常会写出来的代码

长的是什么样子的

前面的头我们就去掉了

这里面我们定义了一个state信号

因为是一个四状态的状态机

所谓state信号是一个两位的

下面用一个always过程描述电路的特性

首先用的是时钟的上升沿

如果有清零信号的话

状态机被复位 清到零状态

然后case语句表示在当前状态是0的时候

下一个状态是1

因为状态机的转移是无条件的转移

对吧

所以就从0转到1 从1转到2 从2转到3

3转到0

然后当前状态是零的时候

Q输出1

其它状态依次输出1935

就是这么一个简单的电路

能够完成我们所需要的这个功能

大家看一下这个代码有没有什么问题

先仔细检查

好ok 是时序逻辑电路

然后case语句都写全了

状态之间的转换好像也都什么没有

都没有什么问题

但实际上这段代码是有问题的

为什么呢

我们说有限状态机

有限状态机在这个always块里边

应该只描述状态机部分

回顾一下我们的图

工作的电路图

回顾一下我们电路图

我们应该是有几个进程去描述电路

一个是状态计算的always块

表述D触发器阵列部分

然后另外有一个输出电路组合逻辑电路

状态计算的组合逻辑电路

以及状态转移的D触发器

对吧

应该有三块电路

对应的话可能会存在三个always块

当然

你简写完了以后可能是两个块

但是简写到一个块的可能性非常小

所以的话

问题就出在这个地方

对于Q的输出

我们不应该把它放到状态转移电路

状态计算的这个always块里边

而应该用一个单独的always去描述

这部分电路应该是一个组合逻辑电路输出

如果按照这种写法

电路里边就会多出一个关于Q的D触发器

或者计算器

导致电路的性质又发生了变化

针对刚才这样的一个电路

我们来结合电路的模型

这是我们的电路结构图来看

代码应该怎么写

我们标准的有限状态机

或者说标准的时序逻辑电路

我们在实现的时候

它的电路模型是这么一个模型 对吧

分为D触发器部分

计算逻辑部分

状态计算逻辑部分以及输出逻辑部分

我们在写的话

正常情况下应该有三段代码

第一段代码是状态计算逻辑

根据它是一个组合逻辑电路

注意它是一个组合逻辑电路

所以它case的是current-state

根据的是当前的状态

我们没有外部的输入的信号

所以它只是根据当前信号

当前状态来判断

如果当前状态是0 0的话

然后下一个状态是0 1

0 1转1 0

1 0转1 1

1 1转0 0 对吧

是这么一个情况

如果我们电路里边还要去对复位信号

进行判断的话

我们要把复位信号加进来

这个电路 这个代码有个小瑕疵

第二个进程描述的D触发器

在时钟的上升沿把next-state

送给current-state

所以的话

我们大概的意思就是

在时钟的上升沿描述的是一个时序逻辑电路

把next-state送给current-state

如果有复位信号的话 把它清零

复位信号的判断可以放在这

也可以放到上面都可以

这两种方式都可以的

第三个逻辑是组合逻辑电路

输出逻辑电路

这是一个输出逻辑电路

它也是组合逻辑电路

所以的话

是按照组合逻辑电路的方法来进行设计

如果是当前状态的话

如果是它的输入信号是当前状态

根据当前状态判断输出的都是什么值

这地方还是刚才所说的小瑕疵

clr信号应该放到敏感表里面去

这样的话

是用3个process

或者说3个always块

来分别表示这三段电路

这是一个标准的书写方法

当然

在工程里边还有各种组合的方式

我们可以把这两个always块

合并成一个always块

描述一个相对复杂的组合逻辑电路

也可以把这两个合在一起

因为它们俩性质都是组合逻辑电路

我们可以把它们合在一起

单独留出D触发器

这也是一种方法

实际上一共有3种代码的书写方式

刚才所直接给出了代码

不是这3种方式之一

就是错误的

最后我们来总结一下

在电路实现的时候的各种方法

我们前面已经理论上

已经把电路实现的用always块的方式

怎么实现电路

以及用连续赋值语句的方式怎么实现电路

最后的话

还有一个元件例化的方式还没有讲

我们在后面会结合实际的例子来讲

怎么用元件例化去实现小电路

我们可以看在一个module里面

我们举一个例子

在一个module里边

可能会存在若干个assign语句

会存在若干个always块

会存在若干个元件例化语句

当然这些元件例化与always块

和assign语句的次序完全可以打乱

可以把这个always块写到前面去

可以把assign句写到后边来

这个元件例化语句也可以写到中间去

它们之间是完全并行的

因为每一个块每一个assign语句

每一个always块

或者每一个元件例化语句对应的

都是一个电路模块

它们之间完全是并行的

然后这些信号的名字表述了

这些块之间的一些块之间的这个链接关系

这就是我们的代码跟电路之间的一个对应关系

大家脑子里一定要有这么一个直观的印象

或者说脑子里看的是这段代码

但是想的是我们电路是一个什么样子

它们之间连接是一个什么样子

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)--作业

Video笔记与讨论

也许你还感兴趣的课程:

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