HDLbits---Circuits---Sequential Logic---Finite State Machines第三部分

1.Fsm onehot

module top_module(
    input         in,
    input  [9:0]  state,
    output [9:0]  next_state,
    output        out1,
    output        out2
);
 
assign next_state[0] = (state[0] & ~in) | (state[1] & ~in) | (state[2] & ~in) | (state[3] & ~in) | (state[4] & ~in) | (state[7] & ~in) | (state[8] & ~in) | (state[9] & ~in);
assign next_state[1] = (state[0] & in) | (state[8] & in) | (state[9] & in);
assign next_state[2] = (state[1] & in);
assign next_state[3] = (state[2] & in);
assign next_state[4] = (state[3] & in);
assign next_state[5] = (state[4] & in);
assign next_state[6] = (state[5] & in);
assign next_state[7] = (state[6] & in) | (state[7] & in);
assign next_state[8] = (state[5] & ~in);
assign next_state[9] = (state[6] & ~in);
 
assign out1 = (state[8] | state[9]);
assign out2 = (state[7] | state[9]);
 
endmodule

2.Fsm ps2

module top_module(
    input        clk,
    input [7:0]  in,
    input        reset,    // Synchronous reset
    output       done
);
 
parameter  IDLE  = 'd0;
parameter  BYTE1 = 'd1;
parameter  BYTE2 = 'd2;
parameter  BYTE3 = 'd3;
 
reg [1:0]   state;
reg [1:0]   next_state;
always @(posedge clk or posedge reset) begin
    if (reset) begin
        state <= IDLE;
    end
    else begin
        state <= next_state;
    end
end
always @(*) begin
    next_state = state;
    case(state)
        IDLE: begin
            if (in[3]) begin
                next_state = BYTE1;
            end
            else begin
                next_state = IDLE;
            end
        end
        BYTE1: begin
            next_state = BYTE2;
        end
        BYTE2: begin
            next_state = BYTE3;
        end
        BYTE3: begin
            if (in[3]) begin
                next_state <= BYTE1;
            end
            else begin
                next_state <= IDLE;
            end
        end
    endcase
end
 
assign done = (state == BYTE3);
 
endmodule

3.Fsm ps2data

module top_module(
    input          clk,
    input  [7:0]   in,
    input          reset,
    output [23:0]  out_bytes,
    output         done
);
 
parameter  IDLE  = 'd0;
parameter  BYTE1 = 'd1;
parameter  BYTE2 = 'd2;
parameter  BYTE3 = 'd3;
 
reg [1:0]   state;
reg [1:0]   next_state;
reg [23:0]  byte_rx;
always @(posedge clk) begin
    if (reset) begin
        state <= IDLE;
    end
    else begin
        state <= next_state;
    end
end
always @(*) begin
    next_state = state;
    case(state)
        IDLE: begin
            if (in[3]) begin
                next_state = BYTE1;
            end
            else begin
                next_state = IDLE;
            end
        end
        BYTE1: begin
            next_state = BYTE2;
        end
        BYTE2: begin
            next_state = BYTE3;
        end
        BYTE3: begin
            if (in[3]) begin
                next_state = BYTE1;
            end
            else begin
                next_state = IDLE;
            end
        end
    endcase
end
 
//
always @(posedge clk) begin
    if (next_state == BYTE1) begin
        byte_rx <= {byte_rx[15:0],in};
    end
    else if (next_state == BYTE2) begin
        byte_rx <= {byte_rx[15:0],in};
    end
    else if (next_state == BYTE3) begin
        byte_rx <= {byte_rx[15:0],in};;
    end
    else begin
        byte_rx <= 'd0;
    end
end
assign done = (state == BYTE3);
assign out_bytes = byte_rx;
endmodule

4.fsm_serial

module top_module(
    input     clk,
    input     in,
    input     reset,
    output    done
);
//状态机状态申明
parameter  IDLE       =  12'b000000000001; 
parameter  START      =  12'b000000000010; 
parameter  DATA_ONE   =  12'b000000000100; 
parameter  DATA_TWO   =  12'b000000001000; 
parameter  DATA_THREE =  12'b000000010000; 
parameter  DATA_FOUR  =  12'b000000100000; 
parameter  DATA_FIVE  =  12'b000001000000; 
parameter  DATA_SIX   =  12'b000010000000; 
parameter  DATA_SEVEN =  12'b000100000000; 
parameter  DATA_EIGHT =  12'b001000000000; 
parameter  STOP       =  12'b010000000000; 
parameter  WAIT       =  12'b100000000000;
 
