summaryrefslogtreecommitdiff
path: root/usrp/fpga/inband_lib/usb_packet_fifo2.v
blob: d815e4e376da646837ec0bf6d5290e4218ba7ec8 (plain)
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
`default_nettype none

module usb_packet_fifo2(reset, usb_clock, fpga_clock, write_enable, write_data, 
        read_enable, skip_packet, read_data, have_space, pkt_waiting, tx_empty) ;
    
    /* Module parameters */
    parameter                       LOG2_N          =   2 ;
    parameter                       BUS_WIDTH       =   16 ;
    parameter                       FIFO_WIDTH      =   32 ;

    input   wire                    reset;
    input   wire                    usb_clock ;
    input   wire                    fpga_clock ;
    input   wire                    write_enable ;
    input   wire    [BUS_WIDTH-1:0] write_data ;
    input   wire                    read_enable ;
    input   wire                    skip_packet ;
    output  wire   [FIFO_WIDTH-1:0] read_data ;
    output  wire                    have_space ;
    output  wire                    pkt_waiting ;
    output  wire                    tx_empty;

    
    /* Variable for generate statement */
    genvar i ;
    
    /* Local wires for FIFO connections */
    wire                      [2**LOG2_N-1:0]     fifo_resets ;
    reg                       [2**LOG2_N-1:0]     fifo_we ;
    wire                      [2**LOG2_N-1:0]     fifo_re ;
    reg                       [FIFO_WIDTH-1:0]    fifo_wdata[2**LOG2_N-1:0] ;
    wire                      [FIFO_WIDTH-1:0]    fifo_rdata[2**LOG2_N-1:0] ;
    wire                      [2**LOG2_N-1:0]     fifo_rempty ;
    wire                      [2**LOG2_N-1:0]     fifo_rfull ;
    wire                      [2**LOG2_N-1:0]     fifo_wempty ;
    wire                      [2**LOG2_N-1:0]     fifo_wfull ;
    
    /* FIFO Select for read and write ports */
    reg     [LOG2_N-1:0]            fifo_rselect ;
    reg     [LOG2_N-1:0]            fifo_wselect ;
    
    /* Used to convert 16 bits usbdata to the 32 bits wide fifo */
    reg                             word_complete ;
    reg     [BUS_WIDTH-1:0]         write_data_delayed ;
    
    /* Assign have_space to empty flag of currently selected write FIFO */
    assign have_space = fifo_wempty[fifo_wselect] ;
    
    /* Assign pkt_waiting to full flag of currently selected read FIFO */
    assign pkt_waiting = fifo_rfull[fifo_rselect] ;
    
    /* Assign the read_data to the output of the currently selected FIFO */
    assign read_data = fifo_rdata[fifo_rselect] ;
    
    /* Figure out if we're all empty */
    assign tx_empty = !(~fifo_rempty) ;
    
    /* Increment fifo_rselect here */
    always @(posedge fpga_clock)
    begin
        if (reset)
            fifo_rselect <= {2**LOG2_N{1'b0}} ;
        
        if (fifo_rempty[fifo_rselect])
            fifo_rselect <= fifo_rselect + 1 ;
            
        if (skip_packet)
            fifo_rselect <= fifo_rselect + 1 ;
    end
    
    /* Increment fifo_wselect and pack data into 32 bits block  */
    always @(posedge usb_clock, reset)
    begin
        if (reset)
          begin
            fifo_wselect <= {2**LOG2_N{1'b0}} ;
            word_complete <= 0;
          end
            
        if (fifo_wfull[fifo_wselect])
            fifo_wselect <= fifo_wselect + 1 ;
            
        if (write_enable)
          begin
            word_complete <= ~word_complete ;
            
            if (word_complete)
                fifo_wdata[fifo_wselect] <= {write_data_delayed, write_data} ;
            else
                write_data_delayed <= write_data ;
              
            /* Avoid to continue to write in the previous fifo when we have 
               just swichted to the next one */ 
            fifo_we[fifo_wselect-1] <= 0 ;
            
            fifo_we[fifo_wselect] <= write_enable & word_complete ;
          end
    end
    
    /* Generate all the single packet FIFOs */
    generate
        for( i = 0 ; i < 2**LOG2_N ; i = i + 1 )
        begin : generate_single_packet_fifos
            assign fifo_re[i] = (fifo_rselect == i) ? read_enable : 1'b0 ;
            assign fifo_resets[i] = (fifo_rselect == i) ? skip_packet : 1'b0 ;
            fifo_512 single_packet_fifo(.wrclk  ( usb_clock      ),
                                        .rdclk  ( fpga_clock     ),
                                        .aclr   ( fifo_resets[i] ), 
                                        .wrreq  ( fifo_we[i]     ),
                                        .data   ( fifo_wdata[i]  ),
                                        .rdreq  ( fifo_re[i]     ),
                                        .q      ( fifo_rdata[i]  ),
                                        .rdfull ( fifo_rfull[i]  ),
                                        .rdempty( fifo_rempty[i] ),
                                        .wrfull ( fifo_wfull[i]  ),
                                        .wrempty( fifo_wempty[i] ) ) ;
        end
    endgenerate
endmodule