mirror of https://gerrit.osmocom.org/libusrp
112 lines
3.1 KiB
Verilog
Executable File
112 lines
3.1 KiB
Verilog
Executable File
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 |