HDLBits118~149

本文详细介绍了有限状态机(FSM)在数字系统设计中的重要性,通过多个具体实例展示了如何使用FSM实现各种功能,包括序列检测、数据处理和通信协议等。FSM的设计涵盖了Mealy型和Moore型,以及同步和异步复位,强调了状态转换逻辑、时序逻辑和组合逻辑的结合。实例包括PS2协议解码、补码运算、序列监测和数据流控制等,深入浅出地阐述了FSM的设计思想和实现技巧。
摘要由CSDN通过智能技术生成

  从下一题开始将进入一个的状态机的学习,我将记录我的状态机的练习。

118Fsm1

module top_module(
    input clk,
    input areset,    // Asynchronous reset to state B
    input in,
    output out);//  

    parameter A=1'b0, B=1'b1; 
    reg state, next_state;
	
    always @(*) begin    // This is a combinational always block
        // State transition logic
        case(state)
            B:begin
                if(in == 0)
                    next_state <= A;
                else
                    next_state <= state;
              end
            A:begin
                if(in == 0)
                    next_state <= B;
                else
                    next_state <= state;
              end
        endcase
    end

    always @(posedge clk, posedge areset) begin    // This is a sequential always block
        // State flip-flops with asynchronous reset
        if(areset) begin
            state <= B;
        end
        else begin
            state <= next_state;
        end
    end

    // Output logic
    assign out = (state == B);

endmodule

119Fsm1s

  题目中给出的格式有点奇怪,不是三段式,其实在第一个基础上改回更加方便

// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
    input clk;
    input reset;    // Synchronous reset to state B
    input in;
    output out;//  
    reg out;

    // Fill in state name declarations

    reg [1:0] present_state, next_state;

    always @(posedge clk) begin
        if (reset) begin  
            present_state <= 2'b01;
            next_state <= 2'b10;
            out <= 1'b1;
        end else begin
            case (present_state)
                2'b01:next_state = (in == 0)?2'b10:2'b01;
                2'b10:next_state = (in == 0)?2'b01:2'b10;
            endcase

            // State flip-flops
            present_state = next_state;   

            case (present_state)
                // Fill in output logic
                2'b01:out = 1'b1;
                2'b10:out = 1'b0;
            endcase
        end
    end

endmodule

120Fsm2

  本题与第一题不同的地方是其中的状态的变化是组合逻辑,而next_state是同步变化的

module top_module(
    input clk,
    input areset,    // Asynchronous reset to OFF
    input j,
    input k,
    output out); //  

    parameter OFF=0, ON=1; 
    reg state, next_state;

    always @(*) begin
        // State transition logic
        state <= next_state;
    end

    always @(posedge clk, posedge areset) begin
        // State flip-flops with asynchronous reset
        if(areset) begin
            next_state  <= OFF;
        end
        else begin
            case(state)
                OFF:begin
                    next_state <= (j ==1)?ON:OFF;
                end
                ON:begin
                    next_state <= (k ==1)?OFF:ON;
                end
            endcase
        end
    end


    assign out = (state == ON);

endmodule

121

  改了一点点,就是改成同步复位就通过了

122Fsm3comb

module top_module(
    input in,
    input [1:0] state,
    output [1:0] next_state,
    output out); //

    parameter A=0, B=1, C=2, D=3;

    // State transition logic: next_state = f(state, in)
    always@(*) begin
        case(state)
            A:begin
                next_state = (in == 1)?B:A;
            end
            B:begin
                next_state = (in == 1)?B:C;
            end
            C:begin
                next_state = (in == 1)?D:A;
            end
            D:begin
                next_state = (in == 1)?B:C;
            end
        endcase
    end

    // Output logic:  out = f(state) for a Moore state machine
            assign out = (state == D)?1:0;

endmodule

123Fsm3onehot

module top_module(
    input in,
    input [3:0] state,
    output [3:0] next_state,
    output out); //

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

    // State transition logic: Derive an equation for each state flip-flop.
    assign next_state[A] = state[A]&~in|state[C]&~in; 
    assign next_state[B] = state[B]&in|state[D]&in|state[A]&in;
    assign next_state[C] = state[B]&~in|state[D]&~in;
    assign next_state[D] = state[C]&in;

    // Output logic: 
    assign out = (state[3] == 1);

endmodule

124Fsm3

