zoukankan      html  css  js  c++  java
  • 状态机实例-寄存器拷贝

          在计算机系统中,有大量的寄存器,用来保存运行过程中的数据。如果要交换两个寄存器的内容,则通常会使用第三个寄存器为临时寄存器的方法。比如,假设要交换寄存器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















































  • 相关阅读:
    0593. Valid Square (M)
    0832. Flipping an Image (E)
    1026. Maximum Difference Between Node and Ancestor (M)
    0563. Binary Tree Tilt (E)
    0445. Add Two Numbers II (M)
    1283. Find the Smallest Divisor Given a Threshold (M)
    C Primer Plus note9
    C Primer Plus note8
    C Primer Plus note7
    C Primer Plus note6
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/10294647.html
Copyright © 2011-2022 走看看