reg  [11:0]   state;
reg  [11:0]   next_state;
always @(posedge clk) begin
      if (reset) begin
          state <= IDLE;
      end
      else begin
          state <= next_state;
      end
end 
always @(*) begin
    next_state = state;
    case(state)
        IDLE: begin
            if (~in) begin
                next_state = START;
            end
            else begin
                next_state = IDLE;
            end
        end
        START: begin
            next_state = DATA_ONE;
        end
        DATA_ONE: begin
            next_state = DATA_TWO;
        end
        DATA_TWO: begin
            next_state = DATA_THREE;
        end
        DATA_THREE:begin
            next_state = DATA_FOUR;
        end
        DATA_FOUR: begin
            next_state = DATA_FIVE;
        end
        DATA_FIVE: begin
            next_state = DATA_SIX;
        end
        DATA_SIX: begin
            next_state = DATA_SEVEN;
        end
        DATA_SEVEN: begin
            next_state = DATA_EIGHT;
        end
        DATA_EIGHT: begin
            if (in) begin
                next_state = STOP;
            end
            else begin
                next_state = WAIT;
            end
        end
        WAIT: begin
            if (in) begin
                next_state = IDLE;
            end
            else begin
                next_state = WAIT;
            end
        end
        STOP: begin
            if (in) begin
                next_state = IDLE;
            end
            else begin
                next_state = START;
            end    
        end
        default: begin
            next_state = IDLE;
        end
    endcase
end 
 
assign done = (state==STOP);
 
endmodule

5.fsm_serialdata

module top_module(
    input         clk,
    input         in,
    input         reset,    // Synchronous reset
    output [7:0]  out_byte,
    output        done
); 
parameter  IDLE       =  12'b000000000001; 
parameter  START      =  12'b000000000010; 
parameter  BIT_ONE    =  12'b000000000100; 
parameter  BIT_TWO    =  12'b000000001000; 
parameter  BIT_THREE  =  12'b000000010000; 
parameter  BIT_FOUR   =  12'b000000100000; 
parameter  BIT_FIVE   =  12'b000001000000; 
parameter  BIT_SIX    =  12'b000010000000; 
parameter  BIT_SEVEN  =  12'b000100000000; 
parameter  BIT_EIGHT  =  12'b001000000000; 
parameter  STOP       =  12'b010000000000; 
parameter  WAIT       =  12'b100000000000;
 
reg  [11:0]   state;
reg  [11:0]   next_state;
always @(posedge clk) begin
    if (reset) begin
        state <= IDLE;
    end
    else begin
        state <= next_state;
    end
end
always @(*) begin
    next_state = state;
    case(state)
        IDLE: begin
            if (~in) begin
                next_state = START;
            end
            else begin
                next_state = IDLE;
            end
        end
        START: begin
            next_state = BIT_ONE;
        end
        BIT_ONE: begin
            next_state = BIT_TWO;
        end
        BIT_TWO: begin
            next_state = BIT_THREE;
        end
        BIT_THREE:begin
            next_state = BIT_FOUR;
        end
        BIT_FOUR: begin
            next_state = BIT_FIVE;
        end
        BIT_FIVE: begin
            next_state = BIT_SIX;
        end
        BIT_SIX: begin
            next_state = BIT_SEVEN;
        end
        BIT_SEVEN: begin
            next_state = BIT_EIGHT;
        end
        BIT_EIGHT: begin
            if (in) begin
                next_state = STOP;
            end
            else begin
                next_state = WAIT;
            end
        end
        WAIT: begin
            if (in) begin
                next_state = IDLE;
            end
            else begin
                next_state = WAIT;
            end
        end
        STOP: begin
            if (in) begin
                next_state = IDLE;
            end
            else begin
                next_state = START;
            end    
        end
        default: begin
            next_state = IDLE;
        end
    endcase
