FPGA中,同步FIFO,读侧16位,写侧8位的设计,仿真验证成功

it2023-10-17  68

基于verilog的不同位宽的同步FIFO设计

工具 quartus13.1

仿真工具modelsimse10.4

参考了两位博主的文章

 

Mr.zhang_FPGA:

基于verilog的同步FIFO设计,

emperor_strange: FIFO读写侧位数不同的处理

一、同步fifo,读写侧位数不同设计

1、FIFO设计难点及主要参数:

主要参数:fifo深度,fifo宽度,空标志,满状态。

同步FIFO设计难点在于判断FIFO的满状态和空状态。

判断空状态:

我们使用一个count计数器,在读状态时:count来一个时钟减一,计数到0,则为空

判断满状态:

在读状态时:count来一个时钟加一,计数到MAX(MAX为FIFO深度-1),则为满

对于不同位宽的同步FIFO设计

即读写两次分别进行控制,要么设置FIFO宽度与写侧相同,在读侧进行控制;要么设置FIFO宽度与读侧相同,在写侧进行控制。我们在让FIFO宽度和读侧相同,在写侧进行控制。

自己是在上面两位博主上面自己改的,所以直接开源了。

直接上代码:

`timescale 1ns / 1ns 1 module snfifo4( 2 input clk, 3 input rst_n, 4 input [15:0] din, 5 input din_vld, 6 input read, 7 8 output[7:0] data_out, 9 output full, 10 output emty 11 ); 12 13 reg [7:0] data_in; 14 reg [7:0] fifo_reg[7:0];//深度为8 15 reg [2:0] w_head,R_tail; 16 reg [2:0] count; 17 reg [7:0] dout; 18 reg f,e; 19 20 reg wr_en; 21 22 23 wire add_cnt; 24 wire end_cnt; 25 reg [1:0] cnt; 26 27 parameter MAX = 7; 28 29 //FIFO宽度与读侧相同 30 //在写侧用一个计数器来控制 31 //din[7:0] ,dout[4:0] 32 33 assign add_cnt = din_vld ; 34 assign end_cnt = add_cnt && cnt == 2-1; 35 36 always @(posedge clk or negedge rst_n)begin 37 if(rst_n==0)begin 38 cnt <= 0; 39 end 40 else if(add_cnt)begin 41 if(end_cnt)begin 42 cnt <= 0; 43 end 44 else 45 cnt <= cnt + 1'b1; 46 end 47 end 48 49 //注意写使能和写数据 50 always @(*)begin 51 if(add_cnt) 52 wr_en = 1; 53 else 54 wr_en = 0; 55 end 56 57 always @(posedge clk or negedge rst_n)begin 58 if(rst_n == 0)begin 59 data_in <= 0; 60 end 61 else if(add_cnt)begin 62 data_in <= din[15 -8*cnt -:8]; 63 end 64 end 65 66 //更新写指针 67 always @ (posedge clk) 68 if(!rst_n) 69 w_head <= 3'd0; 70 else if(wr_en && !full) 71 w_head <= w_head + 1'b1; 72 else if(full) w_head <= 3'd0; 73 //更新读指针 74 always @ (posedge clk) 75 if(!rst_n) 76 R_tail <= 3'd0; 77 else if(read && !emty) 78 R_tail <= R_tail + 1'b1; 79 else if(emty) R_tail <= 3'd0; 80 81 //count计数器 82 always @(posedge clk) 83 if(!rst_n) 84 begin 85 count <= 3'd0; 86 87 end 88 else 89 case({read,wr_en}) 90 2'b00: 91 count <= count; 92 2'b01: 93 if(count != MAX) 94 count <= count + 1'b1; 95 2'b10: 96 if(count != 0) 97 count <= count - 1'b1; 98 2'b11: 99 //; 100 count <= count; 101 endcase 102 //读数据 103 always @(posedge clk) 104 if(!rst_n) 105 dout <= 8'd0; 106 else if(read && !emty) 107 dout <= fifo_reg[R_tail]; 108 ///写数据 109 always @(posedge clk) 110 if(wr_en && !full) 111 fifo_reg[w_head] <= data_in; 112 113 always @ (posedge clk) 114 if(count==0) 115 e <= 1'b1; 116 else e <= 1'b0; 117 always @ (posedge clk) 118 if(count==MAX) 119 f <= 1'b1; 120 else f <= 1'b0; 121 assign full = f; 122 assign emty = e; 123 124 125 assign data_out = dout; 126 127 endmodule 128

仿真测试文件需要自己下载,有能力的可以自己编写,测试文件还是比较简单的。

仿真文件下载连接:https://download.csdn.net/download/longyuzhang/12986849

仿真结果:

对于我这样的新手来说,改动代码还是比较吃力的,花了一个晚上弄这个。目前我自己分析,这个FIFO应该功能仿真时通过要求的。后仿真没有做,时序分析那一块我还没学。求FPGA大佬评论区指点指点。

最新回复(0)