1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-26 11:51:56 +00:00
Files
Gehstock.Mist_FPGA/common/mist/ide_fifo.v
Gyorgy Szombathelyi fe94350806 Update MiST modules
2022-10-09 18:13:55 +02:00

87 lines
2.7 KiB
Verilog

module ide_fifo
(
input clk, // bus clock
input clk_en,
input reset, // reset
input [15:0] data_in, // data in
output reg [15:0] data_out, // data out
input rd, // read from fifo
input wr, // write to fifo
input packet_in,
input packet_out,
input [12:0] packet_count,
output packet_in_last, // last word is read in packet_in state
output full, // fifo is full
output empty, // fifo is empty
output last_out, // the last word of a sector is being read
output last_in // the last word of a sector is being written
);
// local signals and registers
reg [15:0] mem [4095:0]; // 16 bit wide fifo memory
reg [12:0] inptr; // fifo input pointer
reg [12:0] outptr; // fifo output pointer
wire empty_rd; // fifo empty flag (set immediately after reading the last word)
reg empty_wr; // fifo empty flag (set one clock after writting the empty fifo)
reg rd_old;
reg wr_old;
always @(posedge clk)
if (clk_en) begin
rd_old <= rd;
wr_old <= wr;
end
// main fifo memory (implemented using synchronous block ram)
always @(posedge clk)
if (clk_en) begin
if (wr)
mem[inptr[11:0]] <= data_in;
end
always @(posedge clk)
if (clk_en)
data_out <= mem[outptr[11:0]];
// fifo write pointer control
always @(posedge clk)
if (clk_en) begin
if (reset)
inptr <= 0;
else if (wr_old & ~wr)
inptr <= inptr + 1'd1;
end
// fifo read pointer control
always @(posedge clk)
if (clk_en) begin
if (reset)
outptr <= 0;
else if (rd_old & ~rd)
outptr <= outptr + 1'd1;
end
// the empty flag is set immediately after reading the last word from the fifo
assign empty_rd = inptr==outptr ? 1'b1 : 1'b0;
// after writting empty fifo the empty flag is delayed by one clock to handle ram write delay
always @(posedge clk)
if (clk_en)
empty_wr <= empty_rd;
assign empty = empty_rd | empty_wr;
// at least 512 bytes are in FIFO
// this signal is activated when 512th byte is written to the empty fifo
// then it's deactivated when 512th byte is read from the fifo (hysteresis)
// special handlig of packet commands
assign full = (inptr[12:8] != outptr[12:8] && !packet_in && !packet_out) ||
(packet_in && inptr == packet_count && inptr != outptr) ||
(packet_out && inptr == packet_count /*&& inptr != outptr*/);
assign packet_in_last = packet_in && inptr == packet_count && inptr == outptr && inptr != 0;
assign last_out = outptr[7:0] == 8'hFF ? 1'b1 : 1'b0;
assign last_in = inptr [7:0] == 8'hFF ? 1'b1 : 1'b0;
endmodule