杭州高端网站建设,商务网站业务流程,帮人打广告赚钱的平台,诸暨建设局网站同步FIFO(synchronous)的写时钟和读时钟为同一个时钟#xff0c;FIFO内部所有逻辑都是同步逻辑#xff0c;常常用于交互数据缓冲。
异步FIFO#xff1a;数据写入FIFO的时钟和数据读出FIFO的时钟是异步的(asynchronous) 典型同步FIFO有三部分组成:
#xff08;1#xff0…同步FIFO(synchronous)的写时钟和读时钟为同一个时钟FIFO内部所有逻辑都是同步逻辑常常用于交互数据缓冲。
异步FIFO数据写入FIFO的时钟和数据读出FIFO的时钟是异步的(asynchronous) 典型同步FIFO有三部分组成:
1 FIFO写控制逻辑
2FIFO读控制逻辑
3FIFO 存储实体如Memory、Reg。
FIFO写控制逻辑主要功能产生FIFO写地址、写有效信号同时产生FIFO写 满、写错等状态信号
FIFO读控制逻辑主要功能产生FIFO读地址、读有效信号同时产生FIFO读 空、读错等状态信号。 基本概念 FIFO:先进先出(First-in-first-out) FIFO的深度 同一块数据内存的大小 FIFO的宽度写指针Write-pointer 读指针Read-pointer 一般FIFO使用循环指针(计数溢出自动归零)。一般可以称写指针为头head读指针为尾tail。 初始化时读写指针指向同一数据地址。下图可见FIFO初始化时WP和RP指针指向同一数据单元。WP指向下一个将要写入的数据单元RP指向将要读出的数据单元 2种方法判断空满 counter计数器判断有效数据是否等于FIFO的深度为0就表示空 使用fifo_counter记录FIFO RAM中的数据个数等于0时给出empty信号等于BUF_LENGTH时给出full信号。 写而未满时增加1 读而未空时减1 同时发生读写操作时fifo_counter不变 pointer如果深度为8那么3bit就可以表示8个数但是为了判断空满会多定义一位也即4bitWP为1000RP为0000我们使用最高位去判断是否在同一单元用高位判断空满如果高位相异就表示满如果相同表示空。 程序代码 define BUF_WIDTH 4 // 地址宽度为31
define BUF_SIZE 8 // 数据个数FIFO深度
module fifo_counter( clk,rst_n,buf_in,buf_out,wr_en,rd_en,buf_empty,buf_full,fifo_cnt);input clk,rst_n; // 时钟与复位信号input wr_en,rd_en; // 读写使能信号input [7:0] buf_in; // 写数据output reg [7:0] buf_out; // 读数据output wire buf_empty,buf_full; // 空满两个状态信号output reg [BUF_WIDTH-1:0] fifo_cnt; //判断空满计数器// 读写指针数据指针3位宽度0-7索引8个数据深度循环指针0-7-0-7reg [BUF_WIDTH-2:0] rd_ptr,wr_ptr;// 读写容器reg [7:0] buf_mem[0:BUF_SIZE-1];//判断空满 方式1assign buf_empty (fifo_cnt 0); //buf_empty若是reg类型则错不能使用assign持续赋值assign buf_full (fifo_cnt BUF_SIZE);// fifo_cnt 8就是满的//判断空满 方式2assign buf_empty (rd_ptr[3] wr_ptr[3])(rd_ptr[2:0] wr_ptr[2:0]); assign buf_full (rd_ptr[3] ! wr_ptr[3])(rd_ptr[2:0] wr_ptr[2:0]); // 前后必须同时为1//读数据always (posedge clk or negedge rst_n) begin if(!rst_n)buf_out 0;if(rd_en !buf_empty)buf_out buf_mem[rd_ptr];end// 写数据always (posedge clk) beginif(wr_en !buf_full)buf_mem[wr_ptr] buf_in;end// 更改读写指针always (posedge clk or negedge rst_n)beginif(!rst_n)beginwr_ptr 0;rd_ptr 0;endelse begin// 满足写的条件就把写指针1if(!buf_full wr_en)wr_ptr wr_ptr 1;// 满足读的条件就把读指针1if(!buf_empty rd_en)rd_ptr rd_ptr 1;endend// 监控fifo_cntalways (posedge clk or negedge rst_n)beginif(!rst_n)fifo_cnt 0;else if((!buf_fullwr_en)(!buf_emptyrd_en)) // 同时读写数量不变fifo_cnt fifo_cnt;else if(!buf_full wr_en) // 写数据写而未满增加1fifo_cnt fifo_cnt 1;else if(!buf_empty rd_en) // 读数据读而未空减1fifo_cnt fifo_cnt-1;elsefifo_cnt fifo_cnt; // 维持end
endmoduleTestBench define BUF_WIDTH 4 //地址宽度为31
define BUF_SIZE (8) //数据个数FIFO深度
module tb_fifo_counter;reg clk,rst_n;reg wr_en,rd_en;reg [7:0] buf_in; // data input to be pushed to bufferwire [7:0] buf_out; // port to output the data using pop. wire buf_empty,buf_full; // buffer empty and full indicationwire [BUF_WIDTH-1:0] fifo_cnt; // number of data pushed in to bufferfifo_counter dut(.clk(clk),.rst_n(rst_n),.buf_in(buf_in),.buf_out(buf_out),.wr_en(wr_en),.rd_en(rd_en),.buf_empty(buf_empty),.buf_full(buf_full),.fifo_cnt(fifo_cnt));fifo_counter dut(.clk (clk),.rst_n (rst_n),.buf_in (buf_in),.buf_out (buf_out),.wr_en (wr_en),.rd_en (rd_en),.buf_empty (buf_empty),.buf_full (buf_full),.fifo_cnt (fifo_cnt));always #10 clk ~clk;// 定义一个临时的数据将读出来的数据暂存reg [7:0] tempdata;initial beginclk 0;rst_n 0;wr_en 0;rd_en 0;buf_in 0;#15; rst_n 1;push(1);// 同时读写forkpush(2);pop(tempdata); // 读取tempdata 1joinpush(10);push(20);push(30);push(40);push(50);push(60);push(70);// 70push 就会满push(80);push(90);push(100);push(110);push(120);push(130);pop(tempdata); // 读取tempdata 2push(tempdata); pop(tempdata);pop(tempdata);pop(tempdata);pop(tempdata);push(140); // 可以写进去pop(tempdata);push(tempdata);pop(tempdata);pop(tempdata);pop(tempdata);pop(tempdata);pop(tempdata);pop(tempdata);pop(tempdata);pop(tempdata);pop(tempdata);pop(tempdata);pop(tempdata);push(5);pop(tempdata);// 读取tempdata 5#50 $finish;end// 将data写入fifotask push (input [7:0] data);if(buf_full)$display(---Cannot push %d: Buffer Full---,data);else begin$display(Push,,data);buf_in data;wr_en 1;(posedge clk);#5 wr_en 0;endendtask// 将data读取出来task pop(output[7:0] data);if(buf_empty)$display(---Cannot Pop: Buffer Empty---);else beginrd_en 1;(posedge clk);#3 rd_en 0;data buf_out;$display(------Poped:,,data);endendtask
endmodulefind -name *.v file.list makefile文件 all:clean com sim
SEED1
com:vcs -full64 -R -sverilog -debug_all -f file.list -l comp.log ntb_random_seed$(SEED) \-cm linecondfsmbranchtgl -cm_name simv -cm_dir ./covdir.vdb
sim:./simv -l sim.log
rung:./simv -gui -l sim.log
cov:dve -full64 -covdir *.vdb
clean:rm -rf ./csrc *.daidir *.log *.vpd *.vdb simv* *.key *race.out*rm -rf AN.DBrm -rf novas*rm -rf DVEfilesrm -rf urgReportVCS Coverage Metrics Release O-2018.09-1_Full64 Copyright (c) 1991-2018 by Synopsys Inc.
Push 1
Push 2
------Poped: 1
Push 10
Push 20
Push 30
Push 40
Push 50
Push 60
Push 70
---Cannot push 80: Buffer Full---
---Cannot push 90: Buffer Full---
---Cannot push 100: Buffer Full---
---Cannot push 110: Buffer Full---
---Cannot push 120: Buffer Full---
---Cannot push 130: Buffer Full---
------Poped: 2
Push 2
------Poped: 10
------Poped: 20
------Poped: 30
------Poped: 40
Push 140
------Poped: 50
Push 50
------Poped: 60
------Poped: 70
------Poped: 2
------Poped: 140
------Poped: 50
---Cannot Pop: Buffer Empty---
---Cannot Pop: Buffer Empty---
---Cannot Pop: Buffer Empty---
---Cannot Pop: Buffer Empty---
---Cannot Pop: Buffer Empty---
---Cannot Pop: Buffer Empty---
Push 5
------Poped: 5查看波形make rung