Verilog 同步FIFO设计

module sync_FIFO(clk,rs_n,full,empty,count,r_en,w_en,in_s,ou_s);
    input clk;//时钟信号
    input w_en;//写使能,高电平有效
    input r_en;//读使能,高电平有效
    input rs_n;//复位信号,低电平复位
    input [7:0]in_s;//输入数据信号
    
    output reg full;//满信号,高电平有效
    output reg empty;//空信号,高电平有效
    output reg[4:0]count;//计数器
    output reg[7:0]ou_s;//输出数据
    
    
    reg [4:0]w_addr;//写地址
    reg [4:0]r_addr;//读地址
    reg [7:0] ram [19:0];//寄存器ram
    integer i;
    
    //写数据入FIFO
    always@(posedge clk or negedge rs_n)begin
    if(!rs_n)begin//低电平复位
            w_addr<=0;//初始化写地址为0
            for(i=0;i<20;i=i+1)begin
                ram[i]<=0;//初始化ram变量为0
            end
        end 
        else if(w_en & empty)begin//如果写使能为高电平与空标志信号为高电平
            ram[w_addr]<=in_s;//开始写入数据
            w_addr<=w_addr+1;//写地址加1
        end
    end
    
    
    //读出FIFO数据
    always@(posedge clk or negedge rs_n)begin
        if(!rs_n)begin//低电平复位
            ou_s<=0;//初始化输出端口为0
            r_addr<=0;//初始化读地址为0
        end
        else if(r_en & full)begin//如果读使能信号高电平与满标志信号高电平
            ou_s<=ram[r_addr];//读出ram变量的数据
            r_addr<=r_addr+1;//读地址加1
        end
    end
    
    
    //计数器
    always@(posedge clk or negedge rs_n)begin
        if(!rs_n)begin//低电平复位
            count<=0;//计数寄存器为0
        end
        else if(w_en & empty)begin//如果写信号与空标志位高电平
            count<=count+1;//计数器加1
        end
        else if(r_en & full)begin//如果读使能信号与满标志为高电平
            count<=count-1;//计数器减1
        end
    end
    
    
    
    //产生标志信号
    always@(count)begin
        if(count<1)begin//如果计数器小于ram变量的最小值1
            empty<=1;//空标志信号为高电平
            full<=0;//满标志信号为低电平
        end
        else if(count>19)begin//如果计数器大于ram变量的最大值20
            empty<=0;//空标志信号为低电平
            full<=1;//满标志信号为高电平
        end
    end
    

    
endmodule

仿真部分

// Copyright (C) 1991-2013 Altera Corporation
// Your use of Altera Corporation's design tools, logic functions 
// and other software and tools, and its AMPP partner logic 
// functions, and any output files from any of the foregoing 
// (including device programming or simulation files), and any 
// associated documentation or information are expressly subject 
// to the terms and conditions of the Altera Program License 
// Subscription Agreement, Altera MegaCore Function License 
// Agreement, or other applicable license agreement, including, 
// without limitation, that your use is for the sole purpose of 
// programming logic devices manufactured by Altera and sold by 
// Altera or its authorized distributors.  Please refer to the 
// applicable agreement for further details.

// *****************************************************************************
// This file contains a Verilog test bench template that is freely editable to  
// suit user's needs .Comments are provided in each section to help the user    
// fill out necessary details.                                                  
// *****************************************************************************
// Generated on "09/02/2021 19:14:27"
                                                                                
// Verilog Test Bench template for design : sync_FIFO
// 
// Simulation tool : ModelSim-Altera (Verilog)
// 

`timescale 1 ps/ 1 ps
module sync_FIFO_vlg_tst();
// constants                                           
// general purpose registers
reg eachvec;
// test vector input registers
reg clk=0;
reg w_en;
reg rs_n;
reg r_en;
reg [7:0] in_s;
// wires  
wire full;
wire empty;
wire [4:0]count;                                             
wire [7:0]  ou_s;

// assign statements (if any)                          
sync_FIFO i1 (
// port map - connection between master ports and signals/registers   
    .clk(clk),
    .in_s(in_s),
    .ou_s(ou_s),
    .w_en(w_en),
    .r_en(r_en),
    .rs_n(rs_n),
    .count(count),
    .empty(empty),
    .full(full)
);

parameter s_clk=2000;
always #(s_clk) clk=~clk;

wire [127:0]cs=128'hffab0eefabc18002abcd299384011bcd;
wire [15:0]k=16'hfa00bc;
wire [143:0]l={cs,k};

integer i;
initial                                                
begin                                                  
// code that executes only once                        
// insert code here --> begin 
            #(s_clk)rs_n=0;
            #(s_clk)w_en=1;
            #(s_clk)rs_n=1;
        for(i=0;i<19;i=i+1)begin
                #(s_clk*2)in_s<=l>>(i<<3);
                if(in_s==8'hff)begin
                    #(s_clk)w_en<=0;
                    #(s_clk)r_en=1;
                end
          end
// --> end                                             
$display("Running testbench");                       
end                                                    
always                                                 
// optional sensitivity list                           
// @(event1 or event2 or .... eventn)                  
begin                                                  
// code executes for every event on sensitivity list   
// insert code here --> begin                          
                                                      
@eachvec;                                              
// --> end                                             
end                                                    
endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
同步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、付费专栏及课程。

余额充值