HDLBits FSM

Rule90

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output [511:0] q );
    always@(posedge clk)
        begin
            if(load)
                q <= data;
            else
                q <= {1'b0,q[511:1]} ^ {q[510:0],1'b0};//右移异或左移
        end
endmodule

Rule110

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output [511:0] q
); 
    
     always@(posedge clk)begin
        if(load)begin
            q <= data;
        end
        else begin
            q <= ~((~q & ~{q[510:0],1'b0}) | (q & {q[510:0],1'b0} & {1'b0,q[511:1]}));
        end
     end

endmodule

Conwaylife

这个生命游戏暂时没有搞明白,后面再做

simple FSM1

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

    parameter A=0, B=1; 
    reg state, next_state;

    always@(posedge clk or posedge areset)
        begin
            if(areset)
                state <= B;
            else
                state <= next_state;
        end
    always@(*)
        begin
            case(state)
                B: next_state = in ? B : A;
                A: next_state = in ? A : B;
                default: next_state = B;
            endcase
        end
    assign out = state==B ? 1 : 0;

endmodule

后面几个和这个是类似的,就不重复写 了

Fsm3comb

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;
    always@(*)
        begin
            case(state)
                A: next_state = in ? B : A;
                B: next_state = in ? B : C;
                C: next_state = in ? D : A;
                D: next_state = in ? B : C;
                default: next_state = A;
            endcase
        end
    assign out = state==D ? 1'b1 : 1'b0;

endmodule

Fsm3-onehot

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

Design a moor FSM(Exams/ece241 2013 q4)

一开始没有搞懂题的意思是什么。搞懂意思才能知道状态转化
大概可以这么理解一下,有一个水池a,有s1,s2,s3三个传感器作为输入信号,用来指示水位的高低。然后有两个输出信号,相当于两个水池b,c,水位不足时,要从这两个水池向原来的水池a加水,然后根据传感器的状态不同,选择是从b和c哪一个水池向a水池加。
在这里插入图片描述
根据图表,可知状态变化。s[3:1]=000,001,011,111对应的输出会发生变化。

module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output fr3,
    output fr2,
    output fr1,
    output dfr
); 
    reg [2:0] cs,ns;
    parameter idle = 3'd0;
    parameter s1 = 3'd1;   
    parameter s2 = 3'd2;
    parameter s3 = 3'd3;
    always@(posedge clk)
        begin
            if(reset)
                cs <= idle;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                    idle:begin
                        case(s)
                            3'b001: ns = s1;  
                            3'b011: ns = s2;
                            3'b111: ns = s3;
                            default: ns = idle;
                        endcase
                    end
                    s1:begin
                        case(s)
                            3'b001: ns = s1;
                            3'b011: ns = s2;
                            3'b111: ns = s3;
                            default: ns = idle;
                        endcase
                    end
                    s2:begin
                        case(s)
                            3'b001: ns = s1;
                            3'b011: ns = s2;
                            3'b111: ns = s3;
                            default: ns = idle;
                        endcase
                    end
                    s3:begin
                        case(s)
                            3'b001: ns = s1;
                            3'b011: ns = s2;
                            3'b111: ns = s3;
                            default: ns = idle;
                        endcase
                    end
                    default: ns = idle;
            endcase
        end
    assign fr3 = cs==idle ? 1'b1 : 1'b0;
    assign fr2 = (cs==idle || cs==s1) ? 1'b1 : 1'b0;
    assign fr1 = (cs==idle || cs==s1 || cs==s2) ? 1'b1 : 1'b0;
    //当前时刻水位与前一刻水位的高低决定dfr
    //前一时刻低于当前,为0;反之为1
   reg fr1_reg,fr2_reg,fr3_reg;
    always@(posedge clk)
        begin
            fr1_reg <= fr1;
            fr2_reg <= fr2;
            fr3_reg <= fr3;
        end
    always@(*)
        begin
            if(~fr3 & fr3_reg | ~fr2 & fr2_reg | ~fr1 & fr1_reg)
                dfr = 1'b0;
            else if(fr3 & ~fr3_reg | fr2 & ~fr2_reg | fr1 & ~fr1_reg)
                dfr = 1'b1;
        end
        

endmodule

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=0, RIGHT=1, ...
    reg state, next_state;
    parameter left = 0;
    parameter right = 1;
    
    always@(posedge clk or posedge areset)
        begin
            if(areset)
                state <= left;
            else
                state <= next_state;
        end
    always@(*)
        begin
            case(state)
                left: next_state = bump_left ? right : left;
                right: next_state = bump_right ? left : right;
                default: next_state = left;
            endcase
        end
    assign walk_left = state==left;
    assign walk_right = state==right;
    
endmodule

lemmings2

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 ); 

    // parameter LEFT=0, RIGHT=1, ...
    reg [1:0]state, next_state;
    parameter left = 2'd0;
    parameter right = 2'd1;
    parameter g_left = 2'd2;
    parameter g_right = 2'd3;
    
    always@(posedge clk or posedge areset)
        begin
            if(areset)
                state <= left;
            else
                state <= next_state;
        end
    always@(*)
        begin
            case(state)
                left: next_state = ground ? (bump_left ? right : left) : g_left;
                right: next_state = ground ? (bump_right ? left : right) : g_right;
                g_left: next_state = ground ? left : g_left;
                g_right: next_state = ground ? right : g_right;
                default: next_state = left;
            endcase
        end
    assign walk_left = state==left;
    assign walk_right = state==right;
    assign aaah = state==g_left || state==g_right;

endmodule

lemmings3

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 ); 
    //定义状态,fall优先级最高,其次为dig,最后为切换方向
	parameter left = 0;
    parameter right = 1;
    parameter fall_left = 2;
    parameter fall_right = 3;
    parameter dig_left = 4;
    parameter dig_right = 5;
    
    reg [2:0] cs,ns;
    
    always@(posedge clk or posedge areset)
        begin
            if(areset)
                cs <= left;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                left: ns = ground ? (dig ? dig_left : (bump_left ?  right : left)) : fall_left;
                right: ns = ground ? (dig ? dig_right : (bump_right ? left : right)) : fall_right;
                fall_left: ns = ground ? left : fall_left;
                fall_right: ns = ground ? right : fall_right;  
                dig_left: ns = ground ? dig_left : fall_left;
                dig_right: ns = ground ? dig_right : fall_right;
                default:  ns = left;
            endcase
        end
    assign walk_left = (cs==left) ? 1'b1 : 1'b0;
    assign walk_right = (cs==right) ? 1'b1 : 1'b0;
    assign aaah = (cs==fall_left || cs==fall_right) ? 1'b1 : 1'b0;
    assign digging = (cs==dig_left || cs==dig_right) ? 1'b1 : 1'b0;
    
