USB Device Controller in Verilog


module usb_device (
    input wire clk,               // System clock
    input wire reset,             // Reset signal
    input wire usb_dp,            // USB Data Plus line
    input wire usb_dm,            // USB Data Minus line
    output reg usb_power,         // Power control for USB device
    output reg [7:0] data_out,    // Data to send to host
    output reg data_valid         // Data valid signal
);
    // USB states
    parameter IDLE = 3'b000,
              START = 3'b001,
              DATA = 3'b010,
              ACK = 3'b011,
              NACK = 3'b100,
              ERROR = 3'b101;

    reg [2:0] state;              // Current state
    reg [7:0] data_in;            // Data received from USB
    reg [3:0] bit_cnt;            // Bit counter

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            state <= IDLE;
            usb_power <= 1'b0;
            data_out <= 8'b0;
            data_valid <= 1'b0;
            bit_cnt <= 4'b0;
        end else begin
            case (state)
                IDLE: begin
                    usb_power <= 1'b1; // Power on the USB device
                    data_valid <= 1'b0;
                    if (!usb_dp && usb_dm) begin // Start of packet detected
                        state <= START;
                    end
                end

                START: begin
                    // Wait for start bit
                    if (usb_dp && !usb_dm) begin
                        state <= DATA; // Move to data state
                        bit_cnt <= 4'b0; // Reset bit counter
                    end
                end

                DATA: begin
                    // Read data bits
                    if (bit_cnt < 8) begin
                        data_in[bit_cnt] <= usb_dp; // Sample the data line
                        bit_cnt <= bit_cnt + 1;
                    end else begin
                        state <= ACK; // Move to acknowledgment state
                    end
                end

                ACK: begin
                    // Send acknowledgment
                    data_out <= 8'hAA; // Example ACK data
                    data_valid <= 1'b1; // Indicate data is ready
                    state <= IDLE; // Go back to idle
                end

                NACK: begin
                    // Handle NACK if necessary
                    state <= IDLE;
                end

                ERROR: begin
                    // Handle error state if necessary
                    state <= IDLE;
                end

                default: state <= IDLE; // Default to idle
            endcase
        end
    end
endmodule