我是靠谱客的博主 高兴香氛,最近开发中收集的这篇文章主要介绍常见时序逻辑电路触发器计数器移位寄存器序列信号发生器有限同步状态机,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

  • 触发器
    • D触发器
      • 最简D触发器
      • 带复位端的D触发器
    • T触发器
  • 计数器
    • 二进制计数器
    • 任意进制计数器
  • 移位寄存器
  • 序列信号发生器
  • 有限同步状态机
    • 顺序脉冲发生器
    • “11010”序列检测器

与组合逻辑电路不同,时序逻辑电路的输出不仅与当前时刻输入变量的取值有关,而且与电路的原状态(即过去的输入情况有关)。
时序逻辑电路的结构框图如下:
在这里插入图片描述

  • 与组合电路相比,时序逻辑电路有两个优点:
  1. 时序逻辑电路包括组合逻辑电路和存储电路两部分,存储电路具有记忆功能,通常由触发器组成。
  2. 存储电路的状态反馈到组合逻辑电路输入端,与外部输入信号共同决定组合逻辑电路的输出。组合逻辑电路的输出除包括外部输出外,还包含连接到存储电路的内部输出,它将控制存储电路状态的转移。
  • 时序逻辑电路按状态变化的特点,可分为同步时序逻辑电路和异步时序逻辑电路。在同步时序逻辑电路中,电路状态的变化在同一时钟脉冲作用下发生,即各触发器状态的转换同步完成。在异步时序逻辑电路中,没有统一的时钟脉冲信号,即各触发器状态的转换是异步完成的。
  • 对时序逻辑电路功能的描述方式主要有三种:逻辑方程,状态转移表和状态转移图,时序图。
  • 对时序逻辑电路的设计进行描述也有不同的方式,主要有三种:状态转移图描述,基于状态化简的结构性描述,VerilogHDL抽象描述。

触发器

触发器是时序逻辑电路的最基本电路单元,主要有D触发器、JK触发器、T触发器和RS触发器等。根据功能要求的不同,触发器还具有置位、复位、使能、选择等功能。

D触发器

最简D触发器

D触发器的逻辑符号如下所示:
在这里插入图片描述
图中D为信号输入端,clk为时钟控制端,Q为信号输出端。这种触发器的逻辑功能是:不论触发器原来的状态如何,输入端的数据D(无论D=0,还是D=1)都将在时钟clk的上升沿被送入触发器,使得Q=D。其真值表如下所示:
在这里插入图片描述
代码如下:

module DFF (q, clk, data_in);
    output q;
    input clk, data_in;
    reg q;
    always @(posedge clk)   q <= data_in;
endmodule

带复位端的D触发器

在D触发器的实际使用中,有时需要一个复位端(也称清零端)。带有复位端的D触发器的逻辑符号如下所示:
在这里插入图片描述
电路上电时,电路的逻辑处于不定状态,复位脉冲的到来将电路初始化为Q=0的状态。随后,在时钟的控制下,输入端D的数据在每个时钟上升沿被置到输出端Q。同步清0的D触发器的代码如下:

module DFF_rst (q, clk, reset, data_in);
    output q;
    input clk, reset, data_in;
    reg q;
    always @(posedge clk) 
        if (!reset)  q <= 0;
        else         q <= data_in;
endmodule

异步清0的D触发器的代码如下:

module DFF_srst (q, clk, reset, data_in);
    output q;
    input clk, reset, data_in;
    reg q;
    always @(posedge clk or negedge reset)//只要接收到复位信号,立马复位
    	if(!reset)  q <= 0;
    	else        q <= data_in;
endmodule

可以看到,同步清0和异步清0的电路代码只是在always后的敏感向量表上有所不同。对于同步清0,并不是清0信号一变化电路马上就会被置0,清0信号有效后需等待时钟的有效边沿到来后电路才会有动作,因此不应该把清0信号写入敏感向量表中。而异步清0时,只要清0信号有效,电路就会马上更新,输出置0,因此对于异步电路,清0信号有必要写入敏感向量表中。

T触发器

T触发器的逻辑符号如下所示:
在这里插入图片描述
其逻辑功能为:当时钟的有效边沿到来时,如果T=1,则触发器翻转;如果T=0,则触发器的状态保持不变。reset为复位端,异步复位,低电平有效。代码如下:

module TFF (data_out, T, clk, reset);
    output data_out;
    input T, clk, reset;
    reg data_out;
    always @(posedge clk or negedge reset)
   	   if (!reset)     data_out <= 1'b0;
 	   elseif(T)       data_out <= ~data_out;  
endmodule

计数器

计数器是应用最广泛的逻辑部件之一。计数器可以统计输入脉冲的个数,具有计时、计数、分频、定时、产生节拍脉冲等功能、
根据计数器中触发器时钟端的链接方式,分为同步计数器和异步计数器;根据计数方式分为二进制计数器、十进制计数器和任意进制计数器;根据计数器中的状态变化规律,分为加法计数器、减法计数器和加/减计数器。