module top_module(
    input clk,
    input in,
    input areset,
    output out); //
    
    reg [3:0] state,next_state;
	parameter A = 4'b0001;
    parameter B = 4'b0010;
    parameter C = 4'b0100;
    parameter D = 4'b1000;
    
    // State transition logic
    always@(posedge clk or posedge areset) begin
        if(areset) begin
            state <= A;
        end
        else begin
            state <= next_state;
        end
            
    end

    always@(*) begin
        case(state) 
        	A:begin
                next_state= in?B:A;
            end
            B:begin
                next_state = in?B:C;
            end
            C:begin
                next_state = in?D:A;
            end
            D:begin
                next_state = in?B:C;
            end
            default: begin
                next_state = state;
            end
        endcase
    end

    // Output
    assign out = (state == 4'b1000);

endmodule

125Fsm3也是稍加改动即可,不列出来了

126Exams/ece241 2013 q4

  题目转换为状态机如下,我觉得是基于迁移的自动机,输出当前的状态和输入有关,我的状态转换图如下(如果有什么问题,希望指出,但是二段式存在的问题是输出情况不能够明朗的进行判断,所以还是使用三段式书写。

在这里插入图片描述
  二段式仿真错误如下
在这里插入图片描述
  三段式我也是改了好多遍才仿真正确,其中难点我觉得主要在于所有的信号输出在CLK控制下输出,很容易信号早或者晚,其中状态的转换使用输入驱动会更加简单,我的答案如果采用当前状态驱动很容易出错误,所以打算看一下官方答案的书写思路。

module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output fr3,
    output fr2,
    output fr1,
    output dfr
); 
    reg [3:1] control;
    
    parameter A = 4'b0001;
    parameter B = 4'b0010;
    parameter C = 4'b0100;
    parameter D = 4'b1000;
    
    
    reg [3:0] state,next_state;
    
    always@(posedge clk)begin
        if(reset)
            state <= A;  //复位后水库的水假设为最低水平
    	else
            state <= next_state;
    end
    
    always@(*)begin
        next_state = A;
        case(s)
            3'b000:next_state = A;
            3'b001:next_state = B;
            3'b011:next_state = C;
            3'b111:next_state = D;
            default:next_state =A ;
        endcase
    end
    

    always@(posedge clk)begin
        if(reset) begin
            dfr <= 1;
        end
        else begin
            if(state > next_state)
                dfr <= 1;
            else if(state < next_state)
                dfr <= 0;
            else
                dfr <= dfr;
        end
    end
    
    always@(posedge clk)begin
        if(reset) begin
            fr3 <= 1;
            fr2 <= 1;
            fr1 <= 1;
        end
        else begin
            fr3 <= (s[1] == 0);
           	fr2 <= (s[2] == 0);
            fr1 <= (s[3] == 0);
        end
    end

endmodule

127 Lemmings1

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    output walk_left,
    output walk_right); //  

    parameter LEFT=1'b0, RIGHT=1'b1;
    reg state, next_state;
    wire [1:0]  in_bump;
    assign in_bump = {bump_left,bump_right};

    always @(*) begin
        next_state <= LEFT;
        case(state)
            LEFT:next_state <= (bump_left == 1)?RIGHT:LEFT;
            RIGHT:next_state <= (bump_right == 1)?LEFT:RIGHT;
        endcase
    end

    always @(posedge clk, posedge areset) begin
        // State flip-flops with asynchronous reset
        if(areset) begin
            state <= LEFT;
        end
        else 
            state <= next_state;
    end

    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);

endmodule

128 Lemmings2

  通过观察波形图可以看到掉落和障碍物两者,掉落的优先级高,且地方出现后虽然仍然还是有障碍物,但在原方向上还是会行走一个时钟。
  虽然掉落时不区分方向,输出只有aaah,但是着陆后的方向与掉落前方向一致,所以这里将掉落状态分为两个状态更为方便(这里是重点),即向左走的时候发生掉落left_fall和向右走的时候发生掉落right_fall状态。这样当着陆后直接返回相应的left和right状态即可。所以fall_l和fall_r状态之间也不能发生转换。状态机描述如下
在这里插入图片描述

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    output walk_left,
    output walk_right,
    output aaah ); 
    
    wire [3:1] temp;
    assign temp = {ground,bump_left,bump_right};
    reg [1:0] state,next_state;
    
    
    parameter LEFT = 2'b00;
    parameter RIGHT = 2'b01;
    parameter LEFT_FALL = 2'b10;
    parameter RIGHT_FALL = 2'b11;
    
    always@(*) begin
        next_state <= LEFT;
        case(state)
            LEFT: begin
                if(temp[3] == 0)
                    next_state <= LEFT_FALL;
                else if( temp[2] == 1)
                    next_state <= RIGHT;
                else 
                    next_state <= state;
            end
            RIGHT:begin
                if(temp[3] == 0)
                    next_state <= RIGHT_FALL;
                else if( temp[1] == 1)
                    next_state <= LEFT;
                else 
                    next_state <= state;
            end
			LEFT_FALL:begin
                if(temp[3] == 1)
                    next_state <= LEFT;
            	else
                    next_state <= LEFT_FALL;
            end
			RIGHT_FALL:begin
                if(temp[3] == 1)
                    next_state <= RIGHT;
            	else
                    next_state <= RIGHT_FALL;
            end
        endcase
    end
    
    always@(posedge clk or posedge areset) begin
        if(areset) begin
            state <= LEFT;
        end
        else
            state <= next_state;
    end
	
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign aaah = (state == LEFT_FALL || state == RIGHT_FALL);
endmodule

