fifo_rev_0.5.v

来自「Verilog jpec coder encoder source code」· Verilog 代码 · 共 181 行

V
181
字号
////////////////////////////////////////////////////
//
//  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.4		2/10/05		- Address Pointers Updated on Negative Edge
// 						- Write to Address waddr-1
// 						- Needs Fixes to Previous Statements, but
// 						  seems to work in implementation.
// 						- Made this rev 0.4 to match with others
//
/////////////////////////////////////////////////////

`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 infifo(
		.addra(waddr[7:0]-8'h1),
		.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 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 addr_ptr(clk, rst, write_addr, read_addr, empty, full, rd_en, wr_en);

	//
	// Inputs & Outputs
	//
	
	input clk, rst;
	input empty, full;
	input rd_en, wr_en;
	output [7:0] read_addr, write_addr;

	reg [7:0] read_addr, write_addr;
	reg read_cycle;	// read cycle in progress
	reg write_cycle;	// write cycle in progress

	always @ (posedge clk or negedge rst)
	begin
		if(!rst)
		begin
			write_addr <= 8'h0;
			read_addr <= 8'h0;
			read_cycle <= 1'b0;
			write_cycle <= 1'b0;
		end
		// read, not empty
		else if(rd_en && !wr_en && !empty && !read_cycle)
		begin
			read_cycle <= 1'b1;
			write_cycle <= 1'b0;
			read_addr <= read_cycle ? read_addr : read_addr + 8'h1;
		end
		// write, not full
		else if(wr_en && !rd_en && !full && !write_cycle)
		begin
			write_addr <= write_cycle ? write_addr : write_addr + 8'h1;
			write_cycle <= 1'b1;
			read_cycle <= 1'b0;
		end
		// simulataneous read/write, address pointers don't match
		// Will this be ok if fifo is full?? 
		else if(read_addr != write_addr && wr_en && rd_en && !read_cycle && !write_cycle) 
		begin
			write_addr <= write_cycle ? write_addr : write_addr + 8'h1;
			read_addr <= read_cycle ? read_addr : read_addr + 8'h1;
			read_cycle <= 1'b1;
			write_cycle <= 1'b1;
		end
		else if(!rd_en && !wr_en)
		begin
			read_cycle <= 1'b0;
			write_cycle <= 1'b0;
		end
	end
	
endmodule


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?