手撕Verilog面试题专题——(11)同步FIFO

11 同步FIFO
搬运工:http://www.asic-world.com/examples/verilog/syn_fifo.html
Verilog代码:

module syn_fifo (
	clk      , // Clock input
	rst      , // Active high reset
	wr_cs    , // Write chip select
	rd_cs    , // Read chipe select
	data_in  , // Data input
	rd_en    , // Read enable
	wr_en    , // Write Enable
	data_out , // Data Output
	empty    , // FIFO empty
	full       // FIFO full
);    
	
	// FIFO constants
	parameter DATA_WIDTH = 8;
	parameter ADDR_WIDTH = 8;
	parameter RAM_DEPTH = (1 << ADDR_WIDTH);
	// Port Declarations
	input clk ;
	input rst ;
	input wr_cs ;
	input rd_cs ;
	input rd_en ;
	input wr_en ;
	input [DATA_WIDTH-1:0] data_in ;
	output full ;
	output empty ;
	output [DATA_WIDTH-1:0] data_out ;
	
	//-----------Internal variables-------------------
	reg [ADDR_WIDTH-1:0] wr_pointer;
	reg [ADDR_WIDTH-1:0] rd_pointer;
	reg [ADDR_WIDTH :0] status_cnt;
	reg [DATA_WIDTH-1:0] data_out ;
	wire [DATA_WIDTH-1:0] data_ram ;
	
	//-----------Variable assignments---------------
	assign full = (status_cnt == (RAM_DEPTH-1));
	assign empty = (status_cnt == 0);
	
	//-----------Code Start---------------------------
	always @ (posedge clk or posedge rst)
	begin : WRITE_POINTER
	if (rst) begin
		wr_pointer <= 0;
	end else if (wr_cs && wr_en ) begin
		wr_pointer <= wr_pointer + 1;
	end
	end
	
	always @ (posedge clk or posedge rst)
	begin : READ_POINTER
	if (rst) begin
		rd_pointer <= 0;
	end else if (rd_cs && rd_en ) begin
		rd_pointer <= rd_pointer + 1;
	end
	end
	
	always  @ (posedge clk or posedge rst)
	begin : READ_DATA
	if (rst) begin
		data_out <= 0;
	end else if (rd_cs && rd_en ) begin
		data_out <= data_ram;
	end
	end
	
	always @ (posedge clk or posedge rst)
	begin : STATUS_COUNTER
	if (rst) begin
		status_cnt <= 0;
	// Read but no write.
	end else if ((rd_cs && rd_en) &&  ! (wr_cs && wr_en) 
					&& (status_cnt  ! = 0)) begin
		status_cnt <= status_cnt - 1;
	// Write but no read.
	end else if ((wr_cs && wr_en) &&  ! (rd_cs && rd_en) 
				&& (status_cnt  ! = RAM_DEPTH)) begin
		status_cnt <= status_cnt + 1;
	end
	end 
	
	ram_dp_ar_aw #(DATA_WIDTH,ADDR_WIDTH)DP_RAM (
	.address_0 (wr_pointer) , // address_0 input 
	.data_0    (data_in)    , // data_0 bi-directional
	.cs_0      (wr_cs)      , // chip select
	.we_0      (wr_en)      , // write enable
	.oe_0      (1'b0)       , // output enable
	.address_1 (rd_pointer) , // address_q input
	.data_1    (data_ram)   , // data_1 bi-directional
	.cs_1      (rd_cs)      , // chip select
	.we_1      (1'b0)       , // Read enable
	.oe_1      (rd_en)        // output enable
	);     
	
endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值