verilog语法实例学习(10)
常用的时序电路介绍
T触发器和JK触发器
在D触发器输入端添加一些简单的逻辑电路,可以生成另一种类型的存储元件。比如下图所示的T触发器。该电路有一个上升沿触发的触发器和两个与门,一个或门,以及一个反相器组成。
在时钟上升沿到来之时,若T=0,则D=Q,若T=1,则D=~Q,因此,若T=0,在上升沿,电路保持当前状态,若T=1,则当前状态反转。
T触发器特性表图下,T触发器是构建计数器的一个有用元件。任何可以实现该特性的电路都可以称为T触发器。
| T | Q(t+1) |
| 0 | Q(t) |
| 1 | ~Q(t) |

上述电路中D = ~T&Q+T&~Q=T^Q,所以我们也可以用下面的电路,通过一个异或门来实现T触发器。

下面时T触发器的时序图:从图中,我们可以看到如果T=1,在时钟的上升沿,Q翻转信号值。

对T触发器进行一点改动,如下图所示,则形成另一个电路,该电路有两个输入,J,K。该电路中:D = J&(~Q)+~K&Q,它的特性表为:J=K,此时JK触发器等价于T触发器,J不等于K,该电路等价于SR触发器,此时S=J, R=K。D触发器是一种灵活的电路,可以像D触发器和SR触发器一样,存储数据,也可以把JK连接起来当T触发器使用。
| J | K | Q(t+1) |
| 0 | 0 | Q(t) |
| 0 | 1 | 0 |
| 1 | 0 | 1 |
| 1 | 1 | ~Q(t) |

计数器
计数器可以用加法减法器来实现,也可以用寄存器来实现。但由于计数器仅有+1,-1的变化,没必要采用复杂的电路。下面我们来学习用T触发器和D触发器构建的计数器电路。
T触发器构建的异步递增计数器
下图给出了一个3位的计数器电路,计数范围位0~7。三个触发器的时钟采用级联的方式连接。每个触发器的输入端T连接到逻辑电平1。触发器的状态在每个时钟的上升沿发生翻转。我们假设此电路的目的是对时钟脉冲的个数进行计数。如下面的时序图所示,每个时钟周期Q0状态变化一次,该变化发生在时钟上升沿稍后一点的时刻,延时是由于触发器的传输引起的。第二个触发器时钟信号为~Q0,所以Q1在Q0的下降沿稍后一点发生变化。同理,Q2在Q1的下降沿稍后一点发生变化。我们注意到Q2Q1Q0,其时序图为0,1,2,3,…,7,0, 1…等等,此电路是一个模8计数器,因为计数方式每次加1,所以为递增计数器。
因为时钟信号是级联的,而不是同步的,从时序图中可以看到在计数3和4之间,由那么一小段Q2Q1Q0=010(不稳定状态)


T触发器构建的异步递减计数器
采用下面的电路,我们可以得到递减计数器。和递增计数器的区别是Q1和Q2的时钟是接在输入Q,而不是~Q。


T触发器构建的同步递减计数器
上面构建的异步递增/递减计数器电路非常简单,但是运行速度不快。如果用这个电路构建多位计数器,由于时钟级联引起的延时可能会很长以至于不能满足所期望的性能要求。下面的方法,所有的触发器用同一时钟,可以构建一个速度更快的计数器。
下表是一个4位计数器在16个时钟周期内的内容。可以看到,Q0在每个时钟周期都要变化,Q1的状态仅在Q0=1时变化,Q2的状态仅在Q1,Q0都等于1时变化,Q3的状态仅在Q2,Q1,Q0都为1时候变化。一般来说,对于n位计数器,特定的触发器只在前面的触发器输出都为1时才发生变化。因此,用T触发器构建计数器,则输入端为:
T0=1
T1=Q0
T2=Q1Q0
T3=Q2Q1Q0
…
Tn=Qn-1 Qn-2…Q1Q0
| 时钟周期 | Q3 | Q2 | Q1 | Q0 | |
| 0 | 0 | 0 | 0 | 0 | |
| 1 | 0 | 0 | 0 | 1 | |
| 2 | 0 | 0 | 1 | 0 | Q1改变 |
| 3 | 0 | 0 | 1 | 1 | |
| 4 | 0 | 1 | 0 | 0 | Q2改变 |
| 5 | 0 | 1 | 0 | 1 | |
| 6 | 0 | 1 | 1 | 0 | |
| 7 | 0 | 1 | 1 | 1 | |
| 8 | 1 | 0 | 0 | 0 | Q3改变 |
| 9 | 1 | 0 | 0 | 1 | |
| 10 | 1 | 0 | 1 | 0 | |
| 11 | 1 | 0 | 1 | 1 | |
| 12 | 1 | 1 | 0 | 0 | |
| 13 | 1 | 1 | 0 | 1 | |
| 14 | 1 | 1 | 1 | 0 | |
| 15 | 1 | 1 | 1 | 1 |
用上面表达式构建的4位计数器电路图如下:
Q0的的输出要经过两个与门的延时才能到达Q3,这个延时必须小于时钟周期减触发器的建立时间。

