HDLbits答案更新系列12(3.2.5 Finite State Machines 3.2.2.5 Simple state transitions 3等 )

目录

前言

3.2.5 Finite State Machines

3.2.5.5 Simple state transitions 3(Fsm3comb)

3.2.5.6 Simple one-hot state transitions 3(Fsm3onehot)

3.2.5.7 Simple FSM 3 (asynchronous reset)(Fsm3)

3.2.5.8 Simple FSM 3 (synchronous reset)(Fsm3s)

3.2.5.9 Design a Moore FSM (Exams/ece241 2013 q4)

结语

HDLbits网站链接


前言

今天接着更新状态机部分的习题答案。

3.2.5 Finite State Machines

3.2.5.5 Simple state transitions 3(Fsm3comb)

HDLbits答案更新系列12(3.2.5 Finite State Machines 3.2.2.5 Simple state transitions 3等 )_第1张图片

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

    parameter A=2'd0, B=2'd1, C=2'd2, D=2'd3;
	
    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
        endcase
    end
    
    always@(*)begin
        if(state == D)begin
            out <= 1'b1;
        end
        else begin
            out <= 1'b0;
        end
    end          

endmodule

这道题目作者已经给出了状态转移表,直接按照转移表写出verilog设计就好了。

3.2.5.6 Simple one-hot state transitions 3(Fsm3onehot)

HDLbits答案更新系列12(3.2.5 Finite State Machines 3.2.2.5 Simple state transitions 3等 )_第2张图片

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

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

    // 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[A] & in | state[B] & in | state[D] & in;
    assign next_state[C] = state[B] & ~in | state[D] & ~in;
    assign next_state[D] = state[C] & in;

    // Output logic: 
    assign out = state[D];

endmodule

这道题目作者是想让我们用one-hot(独热码)的编码逻辑完成。不过大家也注意到了,该题和我们平时使用的one-hot逻辑不同,我们平时使用的one-hot逻辑实在parameter中定义,比如定义四个状态,那么分别是4'b0001、4'b0010、4'b0100、4'b1000,,这道题目中的parameter还是定义为十进制的1、2、3、4,因为这里作者将输入状态和输出状态都定义为4bit,所以1、2、3、4位定义着state和next_state的4位。

大家要注意,一般我们的状态机编码为了方便都是设置为二进制码,但是如果是状态转移是按顺序转移的话,那么我们可以使用格雷码,因为格雷码每次只变化一个bit,这样可以节约功耗。如果要说速度快,那么可以使用one-hot编码,因为每次仅需判断一位就可以了,当然这种编码会消耗更多的寄存器资源,但是消耗更少的组合逻辑资源。关于这一点,不知道大家还记不记得3-8译码器,one-hot编码可以认为是已经进行过译码的编码单元,所以相比二进制编码和格雷码更节约组合逻辑资源。

如果状态较少,建议大家使用one-hot编码,如果状态较多,建议大家使用格雷码,如果功耗的影响不是那么大并且为了尽快完成设计,建议直接使用二进制编码就好了。

3.2.5.7 Simple FSM 3 (asynchronous reset)(Fsm3)

