Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / fpga / inband_lib / usb_packet_fifo.v
diff --git a/usrp/fpga/inband_lib/usb_packet_fifo.v b/usrp/fpga/inband_lib/usb_packet_fifo.v
new file mode 100755 (executable)
index 0000000..c416e2b
--- /dev/null
@@ -0,0 +1,112 @@
+module usb_packet_fifo 
+  ( input       reset,
+    input       clock_in,
+    input       clock_out,
+    input       [15:0]ram_data_in,
+    input       write_enable,
+    output  reg [15:0]ram_data_out,
+    output  reg pkt_waiting,
+    output  reg have_space,
+    input       read_enable,
+    input       skip_packet          ) ;
+
+    /* Some parameters for usage later on */
+    parameter DATA_WIDTH = 16 ;
+    parameter NUM_PACKETS = 4 ;
+
+    /* Create the RAM here */
+    reg [DATA_WIDTH-1:0] usb_ram [256*NUM_PACKETS-1:0] ;
+
+    /* Create the address signals */
+    reg [7-2+NUM_PACKETS:0] usb_ram_ain ;
+    reg [7:0] usb_ram_offset ;
+    reg [1:0] usb_ram_packet ;
+
+    wire [7-2+NUM_PACKETS:0] usb_ram_aout ;
+    reg isfull;
+
+    assign usb_ram_aout = {usb_ram_packet,usb_ram_offset} ;
+    
+    // Check if there is one full packet to process
+    always @(usb_ram_ain, usb_ram_aout)
+    begin
+        if (reset)
+            pkt_waiting <= 0;
+        else if (usb_ram_ain == usb_ram_aout)
+            pkt_waiting <= isfull;
+        else if (usb_ram_ain > usb_ram_aout)
+            pkt_waiting <= (usb_ram_ain - usb_ram_aout) >= 256;
+        else
+            pkt_waiting <= (usb_ram_ain + 10'b1111111111 - usb_ram_aout) >= 256;
+    end
+    
+    // Check if there is room
+    always @(usb_ram_ain, usb_ram_aout)
+    begin
+        if (reset)
+            have_space <= 1;
+        else if (usb_ram_ain == usb_ram_aout)
+            have_space <= ~isfull;   
+        else if (usb_ram_ain > usb_ram_aout)
+            have_space <= (usb_ram_ain - usb_ram_aout) <= 256 * (NUM_PACKETS - 1);
+        else
+            have_space <= (usb_ram_aout - usb_ram_ain) >= 256;
+    end
+
+    /* RAM Write Address process */
+    always @(posedge clock_in)
+    begin
+        if( reset )
+            usb_ram_ain <= 0 ;
+        else
+            if( write_enable ) 
+              begin
+                usb_ram_ain <= usb_ram_ain + 1 ;
+                if (usb_ram_ain + 1 == usb_ram_aout)
+                   isfull <= 1;
+              end
+    end
+
+    /* RAM Writing process */
+    always @(posedge clock_in)
+    begin
+        if( write_enable ) 
+          begin
+            usb_ram[usb_ram_ain] <= ram_data_in ;
+          end
+    end
+
+    /* RAM Read Address process */
+    always @(posedge clock_out)
+    begin
+        if( reset ) 
+          begin
+            usb_ram_packet <= 0 ;
+            usb_ram_offset <= 0 ;
+            isfull <= 0;
+          end
+        else
+            if( skip_packet )
+              begin
+                usb_ram_packet <= usb_ram_packet + 1 ;
+                usb_ram_offset <= 0 ;
+              end
+            else if(read_enable)
+                if( usb_ram_offset == 8'b11111111 )
+                  begin
+                    usb_ram_offset <= 0 ;
+                    usb_ram_packet <= usb_ram_packet + 1 ;
+                  end
+                else
+                    usb_ram_offset <= usb_ram_offset + 1 ;
+            if (usb_ram_ain == usb_ram_aout)
+               isfull <= 0;                       
+    end
+
+    /* RAM Reading Process */
+    always @(posedge clock_out)
+    begin
+        ram_data_out <= usb_ram[usb_ram_aout] ;
+    end
+
+endmodule
\ No newline at end of file