下面是该电路的时序图,由于所有信号在时钟上升沿经过相同延时后发生变化,所以该电路为同步计数器。

下面是带复位和使能信号的计数器,使能信号直接接在Q0输入端,如果Enable=0,则计数器不会计数,如果Enable=1,则和上面的计数器电路是一样的。复位信号在其的下降沿复位所有的触发器。

D触发器构建的同步计数器
下面的电路结构是D触发器构成的4位同步计数器,计步顺序是0,1,2,…,15,0,1…计数值由触发器的输出端Q3Q2Q1Q0给出,假设使能端Enable=1,则计数器输入端由下面的表达式给出:
D0=Q0=Q0^1
D1=Q1^Q0
D2 = Q2^(Q1&Q0)
D3 = Q3^(Q2&Q1&Q0)
…
Dn=Qn^(Qn-1&Qn-2…Q1&Q0)
公式的推导: to do
加上Enable信号,公式为:
D0=Q0=Q0^Enable
D1=Q1^(Q0& Enable)
D2 = Q2^(Q1&Q0& Enable)
D3 = Q3^(Q2&Q1&Q0& Enable)
…
Dn=Qn^(Qn-1&Qn-2…Q1&Q0& Enable)
由下面的表格可知,第i级触发器的状态只有在它前面所有的触发器都处于Q=1的状态时候才改变。在此状况下,与第i级异或门相连的与门输出都为1,与Di相连的异或门输出为~Qi(与1异或,得到反值),否则或门的输出将使Di=Q,从而使该触发器保持原状态。
| 钟周期 | Q3 | Q2 | Q1 | Q0 | |
| 0 | 0 | 0 | 0 | 0 | |
| 1 | 0 | 0 | 0 | 1 | |
| 2 | 0 | 0 | 1 | 0 | Q1改变 |
| 3 | 0 | 0 | 1 | 1 | |
| 4 | 0 | 1 | 0 | 0 | Q2改变 |
| 5 | 0 | 1 | 0 | 1 | |
| 6 | 0 | 1 | 1 | 0 | |
| 7 | 0 | 1 | 1 | 1 | |
| 8 | 1 | 0 | 0 | 0 | Q3改变 |
| 9 | 1 | 0 | 0 | 1 | |
| 10 | 1 | 0 | 1 | 0 | |
| 11 | 1 | 0 | 1 | 1 | |
| 12 | 1 | 1 | 0 | 0 | |
| 13 | 1 | 1 | 0 | 1 | |
| 14 | 1 | 1 | 1 | 0 | |
| 15 | 1 | 1 | 1 | 1 |
我们增加一个额外的与门以产生输出Z,由于这个输出的存在,可以很容易的把两个4位计数器拼接成一个更大的计数器;同时这个输出还可用于检测计数是否达到了最大值(全部为1)。如果达到了则在下一个时钟周期进行清零。这在实际应用中也是十分有用的。
下面的电路本质上和上面T触发器构成同步计数器是相同的。增加一些电路,可以把D触发器改造成T触发器,D=Q^T,也实现了一个T触发器,
推导:to do

具有并行加载功能的计数器
把上面的电路进行一点小改动,加入一个二路选择器,用Load信号作为选择器的sel信号,来控制是载入还是计数功能。Load=1,并行载入一个计数值,Load=0,正常的计数功能。

同步复位与异步复位
计数器必须有清零的功能,在开始计数前其内容必须置0或复位。通过添加单个触发器的清零功能便可以达到此目的。但是对于在正常计数过程中如何使计数器的内容清零呢?n位的递增计数器使模为2n的计数器。如何得到不是2的幂的计数器呢?例如,模是6的计数器,它的计数序列是0,1,2,3,4,5,0,1等等。
最直接的方法就是计数到5时候复位。可以通过探测Q2=Q0=1就够了,因为只有计数器等于5时,才有Q2=Q0=1。基于这种方法的电路如下图所示。计数器的并行加载功能用于在计数器达到5时使计数器复位。

从下面时序图看出,复位的操作发生在计数到5后的时钟上升沿,它把D2D1D0=000加载到计数器,同时计数器的值在一个完整的时钟周期内建立起来获得期望的序列。

