129 lines
3.5 KiB
Verilog
129 lines
3.5 KiB
Verilog
module fifo_to_tpsram_bridge #(
|
|
parameter DATA_WIDTH = 32,
|
|
parameter ADDR_WIDTH = 11
|
|
)(
|
|
input wire clk,
|
|
input wire reset_n,
|
|
|
|
// FIFO Interface (FWFT)
|
|
input wire [DATA_WIDTH-1:0] fifo_data_out,
|
|
input wire fifo_empty,
|
|
output reg fifo_rd_en,
|
|
|
|
// TPSRAM Interface
|
|
output reg [ADDR_WIDTH-1:0] ram_w_addr,
|
|
output reg [DATA_WIDTH-1:0] ram_w_data,
|
|
output reg ram_w_en,
|
|
|
|
input wire transfer_enable,
|
|
output reg buffer_full
|
|
);
|
|
|
|
// ==============================
|
|
// MARKERS (AFTER BYTE FLIP)
|
|
// ==============================
|
|
localparam START_MARKER = 32'h00112233;
|
|
localparam END_MARKER = 32'hAABBCCDD;
|
|
|
|
// ==============================
|
|
// STATES
|
|
// ==============================
|
|
localparam IDLE = 2'b00,
|
|
IGNORE = 2'b01,
|
|
WRITE = 2'b10;
|
|
|
|
reg [1:0] state, next_state;
|
|
|
|
// ==============================
|
|
// BYTE FLIP (ENDIAN SWAP)
|
|
// ==============================
|
|
wire [31:0] flipped_data;
|
|
assign flipped_data = {fifo_data_out[7:0],
|
|
fifo_data_out[15:8],
|
|
fifo_data_out[23:16],
|
|
fifo_data_out[31:24]};
|
|
|
|
// ==============================
|
|
// ADDRESS COUNTER
|
|
// ==============================
|
|
always @(posedge clk or negedge reset_n) begin
|
|
if (!reset_n) begin
|
|
ram_w_addr <= 0;
|
|
buffer_full <= 0;
|
|
end else if (ram_w_en) begin
|
|
if (ram_w_addr == {ADDR_WIDTH{1'b1}}) begin
|
|
buffer_full <= 1;
|
|
end else begin
|
|
ram_w_addr <= ram_w_addr + 1;
|
|
end
|
|
end
|
|
end
|
|
|
|
// ==============================
|
|
// FSM STATE REGISTER
|
|
// ==============================
|
|
always @(posedge clk or negedge reset_n) begin
|
|
if (!reset_n)
|
|
state <= IDLE;
|
|
else
|
|
state <= next_state;
|
|
end
|
|
|
|
// ==============================
|
|
// NEXT STATE LOGIC
|
|
// ==============================
|
|
always @(*) begin
|
|
next_state = state;
|
|
|
|
case (state)
|
|
IDLE: begin
|
|
if (transfer_enable && !buffer_full)
|
|
next_state = IGNORE;
|
|
end
|
|
|
|
IGNORE: begin
|
|
if (!fifo_empty && flipped_data == START_MARKER)
|
|
next_state = WRITE;
|
|
end
|
|
|
|
WRITE: begin
|
|
if (!fifo_empty && flipped_data == END_MARKER)
|
|
next_state = IGNORE;
|
|
else if (buffer_full)
|
|
next_state = IDLE;
|
|
end
|
|
|
|
default: next_state = IDLE;
|
|
endcase
|
|
end
|
|
|
|
// ==============================
|
|
// OUTPUT LOGIC
|
|
// ==============================
|
|
always @(*) begin
|
|
fifo_rd_en = 0;
|
|
ram_w_en = 0;
|
|
ram_w_data = flipped_data;
|
|
|
|
case (state)
|
|
IGNORE: begin
|
|
// Keep flushing FIFO
|
|
if (!fifo_empty)
|
|
fifo_rd_en = 1;
|
|
end
|
|
|
|
WRITE: begin
|
|
if (!fifo_empty && !buffer_full) begin
|
|
fifo_rd_en = 1;
|
|
|
|
// Do NOT write END marker
|
|
if (flipped_data != END_MARKER) begin
|
|
ram_w_en = 1;
|
|
end
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
|
|
endmodule
|