manta/test/functional_sim/bit_fifo_tb/bit_fifo.v

90 lines
2.7 KiB
Verilog

`default_nettype none
`timescale 1ns/1ps
module bit_fifo(
input wire clk,
input wire en,
input wire [IWIDTH-1:0] in,
input wire in_valid,
output reg [OWIDTH-1:0] out,
output reg out_valid);
parameter IWIDTH = 0;
parameter OWIDTH = 0;
localparam BWIDTH = OWIDTH-1 + IWIDTH;
reg [OWIDTH-1:0] buffer;
reg [$clog2(OWIDTH)-1:0] buffer_size;
initial begin
buffer = 0;
buffer_size = 0;
out = 0;
out_valid = 0;
end
reg [OWIDTH-1:0] mask;
reg [OWIDTH-1:0] top_half;
reg [OWIDTH-1:0] bottom_half;
reg [OWIDTH-1:0] joined_halves;
always @(*) begin
mask = (1 << buffer_size) - 1;
top_half = (buffer & mask) << (OWIDTH - buffer_size);
bottom_half = in >> (IWIDTH- (OWIDTH - buffer_size));
joined_halves = top_half | bottom_half;
end
always @(posedge clk) begin
out_valid <= 0;
// RUN state
if(en && in_valid) begin
// this module should spit out values as soon as it's able,
// so if we'll have enough once the present value's clocked in,
// then we'll need to immediately assign the output as a combination
// of what's in the buffer and what's on the line.
if(buffer_size + IWIDTH >= OWIDTH) begin
// compute buffer size
// -> everything that was in the buffer is now in the output,
// so what we put back in the buffer is purely what's left over
// from our input data once we've sliced out what we need
buffer_size <= buffer_size + IWIDTH - OWIDTH;
// compute buffer contents
buffer <= ( (1 << (buffer_size + IWIDTH - OWIDTH)) - 1 ) & in;
/*
$display("buffer_size: %h in: %b ", buffer_size, in);
$display(" buffer: %b", buffer);
$display(" mask: %b", mask);
$display(" top_half: %b", top_half);
$display(" bottom_half: %b", bottom_half);
$display(" out: %b \n", joined_halves);
*/
// compute output
out <= joined_halves;
out_valid <= 1;
end
else begin
// shift into the right side of the buffer
buffer <= {buffer[BWIDTH-1-IWIDTH:0], in};
buffer_size <= buffer_size + IWIDTH;
end
end
// FLUSH state
else if(buffer_size > 0) begin
out <= (buffer) & ((1 << buffer_size) - 1);
out_valid <= 1;
buffer_size <= 0;
end
end
endmodule
`default_nettype wire