05状态机实现八位移位寄存器与验证

一是设计功能:

       在程序中设计了8位的移位寄存器,在Idle状态下,判断shift_start信号是否为高,如果为高,进入Start状态,在Start状态延迟100个周期,进入Run状态,进行移位处理,如果shift_stop信号有效了,进入Stop状态,在Stop状态,清零q的值,再跳转到Idle状态。

二是设计输入:

module shift_8

(

    input shift_start,

    input shift_stop,

    input rst_n,

    input clk,

    input d,

    output reg [7:0] q

);

    parameter Idle = 2'd0 ; //Idle state

    parameter Start = 2'd1 ; //Start state

    parameter Run = 2'd2 ; //Run state

    parameter Stop = 2'd3 ; //Stop state

    reg [1:0] current_state ; //statement

    reg [1:0] next_state ; //statement

    reg [6:0] delay_cnt ; //delay counter

 

    always@(posedge clk or negedge rst_n)

    if(!rst_n)

        current_state<=Idle;

        else

            current_state<=next_state;

           

    always@(*)

    begin

    case(current_state)

        Idle:

        begin

        if(shift_start)

            next_state<=Start;

        else

            next_state<=Idle;

            end

           

    Start:

        begin

        if(delay_cnt==7'd99)

            next_state<=Run;

            else

                next_state<=Start;

                end

               

    Run:

        begin

            if(shift_stop)

                next_state<=Stop;

            else

                next_state<=Run;

                end

               

    Stop:

        begin

        next_state<=Idle;

        end

    default:next_state<=Idle;

        endcase

    end

 

    //count to 99,timer,,delay_cnt module

 

    //  current_state==Start,条件是当前状态是多少,输出多少 

    always@(posedge clk or negedge rst_n)

    if(!rst_n)

        delay_cnt<=7'd0;

        else if(current_state==Start)

            delay_cnt<=delay_cnt+1'b1;

           

        else

            delay_cnt<=7'd0;

           

    //  current_state==Start,条件是当前状态是多少,输出多少 

    always@(posedge clk or negedge rst_n)

    if(!rst_n)

        q<=8'd0;

        else if(current_state==Run)

            q<={q[6:0],d};

           

        else

            q<=8'd0;

           

            endmodule

设计方法是三段式状态机,且移位方式有两种,位移运算符<<和位拼接符,本设计采用后者。

  • 三段式:用三个always模块来描述状态机。其中一个模块采用同步时序逻辑电路描述状态转移另一个模块采用组合逻辑判断状态转移条件(注意和两段式的区别)。第三个模块描述状态的输出(既可以用组合逻辑也可以用时序逻辑)

 下面是testbench仿真设计代码:

 

//第一行为时间尺度预处理指令,(设置)时间单位与时间精度

//attion..

`timescale 1ns/1ns

//激励文件的名称

module shift_8_tb();

//下面为激励文件的信号的定义

 

reg shift_start ;

reg shift_stop ;

reg rst ;

reg clk ;

reg d ;

//注意点:输入定义为reg,,寄存器型,输出定义为wire

wire [7:0] q ;

//

shift_8 shift_8i (

// port map - connection between master ports and signals/registers  

    .clk(clk),

    .d(d),

    .q(q),

    .rst_n(rst),

    .shift_start(shift_start),

    .shift_stop(shift_stop)

);

 

//激励文件的例化,设置激励的初始值,其他值(其他情况)

//$random(seed),随机数产生函数,seed是参数值

initial

begin

rst = 0 ;

clk = 0 ;

d = 0 ;

#20 rst = 1 ;

forever

begin

#({$random}%100)

d = ~d ;

end

end

 

 

initial

begin

shift_start = 0 ;

shift_stop = 0 ;

#300 shift_start = 1 ;

#2020 shift_start = 0 ;

#2000  shift_stop = 1 ;

#50 shift_stop = 0 ;

$stop;

end

 

 

always #10 clk = ~clk ;

 

endmodule

 

 

 

仿真代码解释: 随机延时0-99ns后,通过调用随机函数$random产生这个延时,再取反一位的移位值。通过(shift_start维持高电平超过100个周期)延时足够的100个时钟周期进入run状态(进行移位操作)在run状态保持一段时间,进入stop状态,仿真结束。

仿真波形如下:

 总结:通过今天这个8位移位寄存器的设计:收获有两个,一是三段式状态机:时序逻辑描述状态转移,组合逻辑判断状态转移条件,描述状态的输出。

二是移位操作:位拼接符实现。q<={q[6:0],d};或po_a <= {po_a[6:0],po_a[7]};

移位运算符:po_a <= po_a<<1;(注意多一个:

else if(po_a == 8'b1000_0000)
po_a <= 8'b0000_0001;

原文地址:https://www.cnblogs.com/Xwangzi66/p/12836755.html