同步FIFO

描述

根据题目提供的双口RAM代码和接口描述,实现同步FIFO,要求FIFO位宽和深度参数化可配置。

电路的接口如下图所示。

端口说明如下表。

双口RAM端口说明:

端口名

I/O

描述

wclk

input

写数据时钟

wenc

input

写使能

waddr

input

写地址

wdata

input

输入数据

rclk

input

读数据时钟

renc

input

读使能

raddr

input

读地址

rdata

output

输出数据

同步FIFO端口说明:

端口名

I/O

描述

clk

input

时钟

rst_n

input

异步复位

winc

input

写使能

rinc

input

读使能

wdata

input

写数据

wfull

output

写满信号

rempty

output

读空信号

rdata

output

读数据

双口RAM代码如下,可在答案中添加并例化此代码。

module dual_port_RAM #(parameter DEPTH = 16,
   parameter WIDTH = 8)(
 input wclk
,input wenc
,input [$clog2(DEPTH)-1:0] waddr  //深度对2取对数,得到地址的位宽。
,input [WIDTH-1:0] wdata      //数据写入
,input rclk
,input renc
,input [$clog2(DEPTH)-1:0] raddr  //深度对2取对数,得到地址的位宽。
,output reg [WIDTH-1:0] rdata //数据输出
);

reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];

always @(posedge wclk) begin
if(wenc)
RAM_MEM[waddr] <= wdata;
end 

always @(posedge rclk) begin
if(renc)
rdata <= RAM_MEM[raddr];
end 

endmodule  

输入描述:

    input                     clk        , 
    input                     rst_n    ,
    input                     winc    ,
    input                      rinc    ,
    input         [WIDTH-1:0]    wdata    

输出描述:

    output reg                wfull    ,
    output reg                rempty    ,
    output wire [WIDTH-1:0]    rdata

参考代码

`timescale 1ns/1ns
/**********************************RAM************************************/
module dual_port_RAM #(parameter DEPTH = 16,
					   parameter WIDTH = 8)(
	 input wclk
	,input wenc
	,input [$clog2(DEPTH)-1:0] waddr  //深度对2取对数,得到地址的位宽。
	,input [WIDTH-1:0] wdata      	//数据写入
	,input rclk
	,input renc
	,input [$clog2(DEPTH)-1:0] raddr  //深度对2取对数,得到地址的位宽。
	,output reg [WIDTH-1:0] rdata 		//数据输出
);
 
reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];
 
always @(posedge wclk) begin
	if(wenc)
		RAM_MEM[waddr] <= wdata;
end 
 
always @(posedge rclk) begin
	if(renc)
		rdata <= RAM_MEM[raddr];
end 
 
endmodule  
 
/**********************************SFIFO************************************/
module sfifo#(
	parameter	WIDTH = 8,
	parameter 	DEPTH = 16
)(
	input 					clk		, 
	input 					rst_n	,
	input 					winc	,
	input 			 		rinc	,
	input 		[WIDTH-1:0]	wdata	,
 
	output 				    wfull	,
	output 				    rempty	,
	output wire [WIDTH-1:0]	rdata
);
 
localparam ADDR_W = $clog2(DEPTH);
reg [ADDR_W:0] waddr,raddr;
wire renc , winc;
wire [ADDR_W:0] fifo_len;
//读写地址加
assign renc = !rempty && rinc;
assign wenc = !wfull && winc;
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		waddr <= 'd0;
	else if(wenc)
		waddr <= waddr +'d1;
	else
		waddr <= waddr;
end 
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		raddr <= 'd0;
	else if(renc)
		raddr <= raddr +'d1;
	else
		raddr <= raddr;
end 


//空满判断
assign wfull = ({~waddr[ADDR_W],waddr[ADDR_W-1:0]}==raddr);
assign rempty= raddr==waddr;
assign fifo_len= (waddr>=raddr)? (waddr-raddr):(waddr+DEPTH-raddr);
 
 
dual_port_RAM #(.DEPTH(DEPTH), .WIDTH(WIDTH))
u_ram (
	.wclk	(clk),
	.wenc	(wenc),
	.waddr	(waddr[ADDR_W-1:0]),
	.wdata	(wdata),
	.rclk	(clk),
	.renc	(renc),
	.raddr	(raddr[ADDR_W-1:0]),
	.rdata	(rdata)
);
 
endmodule

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

king_machine design

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值