下面的电路通过触发器的特性实现清零。因为触发器的清零是低电平有效,所以可以用与非门检测计数值是否为5,如为5,则复位所有的触发器清零。从原理上看,该电路可以正常工作,但该电路存在隐患。当计数值等于5时,电路就会出现问题,因为只要计数等于5,与非门就会触发复位行为,触发器在与非门检测到5后很短时间内就使计数器清零,计数器等于5的时间依赖于电路的延迟而不是时钟,所以计数器等于5的时间很短,远小于一个时钟周期,在某些应用中,可能不能满足要求。这种复位称作异步复位。相比较起来,同步复位方案要比异步复位方案好。


其它类型的计数器
下面来看其它几种常用的计数器,第一中使用十进制序列,另外两种产生非二进制的代码序列。
BCD(二-十进制)计数器
下面是一个二位的BCD码计数器,有两个模10的计数器组成。在模10计数器中,当计数器达到9时,必须将4个触发器复位,于是当Q3=Q0=1时,值Load=1,在时钟的下一个上升沿,将0000装入触发器。第一级的BCD0计数器的输入Enable一直为1,第二级的BCD1的输入Enable只有在第一级BCD0=9时候才为1,使下一个时钟脉冲到来时候,BCD1加1。实际电路中,有一个Clear控制信号控制清零,在下面电路中,Clear为高电平有效。

环形计数器
前面的计数器计数值都是一个二进制数。使用这种计数器时候,如果期望达到某个特定值时候产生一个动作,则必须检测这个计数值是否达到,这可以用与门实现。还有一些特殊的计数器,比如下图移位寄存器电路实现的四位环形计数器。start信号等于1向第一个触发器中置入1,而其它触发器中清零来设置初始值位100…00,start信号等于0,计数器正常计数。start信号的所有变化发生在时钟有效沿之后,以免违反触发器的时序参数。每个计数值都是一个独热码,编码中只有一个1,其它为0。


Johnson计数器
Johnson计数器如下图所示,它的反馈是~Q,n位的Johnson计数器可以产生2n位的计数序列。例如:4位的Johnson计数器的计数序列为0000,1000,1100,1110,1111,0111,0011,0001,0000,1000,…,为了对Johnson计数器进行初始化,必须使所有的触发器复位。不管是Johnson计数器还是环形计数器,如果初始化有错,都不能产生所期望的计数序列。

计数器verilog实现
有并行载入功能的递增计数器
verilog代码如下:
module upncount(R,Rst_n,clk,E,L,Q); parameter n=8;
input [n-1:0] R;
input Rst_n;
input clk;
input E;
input L; output reg [n-1:0] Q; always @(posedge clk, negedge Rst_n)
begin
if(!Rst_n)
Q <= 0;
else if(L)
Q <= R;
else if(E)
Q<= Q + 1;
end endmodule
这些代码在quartus II综合与分析后,电路如下:一个加法器,两个二路选择器一个8位的寄存器。

用下面的testbench,可以得到如下波形。
`timescale 1ns/1ns
`define clock_period 20 module upncount_tb;
reg clk;
reg Rst_n;
reg [7:0] R;
reg L;
reg E;
wire [7:0] Q; upncount #(.n(8)) upncount0(.R(R),.Rst_n(Rst_n),.clk(clk),.E(E),.L(L),.Q(Q)); initial clk = 1;
always #(`clock_period/2) clk = ~clk; initial begin
Rst_n = 1'b1;
E= 1'b1;
L=1'b0;
R=8'd99;
#(`clock_period)
Rst_n = 1'b0;
#(`clock_period)
Rst_n = 1'b1;
#(`clock_period*10);
L = 1'b1;
#(`clock_period);
L = 1'b0;
#(`clock_period*20);
#2000;
$stop;
end endmodule

有并行载入功能的递减计数器
代码和波形如下:
module downncount(R,clk,E,L,Q); parameter n=8;
input [n-1:0] R;
input clk;
input E;
input L; output reg [n-1:0] Q; always @(posedge clk)
begin
if(L)
Q <= R;
else if(E)
Q<= Q - 1;
end endmodule
`timescale 1ns/1ns
`define clock_period 20 module downncount_tb;
reg clk;
reg [7:0] R;
reg L;
reg E;
wire [7:0] Q; downncount #(.n(8)) downncount0(.R(R),.clk(clk),.E(E),.L(L),.Q(Q)); initial clk = 1;
always #(`clock_period/2) clk = ~clk; initial begin
E= 1'b1;
L=1'b0;
R=8'd99;
#(`clock_period*10);
L = 1'b1;
#(`clock_period);
L = 1'b0;
#(`clock_period*20);
#2000;
$stop;
end endmodule