end 
always @(posedge clk) begin
    if (reset) begin
        done     <= 'd0;
        out_byte <= 'd0;
    end
    else begin
        case(next_state)
            IDLE: begin
                done     <= 'd0;
                out_byte <= 'd0;                
            end
            START: begin
                done     <= 'd0;
                out_byte <= 'd0;
            end
            BIT_ONE: begin
                done        <= 'd0;
                out_byte[0] <= in; 
            end
            BIT_TWO: begin
                done        <= 'd0;
                out_byte[1] <= in; 
            end
            BIT_THREE: begin
                done        <= 'd0;
                out_byte[2] <= in; 
            end
            BIT_FOUR: begin
                done        <= 'd0;
                out_byte[3] <= in; 
            end
            BIT_FIVE: begin
                done        <= 'd0;
                out_byte[4] <= in; 
            end
            BIT_SIX: begin
                done        <= 'd0;
                out_byte[5] <= in; 
            end
            BIT_SEVEN: begin
                done        <= 'd0;
                out_byte[6] <= in; 
            end
            BIT_EIGHT: begin
                done        <= 'd0;
                out_byte[7] <= in; 
            end
            WAIT: begin
                done     <= in;
                out_byte <= out_byte;
            end
            STOP: begin
                done     <= 'd1;
                out_byte <= out_byte;
            end
            default: begin
                done     <= 'd0;
                out_byte <= 'd0;
            end
        endcase
    end
end
endmodule

6.Fsm serialdp

module top_module(
    input         clk,
    input         in,
    input         reset,    // Synchronous reset
    output [7:0]  out_byte,
    output        done
); 
parameter  IDLE       =  13'b0000000000001; 
parameter  START      =  13'b0000000000010; 
parameter  BIT_ONE    =  13'b0000000000100; 
parameter  BIT_TWO    =  13'b0000000001000; 
parameter  BIT_THREE  =  13'b0000000010000; 
parameter  BIT_FOUR   =  13'b0000000100000; 
parameter  BIT_FIVE   =  13'b0000001000000; 
parameter  BIT_SIX    =  13'b0000010000000; 
parameter  BIT_SEVEN  =  13'b0000100000000; 
parameter  BIT_EIGHT  =  13'b0001000000000;
parameter  PARITY_BIT =  13'b0010000000000;
parameter  STOP       =  13'b0100000000000; 
parameter  WAIT       =  13'b1000000000000;
reg  [12:0]   state;
reg  [12:0]   next_state;
reg           odd;
always @(posedge clk) begin
    if (reset) begin
        state <= IDLE;
    end
    else begin
        state <= next_state;
    end
end
always @(*) begin
    next_state = state;
    case(state)
        IDLE: begin
            if (~in) begin
                next_state = START;
            end
            else begin
                next_state = IDLE;
            end
        end
        START: begin
            next_state = BIT_ONE;
        end
        BIT_ONE: begin
            next_state = BIT_TWO;
        end
        BIT_TWO: begin
            next_state = BIT_THREE;
        end
        BIT_THREE:begin
            next_state = BIT_FOUR;
        end
        BIT_FOUR: begin
            next_state = BIT_FIVE;
        end
        BIT_FIVE: begin
            next_state = BIT_SIX;
        end
        BIT_SIX: begin
            next_state = BIT_SEVEN;
        end
        BIT_SEVEN: begin
            next_state = BIT_EIGHT;
        end
        BIT_EIGHT: begin
            next_state = PARITY_BIT;
        end
        PARITY_BIT: begin
            if (in) begin
                next_state = STOP;
            end
            else begin
                next_state = WAIT;
            end
        end
        WAIT: begin
            if (in) begin
                next_state = IDLE;
            end
            else begin
                next_state = WAIT;
            end
        end
        STOP: begin
            if (in) begin
                next_state = IDLE;
            end
            else begin
                next_state = START;
            end    
        end
        default: begin
            next_state = IDLE;
        end
    endcase