endmodule

lemmings4

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 ); 
    //定义状态,fall优先级最高,其次为dig,最后为切换方向
	parameter left = 0;
    parameter right = 1;
    parameter fall_left = 2;
    parameter fall_right = 3;
    parameter dig_left = 4;
    parameter dig_right = 5;
    parameter splatter = 6;
    parameter act_end = 7;
    //如果下降超过20个时钟,那lemmings就会死亡、输出为0,直到复位
    //可以定义一个计数器。进行计时
    reg [2:0] cs,ns;
    reg [4:0] cnt;
    
    always@(posedge clk)
        begin
            if(areset)
                cnt <= 5'd0;
            else if(ns==fall_left || ns==fall_right)
                cnt <= cnt+1'b1;
            else
                cnt <= 5'd0;
        end
    always@(posedge clk or posedge areset)
        begin
            if(areset)
                cs <= left;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                left: ns = ground ? (dig ? dig_left : (bump_left ?  right : left)) : fall_left;
                right: ns = ground ? (dig ? dig_right : (bump_right ? left : right)) : fall_right;
                fall_left: ns = ground ? left : (cnt>5'd19 ? splatter : fall_left);
                fall_right: ns = ground ? right : (cnt>5'd19 ? splatter : fall_right);  
                dig_left: ns = ground ? dig_left : fall_left;
                dig_right: ns = ground ? dig_right : fall_right;
                splatter: ns = ground ? act_end : splatter;
                act_end: ns = act_end;
                default:  ns = left;
            endcase
        end
    assign walk_left = (cs==left) ? 1'b1 : 1'b0;
    assign walk_right = (cs==right) ? 1'b1 : 1'b0;
    assign aaah = (cs==fall_left || cs==fall_right || cs==splatter) ? 1'b1 : 1'b0;
    assign digging = (cs==dig_left || cs==dig_right) ? 1'b1 : 1'b0;
    
endmodule

FSM one-hot

module top_module(
    input in,
    input [9:0] state,
    output [9:0] next_state,
    output out1,
    output out2);
    
	//和状态机关系不大。没必要按照状态机写
     
    assign next_state[0] = ~in & (state[0] | state[1] | state[2] | state[3] | state[4] | state[7] | state[8] | state[9]);
    assign next_state[1] = in & (state[0] | state[8] | state[9]);
    assign next_state[2] = in & state[1];
    assign next_state[3] = in & state[2];
    assign next_state[4] = in & state[3];
    assign next_state[5] = in & state[4];
    assign next_state[6] = in & state[5];
    assign next_state[7] = in & (state[6] | state[7]);
    assign next_state[8] = ~in & state[5];
    assign next_state[9] = ~in & state[6];
	
    assign out1 = state[8] | state[9];
    assign out2 = state[7] | state[9];

endmodule

FSM ps2

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output done); //
	
    parameter s0 = 2'd0;
    parameter s1 = 2'd1;
    parameter s2 = 2'd2;
    parameter s3 = 2'd3;
    
    reg[1:0] cs,ns;
    //如果输入数据的第三位为1,指示接收数据的开始,然后3字节后完成
    always@(posedge clk)
        begin
            if(reset)
                cs <= s0;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                s0: ns = in[3] ? s1 : s0;
                s1: ns = s2;
                s2: ns = s3;
                s3: ns = in[3] ? s1 : s0;
                default: ns = s0;
            endcase
        end
    assign done = cs==s3 ? 1'b1 : 1'b0;
   
endmodule

FSM ps2data

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output [23:0] out_bytes,
    output done); //

    parameter s0 = 2'd0;
    parameter s1 = 2'd1;
    parameter s2 = 2'd2;
    parameter s3 = 2'd3;
    
    reg[1:0] cs,ns;
    reg[23:0] out_bytes_reg;
    //如果输入数据的第三位为1,指示接收数据的开始,然后3字节后完成
    always@(posedge clk)
        begin
            if(reset)
                cs <= s0;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                s0: ns = in[3] ? s1 : s0;
                s1: ns = s2;
                s2: ns = s3;
                s3: ns = in[3] ? s1 : s0;
                default: ns = s0;
            endcase
        end
    always@(posedge clk)
        begin
            if(ns==s1)
                out_bytes_reg[23:16] <= in;
        end
    always@(posedge clk)
        begin
            if(ns==s2)
                out_bytes_reg[15:8] <= in;
        end
    always@(posedge clk)
        begin
            if(ns==s3)
                out_bytes_reg[7:0] <= in;
        end
    assign done = cs==s3 ? 1'b1 : 1'b0;
    assign out_bytes = done ? out_bytes_reg : 24'd0;

