【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. 确定输入与输出端口的个数,由于题目说明为设计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	

  • 波形
    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
反馈清零的十一进制计数器
  • 实现思路: 首先确定十一进制计数器需要才有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
移位寄存器
  • 实现思路: 在移位寄存器中,要求每来一个时钟脉冲,寄存器中的数据就会按顺序向左或者向右移动一位。因此,在构成移位寄存器时,必须采用主-从触发器或者边沿触发器,而不能采用电平触发器

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

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

  • 源代码

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  

  • 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
  • 源代码与测试代码
    串行移位

  • 波形图
    串行移位波形

有限同步状态机
  • 有限状态机是时序电路的通用模型,任何时序电路都可以表示为有限状态机。在由时序电路表示的有限状态机中,各个状态之间的转移总是在时钟的触发下进行的,状态信息存储在寄存器中。因为状态的个数是有限的,所以称为有限状态机
    • 有限状态机可以分为同步和异步两种:
      • 状态机的同步置位与复位:
        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
  • 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
  • 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
  • 源文件与测试文件
    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
  • 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
  • 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
  • 源文件与测试文件
    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
  • 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
  • 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
  • 源文件与测试文件
    1011
    1011tb

  • 波形图
    1011m

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目 录 译者序 前言 第1章 简介 1 1.1 什么是Verilog HDL? 1 1.2 历史 1 1.3 主要能力 1 第2章 HDL指南 4 2.1 模块 4 2.2 时延 5 2.3 数据流描述方式 5 2.4 行为描述方式 6 2.5 结构化描述形式 8 2.6 混合设计描述方式 9 2.7 设计模拟 10 第3章 Verilog语言要素 14 3.1 标识符 14 3.2 注释 14 3.3 格式 14 3.4 系统任务和函数 15 3.5 编译指令 15 3.5.1 `define和`undef 15 3.5.2 `ifdef、`else 和`endif 16 3.5.3 `default_nettype 16 3.5.4 `include 16 3.5.5 `resetall 16 3.5.6 `timescale 16 3.5.7 `unconnected_drive和 `nounconnected_drive 18 3.5.8 `celldefine 和 `endcelldefine 18 3.6 值集合 18 3.6.1 整型数 18 3.6.2 实数 19 3.6.3 字符串 20 3.7 数据类型 20 3.7.1 线网类型 20 3.7.2 未说明的线网 23 3.7.3 向量和标量线网 23 3.7.4 寄存器类型 23 3.8 参数 26 第4章 表达式 28 4.1 操作数 28 4.1.1 常数 28 4.1.2 参数 29 4.1.3 线网 29 4.1.4 寄存器 29 4.1.5 位选择 29 4.1.6 部分选择 29 4.1.7 存储器单元 30 4.1.8 函数调用 30 4.2 操作符 30 4.2.1 算术操作符 31 4.2.2 关系操作符 33 4.2.3 相等关系操作符 33 4.2.4 逻辑操作符 34 4.2.5 按位操作符 35 4.2.6 归约操作符 36 4.2.7 移位操作符 36 4.2.8 条件操作符 37 4.2.9 连接和复制操作 37 4.3 表达式种类 38 第5章 门电平模型化 39 5.1 内置基本门 39 5.2 多输入门 39 5.3 多输出门 41 5.4 三态门 41 5.5 上拉、下拉电阻 42 5.6 MOS开关 42 5.7 双向开关 44 5.8 门时延 44 5.9 实例数组 45 5.10 隐式线网 45 5.11 简单示例 46 5.12 2-4解码器举例 46 5.13 主从触发器举例 47 5.14 奇偶电路 47 第6章 用户定义的原语 49 6.1 UDP的定义 49 6.2 组合电路UDP 49 6.3 时序电路UDP 50 6.3.1 初始化状态寄存器 50 6.3.2 电平触发的时序电路UDP 50 6.3.3 边沿触发的时序电路UDP 51 6.3.4 边沿触发和电平触发的混合行为 51 6.4 另一实例 52 6.5 表项汇总 52 第7章 数据流模型化 54 7.1 连续赋值语句 54 7.2 举例 55 7.3 线网说明赋值 55 7.4 时延 55 7.5 线网时延 57 7.6 举例 57 7.6.1 主从触发器 57 7.6.2 数值比较器 58 第8章 行为建模 59 8.1 过程结构 59 8.1.1 initial 语句 59 8.1.2 always语句 61 8.1.3 两类语句在模块中的使用 62 8.2 时序控制 63 8.2.1 时延控制 63 8.2.2 事件控制 64 8.3 语句块 65 8.3.1 顺序语句块 66 8.3.2 并行语句块 67 8.4 过程性赋值 68 8.4.1 语句内部时延 69 8.4.2 阻塞性过程赋值 70 8.4.3 非阻塞性过程赋值 71 8.4.4 连续赋值与过程赋值的比较 72 8.5 if 语句 73 8.6 case语句 74 8.7 循环语句 76 8.7.1 forever 循环语句 76 8.7.2 repeat 循环语句 76 8.7.3 while 循环语句 77 8.7.4 for 循环语句 77 8.8 过程性连续赋值 78 8.8.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值