二进制计数器

采用D触发器实现的二进制计数器的逻辑电路图如下:
在这里插入图片描述
代码如下:

module comp2bit (Q, clk, reset);
    output  q;
    input clk, reset;
    reg Q;
    always @(posedge clk or negedge reset)
    	if (!reset)
   			Q <= 1'b0;
   		else   
  	   	    Q <= ~Q;
endmodule

任意进制计数器

对于M进制的计数器,首先应确定计数器所需触发器的个数。N个触发器对应了2的N次方个状态,其应大于M。
以十一进制计数器为例,最少需要4个触发器。采用反馈清零法设计的十一进制计数器的代码如下:

module comp_11 (count, clk, reset);
    output [3:0]count;
    input clk, reset;
    reg [3:0]count;
    always @(posedge clk)
        if(reset)   count <= 4'b0000;//复位
        else
            if (count == 4'b1010)//一个技术循环结束
                count <= 4'b0000;
            else
                count <= count + 1;
endmodule

移位寄存器

移位寄存器 可以用来实现数据的串并转换,也可以构成移位计数器,进行计数、分频,还可以构成序列码发生器、序列码检测器等。
以环形移位寄存器为例,N位环形寄存器由N个移位寄存器组成,它可以实现环形移位,如下图所示:
在这里插入图片描述
其将每个寄存器的输出作为下一位寄存器的输入,并将高位寄存器的输出作为循环的输入,代码如下:

module shiftregist1 (D, clk, reset);
    parameter shiftregist_width = 4;
    output [shiftregist_width-1:0]D;//[3:0]D
    input clk, reset;
    reg[shiftregist_width-1:0]D;
    always @(posedge clk)
    	if (!reset)
    		D <= 4'b0000;
        else
            D <= {D[shiftregist_width-2:0], D[shiftregist_width-1]};
                //D[2:0], D[3]
endmodule

序列信号发生器

序列信号发生器是能够产生一组或多组序列信号的时序电路,它可以由纯时序电路构成,也可以由包含时序逻辑和组合逻辑的混合电路构成。
以一个产生100111序列的信号发生器为例,可以采用不同的方法:

  1. 由移位寄存器构成
    采用循环移位寄存器,在电路工作前,将所需的序列码置入移位寄存器中,然后循环移位,就可以不断地产生需要的序列。由于移位寄存器输入和输出信号之间没有组合电路,不需要进行组合逻辑的反馈运算,因此所占用的电路的面积很大,结构框图如下:
    在这里插入图片描述
    代码如下:
module signal_maker (out, clk, load, D);
    parameter M = 6;
    output out;
    input clk, load;
    input [M-1:0]D;  
    reg [M-1:0]Q;
    initial     Q = 6'b100111;
    always @(posedge clk)
   		if(load)    Q <= D;
  	    else        Q <= [Q[M-2:0], Q[M-1]];//移位  Q[4:0]+Q[5]
    assign out = Q[M-1]
endmodule

  1. 由移位寄存器和组合逻辑电路构成
    反馈移位寄存器型序列信号发生器的结构框图如下所示:
    在这里插入图片描述
    它由移位寄存器和组合反馈网络组成,从移位寄存器的某一输出端可以得到周期性的序列码。
    代码如下:
module signal_maker2 (out, clk, load, D);
    parameter M = 4;
    output out;
    input clk, load;
    input [M-1:0]D;
    reg [M-1:0]Q;
    wire w1;
    always @(posedge clk)//时序电路部分,移位寄存器
        if(load)        Q <= D;
        else            Q <= {Q[M-2:0], w1};
    assign w1 = (~Q[3])|(~Q[1]&(~Q[0]))|(Q[3]&(~Q[2]));//组合逻辑电路,反馈网络
    assign out = Q[M-1];
endmodule

有限同步状态机

有限状态机是时序电路的通用模型,任何时序电路都可以表示为有限状态机。

  • 根据输出信号的产生方式,有限状态机可以分为米利型(Mealy)和摩尔型(Moore)。Mealy型状态机的输出与当前状态和输入有关,Moore型状态机的输出仅依赖于当前状态,而与输入无关。结构如下所示:
    在这里插入图片描述
  • 状态机的编码方式很多,由此产生的电路也各不相同。常见的编码方式有三种:二进制编码、格雷编码和一位独热编码。
  1. 二进制编码:其状态寄存器是由触发器组成的。N个触发器可以构成2的N次方个状态。二进制编码的优点是使用的触发器个数较少,节省了资源;缺点是状态跳转时可能有多个bit(位)同时变化,引起毛刺,造成逻辑错误。
  2. 格雷编码:与二进制编码类似。格雷编码状态跳转时只有一个bit(位)发生变化,减少了产生毛刺和一些暂态的可能。
  3. 一位独热(One Hot)编码:这是对于n个状态采用n个bit(位)来编码,每个状态编码中只有一个bit(位)为1,如0001、0010、0100、1000。One Hot编码增加了使用触发器的个数,但该种编码方式为以后的译码提供了方便,能有效地节省和简化组合电路。
  • 有限状态机的描述方法有两段式和三段式两种。
    1.两段式描述方法:
//第一个进程,同步时序always块,格式化描述次态寄存器迁移到现态寄存器
always@(posedge clk or negedge rst_n)//异步复位
	if(!rst_n)	current_state <= IDLE;
	else		current_state <= next_state;//非阻塞赋值
//第二个进程,组合逻辑always模块,描述状态转移条件判断
always@(current_state or 输入信号)//电平触发
	begin
		next_state = x;//初始化,使得系统复位后能进入正确的状态
		    case(current_state)
		    	S1:if(...)
		    	next_state = S2;//阻塞赋值
		    	out <= 1'b1;//非阻塞逻辑
		    ...
		    endcase
	 end

2.三段式描述方法:

//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器
always@(posedge clk or negedge rst_n)//异步复位
	if(!rst_n)	current_state <= IDLE;
	else		current_state <= next_state;//非阻塞赋值
//第二个进程,组合逻辑always模块,描述状态转移条件判断
always@(current_state or 输入信号)//电平触发
	begin
		next_state = x;//初始化,使得系统复位后能进入正确的状态
		    case(current_state)
		    	S1:if(...)
		    	next_state = S2;
		    	...
		    endcase
	 end
//第三个进程,同步时序always模块,格式化描述次态寄存器输出
always@(posedge clk or negedge rst_n)
	begin
	...//
		case(next_state or 输入信号)
			S1: out1 <= 1'b1;
			S2: out1 <= 1'b0;
			default:...   //default免除综合工具综合出锁存器
		endcase
	end		

三段式并不是一定要写三个always块,如果状态机更为复杂,always块也会相应增加。

接下来以两个时序电路来说明有限同步状态机的应用。

顺序脉冲发生器

顺序脉冲发生器又称脉冲分配器,其将高电平脉冲依次分配到不同的输出上,保证在每个时钟周期内只有一路输出高电平,不同时钟上的高电平脉冲依次出现在所有输出端。
以4位顺序脉冲发生器为例,其有4路输出S0、S1、S2、S3,每路输出上高电平脉冲依次出现,输出在1000、0100、0010、0001之间循环。4位顺序脉冲发生器的状态转移图如下所示:
在这里插入图片描述
代码如下:

module state4 (OUT, clk, rst_n);
    output [3:0]OUT;
    input clk;
    input rst_n;
    reg [3:0]OUT;
    reg [1:0]STATE, next_STATE;
    always @(STATE)
        case(STATE)
            2'b00;
                begin
                    OUT <= 4'b1000;
                    next_STATE <= 2'b01;
                end
            2'b01;
                begin
                    OUT <= 4'b0100;
                    next_STATE <= 2'b10;
                end
            2'b10:
                begin
                    OUT <= 4'b0010;
                    next_STATE <= 2'b11;
                end
            2'b11;
                begin
                    OUT <= 4'b0001;
                    next_STATE <= 2'b00;
                end
        endcase
    always @(posedge clk or negedge rst_n)
        if (!rst_n)     STATE <= 2'b00;
        else            STATE <= next_STATE;
endmodule

“11010”序列检测器

序列检测器就是将一个指定的序列从数字码流中检测出来。当输入端出现序列11010时,输出为1,否则输出为0。在此不考虑重复序列,即出现指定序列后就重新开始序列检测,不再考虑以前的数据。该序列检测器的状态转移图如下所示:
在这里插入图片描述
代码如下:

module seqdet (D_out, D_in, rst_n, clk);
    parameter IDLE = 3'd0, A = 3'd1, B = 3'd2, C = 3'd3, D = 3'd4, E = 3'd5;
    output D_out;
    input D_in, rst_n, clk;
    reg [2:0]state, next_state;
    wire D_out;
    assign D_out = (state == E)?1:0;
    always @(state or D_in)
        case(state)
            IDLE:if(D_in)   next_state = A;
                 else       next_state = IDLE;
            A:  if(D_in)    next_state = B;
                else        next_state = IDLE;
            B:  if(D_in)    next_state = B;
                else        next_state = C;
            C:  if(D_in)    next_state = D;
                else        next_state = IDLE;
            D:  if(D_in)    next_state = B;
                else        next_state = E;
            E:  if(D_in)    next_state = IDLE;
                else        next_state = A;
             default:    next_state = IDLE;
		endcase
	always @(posedge clk)
		state <= next_state;
endmodule

最后

以上就是高兴香氛为你收集整理的常见时序逻辑电路触发器计数器移位寄存器序列信号发生器有限同步状态机的全部内容,希望文章能够帮你解决常见时序逻辑电路触发器计数器移位寄存器序列信号发生器有限同步状态机所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部