end 
always @(posedge clk) begin
    if (reset) begin
        out_byte <= 'd0;
        done <= 'd0;
    end
    else begin
        case(next_state)
            IDLE: begin
                out_byte <= 'd0;
                done <= 'd0;
            end
            START: begin
                out_byte <= 'd0;
                done <= 'd0;
            end
            BIT_ONE: begin
                out_byte[0] <= in;
                done <= 'd0;
            end
            BIT_TWO: begin
                out_byte[1] <= in;
                done <= 'd0; 
            end
            BIT_THREE: begin
                out_byte[2] <= in;
                done <= 'd0;
            end
            BIT_FOUR: begin
                out_byte[3] <= in;
                done <= 'd0;
            end
            BIT_FIVE: begin
                out_byte[4] <= in;
                done <= 'd0;
            end
            BIT_SIX: begin
                out_byte[5] <= in;
                done <= 'd0; 
            end
            BIT_SEVEN: begin
                out_byte[6] <= in;
                done <= 'd0;
            end
            BIT_EIGHT: begin
                out_byte[7] <= in;
                done <= 'd0; 
            end
            PARITY_BIT: begin
                out_byte <= out_byte;
                done <= 'd0;
                
            end
            WAIT: begin
                out_byte <= out_byte;
                done <= 'd0;
            end
            STOP: begin
                out_byte <= out_byte;
                if (odd=='d1) begin
                    done <= 'd1;    
                end
                else begin
                    done <= 'd0;
                end
            end
            default: begin
                out_byte <= 'd0;
                done <= 'd0;
            end
        endcase
    end
end
wire   rst;  
assign rst = (reset == 1'b1 || next_state == IDLE || next_state == START);
parity u_parity(
    .clk        (clk        ),
    .reset      (rst         ),
    .in         (in            ),
    .odd        (odd        )
);
endmodule

7.fsm_hdlc

module top_module(
    input       clk,
    input       reset,    // Synchronous reset
    input       in,
    output      disc,
    output      flag,
    output      err
);
 
parameter  IDLE       =  10'b0000000001; 
parameter  BIT_ONE    =  10'b0000000010; 
parameter  BIT_TWO    =  10'b0000000100; 
parameter  BIT_THREE  =  10'b0000001000; 
parameter  BIT_FOUR   =  10'b0000010000; 
parameter  BIT_FIVE   =  10'b0000100000; 
parameter  BIT_SIX    =  10'b0001000000; 
parameter  STOP       =  10'b0010000000; 
parameter  DIS        =  10'b0100000000;
parameter  ERROR      =  10'b1000000000;
 
reg  [9:0]   state;
reg  [9:0]   next_state;
always @(posedge clk) begin
    if (reset) begin
        state <= IDLE;
    end
    else begin
        state <= next_state;
    end
end
always @(*) begin
    next_state = state;
    case(state)
        IDLE: begin
            if (in) begin
                next_state = BIT_ONE;
            end
            else begin
                next_state = IDLE;
            end
        end
        BIT_ONE: begin
            if (in) begin
                next_state = BIT_TWO;
            end
            else begin
                next_state = IDLE;
            end
        end
        BIT_TWO: begin
            if (in) begin
                next_state = BIT_THREE;
            end
            else begin
                next_state = IDLE;
            end
        end
        BIT_THREE: begin
            if (in) begin
                next_state = BIT_FOUR;
            end
            else begin
                next_state = IDLE;
            end
        end
        BIT_FOUR: begin
            if (in) begin
                next_state = BIT_FIVE;
            end
            else begin
                next_state = IDLE;
            end
        end
        BIT_FIVE: begin
            if (in) begin
                next_state = BIT_SIX;
            end
            else begin
                next_state = DIS;
            end
        end
        BIT_SIX: begin
            if (~in) begin
                next_state = STOP;
            end
            else begin
                next_state = ERROR;
            end
        end
        STOP: begin
            if (in) begin
                next_state = BIT_ONE;
            end
            else begin
                next_state = IDLE;
            end
        end
        DIS: begin
            if (in) begin
                next_state = BIT_ONE;
            end
            else begin
                next_state = IDLE;
            end
        end
        ERROR: begin
            if (in) begin
                next_state = ERROR;
            end
            else begin
                next_state = IDLE;
            end
        end
        default: begin
            next_state = IDLE;
        end
    endcase
end
always @(posedge clk) begin
    if (reset) begin
        disc <= 'd0;
        flag <= 'd0;
        err  <= 'd0;
    end
    else begin
        case(next_state)
            DIS: begin
                disc <= 'd1;
                flag <= 'd0;
                err  <= 'd0;
            end
            STOP: begin
                disc <= 'd0;
                flag <= 'd1;
                err  <= 'd0;                            
            end
            ERROR: begin
                disc <= 'd0;
                flag <= 'd0;
                err  <= 'd1;
            end
            default: begin
                disc <= 'd0;
                flag <= 'd0;
                err  <= 'd0;
            end
        endcase
    end
end
 
endmodule

你可能感兴趣的:(HDLBits学习,fpga开发)