129Lemmings3

  考虑思路和2相似,分为六个状态,因为只有这样才能用状态区分。还需要注意的是优先级的问题,就是说FALL>dig>dump,状态图如下:
在这里插入图片描述

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    input dig,
    output walk_left,
    output walk_right,
    output aaah,
    output digging );
    
    wire [3:0] temp;
    assign temp = {dig,ground,bump_left,bump_right};
    
    reg [5:0] state,next_state;
    parameter A = 6'b000001;
    parameter B = 6'b000010;
    parameter C = 6'b000100;
    parameter D = 6'b001000;
    parameter E = 6'b010000;
    parameter F = 6'b100000;
    
    always@(posedge clk or posedge areset) begin
        if(areset) begin
            state <= A;
        end
        else
            state <= next_state;
    end
    
    always@(*) begin
        case(state) 
            A:begin
                if(temp[2] == 0 )
                    next_state <= E;
                else if(temp[3] == 1 & temp [2] ==1)
                    next_state <= C;
                else if(temp [1] == 1 )
                    next_state <= B;
                else 
                    next_state <= state;
            end
            B:begin
                if(temp[2] == 0 )
                    next_state <= F;
                else if(temp[3] == 1 & temp [2] == 1)
                    next_state <= D;
                else if(temp [0] == 1 )
                    next_state <= A;
                else 
                    next_state <= state;
            end
            C:begin
                if(temp[2] == 0)
                    next_state <=E;
                else  
                    next_state <= state;
            end
            D:begin
                if(temp[2] == 0)
                    next_state <=F;
                else 
                    next_state <= state;
            end
            E:begin
                if(temp[2] ==1)
                    next_state <= A;
                else 
                    next_state <= state;
            end
            F:begin
                if(temp[2] ==1)
                    next_state <= B;
                else 
                    next_state <= state;
            end
            default:begin
                next_state <= A;
            end
        endcase   
    end

    assign walk_left  = (state == A);
    assign walk_right = (state == B);
    assign aaah = (state == E || state == F);
    assign digging = (state == C || state == D);
    
endmodule

130Lemmings4

  本题在原有的基础上,增加的条件是如果在掉落过程中,地面出现的时间超过20个CLK,则进入死亡状态,只有复位后才能够从初态重新开始,
  所以只需要添加一个状态即可,通过判断计数是否大于20clk即可,但是这里要注意的是时钟的判断在上升沿上,所以计数要通过NEXT_STATE来计数。

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    input dig,
    output walk_left,
    output walk_right,
    output aaah,
    output digging ); 
    
    integer i;
    
	wire [3:0] temp;
    assign temp = {dig,ground,bump_left,bump_right};
    
    reg [7:0] state,next_state;
    parameter A = 7'b0000001; //left
    parameter B = 7'b0000010; //right
    parameter C = 7'b0000100; //left_dig
    parameter D = 7'b0001000; //right_dig
    parameter E = 7'b0010000; //left_fall
    parameter F = 7'b0100000; //right_fall
    parameter G = 7'b1000000; //over_20clk
    
    always@(posedge clk or posedge areset) begin
        if(areset) begin
            state <= A;
        end
        else
            state <= next_state;
    end
    
    always@(posedge clk) begin
        if(next_state == E || next_state == F) begin
            i <= i+1;
        end
        else 
            i <= 0;
    end
    
    always@(*) begin
        case(state) 
            A:begin
                if(temp[2] == 0 )
                    next_state <= E;
                else if(temp[3] == 1 & temp [2] ==1)
                    next_state <= C;
                else if(temp [1] == 1 )
                    next_state <= B;
                else 
                    next_state <= state;
            end
            B:begin
                if(temp[2] == 0 )
                    next_state <= F;
                else if(temp[3] == 1 & temp [2] == 1)
                    next_state <= D;
                else if(temp [0] == 1 )
                    next_state <= A;
                else 
                    next_state <= state;
            end
            C:begin
                if(temp[2] == 0)
                    next_state <=E;
                else  
                    next_state <= state;
            end
            D:begin
                if(temp[2] == 0)
                    next_state <=F;
                else 
                    next_state <= state;
            end
            E:begin
                if(temp[2] ==1) begin
                    if(i <= 20)
                    	next_state <= A;
               		else
                        next_state <= G;
                end
                else 
                    next_state <= state;
            end
            F:begin
               if(temp[2] ==1) begin
                    if(i <= 20)
                    	next_state <= B;
               		else
                        next_state <= G;
                end
                else 
                    next_state <= state;
            end
            G:begin
                if(areset)
                    next_state <= A;
                else
                    next_state <= G;
            end
            default:begin
                next_state <= A;
            end
        endcase   
    end

    assign walk_left  = (state == A && state != G);
    assign walk_right = (state == B && state != G);
    assign aaah = ((state == E || state == F ) && state != G);
    assign digging = ((state == C || state == D) && state != G);
            
    
endmodule