endmodule

FSm serial

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done
); 
    parameter idle = 4'd0;
	parameter start = 4'd1;
    parameter s1 = 4'd2;
    parameter s2 = 4'd3;
    parameter s3 = 4'd4;
    parameter s4 = 4'd5;
	parameter s5 = 4'd6;
    parameter s6 = 4'd7;
    parameter s7 = 4'd8;
    parameter s8 = 4'd9;
    parameter stop = 4'd10;
    parameter WAIT = 4'd11;
    
    reg [3:0]cs,ns;
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= idle;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                idle: ns = in ? idle : start;
                start: ns = s1;
                s1: ns = s2;
                s2: ns = s3;
                s3: ns = s4;
                s4: ns = s5;
                s5: ns = s6;
                s6: ns = s7;
                s7: ns = s8;
                s8: ns = in ? stop : WAIT;
                stop: ns = ~in ? start : idle;
                WAIT: ns = in ? idle : WAIT;
                default: ns = idle;
            endcase
        end
    assign done = cs==stop ? 1'b1 : 1'b0;
endmodule

Fsm serialdata

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); // 
    parameter idle = 3'd0;
    parameter start = 3'd1;
    parameter data = 3'd2;
    parameter stop = 3'd3;
    parameter WAIT = 3'd4;
    
    reg [2:0]cs,ns;
    reg [7:0] out;
    reg [3:0] cnt;  //用来计数什么时候数据传输完成
    
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= idle;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                idle: ns = in ? idle : start;
                start: ns = data;
                data: ns = cnt==4'd8 ? (in ? stop : WAIT) : data;
                stop: ns = in ? idle : start;
                WAIT: ns = in ? idle : WAIT;
                default: ns = idle;
            endcase
        end
    //输出
    always@(posedge clk) 
        begin
            if(reset)
                cnt <= 4'd0;
            else
                cnt <= ns==data ? cnt+1'b1 : 4'd0;
        end
    always@(posedge clk)
        begin
            if(reset)
                done <= 1'b0;
            else
                done <= ns==stop ? 1'b1 : 1'b0;
        end
    always@(posedge clk)
        begin
            if(reset)
                out <= 8'd0;
            else if(ns==data)
                out[cnt] <= in;
            else
                out <= 8'd0;
        end
    reg [7:0] out_bytes;
    always@(posedge clk)
        begin
            if(reset)
                out_bytes <= 8'd0;
            else
                out_bytes <= ns==stop ? out : 8'd0;
        end
     assign out_byte = done? out_bytes : 8'd0;           

