• 状态机实例-寄存器拷贝


          在计算机系统中,有大量的寄存器,用来保存运行过程中的数据。如果要交换两个寄存器的内容,则通常会使用第三个寄存器为临时寄存器的方法。比如,假设要交换寄存器R1,R2的内容,可以先将R2的内容传递到第三个寄存器R3,然后将R1的内容传到R2,最后将R3的内从传递到R1。

          计算机系统的存储器通常是通过下图所示的内部网络互联的。除了与网络互联的信号线,每个寄存器还有两个控制信号,Rkout和Rkin。Rkout使得寄存器Rk的内容传输至互联网络,Rkin信号使得互联网络上的数据传输至寄存器Rk。Rkout和Rkin通过有限状态机控制电路产生。在下图电路中,我们设计当w=1时候,交换寄存器R1和R2的内容,数据交换完成时候输出Done信号。Clock是时钟信号。

    image


          数据转换过程如下步骤:控制信号R2out=1,R3in=1, R2的内容传到到R3,然后R1out=1,R2in=1,R1的内容传输到R2,最后,R3out=1,R1in=1,R3的内容传输到R1,完成两个寄存器内容交换,交换完成后,设置信号Done=1。假设交换的初始条件是产生一个时钟周期的脉冲信号,则时序电路状态图如下。

          初始状态A中,没有信号传输,所有的输出信号为0,电路一直保持该状态,直到w变为1产生交换请求。在状态B中,执行R2的内容传输到R3中的请求信号生效,数据在下一个时钟有效沿传送至R3。不管w为0或者1,在这个时钟沿也使得状态进入C。在状态C中,执行R1的内容传输到R2中的请求信号生效,数据在下一个时钟有效沿传送至R2。不管w为0或者1,在这个时钟沿也使得状态进入D。在状态D中,执行R3的内容传输到R1中的请求信号生效,数据在下一个时钟有效沿传送至R1。不管w为0或者1,在这个时钟沿也使得状态进入A。


    image

          由于有4个状态,所以需要2个状态变量y1,y2,最直接的分配是将状态A,B,C,D分别分配为y2y1=00,01,10,11。下面的是该电路的状态表


    现在状态 下一状态 输出
    w=0 w=1 R1out R1in R2out R2in R3out R3in Done
    A A B 0 0 0 0 0 0 0
    B C C 0 0 1 0 0 1 0
    C D D 1 0 0 1 0 0 0
    D A A 0 1 0 0 1 0 1


    现在状态 下一状态 输出
    w=0 w=1
    y2y1 Y2Y1 Y2Y1 R1out R1in R2out R2in R3out R3in Done
    A 00 00 01 0 0 0 0 0 0 0
    B 01 10 10 0 0 1 0 0 1 0
    C 10 11 11 1 0 0 1 0 0 0
    D 11 00 00 0 1 0 0 1 0 1


    Y1 Y1=w~y1+y2~y1
    w/y2y1 00 01 11 10
    0 0 0 0 1
    1 1 0 0 1
    Y2 Y2=~y2y1+y2~y1
    w/y2y1 00 01 11 10
    0 0 1 0 1
    1 0 1 0 1

    image

    image

    根据这些状态表,我们可以得到如下的输出表达式:

    Y1=w~y1+y2~y1

    Y2=~y2y1+y2~y1

    R2out=R3in=~y2y1

    R1out=R2in=y2~y1

    R1in=R3out=Done=y2y1

    实现的时序电路如下:

    image


    如果我们用10表示D,11表示C,则状态表如下:

    现在状态 下一状态 输出
    w=0 w=1
    y2y1 Y2Y1 Y2Y1 R1out R1in R2out R2in R3out R3in Done
    A 00 00 01 0 0 0 0 0 0 0
    B 01 11 11 0 0 1 0 0 1 0
    C 11 10 10 1 0 0 1 0 0 0
    D 10 00 00 0 1 0 0 1 0 1


    Y1的真值表:

    w/y2y1 00 01 11 10
    0 0 1 0 0
    1 1 1 0 0

    image

    Y2的真值表:

    w/y2y1 00 01 11 10
    0 0 1 1 0
    1 0 1 1 0


    image

    通过卡诺图简化,最终得到如下表达式,相比上面的表达式,这个实现方式要简单一点。

    Y1=w~y2+~y2y1=(w+y1)~y2

    Y2=y1

    R2out=R3in=~y2y1

    R1out=R2in=y2y1

    R1in=R3out=Done=y2~y1

    实现的电路图如下:


    image


    如果用独热码表示状态,则需要四个触发器。用独热码表示的状态表为:


    现在状态 下一状态 输出
    w=0 w=1
    y4y3y2y1 Y4Y3Y2Y1 Y4Y3Y2Y1 R1out R1in R2out R2in R3out R3in Done
    A 0001 0001 0010 0 0 0 0 0 0 0
    B 0010 0100 0100 0 0 1 0 0 1 0
    C 0100 1000 1000 1 0 0 1 0 0 0
    D 1000 0001 0001 0 1 0 0 1 0 1

          我们可以从状态框图中推导出输出表达式:

          不包括复位,有两个弧线进入状态A,这两个弧线表明,如果FSM已经在状态A,且w=0时,触发器y1应该被设置为1,或者FSM已经在状态D,所以Y1=~wy1+y4,同理,如果现在状态时A,且w=1,则触发器y2被设置为1,从而Y2=wy1,如果当前状态是B或C,触发器y3和y4分别被设置为1,从而Y3=y2,Y4=Y3。输出表达式如下:


    R1out=R2in=y3

    R1in=R3out=Done=y4

    R2out=R3in=y2

         通常用独热码表示,虽然用的触发器数量可能增多,但得到的输出表达式则相对简单,相应组合电路的实现变得简单了。


    image


    采用独热码的实现电路为:

    image





          moore型寄存器交换的verilog代码如下:

    module st_moore(clk, Rst_n, w, R1in,R1out,R2in,R2out,R3in,R3out,Done);
      input clk;
      input Rst_n;
      input w;
      output R1in,R1out,R2in,R2out,R3in,R3out,Done;
      reg [1:0] y,Y;
      parameter [1:0] A=2'b00,B=2'b01,C=2'b10,D=2'b11;
    
      //得到下一个状态的组合电路
      always @(w,y) begin
    
        case(y)
    	   A:
    	   	if(w)
    			  Y=B;
    			else
    			  Y=A;
    		B: Y=C;
    		C: Y=D;
    		D: Y=A;
    	 endcase
      end
    
      always @(posedge clk, negedge Rst_n)
        if(Rst_n==0)
    	   y<=A;
    	 else
    	   y<=Y;
    
      //定义输出
      assign R2out=(y==B);
      assign R3in=(y==B);
      assign R1out=(y==C);
      assign R2in=(y==C);
      assign R3out=(y==D);
      assign R1in=(y==D);
      assign Done=(y==D);
    
    endmodule

    testbench代码:

    `timescale 1ns/1ns
    `define clock_period 20
    
    module regswap_tb;
    
      reg clk=0;
      reg Rst_n;
      reg w;
      wire R1in,R1out,R2in,R2out,R3in,R3out,Done;
    
      st_moore st_moore0(.clk(clk),.Rst_n(Rst_n),.w(w),.R1in(R1in),.R1out(R1out),.R2in(R2in),.R2out(R2out),.R3in(R3in),.R3out(R3out),.Done(Done));
      always #(`clock_period/2) clk=~clk;
    
      initial begin
        Rst_n=1;
    	 w=0;
    	 #(`clock_period)
    	 w=1;
    	 Rst_n=0;
    	 #(`clock_period)
    	 Rst_n=1;
    	 #(`clock_period*20)
    	 $stop;
    
      end
    
    
    
    endmodule


    生成的波形图为:

    image


          mealy型寄存器交换状态机如下,状态A仍为复位状态,只要w从0变为1,输出控制信号R2out,R3in就被置位。它们将保持置位直到下一个时钟周期电路离开状态A,进入状态B。在状态B中,不管w=0或是1,输出控制信号R1out,R2in都被置位,最后,在状态C中,通过R3out=1,R1in=1完成交换,并置位Done=1。与moore时钟电路相比,mealy型实现的信号输出要早一个时钟周期。因为有3个状态,所以也需要2个触发器。

          如果采用独热码,则需要3个触发器。状态A,B,C分别取值为y3y2y1=001,y3y2y1=010,y3y2y1=100,类似moore型独热码信号输出公式,我们也可以得到mealy信号输出公式:

         Y1=~wy1+y3

         Y2=wy1

         Y3=y2

         R1out=R2in=y2

         R1in=R3out=Done=y3

         R2out=R3in=y1

    image



    mealy型的寄存器交换verilog代码为

    module st_mealy(clk, Rst_n, w, R1in,R1out,R2in,R2out,R3in,R3out,Done);
      input clk;
      input Rst_n;
      input w;
      output reg R1in,R1out,R2in,R2out,R3in,R3out,Done;
      reg [1:0] y,Y;
      parameter [1:0] A=2'b00,B=2'b01,C=2'b10;
    
      //得到下一个状态的组合电路
      always @(w,y) begin
    
        case(y)
    	   A:
    	   	if(w) begin
    			  Y=B;
    			  R2out=1;
    			  R3in=1;
    			  R3out=0;
    		     R1in=0;
    		     Done=0;
    			end
    			else
    			  Y=A;
    		B:
    		begin
    		  Y=C;
    		  R2out=0;
    		  R3in=0;
    		  R1out=1;
    		  R2in=1;
    		end
    		C:
    		begin
    		  Y=A;
    		  R1out=0;
    		  R2in=0;
    		  R3out=1;
    		  R1in=1;
    		  Done=1;
    		end
    		default:
    		begin
    		  Y=2'bxx;
    		  R2out=1'bx;
    		  R3in=1'bx;
    		  R1out=1'bx;
    		  R2in=1'bx;
    		  R3out=1'bx;
    		  R1in=1'bx;
    		  Done=1'bx;
    		end
    	 endcase
      end
    
      always @(posedge clk, negedge Rst_n)
        if(Rst_n==0)
    	   y<=A;
    	 else
    	   y<=Y;
    
    
    endmodule

    testbench代码为

    `timescale 1ns/1ns
    `define clock_period 20
    
    module regswap_tb;
    
      reg clk=0;
      reg Rst_n;
      reg w;
      wire R1in,R1out,R2in,R2out,R3in,R3out,Done;
    
        st_mealy st_mealy0(.clk(clk),.Rst_n(Rst_n),.w(w),.R1in(R1in),.R1out(R1out),.R2in(R2in),.R2out(R2out),.R3in(R3in),.R3out(R3out),.Done(Done));
    
      always #(`clock_period/2) clk=~clk;
    
      initial begin
        Rst_n=1;
    	 w=0;
    	 #(`clock_period)
    	 w=1;
    	 Rst_n=0;
    	 #(`clock_period)
    	 Rst_n=1;
    	 #(`clock_period*20)
    	 $stop;
    
      end
    

    image















































  • 相关阅读:
    JavaScript函数基础知识
    The type 'Expression<>' is defined in an assembly that is not referenced.You must add a reference to assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
    不可不知的表达式树(2)创建动态查询
    ABP给WebApi添加性能分析组件Miniprofiler
    不可不知的表达式树(3)定制IQueryProvider
    ABP使用Miniprofiler监测EF
    使用Type.MakeGenericType,反射构造泛型类型
    在ABP的Web层中实现复杂请求跨域访问
    不可不知的表达式树(1)Expression初探
    ajax实现无刷新编辑表格,两个demo
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/10294647.html
Copyright © 2020-2023  润新知