131 Fsm onehot

  本题让使用独热码,在我的理解中,独热码不能结果中出现同时为1的情况,那么在状态机中也就不如作为输入,这才能达到使用独热码的目的,便于判断,但本题的意图可能是通过单位的判断来完成状态机,这样使用assign语句更加简单,所以输入中为了加入非独热码的输入,通过assign的判断输出中也会出现同时两位有效的情况。能够SUCCESS的答案链接如下:答案
  有时候参数的以二进制定义且位数过多,可以用_来进行分割。
在这里插入图片描述

132Fsm ps2

  ps2协议的一个解码的状态机,实现的功能比较简单,只是用done信号描述了接收数据的情况,没有对数据进行接收。

    module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output done); //
    reg [2:0] state,next_state;
    
    parameter first    = 3'b001;
    parameter second   = 3'b010;
    parameter third    = 3'b100;
    

    // State transition logic (combinational)
    always@(*) begin
        case(state)
            first:begin
                if(in[3] == 1)
                	next_state <= second;
                else 
                    next_state <= first;
            end 
            second:begin
                    next_state <= third;
            end
            third: 
                next_state <= first;
            default:
                next_state <= first;   
        endcase
    end

    // State flip-flops (sequential)
    always@(posedge clk) begin
        if(reset) 
            state <= first;
        else
            state <= next_state;
    end
        
 
    always@(posedge clk) begin
        if(reset)
            done <= 0;
        else if(state == third) 
            done <= 1;
        else
            done <= 0;
    end

endmodule

133Fsm ps2data

  本题需要输出ps传输的值,状态机部分不变,只需要添加输出逻辑,这里要注意,数据的提前缓存需要的是组合逻辑,而数据的输出是时序逻辑,只有这样才能保证数据遵循规则输出。

 always@(posedge clk) begin
        if(reset)begin
            done <= 0;
        	out_bytes <= 0;
        end
        else if(state == third) begin
            done <= 1;
        	out_bytes <= temp;
        end
        else begin
            done <= 0;
        	out_bytes <= 0;
        end
    end
    always@(*) begin
        case(state)
            first:begin
                temp[23:16] <= in;
            end
            second:begin
                temp[15:8] <= in;
            end
            third:begin
                temp[7:0] <= in;
            end
        endcase
    end

134 Fsm serial

  这道题也卡了一大会,按理说不应该,说明还是对状态机的理解不深,通过这道题后,有以下注意的点,

  • next_state表征的状态总是比真实的state早一个周期,虽然next_state是组合逻辑,但next_state的状态转移是以state的变化为入口的,所以next_state也跟随时钟的变化而变化,只不过能够快速预判下一个状态是什么,然后传递给state,通过state的反馈,在进行下一步的判断
  • state的表征的状态与真实情况一直,然后state结合输入,对输出的结果进行分析
  • 输出也可以是时序逻辑