verilog语法实例学习(10)的更多相关文章
- verilog语法实例学习(4)
Verilog模块 Verilog中代码描述的电路叫模块,模块具有以下的结构: module module_name[ (portname {, portname})]; //端口列表 [parame ...
- verilog语法实例学习(1)
本文档中通过verilog实例来学习verilog语法.Verilog是一种硬件描述语言,它具有并发性和时序性.并发性是指不同硬件模块的同时操作,时序性是指信号的赋值或操作在时钟的边沿进行.由于作者本 ...
- verilog语法实例学习(12)
verilog中的综合和不可综合总结 Verilog中综合的概念 综合就是EDA工具或者说综合工具把我们编写的verilog代码转化成具体电路的过程.Verilog中有很多语法,结构,过程,语句,有些 ...
- verilog语法实例学习(6)
函数和任务 函数 https://wenku.baidu.com/view/d31d1ba8dd3383c4bb4cd283.html verilog中函数的目的是允许代码写成模块的方式而不是定义独立 ...
- verilog语法实例学习(2)
Verilog中的信号类型 线网类型 线网类型表示一个或多个门或者其它类型的信号源驱动的硬件连线.如果没有驱动源,则线网的默认值为z.verilog中定义的线网类型有以下几种: wire,tr ...
- verilog语法实例学习(11)
同步时序电路的一般形式 时序电路由组合逻辑以及一个或多个触发器实现.一般的架构如下图所示:W为输入,Z为输出,触发器中存储的状态为Q.在时钟信号的控制下,触发器通过加在其输入端的组合逻辑输入,使得电路 ...
- verilog语法实例学习(8)
常用的时序电路介绍 在电平敏感的锁存器时钟信号有效期(高电平)期间,锁存器的状态随着输入信号的变化而变化.有时候,我们需要存储器的状态在一个时钟周期只改变一次,这个时候就用到了触发器.触发器(flip ...
- verilog语法实例学习(7)
常用的时序电路介绍 组合电路:这类电路的输出信号值仅却决于输入端信号值. 时序电路:时序电路的输出值不仅取决于当前的输入值,还取决于电路的历史状态,所以时序逻辑电路中包含保存逻辑信号值的存储元件,存储 ...
- verilog语法实例学习(5)
子电路模块 子电路模块的使用 一个verilog模块能够作为一个子电路包含在另一个模块中.采用这种方式,所有的模块都必须定义在一个文件中,那么verilog编译器就必须被告知每个模块的所属.模块例化的 ...
随机推荐
- 移动端h5需要注意的一些事
1.移动端点击a标签出现的背景色 a, a:hover, a:active, a:visited, a:link, a:focus { -webkit-tap-highlight-color: rgb ...
- django URLconf调度程序
路由的编写方式是Django2.0和1.11最大的区别所在,Django官方迫于压力和同行的影响,不得不将原来的正则匹配表达式,改为更加简单的path表达式,但依然通过re_path()方法保持对1. ...
- 异常日志框架Exceptionless结合.NET Core(本地部署)
一.前言 1.分布式异常日志收集框架Exceptionless是开源的工具,根据官方给出的说明: Exceptionless可以为您的ASP.NET.Web API.WebFrm.WPF.控制台和MV ...
- NOIP练习赛题目3
魔兽争霸 难度级别:C: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 小x正在销魂地玩魔兽他正控制着死亡骑士和n个食尸鬼(编号1-n)去打 ...
- Linux 系统及编程相关知识总汇
Linux C function() 参考手册 STL 学习文档 Linux内核
- BZOJ 2821作诗(Poetize) 分块
Description 有一个长度为n的序列,序列每个元素的范围[1,c],有m个询问x y,表示区间[x,y]中出现正偶数次的数的种类数. Solution 大力分块解决问题. 把序列分块,f[i] ...
- Codeforces Round #258 (Div. 2) D. Count Good Substrings 水题
D. Count Good Substrings 题目连接: http://codeforces.com/contest/451/problem/D Description We call a str ...
- centos7 打造基于python语言Selenium2自动化开发环境
1. 准备 安装模块 # yum groupinstall "Development tools" # yum install zlib-devel bzip2-devel ope ...
- j.u.c系列(04)---之AQS:同步状态的获取与释放
写在前面 在前面提到过,AQS是构建Java同步组件的基础,我们期待它能够成为实现大部分同步需求的基础.AQS的设计模式采用的模板方法模式,子类通过继承的方式,实现它的抽象方法来管理同步状态,对于子类 ...
- 关于java中的锁(转)
对于锁一直处于比较模糊的状态,最近一天晚上偶然想看看,就翻了几本书,然后弄明白了一些概念,有一些仍然没明白,例如AQS,先把搞明白的记录一下吧. 什么是线程安全? 当多个线程访问一个对象时,如果不用考 ...