【FPGA学习笔记】VL46 同步FIFO

根据题目提供的双口RAM代码和接口描述,实现同步FIFO,要求FIFO位宽和深度参数化可配置。

 

电路的接口如下图所示。

 

 

 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
`timescale 1ns/1ns
/**********************************RAM************************************/
module dual_port_RAM #(parameter DEPTH = 16,
                       parameter WIDTH = 8)(
     input wclk
    ,input wenc
    ,input [$clog2(DEPTH)-1:0] waddr  //深度对2取对数,得到地址的位宽。
    ,input [WIDTH-1:0] wdata        //数据写入
    ,input rclk
    ,input renc
    ,input [$clog2(DEPTH)-1:0] raddr  //深度对2取对数,得到地址的位宽。
    ,output reg [WIDTH-1:0] rdata       //数据输出
);
 
reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];
 
always @(posedge wclk) begin
    if(wenc)
        RAM_MEM[waddr] <= wdata;
end
 
always @(posedge rclk) begin
    if(renc)
        rdata <= RAM_MEM[raddr];
end
 
endmodule 
 
/**********************************SFIFO************************************/
module sfifo#(
    parameter   WIDTH = 8,
    parameter   DEPTH = 16
)(
    input                   clk     ,
    input                   rst_n   ,
    input                   winc    ,
    input                   rinc    ,
    input       [WIDTH-1:0] wdata   ,
 
    output reg              wfull   ,
    output reg              rempty  ,
    output wire [WIDTH-1:0] rdata
);
    reg [4:0] wp,rp;  //读写指针
 
//---------------写操作----------------------------------------
    always @(posedge clk or negedge rst_n)  begin
        if(!rst_n)
            wp<=5'b0;
        else if(wenc)
            wp<=wp+1'b1;
    end
 
//---------------读操作----------------------------------------
    always @(posedge clk or negedge rst_n)  begin
        if(!rst_n)
            rp<=5'b0;
        else if(renc)
            rp<=rp+1'b1;
    end   
 
//----------空满信号-----------------------------------------
    always @(posedge clk or negedge rst_n)  begin
        if(!rst_n)
            rempty<=0;
        else if(wp==rp)
            rempty<=1'b1;
        else
            rempty<=1'b0;
    end
 
    always @(posedge clk or negedge rst_n)  begin
        if(!rst_n)
            wfull<=0;
        else if(wp=={!rp[4],rp[3:0]})
            wfull<=1'b1;
        else
            wfull<=1'b0;
    end
    //assign rempty=(wp==rp);       //这里答案的空满判断是打一拍后再比较的,造成空满判断滞后,应该用组合逻辑
    //assign wfull=(wp=={!rp[4],rp[3:0]});
 
//------------例化-------------------------------------
    wire wenc,renc;
    assign wenc=winc&!wfull;
    assign renc=rinc&!rempty;
 
    dual_port_RAM dual_port_RAM(
        .wclk         (clk),
        .wenc         (wenc),
        .waddr        (wp),
        .wdata        (wdata),
 
        .rclk         (clk),
        .renc         (renc),
        .raddr        (rp),
        .rdata        (rdata)
    );
 
endmodule
posted @ 2022-07-18 10:59  220nf绿波电龙  阅读(67)  评论(0编辑  收藏  举报