Verilog学习之路(8)— 时序电路的设计

Verilog学习之路(8)— 时序电路的设计

一、前言

时序逻辑电路的输出不仅与当前时刻输入变量的取值有关,而且与电路的原状态,即与过去的输入情况有关。

时序逻辑电路的两个特点:

  1. 时序逻辑电路包括组合逻辑电路和存储电路两部分,存储电路具有记忆功能,通常由触发器组成;
  2. 存储电路的状态反馈到组合逻辑电路输入端,与外部输入信号共同决定组合逻辑电路的输出。

时序逻辑电路的结构框图如下所示:
在这里插入图片描述
其中各部分代表的含义如下:

  • X(x1, x2, …, xn)是外部输入信号,;
  • Q(q1, q2, … , qj)是存储电路的状态输出,也是组合逻辑电路的内部输入;
  • Z(z1, z2, …, zm)为外部输出信号;
  • Y(y1, y2, …, yk)为存储电路的激励信号,也是组合电路的内部输出。

我们可以写出三大方程如下所示:
在这里插入图片描述
方程中的上标n和n+1表示相邻的两个离散时间(或称为相邻的两个节拍),n表示当前状态,n+1表示下一状态。

二、状态机

鉴于时序电路在工作时是在电路的有限个状态间按一定的规律转换的,所以又将时序电路称为状态机(State Machine, 简称SM )、有限状态机(Finite State Machine, 简称FSM)或算法状态机(Algorithmic State Machine, 简称ASM)。

有时还会根据输出信号的特点将状态机分成米利(Mealy)型状态机和摩尔(Moore)型状态机两种。

  • 摩尔型状态机:输出仅仅取决于储存电路的状态;
  • 米利型状态机:输出不仅取决于存储电路的状态,而且还取决于输入变量。

在这里插入图片描述

另外,根据状态机的描述方式,可以分为一段式、两段式以及三段式状态机。

  • 一段式:整个状态机写到一个always 模块里面。在该模块中既描述状态转移,又描述状态的输入和输出。
  • 两段式:用两个always模块来描述状态机。其中一个always 模块采用同步时序描述状态转移,另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律及其输出。
  • 三段式:使用3个always模块。一个always 块采用同步时序描述状态转移,一个always采用组合逻辑判断状态转移条件和描述其状态转移规律,另一个always模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。

三、序列检测器

  • 设计一个111的序列检测器,当输入三个或三个以上1时,电路输出为1,否则为0。

我们可以得到状态转移图如下所示:
在这里插入图片描述

我们即可编写代码check0.v如下所示

module checker0(Z, X, clk, rst_n);
	output reg Z;			// 输出检测结果
	input X, clk, rst_n;	// 输入序列,时钟,复位
	
	// 对状态进行定义
	parameter	s0 = 2'b00,
				s1 = 2'b01,
				s2 = 2'b11,
				s3 = 2'b10;
				
	reg[1:0] state, next_state;
	
	// 描述状态转移
	always@(posedge clk or negedge rst_n) begin
		if(!rst_n) begin
			state = s0;
			next_state = s0;
		end
		else
			state <= next_state;
	end 
	
	// 判断状态转移条件和状态输出	
	always@(X, state) begin
		case(state) 
			s0:	if(X) begin
					next_state <= s1;
					Z <= 0;
				end 
				else begin
					next_state <= s0;
					Z <= 0;
				end 
			s1:	if(X) begin
					next_state <= s2;
					Z <= 0;
				end 
				else begin
					next_state <= s0;
					Z <= 0;
				end 
			s2:	if(X) begin
					next_state <= s3;
					Z <= 1;
				end 
				else begin
					next_state <= s0;
					Z <= 0;
				end 
			s3:	if(X) begin
					next_state <= s3;
					Z <= 1;
				end 
				else begin
					next_state <= s0;
					Z <= 0;
				end 
		endcase
	end 

endmodule

编写测试代码tb.sv如下所示

module tb;

	reg clk, rst_n, X;
	wire Z;
	bit data_in[] = {0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0};

	checker0 dut(Z, X, clk, rst_n);
	
	always#10 clk = ~clk;
	
	initial begin
		clk = 0; rst_n = 0;
		#51 rst_n = 1'b1;
		foreach(data_in[i]) begin
			#20;
			X = data_in[i];
		end 
		#100;
		$stop;
	end
	
endmodule 

仿真波形如下所示
在这里插入图片描述
我们可以看到,这是一个米利型的状态机,输出不仅和当前状态有关,还和输入有关。

四、附录

上一篇:Verilog学习之路(7)— 数字加法器
下一篇:Verilog学习之路(9)—计数器和移位寄存器

  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值