verilog语法实例学习(11)

同步时序电路的一般形式

   时序电路由组合逻辑以及一个或多个触发器实现。一般的架构如下图所示:W为输入,Z为输出,触发器中存储的状态为Q。在时钟信号的控制下,触发器通过加在其输入端的组合逻辑输入,使得电路从一个状态变成另一个状态。采用边沿触发的触发器可以确保一个时钟周期内只发生一次状态变化。它们可以由时钟上升沿或下降沿触发,产生这种状态变化的时钟边沿称为有效时钟边沿。

image_thumb211

      触发器有两路组合逻辑输入,分别为原始输入W和触发器的当前输出Q,因此当前状态的改变不仅却决于触发器的当前状态,还取决于电路的原始输入。在上图中,可以得知,时序电路的输出由另一个组合电路产生,该组合电路是当前原始输入和触发器当前状态的函数。时序电路输出总取决于电路当前状态,却不一定直接依赖原始输入,图中的虚线表示可能存在也可能不存在。为了区分这两种存在,通常将输出仅由电路状态决定的时序电路称为Moore型,而输出由电路状态和原始输入共同决定的称为Mealy型

摩尔有限状态机

     一个实际问题的描述:假设自动驾驶的汽车,以一定的速度运行,w=0,表示运行速度正常,w=1,表示运行超速。速度控制的策略,等间隔时间检测速度,如果两次或多次连续超速(w=1),则在一个时间间隔开始设置减速信号z=1,否则z=0。如果用电路描述上述问题,则等时间间隔为时钟周期,在每个时钟的上升沿进行状态判断。输入输出信号时序序列如下:

时钟周期t0t1t2t3t4t5t6t7t8t9t10
w01011011101
z00000100110

      我们用状态机来描述该问题:首先有一个起始状态A,电路加载或复位后为该状态。假设当前为A状态,如果w=0,不做任何事情,输出z=0,在时钟上升沿检测后,仍保持A状态,输出z=0,如果w=1,仍输出z=0,在下一个时钟周期边沿进入状态B,输出z=0;假设当前为B状态,如果w=0,输出z=0,在下一个时钟上升沿进入A状态,输出z=0,如果w=1,此时z输出仍为0,在下一个时钟上升沿,进入状态C,此时输出z=1;假设当前状态为C状态,如果w=0,此时仍有z=1,在下一个时钟上升沿进入A状态,此时输出z=0,如果w=1,在下一个时钟上升沿,仍操持状态C,输出z=1。

   该状态机的状态表如下:


现在状态下一状态输出 z
w=0w=1
AAB0
BAC0
CAC1


状态机如下:复位信号强制电路进入A状态,任何条件下复位都成立,图中用箭头表示。

image

     上面的状态图和状态表中,我们用了3个状态A,B,C。在逻辑电路实现过程中,每个状态用状态变量的特定取值(值的组合)来表示。每个状态变量可能以触发器来实现。由于需要实现3种状态,因此采用2个状态变量就可以满足要求,令两个状态变量分别用y1,y2,来表示电路当前状态。另外用Y1,Y2表示下一状态,它由反馈电路和输入w决定。

image


从而,我们得到详细的状态赋值表。根据这个赋值表,我们能设计出具体电路。状态11在这个电路中没有使用。

现在状态 下一状态输出 
w=0 w=1
y2y1Y2Y1Y2Y1z
A0000010
B0100100
C1000101
11ddddd

Y1的真值表

w/y2y100011110
000d0
110d0

Y2的真值表

w/y2y100011110
000d0
101d1

z的真值表

y2/y101
000
11d


从上面赋值表中,我们能够得到下一个状态Y1,Y2的逻辑表达式为:

Y1=w~y1~y2

Y2=wy1~y2+w~y1y2(或w(y1+y2))

z=~y1y2(或z=y2)

考虑11状态,可以画出卡诺图来简化电路,简化后的电路Y2和z如上面括号中的蓝色表达式。


image



状态机的verilog代码:

