Merged features/inband -r4812:5218 into trunk. This group of changes
[debian/gnuradio] / usrp / fpga / inband_lib / usb_fifo_reader.v
1 module usb_fifo_reader (tx_clock, fifodata, pkt_waiting, reset,
2       rdreq, skip, done_chan, WR_chan, tx_data_bus);
3       
4     /* Module parameters */
5     parameter                       NUM_CHAN      =   2 ;
6     parameter                       WIDTH         =   32 ;
7     
8     input   wire                    tx_clock ;
9     input   wire                    reset ;
10     input   wire       [WIDTH-1:0]  fifodata ;
11     input   wire                    pkt_waiting ;
12     output  reg                     rdreq ;
13     output  reg                     skip ;
14     output  reg        [NUM_CHAN:0] done_chan ;
15     output  reg        [NUM_CHAN:0] WR_chan ;
16     output  reg        [WIDTH-1:0]  tx_data_bus ;
17      
18    
19    
20     /* States definition */
21     `define IDLE                      3'd0
22     `define WAIT                      3'd1
23     `define READ_HEADER               3'd2
24     `define FORWARD_DATA              3'd3
25     `define SKIP_REST                 3'd4
26    
27     /* Channel Ids */
28     `define TXCHAN0                   5'h0
29     `define TXCHAN1                   5'h1
30     `define TXCMD                     5'h1F
31    
32     /* Local registers */
33     reg                      [2:0]    reader_state ;
34     reg                      [2:0]    reader_next_state ;
35     reg                      [4:0]    channel ;
36     reg                      [8:0]    pkt_length ;
37     reg                      [8:0]    read_length ;
38     
39     /* State Machine */
40     always @(posedge tx_clock)
41     begin
42         if (reset) 
43                   begin
44                       reader_state <= `IDLE ;
45             reader_next_state <= `IDLE ;
46             rdreq <= 0 ;
47             skip <= 0 ;
48             WR_chan <= {NUM_CHAN+1{1'b0}} ;
49             done_chan <= {NUM_CHAN+1{1'b0}} ;
50           end
51         else 
52                   begin
53             reader_state = reader_next_state ;
54             
55             case(reader_state)
56             `IDLE: 
57                                 begin
58                                     reader_next_state <= pkt_waiting ? `WAIT : `IDLE ;
59                 rdreq <= pkt_waiting ;
60             end
61      
62             /* Wait for the fifo's data to show up */
63             `WAIT:
64             begin
65                                reader_next_state <= `READ_HEADER ;
66             end
67                
68             `READ_HEADER: 
69                            begin
70                 reader_next_state <= `FORWARD_DATA ;
71                   
72                 /* Read header fields */
73                 channel <= (fifodata & 32'h1F0000) ;
74                 pkt_length <= (fifodata & 16'h1FF) + 4 ;
75                 read_length <= 9'd0 ;
76                   
77                 /* Forward data */
78                 case (channel)
79                     `TXCHAN0: WR_chan[0] <= 1 ;
80                     `TXCHAN1: WR_chan[1] <= 1 ;
81                     `TXCMD:   WR_chan[2] <= 1 ;
82                     default:  WR_chan <= 1 ;
83                 endcase
84                 tx_data_bus <= fifodata ;
85             end
86                
87             `FORWARD_DATA:
88                            begin
89                 read_length <= read_length + 4 ;
90                   
91                 // If end of payload...
92                 if (read_length == pkt_length)
93                                     begin
94                     reader_next_state <= `SKIP_REST ;
95                     /* If the packet is 512 bytes, don't skip */
96                     skip <= pkt_length < 506 ;
97                      
98                     /* Data pushing done */
99                     WR_chan <= {NUM_CHAN+1{1'b0}} ;
100                     
101                     /* Notify next block */
102                     case (channel)
103                        `TXCHAN0: done_chan[0] <= 1 ;
104                        `TXCHAN1: done_chan[1] <= 1 ;
105                        `TXCMD:   done_chan[2] <= 1 ;
106                        default:  done_chan[0] <= 1 ;
107                     endcase
108                 end
109                 else if (read_length == pkt_length - 4)
110                     rdreq <= 0 ;
111                     
112                 /* Forward data */
113                 tx_data_bus <= fifodata ;
114             end
115                
116             `SKIP_REST: 
117                            begin
118                                reader_next_state <= pkt_waiting ? `READ_HEADER : `IDLE ;
119                 done_chan <= {NUM_CHAN+1{1'b0}} ;
120                 rdreq <= pkt_waiting ;
121                 skip <= 0 ;
122             end
123                 
124             default: 
125                            begin
126                 reader_state <= `IDLE;
127                 reader_next_state <= `IDLE;
128             end
129             endcase
130         end
131     end  
132 endmodule
133        
134    
135