verilog 同步fifo

同步fifo的实现:


// 同步fifo的实现
module sy_fifo(
    input	wire		clk,
    input	wire		rst_n,
    input	wire		wr_en,  	// 写信号
    input	wire[7:0]	data_in, 	// 输入
    input	wire		rd_en,		// 读信号
    output	wire		full,		// 写满
    output	reg	[7:0]	data_out,   // 输出
    output	wire		empty       // 空
);
 
localparam deepth = 256;   // 深度  2^8 = 256, 二进制计数需要8bit
localparam width  = 8;     // 宽度
 
reg [width-1:0] mem [deepth-1:0];  // 一个名为mem的存储器,该存储器有deepth个width位的寄存器
reg [8:0] 		count;    // 二进制计数需要8bit
reg [7:0] 		rd_addr;  // 读计数
reg [7:0] 		wr_addr;  // 写计数
wire  			wr;		  // 可写
wire  			rd;       // 可读
 
assign wr = (wr_en) && (~full);  // 不满且写信号,可写
assign rd = (rd_en) && (~empty); // 不空且读信号,可读
 
//wr_addr ctrl  写信号下 写计数
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        wr_addr <= 8'd0;
    else if(wr)
        wr_addr <= wr_addr + 1'b1;
    else 
        wr_addr <= wr_addr;
end
 
//wr_data;  写信号下 写进fifo
always @(posedge clk) begin
    if(wr)
        mem[wr_addr] <= data_in;  // 计数作为地址,输入写入men
    else 
        mem[wr_addr] <= mem[wr_addr];   // 某地址下存储器数据不变
end
 
//rd_addr ctrl  // 读信号下 读计数
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        rd_addr <= 8'd0;
    else if(rd)
        rd_addr <= rd_addr +1'b1;
    else 
        rd_addr <= rd_addr;
end
 
// rd data;   // 读信号下 读出数据
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        data_out <= 8'd0;
    else if(rd)
        data_out <= mem[rd_addr];  // 读信号,读计数作为地址,依次读出
    else 
        data_out <= data_out;   // 没有读信号,维持数据输出,不继续读出
end
 
// count 满计数 
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        count <= 8'd0;
    else if(rd && ~wr && (count >=1))  // 读信号且没写信号,满计数-1
        count <= count  - 1'd1;  
    else if(wr && ~rd &&(count <=255))  // 写信号没读信号,满计数+1
        count <= count + 1'd1; 
    else     
        count <= count;    // 同时读写时,满计数不变
end 
 
//full empty 空满状态判断
 
assign empty = (count == 8'd0) ? 1'b1:1'b0;  // 满计数=0 空
assign full = (count == 9'd256) ? 1'b1:1'b0;  // 满计数=256 满

endmodule 

//-------------------------------------------
// -----------testbench----------------

`timescale 1ns/1ps
`define clock_period 20
 
module sy_fifo_tb;

reg 			clk;
reg 			rst_n;
reg 			wr_en;
reg 			rd_en;
reg		[7:0]	data_in;
wire	[7:0]	data_out;
wire			full;
wire			empty;
 
initial clk = 1'b1;

always #(`clock_period/2) clk = ~clk;

integer i;
initial begin
    wr_en = 0; data_in =0; rst_n = 0; rd_en =0;
    #100; 
    rst_n =1;
    #100;
    
    for (i =0; i<256; i=i+1)begin
        @(posedge clk) 
        	data_in = {$random}%256;  // 随机数 -256~256
        wr_en = 1'b1;
        if(i==128)   // 写到一半内存,开始读
            rd_en =1;
    end
    #30;
    wr_en =0;
    
      
end

// 例化
sy_fifo sy_fifo_inst(
    .clk(clk),
    .rst_n(rst_n),
    .wr_en(wr_en),
    .data_in(data_in),
    .rd_en(rd_en),
    .full(full),
    .data_out(data_out),
    .empty(empty)
);
 
endmodule

在这里插入图片描述
i=128,下个clk,rd拉高,下个clk,开始读出。写入并读出时,满信号count不变。

在这里插入图片描述
count = 256 满状态,不再写入
在这里插入图片描述


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
同步FIFO是一种常用的电子电路,用于在两个或多个时钟域之间传输数据。它具有先入先出的性质,可以保证数据传输的顺序不变。 Verilog语言中,同步FIFO可以使用一组寄存器实现。下面是一个简单的同步FIFOVerilog代码: ``` module sync_fifo ( input clk_w, // 写时钟 input rst_w, // 写复位 input wr_en, // 写使能 input [7:0] wr_data, // 写数据 input clk_r, // 读时钟 input rst_r, // 读复位 input rd_en, // 读使能 output [7:0] rd_data, // 读数据 output full, // 满标志 output empty // 空标志 ); parameter WIDTH = 8; // 数据宽度 parameter DEPTH = 16; // 深度 reg [WIDTH-1:0] fifo [0:DEPTH-1]; // FIFO存储器 reg [WIDTH-1:0] rd_data_reg; // 读数据寄存器 reg [DEPTH-1:0] wr_ptr; // 写指针 reg [DEPTH-1:0] rd_ptr; // 读指针 wire [DEPTH-1:0] count; // 元素个数 // 写逻辑 always @(posedge clk_w or posedge rst_w) begin if (rst_w) begin wr_ptr <= 0; fifo <= 0; end else if (wr_en && ~full) begin fifo[wr_ptr] <= wr_data; wr_ptr <= wr_ptr + 1; end end // 读逻辑 always @(posedge clk_r or posedge rst_r) begin if (rst_r) begin rd_ptr <= 0; rd_data_reg <= 0; end else if (rd_en && ~empty) begin rd_data_reg <= fifo[rd_ptr]; rd_ptr <= rd_ptr + 1; end end // 元素个数计算 assign count = wr_ptr - rd_ptr; // 满标志 assign full = (count == DEPTH); // 空标志 assign empty = (count == 0); // 读数据输出 assign rd_data = rd_data_reg; endmodule ``` 在这个Verilog代码中,FIFO存储器使用一组寄存器实现,写指针和读指针分别指向下一个写入位置和读取位置。当写使能信号wr_en有效且FIFO未满时,写入数据wr_data,并将写指针加1;当读使能信号rd_en有效且FIFO非空时,读取数据并将读指针加1。元素个数count可以通过写指针和读指针的差值计算得到,满标志full和空标志empty分别表示FIFO是否已满和是否为空。最后,读数据rd_data通过一个寄存器输出,以保证读数据的正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值