diff options
Diffstat (limited to 'usrp/fpga/inband_lib/usb_packet_fifo2.v')
-rwxr-xr-x | usrp/fpga/inband_lib/usb_packet_fifo2.v | 119 |
1 files changed, 119 insertions, 0 deletions
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 |