endmodule
module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
	parameter idle = 4'd0;
    parameter start = 4'd1;
    parameter s1 = 4'd2;
    parameter s2 = 4'd3;
    parameter s3 = 4'd4;
    parameter s4 = 4'd5;
    parameter s5 = 4'd6;
    parameter s6 = 4'd7;
    parameter s7 = 4'd8;
    parameter s8 = 4'd9;
    parameter PARITY = 4'd10;
    parameter stop = 4'd11;
    parameter WAIT = 4'd12;
    
    reg [3:0] cs,ns;
    wire odd;
    reg [7:0] out;
    reg [7:0] out_bytes;
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= idle;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                idle:  begin ns = in ? idle : start; end
                start: begin ns = s1; out[0] = in;   end
                s1:    begin ns = s2; out[1] = in;   end
                s2:    begin ns = s3; out[2] = in;   end
                s3:    begin ns = s4; out[3] = in;   end
                s4:    begin ns = s5; out[4] = in;   end
                s5:    begin ns = s6; out[5] = in;   end
                s6:    begin ns = s7; out[6] = in;   end
                s7:    begin ns = s8; out[7] = in;   end
                s8: ns = PARITY; 
                PARITY: ns = in ? stop : WAIT;
                stop: ns = in ? idle : start;
                WAIT: ns = in ? idle : WAIT;
                default: ns = idle;
            endcase
        end
    always@(posedge clk)
        begin
            if(reset)
                done <= 1'b0;
            else
                done <= (ns==stop && odd) ? 1'b1 : 1'b0;
        end
    always@(posedge clk)
        begin
            if(reset)
                out_bytes <= 8'd0;
            else
                out_bytes <= (ns==stop && odd) ? out : 8'd0;
        end
    assign out_byte = done ? out_bytes : 8'd0;
    wire isdone;
    assign isdone = ns==start;
    parity u0(
        .clk(clk),
        .reset(isdone),
        .in(in),
        .odd(odd)
    );
    
endmodule

