「Verilog学习笔记」异步FIFO
2023-12-13 09:30:28
专栏前言
本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网
?
`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
/***************************************AFIFO*****************************************/
module asyn_fifo#(
parameter WIDTH = 8,
parameter DEPTH = 16
)(
input wclk ,
input rclk ,
input wrstn ,
input rrstn ,
input winc ,
input rinc ,
input [WIDTH-1:0] wdata ,
output wire wfull ,
output wire rempty ,
output wire [WIDTH-1:0] rdata
);
localparam ADDR_WIDTH = $clog2(DEPTH) ;
reg [ADDR_WIDTH:0] waddr, raddr ;
always @ (posedge wclk or negedge wrstn) begin
if (~wrstn) waddr <= 'b0 ;
else
if (winc && ~wfull) waddr <= waddr + 1'b1 ;
else waddr <= waddr ;
end
always @ (posedge rclk or negedge rrstn) begin
if (~rrstn) raddr <= 'b0 ;
else
if (rinc && ~rempty) raddr <= raddr + 1'b1 ;
else raddr <= raddr ;
end
wire [ADDR_WIDTH:0] waddr_gray, raddr_gray ;
assign waddr_gray = waddr ^ (waddr >> 1) ;
assign raddr_gray = raddr ^ (raddr >> 1) ;
reg [ADDR_WIDTH:0] waddr_gray_reg, raddr_gray_reg ;
always @ (posedge wclk or negedge wrstn) begin
if (~wrstn) waddr_gray_reg <= 'd0 ;
else waddr_gray_reg <= waddr_gray ;
end
always @ (posedge rclk or negedge rrstn) begin
if (~rrstn) raddr_gray_reg <= 'd0 ;
else raddr_gray_reg <= raddr_gray ;
end
reg [ADDR_WIDTH:0] addr_r2w_t, addr_r2w ;
always @ (posedge wclk or negedge wrstn) begin
if (~wrstn) begin
addr_r2w_t <= 'd0 ;
addr_r2w <= 'd0 ;
end
else begin
addr_r2w_t <= raddr_gray_reg ;
addr_r2w <= addr_r2w_t ;
end
end
reg [ADDR_WIDTH:0] addr_w2r_t, addr_w2r ;
always @ (posedge rclk or negedge rrstn) begin
if (~rrstn) begin
addr_w2r_t <= 'd0 ;
addr_w2r <= 'd0 ;
end
else begin
addr_w2r_t <= waddr_gray_reg ;
addr_w2r <= addr_w2r_t ;
end
end
assign wfull = (waddr_gray_reg == {~addr_r2w[ADDR_WIDTH:ADDR_WIDTH - 1], addr_r2w[ADDR_WIDTH - 2 : 0]}) ;
assign rempty = (raddr_gray_reg == addr_w2r) ;
dual_port_RAM # (.DEPTH(DEPTH), .WIDTH(WIDTH)) dual_port_RAM_U0
(
.wclk(wclk),
.wenc(winc&&~wfull),
.waddr(waddr[ADDR_WIDTH-1:0]), //深度对2取对数,得到地址的位宽。
.wdata(wdata), //数据写入
.rclk(rclk),
.renc(rinc&&~rempty),
.raddr(raddr[ADDR_WIDTH-1:0]), //深度对2取对数,得到地址的位宽。
.rdata(rdata) //数据输出
);
endmodule
?
文章来源:https://blog.csdn.net/m0_54689021/article/details/134893375
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!