2021年5月2日 星期日

HBLbits_Verilog Basic_Fsm ps2data

 HBLbits_Verilog Basic_Fsm ps2data

See also: PS/2 packet parser.
Now that you have a state machine that will identify three-byte messages in a PS/2 byte stream, add a datapath that will also output the 24-bit (3 byte) message whenever a packet is received (out_bytes[23:16] is the first byte, out_bytes[15:8] is the second byte, etc.).
out_bytes needs to be valid whenever the done signal is asserted. You may output anything at other times (i.e., don't-care).
For example:





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

parameter Byte1=0, Byte2=1, Byte3=2, Done=3;
    reg [2:0] state, state_next;
    wire Byte12Byte2, Byte22Byte3, Byte32Done, Done2Byte1, Done2Byte2;
    reg [7:0] data1, data2, data3;
    
    always@(posedge clk) begin
        if(reset)
            state <= Byte1;
        else begin
            state <= state_next;
        end
    end
    
    always@(*) begin
        case (state)
            Byte1:begin
                if(Byte12Byte2)
                    state_next = Byte2;
                else
                    state_next = state;
            end
            Byte2:begin
                if(Byte22Byte3)
                    state_next = Byte3;
            end
            Byte3:begin
                if(Byte32Done)
                    state_next = Done;
            end
            Done:begin
                if(Done2Byte1)
                    state_next = Byte1;
                else 
                    state_next = Byte2;
            end
        endcase 
    end
    assign Byte12Byte2 = in[3]==1;
    assign Byte22Byte3 = 1;
    assign Byte32Done = 1;
    assign Done2Byte1 = in[3]==0;
    
    always@(posedge clk) begin
        if(reset) begin
            data1<=0;
            data2<=0;
            data3<=0;
        end
        else begin
            if(state == Byte1)
                data1 <= in;
            else if(state == Byte2)
                data2 <= in;
            else if(state == Byte3)
                data3 <= in;
            else if(state == Done)
                data1 <= in;
            else begin
                data1<=0;
            data2<=0;
            data3<=0;
        end
        end
    end
   
    assign done = state == Done;
    assign out_bytes = (state == Done)?{data1, data2, data3}:24'hZZZZZZ;
endmodule

另一方法

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

    reg [1:0] state, next_state;
    localparam D1 = 0, D2 = 1, D3 = 2, DONE = 3;
 
    // State transition logic (combinational)
    always@(*) begin
        case(state)
            D1: begin
                if(in[3] == 1) next_state = D2;
                else next_state = D1;
            end
            D2: begin
                next_state = D3;
            end
            D3: begin
                next_state = DONE;
            end
            DONE: begin
                if(in[3] == 1) next_state = D2;
                else next_state = D1;
            end
            default: begin
                next_state = D1;
            end
        endcase
    end
    
    always@(posedge clk) begin
        if(reset) state <= D1;
        else state <= next_state;
    end
 
    // New: Datapath to store incoming bytes.
    reg [7:0] in_r;
    reg [1:0] state_r;
    always@(posedge clk) begin
        if(reset) begin 
            in_r <= 0;
            state_r <= D1;
        end
        else begin
            state_r <= state; 
            in_r <= in;
        end
    end
    
    reg [23:0] out_bytes_mid;
    always@(*) begin
        case(state)
            D1: begin
                if(in[3] == 1) out_bytes_mid[23:16] = in;
            end
            D2: begin
                if(state_r == DONE && in_r[3] == 1) begin
                    out_bytes_mid[15:8] = in;
                    out_bytes_mid[23:16] = in_r;
                end
                else out_bytes_mid[15:8] = in;
            end
            D3: begin
                out_bytes_mid[7:0] = in;
            end
            DONE: begin
                ;
            end
            default: begin
                ;
            end
        endcase
    end
    assign out_bytes = (done == 1)? out_bytes_mid:'bx;
    assign done = (state == DONE)?1:0;
endmodule

沒有留言:

張貼留言

WOKWI LED + MQTT Node-Red SQLite

WOKWI LED + MQTT Node-Red SQLite const char *mqtt_broker = "broker.mqtt-dashboard.com" ; const char *topic1 = "alex9ufo/e...