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