上面对parity调用时,复位信号是,如果下一个状态是开始,那么在一开始就进行奇校验。
这种方法虽然可以实现,但是会生成锁存器。而且对于这种实现 方法,比较麻烦,如果要传输的数据流位数很多,那么状态太多。因此可以考虑下一种办法。
计数器实现,用计数器标定数据传输的阶段.

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
	parameter idle = 4'd0;
    parameter start = 4'd1;
    parameter data = 4'd2;
    parameter stop = 4'd3;
    parameter WAIT = 4'd4;
    
    reg [3:0] cs,ns;
    reg [7:0] out;
    reg [7:0] out_bytes;
    wire reset_p; //parity的复位信号
    reg [3:0] cnt;
    reg odd;
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= idle;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                idle:  ns = in ? idle : start;
                start: ns = data;
                data:  ns = cnt==4'd9 ? (in ? stop : WAIT) : data;
                stop:  ns = in ? idle : start;
                WAIT:  ns = in ? idle : WAIT;
                default: ns = idle;
            endcase
        end
    //output
    always@(posedge clk)
        begin
            if(reset)
                cnt <= 4'd0;
            else
                cnt <= ns==data ? cnt+1'b1 : 4'd0;
        end
    always@(posedge clk) 
        begin
            if(reset)
                done <= 1'b0;
            else
                done <= (ns==stop && odd==1'b1) ? 1'b1 : 1'b0;
        end
    always@(posedge clk)
        begin
            if(reset)
                out <= 8'd0;
            else
                out[cnt] <= ns==data ? in : 8'd0;
        end
    always@(posedge clk)
        begin
            if(reset)
                out_bytes <= 8'd0;
            else
                out_bytes <= (ns==stop && odd==1'b1) ? out : 8'd0;
        end
    assign out_byte = done ? out_bytes : 8'd0;
    assign reset_p = ns==start ? 1'b1 : 1'b0;
    parity u0(
        .clk(clk),
        .reset(reset_p),
        .in(in),
        .odd(odd)
    );
    
    
endmodule

Fsm hdlc

module top_module(
    input clk,
    input reset,    // Synchronous reset
    input in,
    output disc,
    output flag,
    output err);
    
    parameter s0 = 4'd0;
    parameter s1 = 4'd1;
    parameter s2 = 4'd2;
    parameter s3 = 4'd3;
    parameter s4 = 4'd4;
    parameter s5 = 4'd5;
    parameter s6 = 4'd6;
    parameter DISC = 4'd7;
    parameter ERR = 4'd8;
    parameter FLAG = 4'd9;
    
    reg [3:0] cs,ns;
    always@(posedge clk)
        begin
            if(reset)
                cs <= s0;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                s0: ns = in ? s1 : s0;   //0
                s1: ns = in ? s2 : s0;   //1
                s2: ns = in ? s3 : s0;   //1
                s3: ns = in ? s4 : s0;   //1
                s4: ns = in ? s5 : s0;   //1
                s5: ns = in ? s6 : DISC; //1
                s6: ns = in ? ERR : FLAG;//1
                DISC: ns  = in ? s1 : s0;
                ERR: ns = in ? ERR : s0;
                FLAG: ns = in ? s1 : s0;
                default: ns = s0;
            endcase
        end
    
    assign flag = cs==FLAG ? 1'b1 : 1'b0;
    assign err = cs==ERR ? 1'b1 : 1'b0;
    assign disc = cs==DISC ? 1'b1 : 1'b0;
endmodule

q8

module top_module (
    input clk,
    input aresetn,    // Asynchronous active-low reset
    input x,
    output z ); 
    
    parameter s1 = 2'd0;
    parameter s2 = 2'd1;
    parameter s3 = 2'd2;
    
    reg [1:0] cs,ns;
    
    always@(posedge clk or negedge aresetn)
        begin
            if(!aresetn)
                cs <= s1;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                s1: ns = x ? s2 : s1; 
                s2: ns = x ? s2 : s3;
                s3: ns = x ? s2 : s1;
                default: ns = s1;
            endcase
        end
    assign  z = cs==s3 ? x : 1'b0;
  // assign  z = cs==s3 && x==1 ? 1'b1 : 1'b0   这么写也是可以的。
endmodule

q5a:补码输出状态机

一开始没有明白意思,写了几个例子,看了一下,才明白是怎么跳转的。
这里没有考虑符号位的问题,全部按照负数计算。
输入x: 000(低位-高位),则反码为:111,补码为:(1)000。即z=000;
输入x:00010,反码为: 11101,补码为: 00011;
输入x:00101,反码为: 11010,补码为: 00110;
可以看到,输入从0(低位)开始,出现第一个1时,补码为1,之后输入为0,补码为1,输入为1,补码为0.
因此,可以采用状态机。moore或者Melay都可以写。

odule top_module (
    input clk,
    input areset,
    input x,
    output z
); 
	parameter idle = 2'd0;
    parameter s1 = 2'd1;
    parameter s_one = 2'd2;   //出现1
    parameter s_zero = 2'd3;  //出现0
    
    reg [1:0] cs,ns;
    
    always@(posedge clk or posedge areset)
        begin
            if(areset)
                cs <= idle;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                idle: ns = x ? s1 : idle;  //从0开始,出现输入为1时,输出为1.到下一个状态
                s1: ns = x ? s_one : s_zero;  //在此之后,输入为0,输出为1,输入为1,输出为0
                s_one: ns = x ? s_one : s_zero;
                s_zero: ns = x ? s_one : s_zero;
                default: ns = idle;
            endcase
        end
    assign z = cs ==s1 || cs==s_zero;
endmodule

q5b

module top_module (
    input clk,
    input areset,
    input x,
    output z
); 
    parameter A = 2'b01;
    parameter B = 2'b10;
    
    reg [1:0] cs,ns;
    
    always@(posedge clk or posedge areset)
        begin
            if(areset)
                cs <= A;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                A: ns = x ? B : A;
                B: ns = B;
                default: ns = A;
            endcase
        end
    assign z = (cs==A && x==1'b1) || (cs==B && x==1'b0);

endmodule

q3fsma

定义两个计数器,一个用来计算时钟数。满3重新计数,一个用来计w中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] cs,ns;
    reg [1:0] cnt1,cnt2;
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= A;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                A: ns = s ? B : A;
                B: ns = B;
                default: ns = A;
            endcase
        end
    //计时3个时钟,满3重新计数
    always@(posedge clk)
        begin
            if(reset)
                cnt1 <= 2'd0;
            else if(cnt1==2'd2)
                cnt1 <= 2'd0;
            else
                cnt1 <= cs==B ? cnt1+1'b1 : 2'd0;
        end
    //计算输入w中1的数量
    always@(posedge clk)
        begin
            if(reset)
                cnt2 <= 2'd0;
            else if(cnt1==2'd0)
                cnt2 <= w ? 1'b1 : 1'b0;
            else 
                cnt2 <= cs==B ? (w ? cnt2+1'b1 : cnt2) : 2'd0;
        end
    assign z = cnt1==2'd0 && cnt2==2'd2 && cs==B;       
endmodule

q3bfsm

module top_module (
    input clk,
    input reset,   // Synchronous reset
    input x,
    output z
);
	parameter idle = 3'b000;
    parameter s1 = 3'b001;
    parameter s2 = 3'd010;
    parameter s3 = 3'd011;
    parameter s4 = 3'd100;
    
    reg [2:0] cs,ns;
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= idle;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                idle: ns = x ? s1 : idle;
                s1: ns = x ? s4 : s1;
                s2: ns = x ? s1 : s2;
                s3: ns = x ? s2 : s1;
                s4: ns = x ? s4 : s3;
                default: ns = idle;
            endcase
        end
    assign z = cs==s3 || cs==s4;
endmodule

q3cfsm

module top_module (
    input clk,
    input [2:0] y,
    input x,
    output Y0,
    output z
);
    assign z = y==3'b011 || y==3'b100;
    assign Y0 = x&&y==3'b000 || x&&y==3'b010 || ~x&&y==3'b001 || ~x&&y==3'b011 || ~x&&y==3'b100;
endmodule

q6bfsm

其实不用这么麻烦,直接写真值表就行了

module top_module (
    input [3:1] y,
    input w,
    output Y2);
	parameter A = 3'b000;
    parameter B = 3'b001;
    parameter C = 3'b010;
    parameter D = 3'b011;
    parameter E = 3'b100;
    parameter F = 3'b101;
    
    reg [2:0] cs,ns;
    wire reset,clk;
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= A;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                A: ns = w ? A : B;
                B: ns = w ? D : C;
                C: ns = w ? D : E;
                D: ns = w ? A : F;
                E: ns = w ? D : E;
                F: ns = w ? D : C;
                default: ns = A;
            endcase
        end
    assign Y2 = y==B || y==C && w || y==E && w || y==F;
                
    
endmodule

或者

module top_module (
    input [3:1] y,
    input w,
    output Y2);

    assign Y2 = (y == 3'b001 | y == 3'b101) & ~w | (y == 3'b001 | y == 3'b010 | y == 3'b100 | y == 3'b101) & w;
    
endmodule

q6c

写真值表。用独热码编码

module top_module (
    input [6:1] y,
    input w,
    output Y2,
    output Y4);
    assign Y2 = y[1] & ~w;
    assign Y4 = y[2] & w | y[3] & w | y[5] & w | y[6]&w;
endmodule

q6

module top_module (
    input clk,
    input reset,     // synchronous reset
    input w,
    output z);

	parameter A = 1;
    parameter B = 2;
    parameter C = 3;
    parameter D = 4;
    parameter E = 5;
    parameter F = 6;
    
    reg [2:0] cs,ns;
    
    always@(posedge clk)
        begin
            if(reset)
                cs <= A;
            else
                cs <= ns;
        end
    always@(*)
        begin
            case(cs)
                A: ns = w ? A : B;
                B: ns = w ? D : C;
                C: ns = w ? D : E;
                D: ns = w ? A : F;
                E: ns = w ? D : E;
                F: ns = w ? D : C;
                default: ns = A;
            endcase
        end
    assign z = cs==E ||cs==F;
endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值