module top_module(
    input clk,
    input in,
    input areset,
    output out); //

    parameter A=2'd0, B=2'd1, C=2'd2, D=2'd3;
    reg [1:0]	current_state;
    reg [1:0]	next_state;
    
    always@(posedge clk or posedge areset)begin
        if(areset)begin
            current_state <= A;
        end
        else begin
            current_state <= next_state;
        end
    end
    
    always@(*)begin
        case(current_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
        endcase
    end
    
    always@(*)begin
        if(current_state == D)begin
            out <= 1'b1;
        end
        else begin
            out <= 1'b0;
        end
    end

endmodule

和上题一样,只不过加上了时钟,这里注意,这道题目要求异步复位。

3.2.5.8 Simple FSM 3 (synchronous reset)(Fsm3s)

module top_module(
    input clk,
    input in,
    input reset,
    output out); //

parameter A=2'd0, B=2'd1, C=2'd2, D=2'd3;
    reg [1:0]	current_state;
    reg [1:0]	next_state;
    
    always@(posedge clk)begin
        if(reset)begin
            current_state <= A;
        end
        else begin
            current_state <= next_state;
        end
    end
    
    always@(*)begin
        case(current_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
        endcase
    end
    
    always@(*)begin
        if(current_state == D)begin
            out <= 1'b1;
        end
        else begin
            out <= 1'b0;
        end
    end

endmodule

和上题相同,只不过这里换成了同步复位。

3.2.5.9 Design a Moore FSM (Exams/ece241 2013 q4)

HDLbits答案更新系列12(3.2.5 Finite State Machines 3.2.2.5 Simple state transitions 3等 )_第3张图片

module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output fr3,
    output fr2,
    output fr1,
    output dfr
); 
    
    parameter IDLE = 3'd0, SENSOR_1 = 3'd1;
    parameter SENSOR_2 = 3'd2, SENSOR_3 = 3'd3;
    reg	[2:0]	current_state;
    reg [2:0]	next_state;
    
    always@(posedge clk)begin
        if(reset)begin
            current_state <= 'd0;
        end
        else begin
            current_state <= next_state;
        end
    end
    
    always@(*)begin
        case(current_state)
            IDLE:begin
                case(s)
                    3'b001:begin
                        next_state = SENSOR_1;
                    end
                    3'b011:begin
                        next_state = SENSOR_2;
                    end
                    3'b111:begin
                        next_state = SENSOR_3;
                    end
                    default:begin
                        next_state = IDLE;
                    end
                endcase
                //next_state = (s == 3'b001) ? SENSOR_1 : IDLE;
            end
            SENSOR_1:begin
                case(s)
                    3'b001:begin
                        next_state = SENSOR_1;
                    end
                    3'b011:begin
                        next_state = SENSOR_2;
                    end
                    3'b111:begin
                        next_state = SENSOR_3;
                    end
                    default:begin
                        next_state = IDLE;
                    end
                endcase
                //next_state = (s == 3'b011) ? SENSOR_2 : IDLE;
            end
            SENSOR_2:begin
                case(s)
                    3'b001:begin
                        next_state = SENSOR_1;
                    end
                    3'b011:begin
                        next_state = SENSOR_2;
                    end
                    3'b111:begin
                        next_state = SENSOR_3;
                    end
                    default:begin
                        next_state = IDLE;
                    end
                endcase
                //next_state = (s == 3'b111) ? SENSOR_3 : IDLE;
            end
            SENSOR_3:begin
                case(s)
                    3'b001:begin
                        next_state = SENSOR_1;
                    end
                    3'b011:begin
                        next_state = SENSOR_2;
                    end
                    3'b111:begin
                        next_state = SENSOR_3;
                    end
                    default:begin
                        next_state = IDLE;
                    end
                endcase
                //next_state = (s == 3'b011) ? SENSOR_2 : ( (s == 3'b001) ? SENSOR_1 : IDLE );
            end
            default:begin
                next_state = IDLE;
            end
        endcase
    end
    
    assign fr3 = (current_state == IDLE);
    assign fr2 = (current_state == IDLE || current_state == SENSOR_1);
    assign fr1 = (current_state == IDLE || current_state == SENSOR_1 || current_state == SENSOR_2);
    //assign dfr = (current_state == SENSOR_2 && next_state == SENSOR_1 || current_state == SENSOR_3 && next_state == SENSOR_1 || current_state == SENSOR_3 && next_state == SENSOR_2);

    
    reg fr3_reg;
    reg fr2_reg;
    reg fr1_reg;
    always@(posedge clk)begin
        fr3_reg <= fr3;
    end
    always@(posedge clk)begin
        fr2_reg <= fr2;
    end
    always@(posedge clk)begin
        fr1_reg <= fr1;
    end
    
    //assign dfr = ~fr3 & fr3_reg | ~fr2 & fr2_reg | ~fr1 & fr1_reg ? 1'b0 : 1'b1;
    
    always@(*)begin
        if(~fr3 & fr3_reg | ~fr2 & fr2_reg | ~fr1 & fr1_reg)begin
        	dfr = 1'b0;
    	end
        else if(fr3 & ~fr3_reg | fr2 & ~fr2_reg | fr1 & ~fr1_reg)begin
            dfr = 1'b1;
        end
    end  
    
endmodule

/*
//second way
module top_module (
	input clk,
	input reset,
	input [3:1] s,
	output reg fr3,
	output reg fr2,
	output reg fr1,
	output reg dfr
);


	// Give state names and assignments. I'm lazy, so I like to use decimal numbers.
	// It doesn't really matter what assignment is used, as long as they're unique.
	// We have 6 states here.
	parameter A2=0, B1=1, B2=2, C1=3, C2=4, D1=5;
	reg [2:0] state, next;		// Make sure these are big enough to hold the state encodings.
	


    // Edge-triggered always block (DFFs) for state flip-flops. Synchronous reset.	
	always @(posedge clk) begin
		if (reset) state <= A2;
		else state <= next;
	end



    // Combinational always block for state transition logic. Given the current state and inputs,
    // what should be next state be?
    // Combinational always block: Use blocking assignments.    
	always@(*) begin
		case (state)
			A2: next = s[1] ? B1 : A2;
			B1: next = s[2] ? C1 : (s[1] ? B1 : A2);
			B2: next = s[2] ? C1 : (s[1] ? B2 : A2);
			C1: next = s[3] ? D1 : (s[2] ? C1 : B2);
			C2: next = s[3] ? D1 : (s[2] ? C2 : B2);
			D1: next = s[3] ? D1 : C2;
			default: next = 'x;
		endcase
	end
	
	
	
	// Combinational output logic. In this problem, a procedural block (combinational always block) 
	// is more convenient. Be careful not to create a latch.
	always@(*) begin
		case (state)
			A2: {fr3, fr2, fr1, dfr} = 4'b1111;
			B1: {fr3, fr2, fr1, dfr} = 4'b0110;
			B2: {fr3, fr2, fr1, dfr} = 4'b0111;
			C1: {fr3, fr2, fr1, dfr} = 4'b0010;
			C2: {fr3, fr2, fr1, dfr} = 4'b0011;
			D1: {fr3, fr2, fr1, dfr} = 4'b0000;
			default: {fr3, fr2, fr1, dfr} = 'x;
		endcase
	end
*/

这道题目,建议大家认真读几遍题目,博主也是读了几遍题目才弄清楚作者的意图。博主想到的答案是答案一,作者给出的答案是答案二,建议大家使用作者给出的答案,博主的答案太繁琐了,最后还使用了边沿检测来判断dfr,实在是不如作者给出的简洁,不过博主还是厚脸皮地把自己的答案放上去吧,供大家参考。

之后博主会单独出一期边沿检测的相关知识供大家学习,边沿检测的应用实在是太广泛了,不得不重视这部分内容。

结语

今天更新这几道题目吧,重点是one-hot编码的部分,这部分在实际应用以及笔试面试中算是常考题目,包括one-hot编码的优缺点等等,希望大家可以掌握。

HDLbits网站链接

https://hdlbits.01xz.net/wiki/Main_Page

你可能感兴趣的:(HDLbits答案更新系列12(3.2.5 Finite State Machines 3.2.2.5 Simple state transitions 3等 ))