module moore(clk, w, Rst_n, z);

   input clk;   //时钟信号
	input w;
	input Rst_n; //复位信后
	output z;
   reg [1:0] y, Y; //现在的状态

	parameter A=2'b00,B=2'b01,C=2'b10;

	always @(w,y)
	begin
	  case(y)
	    A:
		    if(w==0) Y=A;
		    else Y=B;
		 B:
		    if(w==0) Y=A;
		    else Y=C;
	    C:
		    if(w==0) Y=A;
		    else Y=C;
	    default: Y=2'bxx;
	  endcase

	end

	always @(posedge clk,negedge Rst_n)
	begin
	  if(Rst_n==0)
	    y <= A;
	  else
	    y <= Y;
	end

	assign z=(y==C);
endmodule


testbench为:

`timescale 1ns/1ns
`define clock_period 20

module moore_tb;
  reg w;
  reg clk=1;
  reg Rst_n;
  wire z;


  moore moore0(.clk(clk),.w(w),.Rst_n(Rst_n),.z(z));
  always # (`clock_period/2) clk = ~clk;

  initial
  begin
    w = 1'b0;
	 Rst_n = 1'b1;
	 #(`clock_period)
	 Rst_n = 1'b0;
	 #(`clock_period)
	 Rst_n = 1'b1;
	 w = 1'b0;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b0;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b0;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b0;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b1;

	 #(`clock_period*20)
    $stop;
  end

endmodule

image

如果用2’b11表示状态C,则有下面的状态表:

现在状态 下一状态输出 
w=0 w=1
y2y1Y2Y1Y2Y1z
A0000010
B0100110
C1100111
10ddddd

Y1的真值表

w/y2y100011110
0000d
1111d

Y2的真值表

w/y2y100011110
0000d
1011d

Z的真值表

y2/y101
000
11d

则有Y1=w

Y2=wy1

z=y2

可以用下面更简化的电路实现:

image

假设用独热码表示状态A,B,C,则需要三位状态码,如下面的表格所示:


现在状态 下一状态输出 
w=0 w=1
y3y2y1Y3Y2Y1Y3Y2Y1z
0010010100
0100011000
1000011001

Y1的真值表

wy3/y2y100011110
00d1d1
011ddd
110ddd
10d0d0

Y2的真值表

wy3/y2y100011110
00d0d0
010ddd
110ddd
10d1d0

Y3的真值表

wy3/y2y100011110
00d0d0
010ddd
111ddd
10d0d1

Z的真值表

y3/y2y100011110
0d0d0
11ddd

所以有

Y1=~w

Y2=wy1

Y3=w~y1

z=y3

没有下一个状态与y2有关,所以可以优化掉y2触发器。


梅利有限状态机

一个实际问题的描述:假设前面自动驾驶的例子中,我们做一个修改,第二次检测到w=1的相同的周期内,z=1。输入输出信号时序序列如下:

时钟周期t0t1t2t3t4t5t6t7t8t9t10
w01011011101
z00001001100

      我们用状态机来描述该问题:首先有一个起始状态A,电路加载或复位后为该状态。假设当前为A状态,如果w=0,输出z=0,如果w=1,输出z=0,在下一个时钟周期边沿进入状态B;假设当前为B状态,如果w=0,输出z=0,在下一个时钟上升沿进入A状态,如果w=1,输出最z=1,在下一个时钟上升沿,仍保持状态B。

状态图如下:

image


该状态机的状态表如下:

现在状态下一状态输出 z
w=0w=1w=0w=1
AAB00
BAB11


状态分配表如下:
现在状态 下一状态输出 z
w=0 w=1w=0w=1
yYYzz
A00100
B10101

Y的真值表:

w/y01
000
111

z的真值表:

w/y01
000
101

Y=w

z=wy

状态机的实现电路:

image

module mealy(clk, w, Rst_n, z);

   input clk;   //时钟信号
	input w;
	input Rst_n; //复位信后
	output  reg z;
   reg  y, Y; //现在的状态

	parameter A=1'b0,B=1'b1	;

	always @(w,y)
	begin
	  case(y)
	    A:
		    if(w==0)
			 begin
			    Y=A;
				 z=0;
			 end
			 else
			 begin
			    Y=B;
				 z=0;
			 end

		 B:
		    if(w==0)
			 begin
			    Y=A;
				 z=0;
			 end
			 else
			 begin
			    Y=B;
				 z=1;
			 end
	    //default: Y=1'bx;		 
	  endcase

	end

	always @(posedge clk,negedge Rst_n)
	begin
	  if(Rst_n==0)
	    y <= A;
	  else
	    y <= Y;
	end

endmodule



image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值