📄 fifo_rev1.0.v
字号:
////////////////////////////////////////////////////
//
// Module Name: fifo
// Descr: Synchronous FIFO for Input
// Using 256x16 Dual Port BRAM
// Author: James Rosenthal
// Date: 10/28/04
//
//
// Version Date Modifications
// ---------------------------------
// 0.0 10/28/04 - Initial
// 0.1 12/20/04 - Add Address Pointer Outputs
// for visibility at higher
// level modules
// 0.2 02/10/05 - Address Pointers Updated on Negative Edge
// - Write to Address waddr-1
// - Needs Fixes to Previous Statements, but
// seems to work in implementation.
// 1.0 02/20/05 - FIFO interconnect Module
// - Connects Address Pointers, Flags, and
// Block RAM Modules
//
/////////////////////////////////////////////////////
`timescale 1ns / 10ps
module fifo(
clk, // Clock Sync'd for both R&W
din, // 13-Bit Data Input
wr_en, // Write Enable
rd_en, // Read Enable
rst, // Active Low Reset
dout, // 13-bit Data Output
full, // Full Flag
empty, // Empty Flag
raddr, // Read Address Pointer
waddr // Write Address Pointer
);
//
// Inputs & Outputs
//
input [12:0] din; // Data Input
input wr_en; // Write Enable
input rd_en; // Read Enable
input rst; // Active Low Reset
input clk; // Input clk
output [12:0] dout; // Data Output
output [ 7:0] raddr;// Read Address Pointer
output [ 7:0] waddr;// Write Address Pointer
output full; // Full Flag
output empty; // Empty Flag
//
// Registers & Wires
//
wire [15:0] doutf;
wire [7:0] raddr, waddr;
wire empty, full;
//
// Behavioral Description
//
assign dout = doutf[12:0];
// Empty/Full Flag Generation
flags flags(
.read_addr(raddr),
.write_addr(waddr),
.empty(empty),
.full(full));
// Address Pointers
addr_ptr addr_ptr(
.clk(clk),
.rst(rst),
.write_addr(waddr),
.read_addr(raddr),
.empty(empty),
.full(full),
.rd_en(rd_en),
.wr_en(wr_en)
);
// Instantiate Block RAM
// A - Write, B - Read
bram_256x16 ram(
.addra(waddr[7:0]),
.addrb(raddr[7:0]),
.clka(clk),
.clkb(clk),
.dina({3'h0,din}),
.doutb(doutf),
.enb(rd_en & !empty),
.sinita(rst),
.sinitb(rst),
.wea(wr_en & !full)
);
endmodule
////////////////////////////////////////////////////
//
// Module Name: flags
// Descr: Synchronous flag generation for
// Synchronous FIFO
// Author: James Rosenthal
// Date: 10/28/04
//
//
// Version Date Modifications
// ---------------------------------
// 0.0 10/28/04 - Initial
// 0.1 12/20/04 - Add Address Pointer Outputs
// for visibility at higher
// level modules
// 0.2 02/10/05 - Address Pointers Updated on Negative Edge
// - Write to Address waddr-1
// - Needs Fixes to Previous Statements, but
// seems to work in implementation.
// 1.0 02/20/05 - Combinatorial Flag Generation for
// Synchrounous FIFO.
//
/////////////////////////////////////////////////////
module flags(read_addr, write_addr, empty, full);
//
// Inputs & Outputs
//
input [7:0] read_addr, write_addr;
output empty, full;
//
// Module Begin
//
assign empty = read_addr == write_addr;
assign full = write_addr > read_addr ?
(write_addr - read_addr) == 8'd255 : read_addr - write_addr == 8'd1;
endmodule
////////////////////////////////////////////////////
//
// Module Name: addr_ptr
// Descr: Address Pointer Management for
// Synchronous FIFO.
// Author: James Rosenthal
// Date: 10/28/04
//
//
// Version Date Modifications
// ---------------------------------
// 0.0 10/28/04 - Initial
// 0.1 12/20/04 - Add Address Pointer Outputs
// for visibility at higher
// level modules
// 0.2 02/10/05 - Address Pointers Updated on Negative Edge
// - Write to Address waddr-1
// - Needs Fixes to Previous Statements, but
// seems to work in implementation.
// 1.0 02/20/05 - Address Pointer Generation.
// - Update Address Pointer on Negative Edge
// of System Clock.
//
/////////////////////////////////////////////////////
module addr_ptr(clk, rst, write_addr, read_addr, empty, full, rd_en, wr_en);
//
// Inputs & Outputs
//
input clk; // System Clock
input rst; // Async. Active Low Reset
input empty, full; // Empty/Full Flags
input rd_en, wr_en; // Read/Write Enables
output [7:0] read_addr, write_addr; // Read/Write Address Pointers
//
// Registers
//
reg [7:0] read_addr, write_addr; // Read/Write Address Pointers
reg [1:0] state; // State Reg
//
// Parameters
//
parameter IDLE = 2'h0; // No Updates Necessary
parameter READ = 2'h1; // Read Cycle Occurred
parameter WRITE = 2'h2; // Write Cycle Occurred
parameter RW = 2'h3; // Simultaneous Read/Write Occurred
//
// Behavioral Description
//
always @ (posedge clk or negedge rst)
begin
if(!rst) // Reset State Reg
state <= 2'h0;
else // State Update
begin
if(rd_en && wr_en && !full && !empty)
state <= RW;
else if(rd_en && wr_en && !full && empty)
state <= WRITE;
else if(rd_en && wr_en && full && !empty)
state <= READ;
else if(!rd_en && wr_en && !full)
state <= WRITE;
else if(rd_en && !wr_en && !empty)
state <= READ;
else
state <= IDLE;
end
end
always @ (negedge clk or negedge rst)
begin
if(!rst) // Reset Addr Pointers
begin
write_addr <= 8'h0;
read_addr <= 8'h0;
end
else // Update Addr Pointers
begin
case(state)
// Update Read Addr Pointer if not Empty
READ: if(!empty) read_addr <= read_addr + 8'h1;
// Update Write Addr Pointer if not Full
WRITE: if(!full) write_addr <= write_addr + 8'h1;
// Updates for Simultaneous R/W
RW:
begin
if(!empty && !full)
begin
read_addr <= read_addr + 8'h1;
write_addr <= write_addr + 8'h1;
end
else if(!empty && full)
read_addr <= read_addr + 8'h1;
else if(empty && !full)
write_addr <= write_addr + 8'h1;
end
endcase
end
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -