HDLbits: Fsm serial

根据题意设计了四个状态,写出代码如下:

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done
); 
    parameter IDLE = 3'b000, START = 3'b001, DATA = 3'b010, STOP = 3'b100, bit_counter_end = 4'd7;
    
    reg [2:0] state,next_state;
    
    reg [3:0] bit_counter;
    
    always@(*)begin
        case(state)
            START: next_state = DATA;
            DATA: next_state = (bit_counter >= bit_counter_end)? (in?STOP:IDLE):DATA;
            STOP: next_state = in?IDLE:START;
            IDLE: next_state = in?IDLE:START;
            default: next_state = IDLE;
        endcase
    end
    
    always@(posedge clk)begin
        if(reset)
            state <= IDLE;
        else
            state <= next_state;
    end
    
    always@(posedge clk)begin
        if(reset)
           bit_counter <= 4'd0;            
        else if(state == DATA)
           bit_counter <= bit_counter + 4'd1;  
        else
           bit_counter <= 4'd0;
    end
        
    assign done = (state == STOP);    

endmodule

时序图如下,有误:

HDLbits: Fsm serial_第1张图片

参考网上的答案,加入了一个ERROR状态表示例题时序图"?"的时候,下面代码没问题了

注意bit_counter计数的那块如果用state==DATA判断,那么上面长度判断就得用7,如果用next_state==DATA判断,上面长度判断就得用8

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done
); 
    parameter IDLE = 4'b0000, START = 4'b0001, DATA = 4'b0010, STOP = 4'b0100, ERROR = 4'b1000, 
    bit_counter_end = 4'd7;
    
    reg [3:0] state,next_state;
    
    reg [3:0] bit_counter;
    
    always@(*)begin
        case(state)
            START: next_state = DATA;
            DATA: next_state = (bit_counter >= bit_counter_end)? (in?STOP:ERROR):DATA;
            STOP: next_state = in?IDLE:START;
            ERROR: next_state = in?IDLE:ERROR;
            IDLE: next_state = in?IDLE:START;
            default: next_state = IDLE;
        endcase
    end
    
    always@(posedge clk)begin
        if(reset)
            state <= IDLE;
        else
            state <= next_state;
    end
    
    always@(posedge clk)begin
        if(reset)
           bit_counter <= 0;            
        else if(state == DATA)          
           bit_counter <= bit_counter + 1;
        else
           bit_counter <= 0;
    end
        
    assign done = (state == STOP);    

endmodule

你可能感兴趣的:(verilog学习)