summaryrefslogtreecommitdiff
path: root/usrp/fpga/inband_lib
diff options
context:
space:
mode:
Diffstat (limited to 'usrp/fpga/inband_lib')
-rwxr-xr-xusrp/fpga/inband_lib/chan_fifo_reader.v197
-rwxr-xr-xusrp/fpga/inband_lib/data_packet_fifo.v128
-rwxr-xr-xusrp/fpga/inband_lib/tx_buffer_inband.v183
-rwxr-xr-xusrp/fpga/inband_lib/usb_fifo_reader.v135
-rwxr-xr-xusrp/fpga/inband_lib/usb_packet_fifo.v112
-rwxr-xr-xusrp/fpga/inband_lib/usb_packet_fifo2.v119
6 files changed, 874 insertions, 0 deletions
diff --git a/usrp/fpga/inband_lib/chan_fifo_reader.v b/usrp/fpga/inband_lib/chan_fifo_reader.v
new file mode 100755
index 000000000..2b3178da7
--- /dev/null
+++ b/usrp/fpga/inband_lib/chan_fifo_reader.v
@@ -0,0 +1,197 @@
+module chan_fifo_reader
+ ( input reset,
+ input tx_clock,
+ input tx_strobe,
+ input [31:0]adc_clock,
+ input [3:0] samples_format,
+ input [15:0] fifodata,
+ input pkt_waiting,
+ output reg rdreq,
+ output reg skip,
+ output reg [15:0]tx_q,
+ output reg [15:0]tx_i,
+ output reg overrun,
+ output reg underrun) ;
+
+ // Should not be needed if adc clock rate < tx clock rate
+ `define JITTER 5
+
+ //Samples format
+ // 16 bits interleaved complex samples
+ `define QI16 4'b0
+
+ // States
+ `define IDLE 4'd0
+ `define READ 4'd1
+ `define HEADER1 4'd2
+ `define HEADER2 4'd3
+ `define TIMESTAMP1 4'd4
+ `define TIMESTAMP2 4'd5
+ `define WAIT 4'd6
+ `define WAITSTROBE 4'd7
+ `define SENDWAIT 4'd8
+ `define SEND 4'd9
+ `define FEED 4'd10
+ `define DISCARD 4'd11
+
+ // State registers
+ reg[3:0] reader_state;
+ reg[3:0] reader_next_state;
+
+ //Variables
+ reg[8:0] payload_len;
+ reg[8:0] read_len;
+ reg[31:0] timestamp;
+ reg burst;
+ reg qsample;
+ always @(posedge tx_clock)
+ begin
+ if (reset)
+ begin
+ reader_state <= `IDLE;
+ reader_next_state <= `IDLE;
+ rdreq <= 0;
+ skip <= 0;
+ overrun <= 0;
+ underrun <= 0;
+ burst <= 0;
+ qsample <= 1;
+ end
+ else
+ begin
+ reader_state = reader_next_state;
+ case (reader_state)
+ `IDLE:
+ begin
+ if (pkt_waiting == 1)
+ begin
+ reader_next_state <= `READ;
+ rdreq <= 1;
+ underrun <= 0;
+ end
+ else if (burst == 1)
+ underrun <= 1;
+ end
+
+ // Just wait for the fifo data to arrive
+ `READ:
+ begin
+ reader_next_state <= `HEADER1;
+ end
+
+ // First part of the header
+ `HEADER1:
+ begin
+ reader_next_state <= `HEADER2;
+
+ //Check Start burst flag
+ if (fifodata[3] == 1)
+ burst <= 1;
+
+ if (fifodata[4] == 1)
+ burst <= 0;
+ end
+
+ // Read payload length
+ `HEADER2:
+ begin
+ payload_len <= (fifodata & 16'h1FF);
+ read_len <= 9'd0;
+ reader_next_state <= `TIMESTAMP1;
+ end
+
+ `TIMESTAMP1:
+ begin
+ timestamp <= {fifodata, 16'b0};
+ rdreq <= 0;
+ reader_next_state <= `TIMESTAMP2;
+ end
+
+ `TIMESTAMP2:
+ begin
+ timestamp <= timestamp + fifodata;
+ reader_next_state <= `WAIT;
+ end
+
+ // Decide if we wait, send or discard samples
+ `WAIT:
+ begin
+ // Wait a little bit more
+ if (timestamp > adc_clock + `JITTER)
+ reader_next_state <= `WAIT;
+ // Let's send it
+ else if ((timestamp < adc_clock + `JITTER
+ && timestamp > adc_clock)
+ || timestamp == 32'hFFFFFFFF)
+ begin
+ reader_next_state <= `WAITSTROBE;
+ end
+ // Outdated
+ else if (timestamp < adc_clock)
+ begin
+ reader_next_state <= `DISCARD;
+ skip <= 1;
+ end
+ end
+
+ // Wait for the transmit chain to be ready
+ `WAITSTROBE:
+ begin
+ // If end of payload...
+ if (read_len == payload_len)
+ begin
+ reader_next_state <= `DISCARD;
+ skip <= (payload_len < 508);
+ end
+
+ if (tx_strobe == 1)
+ reader_next_state <= `SENDWAIT;
+ end
+
+ `SENDWAIT:
+ begin
+ rdreq <= 1;
+ reader_next_state <= `SEND;
+ end
+
+ // Send the samples to the tx_chain
+ `SEND:
+ begin
+ reader_next_state <= `WAITSTROBE;
+ rdreq <= 0;
+ read_len <= read_len + 2;
+ case(samples_format)
+ `QI16:
+ begin
+ tx_q <= qsample ? fifodata : 16'bZ;
+ tx_i <= ~qsample ? fifodata : 16'bZ;
+ qsample <= ~ qsample;
+ end
+ default:
+ begin
+ // Assume 16 bits complex samples by default
+ $display ("Error unknown samples format");
+ tx_q <= qsample ? fifodata : 16'bZ;
+ tx_i <= ~qsample ? fifodata : 16'bZ;
+ qsample <= ~ qsample;
+ end
+ endcase
+ end
+
+ `DISCARD:
+ begin
+ skip <= 0;
+ reader_next_state <= `IDLE;
+ end
+
+ default:
+ begin
+ $display ("Error unknown state");
+ reader_state <= `IDLE;
+ reader_next_state <= `IDLE;
+ end
+ endcase
+ end
+ end
+
+endmodule \ No newline at end of file
diff --git a/usrp/fpga/inband_lib/data_packet_fifo.v b/usrp/fpga/inband_lib/data_packet_fifo.v
new file mode 100755
index 000000000..5b37b14ea
--- /dev/null
+++ b/usrp/fpga/inband_lib/data_packet_fifo.v
@@ -0,0 +1,128 @@
+module data_packet_fifo
+ ( input reset,
+ input clock,
+ input [15:0]ram_data_in,
+ input write_enable,
+ output reg have_space,
+ output reg [15:0]ram_data_out,
+ output reg pkt_waiting,
+ input read_enable,
+ input pkt_complete,
+ 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:0] usb_ram_offset_out ;
+ reg [1:0] usb_ram_packet_out ;
+ reg [7:0] usb_ram_offset_in ;
+ reg [1:0] usb_ram_packet_in ;
+
+ wire [7-2+NUM_PACKETS:0] usb_ram_aout ;
+ wire [7-2+NUM_PACKETS:0] usb_ram_ain ;
+ reg isfull;
+
+ assign usb_ram_aout = {usb_ram_packet_out, usb_ram_offset_out} ;
+ assign usb_ram_ain = {usb_ram_packet_in, usb_ram_offset_in} ;
+
+ // 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 <= 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)
+ begin
+ if( reset )
+ begin
+ usb_ram_offset_in <= 0 ;
+ usb_ram_packet_in <= 0 ;
+ end
+ else
+ if( pkt_complete )
+ begin
+ usb_ram_packet_in <= usb_ram_packet_in + 1;
+ usb_ram_offset_in <= 0;
+ end
+ else if( write_enable )
+ begin
+ if (usb_ram_offset_in == 8'b11111111)
+ begin
+ usb_ram_offset_in <= 0;
+ usb_ram_packet_in <= usb_ram_packet_in + 1;
+ end
+ else
+ usb_ram_offset_in <= usb_ram_offset_in + 1 ;
+ if (usb_ram_ain + 1 == usb_ram_aout)
+ isfull <= 1;
+ end
+ end
+
+ /* RAM Writing process */
+ always @(posedge clock)
+ begin
+ if( write_enable )
+ begin
+ usb_ram[usb_ram_ain] <= ram_data_in ;
+ end
+ end
+
+ /* RAM Read Address process */
+ always @(posedge clock)
+ begin
+ if( reset )
+ begin
+ usb_ram_packet_out <= 0 ;
+ usb_ram_offset_out <= 0 ;
+ isfull <= 0;
+ end
+ else
+ if( skip_packet )
+ begin
+ usb_ram_packet_out <= usb_ram_packet_out + 1 ;
+ usb_ram_offset_out <= 0 ;
+ end
+ else if(read_enable) begin
+ if( usb_ram_offset_out == 8'b11111111 )
+ begin
+ usb_ram_offset_out <= 0 ;
+ usb_ram_packet_out <= usb_ram_packet_out + 1 ;
+ end
+ else
+ usb_ram_offset_out <= usb_ram_offset_out + 1 ;
+ end
+ if (usb_ram_ain == usb_ram_aout)
+ isfull <= 0;
+ end
+
+ /* RAM Reading Process */
+ always @(posedge clock)
+ begin
+ ram_data_out <= usb_ram[usb_ram_aout] ;
+ end
+
+endmodule
diff --git a/usrp/fpga/inband_lib/tx_buffer_inband.v b/usrp/fpga/inband_lib/tx_buffer_inband.v
new file mode 100755
index 000000000..56c07807a
--- /dev/null
+++ b/usrp/fpga/inband_lib/tx_buffer_inband.v
@@ -0,0 +1,183 @@
+module tx_buffer_inband
+ ( input usbclk,
+ input bus_reset, // Used here for the 257-Hack to fix the FX2 bug
+ input reset, // standard DSP-side reset
+ input [15:0] usbdata,
+ input wire WR,
+ output wire have_space,
+ output reg tx_underrun,
+ input wire [3:0] channels,
+ output [15:0] tx_i_0,
+ output [15:0] tx_q_0,
+ output [15:0] tx_i_1,
+ output [15:0] tx_q_1,
+ //NOT USED
+ output reg [15:0] tx_i_2,
+ output reg [15:0] tx_q_2,
+ output reg [15:0] tx_i_3,
+ output reg [15:0] tx_q_3,
+ input txclk,
+ input txstrobe,
+ input clear_status,
+ output wire tx_empty,
+ output [11:0] debugbus
+ );
+
+ wire [15:0] tx_data_bus;
+
+ wire WR_chan_0;
+ wire chan_0_done;
+ wire OR0;
+ wire UR0;
+
+ wire WR_chan_1;
+ wire chan_1_done;
+ wire OR1;
+ wire UR1;
+
+ // NOT USED yet
+ wire WR_cmd;
+ wire cmd_done;
+
+ //EXTERNAL REGISTER
+ //TODO: increment it
+ reg [31:0] time_counter;
+ reg [7:0] txstrobe_rate_0;
+ reg [7:0] txstrobe_rate_1;
+
+
+ //Usb block
+ wire [15:0] tupf_fifodata;
+ wire tupf_pkt_waiting;
+ wire tupf_rdreq;
+ wire tupf_skip;
+ wire tupf_have_space;
+
+ usb_packet_fifo2 tx_usb_packet_fifo
+ ( .reset (reset),
+ .usb_clock (usbclk),
+ .fpga_clock (txclk),
+ .write_data (usbdata),
+ .write_enable (WR),
+ .read_data (tupf_fifodata),
+ .pkt_waiting (tupf_pkt_waiting),
+ .read_enable (tupf_rdreq),
+ .skip_packet (tupf_skip),
+ .have_space (tupf_have_space),
+ .tx_empty (tx_empty)
+ );
+
+ usb_fifo_reader tx_usb_packet_reader (
+ .reset(reset),
+ .tx_clock(txclk),
+ .tx_data_bus(tx_data_bus),
+ .WR_chan_0(WR_chan_0),
+ .WR_chan_1(WR_chan_1),
+ .WR_cmd(WR_cmd),
+ .chan_0_done(chan_0_done),
+ .chan_1_done(chan_1_done),
+ .cmd_done(cmd_done),
+ .rdreq(tupf_rdreq),
+ .skip(tupf_skip),
+ .pkt_waiting(tupf_pkt_waiting),
+ .fifodata(tupf_fifodata)
+ );
+
+
+ //Channel 0 block
+ wire [15:0] tdpf_fifodata_0;
+ wire tdpf_pkt_waiting_0;
+ wire tdpf_rdreq_0;
+ wire tdpf_skip_0;
+ wire tdpf_have_space_0;
+ wire txstrobe_chan_0;
+
+ data_packet_fifo tx_data_packet_fifo_0
+ ( .reset(reset),
+ .clock(txclk),
+ .ram_data_in(tx_data_bus),
+ .write_enable(WR_chan_0),
+ .ram_data_out(tdpf_fifodata_0),
+ .pkt_waiting(tdpf_pkt_waiting_0),
+ .read_enable(tdpf_rdreq_0),
+ .pkt_complete(chan_0_done),
+ .skip_packet(tdpf_skip_0),
+ .have_space(tdpf_have_space_0)
+ );
+
+ strobe_gen strobe_gen_0
+ ( .clock(txclk),
+ .reset(reset),
+ .enable(1'b1),
+ .rate(txstrobe_rate_0),
+ .strobe_in(txstrobe),
+ .strobe(txstrobe_chan_0)
+ );
+
+ chan_fifo_reader tx_chan_0_reader (
+ .reset(reset),
+ .tx_clock(txclk),
+ .tx_strobe(txstrobe),
+ //.tx_strobe(txstrobe_chan_0),
+ .adc_clock(time_counter),
+ .samples_format(4'b0),
+ .tx_q(tx_q_0),
+ .tx_i(tx_i_0),
+ .overrun(OR0),
+ .underrun(UR0),
+ .skip(tdpf_skip_0),
+ .rdreq(tdpf_rdreq_0),
+ .fifodata(tdpf_fifodata_0),
+ .pkt_waiting(tdpf_pkt_waiting_0)
+ );
+
+
+ //Channel 1 block
+ wire [15:0] tdpf_fifodata_1;
+ wire tdpf_pkt_waiting_1;
+ wire tdpf_rdreq_1;
+ wire tdpf_skip_1;
+ wire tdpf_have_space_1;
+ wire txstrobe_chan_1;
+
+ data_packet_fifo tx_data_packet_fifo_1
+ ( .reset(reset),
+ .clock(txclk),
+ .ram_data_in(tx_data_bus),
+ .write_enable(WR_chan_1),
+ .ram_data_out(tdpf_fifodata_1),
+ .pkt_waiting(tdpf_pkt_waiting_1),
+ .read_enable(tdpf_rdreq_1),
+ .pkt_complete(chan_1_done),
+ .skip_packet(tdpf_skip_1),
+ .have_space(tdpf_have_space_1)
+ );
+
+ strobe_gen strobe_gen_1
+ ( .clock(txclk),
+ .reset(reset),
+ .enable(1'b1),
+ .rate(txstrobe_rate_1),
+ .strobe_in(txstrobe),
+ .strobe(txstrobe_chan_1)
+ );
+
+ chan_fifo_reader tx_chan_1_reader (
+ .reset(reset),
+ .tx_clock(txclk),
+ .tx_strobe(txstrobe),
+ //.tx_strobe(txstrobe_chan_1),
+ .adc_clock(time_counter),
+ .samples_format(4'b0),
+ .tx_q(tx_q_1),
+ .tx_i(tx_i_1),
+ .overrun(OR1),
+ .underrun(UR1),
+ .skip(tdpf_skip_1),
+ .rdreq(tdpf_rdreq_1),
+ .fifodata(tdpf_fifodata_1),
+ .pkt_waiting(tdpf_pkt_waiting_1)
+ );
+
+endmodule // tx_buffer
+
diff --git a/usrp/fpga/inband_lib/usb_fifo_reader.v b/usrp/fpga/inband_lib/usb_fifo_reader.v
new file mode 100755
index 000000000..170c70fd4
--- /dev/null
+++ b/usrp/fpga/inband_lib/usb_fifo_reader.v
@@ -0,0 +1,135 @@
+module usb_fifo_reader (tx_clock, fifodata, pkt_waiting, reset,
+ rdreq, skip, done_chan, WR_chan, tx_data_bus);
+
+ /* Module parameters */
+ parameter NUM_CHAN = 2 ;
+ parameter WIDTH = 32 ;
+
+ input wire tx_clock ;
+ input wire reset ;
+ input wire [WIDTH-1:0] fifodata ;
+ input wire pkt_waiting ;
+ output reg rdreq ;
+ output reg skip ;
+ output reg [NUM_CHAN:0] done_chan ;
+ output reg [NUM_CHAN:0] WR_chan ;
+ output reg [WIDTH-1:0] tx_data_bus ;
+
+
+
+ /* States definition */
+ `define IDLE 3'd0
+ `define WAIT 3'd1
+ `define READ_HEADER 3'd2
+ `define FORWARD_DATA 3'd3
+ `define SKIP_REST 3'd4
+
+ /* Channel Ids */
+ `define TXCHAN0 5'h0
+ `define TXCHAN1 5'h1
+ `define TXCMD 5'h1F
+
+ /* Local registers */
+ reg [2:0] reader_state ;
+ reg [2:0] reader_next_state ;
+ reg [4:0] channel ;
+ reg [8:0] pkt_length ;
+ reg [8:0] read_length ;
+
+ /* State Machine */
+ always @(posedge tx_clock)
+ begin
+ if (reset)
+ begin
+ reader_state <= `IDLE ;
+ reader_next_state <= `IDLE ;
+ rdreq <= 0 ;
+ skip <= 0 ;
+ WR_chan <= {NUM_CHAN+1{1'b0}} ;
+ done_chan <= {NUM_CHAN+1{1'b0}} ;
+ end
+ else
+ begin
+ reader_state = reader_next_state ;
+
+ case(reader_state)
+ `IDLE:
+ begin
+ reader_next_state <= pkt_waiting ? `WAIT : `IDLE ;
+ rdreq <= pkt_waiting ;
+ end
+
+ /* Wait for the fifo's data to show up */
+ `WAIT:
+ begin
+ reader_next_state <= `READ_HEADER ;
+ end
+
+ `READ_HEADER:
+ begin
+ reader_next_state <= `FORWARD_DATA ;
+
+ /* Read header fields */
+ channel <= (fifodata & 32'h1F0000) ;
+ pkt_length <= (fifodata & 16'h1FF) + 4 ;
+ read_length <= 9'd0 ;
+
+ /* Forward data */
+ case (channel)
+ `TXCHAN0: WR_chan[0] <= 1 ;
+ `TXCHAN1: WR_chan[1] <= 1 ;
+ `TXCMD: WR_chan[2] <= 1 ;
+ default: WR_chan <= 1 ;
+ endcase
+ tx_data_bus <= fifodata ;
+ end
+
+ `FORWARD_DATA:
+ begin
+ read_length <= read_length + 4 ;
+
+ // If end of payload...
+ if (read_length == pkt_length)
+ begin
+ reader_next_state <= `SKIP_REST ;
+ /* If the packet is 512 bytes, don't skip */
+ skip <= pkt_length < 506 ;
+
+ /* Data pushing done */
+ WR_chan <= {NUM_CHAN+1{1'b0}} ;
+
+ /* Notify next block */
+ case (channel)
+ `TXCHAN0: done_chan[0] <= 1 ;
+ `TXCHAN1: done_chan[1] <= 1 ;
+ `TXCMD: done_chan[2] <= 1 ;
+ default: done_chan[0] <= 1 ;
+ endcase
+ end
+ else if (read_length == pkt_length - 4)
+ rdreq <= 0 ;
+
+ /* Forward data */
+ tx_data_bus <= fifodata ;
+ end
+
+ `SKIP_REST:
+ begin
+ reader_next_state <= pkt_waiting ? `READ_HEADER : `IDLE ;
+ done_chan <= {NUM_CHAN+1{1'b0}} ;
+ rdreq <= pkt_waiting ;
+ skip <= 0 ;
+ end
+
+ default:
+ begin
+ reader_state <= `IDLE;
+ reader_next_state <= `IDLE;
+ end
+ endcase
+ end
+ end
+endmodule
+
+
+ \ No newline at end of file
diff --git a/usrp/fpga/inband_lib/usb_packet_fifo.v b/usrp/fpga/inband_lib/usb_packet_fifo.v
new file mode 100755
index 000000000..c416e2bdb
--- /dev/null
+++ b/usrp/fpga/inband_lib/usb_packet_fifo.v
@@ -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
diff --git a/usrp/fpga/inband_lib/usb_packet_fifo2.v b/usrp/fpga/inband_lib/usb_packet_fifo2.v
new file mode 100755
index 000000000..d815e4e37
--- /dev/null
+++ b/usrp/fpga/inband_lib/usb_packet_fifo2.v
@@ -0,0 +1,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 \ No newline at end of file