• 【Verilog】时序逻辑电路 -- 程序设计与应用


    时序逻辑电路特点

    1. 时序逻辑电路包括组合逻辑电路和存储电路两部分,存储电路具有记忆功能,通常由触发器组成
    2. 存储电路的状态反馈到组合逻辑电路输入端,与外部输入信号共同决定组合逻辑电路的输出,组合逻辑电路的输出除包括外部输出外,还包括连接到存储电路的内部输出,他将控制存储电路状态的转移

    D触发器

    • 设计原理:D触发器是在时钟上升沿到来时,输出等于此时状态下的输入。即就是D触发器的输出状态与时钟上升沿时的输入状态相同,之后输出保持不变,直到在来一个时钟上升沿来改变他的输出状态。
    • 源代码
    module Dff(Q,D,CLK);
    	input Q,CLK;
    	output D;
    	reg D;
    	
    	always@(posedge CLK)
    		D <= Q;
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 代码解释说明

      1. 确定输入与输出端口的个数,由于题目说明为设计D触发器,则设置一个输入端口Q,设置一个时钟控制端口CLK,设置一个输出端口D;
      2. 确定输入和输出的位宽大小以及对其数据类型进行说明;
      3. 因为需要设计D触发器,则在选择sel取不同值时,输出端口会选择其中一路输入作为输出,这里设定为在时钟上升沿到来时D = Q;
      4. 完成功能模块之后需要编写测试模块,按照测试模块的书写规则,进行编写;
      5. 在编写激励向量时,为方便观察,将每个状态延时设为10s与5s。
    • testbench

    module Dff_tb;
    	reg CLK,Q;
    	wire D;
    	
    	Dff u1(Q,D,CLK);
    	always
    		#5 CLK = ~CLK;
    	initial
    	begin
    		CLK = 0;
    		Q = 0;
    		#10 Q = 1;
    		#10 Q = 0;
    		#10 Q = 1;
    		#10 Q = 0;
    		#5 Q = 1;	
    		#5 Q = 0;
    	end
    endmodule	
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 波形
      D触发器波形

    • 波形图解释:由图可知,在第一个时钟上升沿到来时,输入端Q = 0输出端D = 0,并持续保持此状态;在第二个时钟上升沿到来时,输入端Q = 1输出端D = 1,此时输出不在保持上一个状态的输入值,而改变为此上升沿状态时的输入值。实现了D触发器,与代码解释保持一致

    采用D触发器的二进制计数器
    • 逻辑框图
      D触发器

    • 源代码

    module comp2bit(Q, clk, rst);
        output Q;
        input clk, rst;
        reg Q;
        always@(posedge clk or negedge rst)
            if (!rst)
                Q <= 1'b0;
            else
                Q <= ~Q;
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    反馈清零的十一进制计数器
    • 实现思路: 首先确定十一进制计数器需要才有4位来进行计数,但4位可以表示16种数据,所以需要在第11个状态跳回初始状态;由于使用的方法是反馈清零,故当计数器计到第11个状态时,后一个状态直接清零跳到初始状态,即可实现反馈清零的十一进制计数器

    • 源代码

    module comp11(count, clk, rst);
        output [3:0] count;
        input clk, rst;
        reg [3:0] count;
        always@(posedge clk)
            if (!rst)
                count <= 4'b0000;
            else
                if (count == 4'b1010)
                    count <= 4'b0000;
                else
                    count <= count + 1;
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    移位寄存器

    • 实现思路: 在移位寄存器中,要求每来一个时钟脉冲,寄存器中的数据就会按顺序向左或者向右移动一位。因此,在构成移位寄存器时,必须采用主-从触发器或者边沿触发器,而不能采用电平触发器

    • 数据输入移位寄存器的方式有串行输入和并行输入两种。下图是串行输入移位寄存器。在时钟的作用下,输入数据进入移位寄存器最左位,同时,将已存入寄存器的数据右移一位。并行输入方式是把全部输入数据同时存入寄存器。

    • 串行输入移位寄存器逻辑框图
      串行移位寄存器

    • 源代码

    module yiwei(clk,en,din,dout);  
         input en,clk;  
         input [7:0] din;  
         output [7:0] dout;  
         reg [7:0] dout;  
         reg [7:0] temp;
       
         always @(posedge clk)  
            begin   
    		if(en == 0)  
                temp <= din;  
            else  
                       //dout <= {temp[0], temp[7:1]};
                temp <= {temp[0], temp[7:1]};
                dout <= temp;
            end  
    
     endmodule  
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • testbench
    module yiwei_tb;  
        reg [7:0] din;  
        reg clk;  
        reg en;  
        wire [7:0]dout;
        wire [7:0] lout [7:0];
        yiwei u1(clk,en,din,dout);
    	LED uu0(dout[0],lout[0]);
    	LED uu1(dout[1],lout[1]);
    	LED uu2(dout[2],lout[2]);
    	LED uu3(dout[3],lout[3]);
    	LED uu4(dout[4],lout[4]);
    	LED uu5(dout[5],lout[5]);
    	LED uu6(dout[6],lout[6]);
    	LED uu7(dout[7],lout[7]);
        always  #10 clk = ~clk;  
        initial  
           begin  
               clk = 0;  
               en = 1'b1; 
    		   din = 8'b11100010; 
               #20 en = 1'b0;  
               #20 en=1'b1;  
           end  
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 源代码与测试代码
      串行移位

    • 波形图
      串行移位波形

    有限同步状态机

    • 有限状态机是时序电路的通用模型,任何时序电路都可以表示为有限状态机。在由时序电路表示的有限状态机中,各个状态之间的转移总是在时钟的触发下进行的,状态信息存储在寄存器中。因为状态的个数是有限的,所以称为有限状态机
      • 有限状态机可以分为同步和异步两种:
        • 状态机的同步置位与复位:
          always@(posedge clk )
          if(!rst)
        • 状态机的异步置位与复位:
          always@(posedge clk or negedge rst)
      • 主要讨论有限同步状态机,有限状态机也是由两部分组成:存储电路和组合逻辑电路,存储电路用来生成状态机的状态,组合逻辑电路用来提供输出以及状态机跳转的条件
    • 状态机常见编码方式
      1. 二进制编码
      2. 格雷编码
      3. 一位独热编码
    同步时序/异步时序
    • 同步时序逻辑电路: 电路状态的变化在同一时钟脉冲作用下发生,即各触发器状态的转换同步完成
    • 异步时序逻辑电路: 没有统一的时钟脉冲信号,即各触发器状态的转换是异步完成的

    同步时序

    moore型与mealy型
    • moore型

      • Mealy型状态机的输出信号不仅与当前状态有关,而且还与输入信号有关,即可以把Mealy型有限状态机的输出看成是当前状态和输入信号的函数
    • moore型逻辑框图
      Moore

    • mealy型

      • Moore型状态机的输出仅与当前状态有关,即可以把Moore型有限状态的输出看成是当前状态的函数
    • mealy型逻辑框图
      mealy

    接收“111”的Moore型和Mealy型有限状态机
    • 状态设计

      • parameter ST0 = 4‘b000; //接收到零个1的状态
      • parameter ST1 = 4’b001; //接收到一个1的状态
      • parameter ST2 = 4‘b010; //接收到两个1的状态
      • parameter ST3 = 4’b100; //接收到三个1的状态
    • 状态转移图
      111

    • moore型源代码

    module moore111(clk,clr,in,out);
    	input clk,clr,in;
    	output out;
    	reg out;
    	reg [1:0] present_state,next_state;
    	parameter s0 = 2'b00,s1 = 2'b01,s2 = 2'b10,s3 = 2'b11;
    	always @(posedge clk or posedge clr)
    		if(clr)
    			present_state <= s0;
    		else
    			present_state <= next_state;
    	always @(*)
    		begin
    			case(present_state)
    				s0: if(in) begin next_state = s1; out = 0; end
    				    else begin next_state = s0; out = 0; end
    				s1: if(in) begin next_state = s2; out = 0; end 
    					else	begin next_state = s0; out = 0; end
    				s2: if(in) begin next_state = s3; out = 0; end
    				    else	begin next_state = s0; out = 0; end
    				s3: if(in) begin next_state = s3; out = 1; end
    				    else	begin next_state = s0; out = 1; end
    				default:  begin next_state = 0; out = 0; end		
    			endcase
    		end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • mealy型源代码
    module mealy111(
    	input wire clk,
    	input wire clr,
    	input wire din,
    	output reg dout);
    	reg [1:0] present_state,next_state;
    	parameter s0=2'b00,s1=2'b01,s2=2'b11;
    	always @ (posedge clk or posedge clr)
    		begin
    			if(clr==1) present_state<=s0;
    			else       present_state<=next_state;
    		end
    	always @(*) 
    		begin 
    			case(present_state)
    				s0:if(din==1) begin next_state=s1;dout=0;end
    				   else       begin next_state=s0;dout=0;end
    				s1:if(din==1) begin next_state=s2;dout=0;end
    				   else       begin next_state=s0;dout=0;end
    				s2:if(din==1) begin next_state=s2;dout=1;end
    				   else       begin next_state=s0;dout=0;end
    				default:next_state=s0;
    			endcase
    		end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • testbench
    module seq111_tb;
    	reg clk;
    	reg clr;
    	reg din;
    	wire dout;
    	mealy111 u1(clk,clr,din,dout);
    	moore111 u2(clk,clr,din,dout);
    	always #100 clk=~clk;
    	initial begin
    		clk=0;clr=1;din=0;
    		#500 clr=0;
    		#200 din=1;
    		#200 din=0;
    		#200 din=1;
    		#400 din=0;
    		#400 din=1;
    		#600 din=0;
    		#400 din=1;
    	end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 源文件与测试文件
      111
      111tb

    • 波形图
      111m

    接收“1111”的Moore型和Mealy型有限状态机
    • moore型源代码
    module moore1111(clk,rst,in,out);
    	input clk,rst,in;
    	output out;
    	reg out;
    	reg [2:0] present_state,next_state;
    	parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100;
    	always @(posedge clk or negedge rst)
    		if(!rst)
    			present_state <= s0;
    		else
    			present_state <= next_state;
    
    	always @(*)
    		begin
    			case(present_state)
    				s0: if(in) begin next_state = s1;out = 0; end
    				    else   begin next_state = s0;out = 0; end
    				s1: if(in) begin next_state = s2;out = 0; end
    				    else   begin next_state = s0;out = 0; end
    				s2: if(in) begin next_state = s3;out = 0; end
    				    else   begin next_state = s0;out = 0; end
    				s3: if(in) begin next_state = s4;out = 0; end
    				    else   begin next_state = s0;out = 0; end
    				s4: if(in) begin next_state = s4;out = 1; end
    				    else   begin next_state = s0;out = 1; end	
    				default:   begin next_state = s0;out = 0; end
    			endcase
    		end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • mealy型源代码
    module mealy1111(
      input   wire  clk,
      input   wire  rst,
      input   wire  din,
      output  reg   dout
    );
      reg [1:0] present_state,next_state;  
      parameter s0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;
      
    
      always @ (posedge clk or negedge rst)
        if (!rst)
    		present_state <= s0;
        else
    		present_state <= next_state;
      
    	always @ (*)
    		case (present_state)
    			s0: if (din == 1) begin next_state = s1;dout = 0; end  
    				else          begin next_state = s0;dout = 0; end
    			s1: if (din == 1) begin next_state = s2;dout = 0; end  
    				else          begin next_state = s0;dout = 0; end
    			s2: if (din == 1) begin next_state = s3;dout = 0; end  
    				else          begin next_state = s0;dout = 0; end 
    			s3: if (din == 1) begin next_state = s3;dout = 1; end  
    				else          begin next_state = s0;dout = 0; end 		
    			default:          next_state = s0;
    		endcase          
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • testbench
    module seq1111_tb;
    	reg in;
    	reg clk;
    	reg rst;
    	wire out;
    
    	mealy1111 u1(clk,rst,in,out);
    	moore1111 u2(clk,rst,in,out);
    	always #100 clk=~clk;
    	initial begin
    		clk=0;
    		rst=0;
    		in=0;
    		#300 rst=1;
    		#200 in=0;
    		#200 in=1;
    		#200 in=0;
    		#200 in=1;
    		#800 in=0;
    		#400 in=1;		
    		#600 in=0;
    		#400 in=1;
    		#1000 in=0;
    		#200 in=0;		
    	end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 源文件与测试文件
      1111
      1111tb

    • 波形图
      1111m

    接收“1011”的Moore型和Mealy型有限状态机
    • moore型源代码
    module moore1011(input wire clk,input wire clr,input wire din,output reg dout);
    	reg [2:0] present_state,next_state;
    	parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100;
    	always @ (posedge clk or posedge clr)
    		if(clr==1) present_state<=s0;
    		else       present_state<=next_state;
    	always @(*) 
    		begin 
    			case(present_state)
    				s0:if(din==1)  next_state=s1;
    				   else        next_state=s0;
    				s1:if(din==1)  next_state=s1;
    				   else        next_state=s2;
    				s2:if(din==1)  next_state=s3;
    				   else        next_state=s0;
    				s3:if(din==1)  next_state=s4;
    				   else        next_state=s2;
    				s4:if(din==1)  next_state=s1;
    				   else	       next_state=s2;
    				default:next_state=s0;
    			endcase
    		end
    	always @(*)
    		begin
    			if(present_state==s4) dout=1;
    			else				  dout=0;
    		end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • mealy型源代码
    module mealy1011(
    	input wire clk,
    	input wire clr,
    	input wire din,
    	output reg dout);
    	reg [1:0] present_state,next_state;
    	parameter s0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;
    	always @ (posedge clk or posedge clr)
    		begin
    			if(clr==1) present_state<=s0;
    			else       present_state<=next_state;
    		end
    	always @(*) 
    		begin 
    			case(present_state)
    				s0:if(din==1) begin next_state=s1;dout=0;end
    				   else       begin next_state=s0;dout=0;end
    				s1:if(din==1) begin next_state=s1;dout=0;end
    				   else       begin next_state=s2;dout=0;end
    				s2:if(din==1) begin next_state=s3;dout=0;end
    				   else       begin next_state=s0;dout=0;end
    				s3:if(din==1) begin next_state=s1;dout=1;end
    				   else       begin next_state=s2;dout=0;end  
    				default:next_state=s0;
    			endcase
    		end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • testbench
    module seq1011_tb;
    	reg clk;
    	reg clr;
    	reg din;
    	wire dout;
    	mealy1011 u1(clk,clr,din,dout);
    	moore1011 u2(clk,clr,din,dout);
    	always #100 clk=~clk;
    	initial begin
    		clk=0;clr=1;din=0;
    		#300 clr=0;
    		#200 din=1;
    		#200 din=0;
    		#200 din=1;
    		#200 din=1;
    		#400 din=1;
    		#600 din=0;
    		#400 din=1;
    	end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 源文件与测试文件
      1011
      1011tb

    • 波形图
      1011m

  • 相关阅读:
    HarmonyOS 学习记录
    【Apollo学习笔记】——规划模块TASK之RULE_BASED_STOP_DECIDER
    Redis的三大问题
    基于python-CNN的常见鱼类分类识别-含数据集+pyqt界面
    企业小程序商城的推广方式有哪些_分享小程序商城的作用
    关于阿里云服务器Ubuntu编译jdk8中遇到的坑及解决方案
    使用cli批量下载GitHub仓库中所有的release
    设计模式之中介者模式
    渲染富文本编辑器并设置富文本编辑器的高度
    EasyRecovery14数据恢复软件官方功能简介
  • 原文地址:https://blog.csdn.net/weixin_44321600/article/details/126150759