top.v 2.23 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
`default_nettype none

module top
        (
         inout wire [7:0] data_io,
         output reg [7:0] rdata_o,
         input wire [7:0] wdata_i,
         input wire       rxf_n_i,
         input wire       txe_n_i,
         output reg       rd_n_o,
         output reg       wr_n_o,
         output reg       siwua_n_o,
         input wire       clk_i,
         output reg       oe_n_o,
         input wire       suspend_n_i
         );

        initial begin
                rdata_o = {8{1'b0}};
                rd_n_o = 1;
                wr_n_o = 1;
                siwua_n_o = 1; /* Never flush TX data. */
        end

        assign data_io = (!txe_n_i && !wr_n_o) ? wdata_i : {8{1'bz}};

        always @(posedge clk_i, negedge suspend_n_i) begin
                if (!suspend_n_i) begin
                        wr_n_o <= 1;
                        rd_n_o <= 1;
                        oe_n_o <= 1;
                        rdata_o <= {8{1'b0}};
                end
                else begin
                        // Give TX bus precedence.
                        if (!txe_n_i) begin
                                wr_n_o <= 0;
                                rd_n_o <= 1;
                                oe_n_o <= 1;
                                rdata_o <= {8{1'b0}};
                        end
                        // oe_n_o must be driven low at least one period before we can read.
                        else if (!rxf_n_i && oe_n_o) begin
                                wr_n_o <= 1;
                                rd_n_o <= 1;
                                oe_n_o <= 0;
                                rdata_o <= {8{1'b0}};
                        end
                        else if (!rxf_n_i && !oe_n_o) begin
                                wr_n_o <= 1;
                                rd_n_o <= 0;
                                oe_n_o <= 0;
                                rdata_o <= data_io;
                        end
                        else begin
                                wr_n_o <= 1;
                                rd_n_o <= 1;
                                oe_n_o <= 1;
                                rdata_o <= {8{1'b0}};
                        end
                end // else: !if(!suspend_n_i)
        end

endmodule // usb