module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done
); 
    reg [3:0] count; 
    reg [3:0] state,next_state;
    
    parameter START = 4'b0001;
    parameter DATA = 4'b0010;
    parameter STOP = 4'b0100;
    parameter NONE = 4'b1000;
    
    always@(posedge clk) begin
        if(reset)
            state <= START;
        else 
            state <= next_state;
    end
        
    
    always@(posedge clk)begin
        if(reset)
            count <= 4'b0000;
        else if (next_state == DATA)
            count <= count + 1;
        else if (count == 4'b1000)
            count <= 4'b0000;
    end
    
    always@(*) begin
        case(state)
            START:begin
                if(in == 0 && reset == 0)
                    next_state <= DATA;
                else
                    next_state <= START;
            end
            DATA:begin
                if(count == 4'b1000)
                    next_state <= STOP;
                else
                    next_state <= DATA;
            end
            STOP:begin
                if(in == 1) 
                    next_state <= START;
                else
                    next_state <= NONE;
            end
            NONE:begin
                if(in == 1) 
                    next_state <= START;
                else
                    next_state <= NONE;
            end
            default:
                next_state <= START;
        endcase
    end
  
 
    always@(posedge clk) begin
        if(state == STOP && in == 1)
            done <= 1;
        else
            done <= 0;
    end
endmodule

135 Fsm serial

只需要添加输出即可

    assign out_byte = (done == 1)?out_temp:0 ;
    always@(posedge clk)begin
        if(reset)
            out_temp <= 0;
        else if (count >= 4'b0001 && count <= 4'b1000) 
            out_temp[count-1] <= in ;
    end  

136Fsm serialdp

  这个题我做的有问题,没做出来,先通过,后面在进行练习。

 1 module top_module(
 2     input clk,
 3     input in,
 4     input reset,    // Synchronous reset
 5     output [7:0] out_byte,
 6     output done
 7 ); //
 8     parameter IDLE = 4'd0, START = 4'd1, RXD = 4'd2,STOP = 4'd3,WAIT = 4'd4,PARITY = 4'd5;
 9     reg [7:0]     out_byte_reg;
10     reg [3:0]    current_state;
11     reg [3:0]    next_state;
12     wire odd;
13     wire re;
14     reg [3:0]cnt_byte;
15     
16     always@(posedge clk)begin
17         if(reset)begin
18             current_state <= IDLE;
19         end
20         else begin
21             current_state <= next_state;
22         end
23     end
24     
25     always@(*)begin
26         case(current_state)
27             IDLE:
28                 next_state = in ? IDLE : START;
29             START:
30                 next_state = RXD;
31             RXD:
32                 next_state = (cnt_byte==8)?PARITY:((cnt_byte>8)?WAIT:RXD);    //cnt_byte不会大于8(直接进入WAIT状态),可省略内层判断
33             PARITY:
34                 next_state = in ? STOP : WAIT;
35             WAIT:
36                 next_state = in ? IDLE : WAIT;
37             STOP:
38                 next_state = in ? IDLE : START;            
39             default:
40                 next_state = IDLE;
41         endcase
42     end
43     
44     always@(posedge clk)begin
45         if(reset || next_state == IDLE || next_state == START)
46             cnt_byte <= 0;
47         else if(next_state==RXD)begin                //数据data接受状态
48             out_byte_reg[cnt_byte] <= in;            //8bit数据寄存,利用计数器当位置索引        
49             cnt_byte <= cnt_byte+4'd1;
50         end
51     end
52     
53     assign re = reset || next_state == IDLE || next_state == START;    //IDLE或START为新一轮数据传输开始,奇偶校验清零信号
54     parity u_parity(
55                     .clk(clk),
56                     .reset(re),
57                     .in(in),
58                     .odd(odd)
59                     );
60  
61     assign done = (current_state==STOP)&&~odd;        //因为在STOP状态又进行奇校验反转了一次,odd取反    
62     assign out_byte = done?out_byte_reg:8'bz;
63     
64 endmodule

137Fsm hdlc

  序列监测写的是Mealy型有限状态机,当前的输出是根据当前的状态和输入决定的,但是因为要根据上升沿的状态进行判断,相比Moore型状态机,整体的状态是延迟一个时钟的。
  电路的状态表示收到连续1的个数,其中我觉得这道题中要参考的地方还有IDLE,还有DISC和FLAG信号的加入,巧妙的连接了两次序列监测之间的问题,这个我第一次写的时候考虑的不是很清楚。

module top_module(
    input clk,
    input reset,    // Synchronous reset
    input in,
    output disc,
    output flag,
    output err);
    
    
    reg [4:0] state;
    
    parameter [3:0] IDLE = 4'b0000, B1 = 4'b0001,B2 = 4'b0010,B3 = 4'b0011, B4 = 4'b0100,
    				B5 = 4'b0101,B6 = 4'b0110,C1 = 4'b0111,DISC= 4'b1000,FLAG = 4'b1001;
    
    always@(posedge clk) begin
        if(reset) begin
			state = IDLE;
        end
        else
            case(state)
                IDLE:state = in?B1:IDLE;
                B1  :state = in?B2:IDLE;
                B2  :state = in?B3:IDLE;
                B3  :state = in?B4:IDLE;
                B4  :state = in?B5:IDLE;
                B5  :state = in?B6:DISC;
                B6  :state = in?C1:FLAG;
                C1  :state = in?C1:IDLE;
                DISC:state = in?B1:IDLE;
                FLAG:state = in?B1:IDLE;
                default:state = IDLE;
        	endcase
  	end
            
    assign disc =(state == DISC);
    assign flag = (state == FLAG);
    assign err = (state == C1);

endmodule

138Exams/ece241 2013 q8

  重叠型序列检测器,题目中好像让使用三个状态,但我还是使用了4个状态。

在这里插入图片描述

module top_module (
    input clk,
    input aresetn,    // Asynchronous active-low reset
    input x,
    output z ); 
    
    reg [3:0] state;
    
    parameter [3:0] IDLE = 4'b0001,s1 = 4'b0010,s2 = 4'b0100,s3 = 4'b1000;
    
    always@(posedge clk or negedge aresetn) begin
        if(~aresetn)
            state = IDLE;
        else
            case(state)
               IDLE:state = x?s1:IDLE;
                s1: state = x?s1:s2;
                s2: state = x?s3:IDLE;
                s3: state = x?s1:s2;
                default:state = IDLE;
            endcase
    end
    
    assign z = (state == s2 && x == 1);

endmodule

139Exams/ece241 2014 q5a_Moore,补码运算

  本题刚开始的意思我刚开始还没搞清楚,看了别人的理解,本题的意思是对于不端输入的位宽变换的数据,计算新输入位所得的补码的值,和我们通常整体 计算的补码的值还有些不同,这是本题的题意。

  其实补码的运算按照本题的运算并不难,一定要用状态机的思路是解决该问题,我刚开始考虑的时候采用的是所有位的异或运算,这样难度大大加大,补码的运算有一个口诀就是,从左左至右,除过符号位为负,数据位依次取反,碰到最后一位为1时停止,举例:原码 = 8‘b0101 1101’,补码就是 =8‘b1010 0011```,通过罗列几个例子可以得到,当为输入全0,或者再输入序列中只出现了一位1,那么就是不变(出现的1就是最后的防线,不变),在出现一个1后,无论输入是0、1,都是取反,和口诀中的逻辑是一样的。通过看别人的Mealy型,发现多了一个状态,而Moore型的状态需要通过时钟判断当前的状态来确定输出。

module top_module (
    input clk,
    input areset,
    input x,
    output z); 
    
    parameter [1:0] s0 = 2'b01, s1 = 2'b10;
    reg [1:0] state;
    
    always@(posedge clk or posedge areset) begin
        if(areset) begin
            state <= s0;
        end
        else 
            case(state)
                s0:state = (x==0)?s0:s1;
                s1:state = s1;
                default:state = s0;
            endcase
    end
    
    always@(posedge clk or posedge areset)begin
        if(areset)
            z <= 1'b0;
        else if(state == s0)
    		z = x;
        else if(state == s1)
            z = !x;
        else
            z = 1'b0;
   end
endmodule

140Exams/ece241 2014 q5a_Mealy,补码运算

 &emso;Mealy型由状态和输入共同驱动,可以看到Mealy型的输出结果会立即反映到输出上,比Moore型快一个时钟,其中包含了两个always块,一个always块用clk作为敏感信号,进行状态转移,另一个always块用状态信号和输入信号作为敏感信号,因此状态和x的变化会立即反映到输出z,而不是下一个时钟的上升沿,这正好符合Mealy 型FSM的要求。
  用更加简单的话说就是,状态的转换是受时钟驱动的state和输入的变化所驱动。

module top_module (
    input clk,
    input areset,
    input x,
    output z
); 
    reg [1:0] state,STATE;
    
    parameter A = 2'b00;
    parameter B = 2'b01;
    
    always@(posedge clk or posedge areset) begin
        if(areset) begin
            state <= A;
        end
        else
            state <= STATE;
    end
        
    always@(state,x) begin
            case(state)
                A:
                    if(x)begin
                        STATE <= B;
                        z <= 1'b1;
                    end
                	else begin
                        STATE <= A;
                        z <= 1'b0;
                    end
                B:begin
                    STATE <= B;
                    z <= ~x;
                end
                default:begin
                    state <= A;
                    z <= 1'b0;
                end
            endcase
    end

endmodule

141Exams/2014 q3fsm

  本题的题意中三个输入其中需要两个为1,不是连续叠加的,这是要注意的点,需要增加一个计数的部分,同时我通过移位来更新输入的情况,功能仿真如下:
在这里插入图片描述

module top_module (
    input clk,
    input reset,   // Synchronous reset
    input s,
    input w,
    output z
);
    parameter A = 2'b00;
    parameter B = 2'b01;
    reg [1:0] count;
    reg       count_flag;
    reg [2:0] mem;
    
    reg [1:0] state; 
    
    always@(posedge clk) begin
        if(reset) begin
            state <= A;
        end
        else
            case(state)
                A:begin
                    if(s == 1'b0)
                        state <= A;
                    else
                        state <= B;
                end
                B:begin
                    state <= B;
                end
                default:begin
                    state <= A;
                end 
            endcase        
    end
    
    always@(posedge clk)begin
        if(reset)begin
            mem <= 3'b000;
        end
        else if(state == B)begin
            mem <= {mem[1:0],w}; 
        end  
    end
    

    
    always@(posedge clk)begin
        if(reset) begin
            count <= 2'b00;
            count_flag <= 1'b0;
        end
        else if(state == B)begin
            if(count == 2'b10)begin
                count <= 2'b00;
            	count_flag <= 1'b1;
            end
            else begin
          		count <=  count + 1'b1;
            	count_flag <= 1'b0;
            end
        end
    end
    
    assign z = (count_flag) ? (mem==3'b011 || mem == 3'b101 || mem == 3'b110):1'b0;   
endmodule
///仿真代码
module tb_HDB_top_module();
    reg     clk;
    reg     reset;
    reg     s;
    reg     w;
    wire    z;

    always begin
        #5 clk = ~clk;
    end

    initial begin
        clk = 0;
        reset = 1'b1;
        #15;
        reset = 1'b0;
    end

    initial begin
        s <= 1'b0;
        w <= 1'b0;
        #35
        s <= 1'b1;
        #10
        w <= 1'b1;
        #30

        w <= 1'b0;
        #5

        w <= 1'b1;
        #10

        w <= 1'b0;
        #5

        w <= 1'b1;
        #10

        w <= 1'b0;
        #5

        w <= 1'b1;
        #5

        w <= 1'b0;
        #5

        w <= 1'b1;
        #5
               
        w <= 1'b0;
        #5

        w <= 1'b1;
        #10

        w <= 1'b0;
        #5;
    end

    top_module tb_top_module(
        .clk(clk),
        .reset(reset),
        .s(s),
        .w(w),
        .z(z)
    );

endmodule


142 Exams/2014 q3bfsm

module top_module (
    input clk,
    input reset,   // Synchronous reset
    input x,
    output z
);
    reg [2:0] state,next_state;
    always@(posedge clk) begin
        if(reset)
            state <= 3'b000;
    	else
        	state <= next_state;
    end
    
    always@(*)begin
        if(reset)
            next_state <= 3'b000;
        else begin
        	case(state)
            	3'b000: next_state = (x == 1'b1)?3'b001:3'b000;
            	3'b001: next_state = (x == 1'b1)?3'b100:3'b001;
            	3'b010: next_state = (x == 1'b1)?3'b001:3'b010;
            	3'b011: next_state = (x == 1'b1)?3'b010:3'b001;
                3'b100: next_state = (x == 1'b1)?3'b100:3'b011;
                default:next_state = 3'b000;
        	endcase
        end
    end
    
    assign z = (state == 3'b011 || state == 3'b100);

endmodule

143 Exams/2014 q3c

module top_module (
    input clk,
    input [2:0] y,
    input x,
    output Y0,
    output z
);
    reg [2:0] state,next_state;
    
    always@(posedge clk) begin
        state <= next_state;
    end
        
    always@(*)begin
        case(y)
            3'b000: next_state = (x == 1'b1)?3'b001:3'b000;
            3'b001: next_state = (x == 1'b1)?3'b100:3'b001;
            3'b010: next_state = (x == 1'b1)?3'b001:3'b010;
            3'b011: next_state = (x == 1'b1)?3'b010:3'b001;
            3'b100: next_state = (x == 1'b1)?3'b100:3'b011;
            default:next_state = 3'b000;
        endcase
    end
    
    assign z = (y == 3'b011 || y == 3'b100)?1:0;
    assign Y0 = next_state[0];

endmodule

144 Exams/m2014 q6b

module top_module (
    input [3:1] y,
    input w,
    output Y2);
    
    reg [2:0] next_state;
    
    always@(y)begin
        case(y)
            3'b000:next_state <=w?3'b000:3'b001;
            3'b001:next_state <=w?3'b011:3'b010;
            3'b010:next_state <=w?3'b011:3'b100;
            3'b011:next_state <=w?3'b000:3'b101;
            3'b100:next_state <=w?3'b011:3'b100;
            3'b101:next_state <=w?3'b011:3'b010;
            default:next_state <= 3'b000;     
        endcase
    end
    
    assign Y2 = next_state[1];

endmodule

145 Exams/m2014 q6c

module top_module (
    input [6:1] y,
    input w,
    output Y2,
    output Y4);
    
    parameter A = 6'b000001,B = 6'b000010,C = 6'b000100,
    		  D = 6'b001000,E = 6'b010000,F = 6'b100000;
    reg [6:1] d,state;
    assign state  = (y == (A || B || C || D || E || F))?y:state;
    always@(state)
        begin
            case(state)
                A:d = w?A:B;
                B:d = w?D:C;
                C:d = w?D:E;
                D:d = w?A:F;
                E:d = w?D:E;
                F:d = w?D:C;
            endcase
        end
        
    assign Y2 = (y[1] & ~w) ;
    assign Y4 = (y[2] & w) | (y[3] & w) | (y[5] & w) | (y[6] & w);
endmodule

146 Exams/m2014 q6

module top_module (
    input clk,
    input reset,     // synchronous reset
    input w,
    output z);
    
    parameter A = 6'b000001,B = 6'b000010,C = 6'b000100,
    		  D = 6'b001000,E = 6'b010000,F = 6'b100000;
    
    reg [6:1] state,d;
    
    always@(*)begin
        if(reset) begin
            d <= A;
        end
    	else begin
        	case(state)
                A:d = w?A:B;
                B:d = w?D:C;
                C:d = w?D:E;
                D:d = w?A:F;
                E:d = w?D:E;
                F:d = w?D:C;
                default: d <= A;
            endcase
        end   
    end

    always@(posedge clk)begin
        if(reset) begin
            state <= A;
        end
    	else 
        	state <= d;
    end

    assign z = (state == E || state == F);
endmodule

147 exams/2012_q2b

module top_module (
    input [5:0] y,
    input w,
    output Y1,
    output Y3
);
    parameter A = 6'b000001,B = 6'b000010,C = 6'b000100,
    		  D = 6'b001000,E = 6'b010000,F = 6'b100000;
    
    reg [5:0] d;
    always@(*)begin
        case(y)
        	A:d = w?B:A;
            B:d = w?C:D;
            C:d = w?E:D;
            D:d = w?F:A;
            E:d = w?E:D;
            F:d = w?C:D;
        endcase
    end
            
    assign Y1 =y[0]&w;
    assign Y3 =(y[1]|y[2]|y[4]|y[5])&~w;
endmodule

148 Exams/2013 q2afsm

module top_module (
    input clk,
    input resetn,    // active-low synchronous reset
    input [3:1] r,   // request
    output [3:1] g   // grant
); 
    reg [3:0] state,next_state;
    reg out1,out2,out3;
    
    parameter S0 = 4'b0001,S1 = 4'b0010,S2 = 4'b0100,S3 = 4'b1000;
    
    always@(*) begin
        if(resetn == 1'b0) begin
        	next_state <= S0;
        end
        else begin
            case(state)
                 S0:begin
                     if(r[1])
                         next_state <= S1;
                     else if(r[2])
                         next_state <= S2;
                     else if(r[3])
                         next_state <= S3;
                     else
                         next_state <= S0;
                 end
                 S1:begin
                     if(r[1])
                         next_state <= S1;
                     else 
                          next_state <= S0;
                 end
                 S2:begin
                     if(r[2])
                         next_state <= S2;
                     else 
                         next_state <= S0;
                 end
                 S3:begin
                     if(r[3])
                         next_state <= S3;
                     else 
                         next_state <= S0;
                 end
                 default: next_state <= S0;
            endcase
    	end
    end
    
    always@(posedge clk) begin
        if(resetn == 1'b0) begin
            state <= S0;
        end
        else 
            state <= next_state;
    end
    
            
    assign out1 = (state == S1);
    assign out2 = (state == S2);
    assign out3 = (state == S3);
   	assign g = {out3,out2,out1};
    

endmodule

149 Exams/2013 q2afsm

module top_module (
    input clk,
    input resetn,    // active-low synchronous reset
    input x,
    input y,
    output reg  f,
    output    g
); 
    parameter RESET = 0,A = 1,B = 2, C=  3,D = 4;
    parameter S0 = 5, S1 = 6, S2 = 7,ERROR = 8;
    
    reg [3:0] state,state_next;
    reg in_reg;

    always@(posedge clk)begin
        in_reg <= resetn;
    end

    wire mid_pos = ~in_reg & resetn;

    always@(posedge clk) begin
        if(resetn == 1'b0)
            f <= 1'b0;
        else if(mid_pos)
            f <= 1'b1;
        else
            f <= 1'b0;
    end

    always @(posedge clk) 
        begin
            if (!resetn) state <= RESET;
            else 		 state <= state_next;
        end


    always @(*) begin
        if(resetn == 1'b0)
            state_next <= RESET;
        else 
            case (state)
                RESET : begin
                    if (resetn == 1'b1) state_next <= A;
                    else    state_next <= RESET;
                end
                A : begin
                    state_next <= B;
                end
                B: begin
                    if(x) state_next <= C;
                    else state_next <= B;
                end
                C : begin
                    if (!x) state_next <= D;
                    else    state_next <= C;
                end
                D : begin
                    if (x) state_next <= S0;
                    else   state_next <= B;
                end
                S0 : begin
                    if (y) state_next <= S2;
                    else   state_next <= S1;
                end
                S1 : begin
                    if (y) state_next <= S2;
                    else 	state_next <= ERROR;
                end
                S2:
                    state_next <= S2;
                ERROR: 
                    state_next <= ERROR;
            endcase
    end
assign g = (state == S0) | (state == S1) | (state == S2);
endmodule

  仿真文件,以及功能仿真结果,但我决定
在这里插入图片描述

`timescale 1ns / 1ps
module tb_top( );
    reg clk;
    reg resetn;
    reg x;
    reg y;
    wire f;
    wire g;
    
    initial begin
        clk = 0;
        resetn = 1'b1;
        #4;
        resetn = 1'b0;
        #4 resetn = 1'b1;
    end

    initial begin
        x = 1;
        #10
        @(posedge clk);
        x = 0;
        #2 
        x = 1;
        #4
        x = 0;
        #6
        x = 1;
        #4
        x = 0;
        #12
        x = 1;
        #2
        x =0;
        #2
        x = 1;
        #2
        x =0;
        #4
        x =1;
        #4
        x =0;
        #2
        x =1;
        #6
        x =0;
        #2
        x =1;
        #4;
        x =0;
        #2;
    end

    initial begin
        y = 0;
        #10
        @(posedge clk);
        y = 1;
        #4
        y = 0;
        #2
        y = 1;
        #4
        y = 0;
        #2
        y = 1;
        #4
        y = 0;
        #2
        y = 1;
        #2
        y = 0;
        #2
        y = 1;
        #2
        y = 0;
        #4
        y = 1;
        #2
        y = 0;
        #2
        y = 1;
        #4
        y = 0;
        #2
        y = 1;
        #2
        y = 0;
        #8
        y = 1;
        #4
        y = 0;
        #2
        y = 1;
        #2
        y = 0;
        #2;
        y = 1;
        #2;
    end




    always begin
        #2 clk = ~clk;
    end

    top1_module tb_top1_module(
        .clk(clk),
        .resetn(resetn),
        .x(x),
        .y(y),
        .f(f),
        .g(g)

    );



endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值