2021-07-07 18:53:01 +00:00
|
|
|
module complex_fifo #(
|
2021-10-10 10:33:14 +00:00
|
|
|
parameter ADDR_WIDTH = 10,
|
2021-09-03 20:17:44 +00:00
|
|
|
parameter DATA_WIDTH = 16
|
2021-07-07 18:53:01 +00:00
|
|
|
)
|
|
|
|
(
|
2021-09-03 20:17:44 +00:00
|
|
|
input wire wr_rst_i,
|
|
|
|
input wire wr_clk_i,
|
|
|
|
input wire wr_en_i,
|
|
|
|
input wire [2*DATA_WIDTH-1:0] wr_data_i,
|
2021-07-07 18:53:01 +00:00
|
|
|
|
2021-09-03 20:17:44 +00:00
|
|
|
input wire rd_rst_i,
|
|
|
|
input wire rd_clk_i,
|
|
|
|
input wire rd_en_i,
|
|
|
|
output reg [2*DATA_WIDTH-1:0] rd_data_o,
|
2021-07-07 18:53:01 +00:00
|
|
|
|
2021-09-03 20:17:44 +00:00
|
|
|
output reg full_o,
|
|
|
|
output reg empty_o
|
2021-07-07 18:53:01 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
reg [ADDR_WIDTH-1:0] wr_addr;
|
|
|
|
reg [ADDR_WIDTH-1:0] rd_addr;
|
|
|
|
|
|
|
|
always @(posedge wr_clk_i) begin
|
2021-09-03 20:17:44 +00:00
|
|
|
if (wr_rst_i) begin
|
|
|
|
wr_addr <= 0;
|
|
|
|
full_o <= 1'b0;
|
|
|
|
end else begin
|
|
|
|
if (wr_en_i) begin
|
|
|
|
wr_addr <= wr_addr + 1'b1;
|
|
|
|
full_o <= (wr_addr + 2) == rd_addr;
|
|
|
|
mem_i[wr_addr] <= wr_data_i[31:16];
|
|
|
|
mem_q[wr_addr] <= wr_data_i[15:0];
|
|
|
|
end else begin
|
|
|
|
full_o <= full_o & ((wr_addr + 1'b1) == rd_addr);
|
|
|
|
end
|
|
|
|
end
|
2021-07-07 18:53:01 +00:00
|
|
|
end
|
|
|
|
|
2021-09-04 21:08:57 +00:00
|
|
|
//reg [1:0] cnt;
|
|
|
|
|
2021-07-07 18:53:01 +00:00
|
|
|
always @(posedge rd_clk_i) begin
|
2021-09-03 20:17:44 +00:00
|
|
|
if (rd_rst_i) begin
|
|
|
|
rd_addr <= 0;
|
|
|
|
empty_o <= 1'b1;
|
2021-09-04 21:08:57 +00:00
|
|
|
//cnt <= 2'b00;
|
2021-09-03 20:17:44 +00:00
|
|
|
end else begin
|
|
|
|
if (rd_en_i) begin
|
|
|
|
rd_addr <= rd_addr + 1'b1;
|
|
|
|
empty_o <= (rd_addr + 1) == wr_addr;
|
2021-09-04 21:08:57 +00:00
|
|
|
// big endien to little endien the following is the regular read, and it is
|
|
|
|
// followed by the converted form
|
|
|
|
//rd_data_o[29:16] <= mem_i[rd_addr][13:0];
|
|
|
|
//rd_data_o[15:0] <= mem_q[rd_addr];
|
|
|
|
//rd_data_o[31:30] <= cnt;
|
|
|
|
//cnt <= cnt + 1;
|
|
|
|
rd_data_o[31:24] <= mem_q[rd_addr][7:0];
|
|
|
|
rd_data_o[23:16] <= mem_q[rd_addr][15:8];
|
|
|
|
rd_data_o[15:8] <= mem_i[rd_addr][7:0];
|
|
|
|
rd_data_o[7:0] <= mem_i[rd_addr][15:8];
|
2021-09-03 20:17:44 +00:00
|
|
|
end else begin
|
|
|
|
empty_o <= empty_o & (rd_addr == wr_addr);
|
|
|
|
end
|
|
|
|
end
|
2021-07-07 18:53:01 +00:00
|
|
|
end
|
|
|
|
|
2021-09-03 20:17:44 +00:00
|
|
|
reg [DATA_WIDTH-1:0] mem_i[(1<<ADDR_WIDTH)-1:0];
|
|
|
|
reg [DATA_WIDTH-1:0] mem_q[(1<<ADDR_WIDTH)-1:0];
|
2021-07-07 18:53:01 +00:00
|
|
|
|
2021-09-03 20:17:44 +00:00
|
|
|
endmodule
|