OpenCores
URL https://opencores.org/ocsvn/usb_fpga_2_14/usb_fpga_2_14/trunk

Subversion Repositories usb_fpga_2_14

[/] [usb_fpga_2_14/] [trunk/] [examples/] [memfifo/] [fpga-2.16/] [bram_fifo.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
/*%
2
   memfifo -- Connects the bi-directional high speed interface of default firmware to a FIFO built of on-board SDRAM or on-chip BRAM
3
   Copyright (C) 2009-2017 ZTEX GmbH.
4
   http://www.ztex.de
5
 
6
   Copyright and related rights are licensed under the Solderpad Hardware
7
   License, Version 0.51 (the "License"); you may not use this file except
8
   in compliance with the License. You may obtain a copy of the License at
9
 
10
       http://solderpad.org/licenses/SHL-0.51.
11
 
12
   Unless required by applicable law or agreed to in writing, software, hardware
13
   and materials distributed under this License is distributed on an "AS IS"
14
   BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15
   implied. See the License for the specific language governing permissions
16
   and limitations under the License.
17
%*/
18
 
19
/*
20
   Implements a FWFT FIFO from BRAM. It does not use the cascading approach described
21
   in ug437 because it is to slow.
22
*/
23
 
24
 
25
module bram_fifo # (
26
        parameter BRAM_N = 256          // Number of BRAM blocks; 365 are available on 7A200.
27
                                        // Due to an limitation if the synthesizer (Vivado 13.2)
28
                                        // Maximum possible number is 256.
29
    ) (
30
        input reset,                    // reset
31
        // FIFO protocol equal to FWFT FIFO in "7 Series Memory Resources" user guide (ug743)
32
        // input fifo interface
33
        input [31:0] DI,                // must be hold while FULL is asserted
34
        output FULL,                    // 1-bit output: Full flag
35
        output reg WRERR,               // 1-bit output: Write error
36
        input WRCLK,                    // 1-bit input: Rising edge write clock.
37
        input WREN,                     // 1-bit input: Write enable
38
 
39
        // output fifo interface
40
        output reg [31:0] DO,
41
        output reg EMPTY,               // 1-bit output: Empty flag, can be used as data valid indicator
42
        output reg RDERR,               // 1-bit output: Read error
43
        input RDCLK,                    // 1-bit input: Read clock
44
        input RDEN                      // 1-bit input: Read enable
45
    );
46
 
47
    localparam ADDR_WIDTH = 19;
48
    localparam ADDR_MAX = 1024*BRAM_N-1;
49
 
50
    reg [31:0] BRAM[0:ADDR_MAX];
51
 
52
    // DRAM controller: writing
53
    reg reset_wr, WREN_BUF;
54
    reg [7:0] reset_wr_buf = 8'd0;
55
    reg [ADDR_WIDTH-1:0] WR_ADDR, WR_ADDR_NEXT, RD_ADDR_WR1, RD_ADDR_WR2, RD_ADDR_WR3;
56
 
57
    // DRAM controller: reading
58
    reg reset_rd;
59
    reg [7:0] reset_rd_buf = 8'd0;
60
    reg [ADDR_WIDTH-1:0] RD_ADDR, RD_ADDR_NEXT, WR_ADDR_RD1, WR_ADDR_RD2, WR_ADDR_RD3;
61
 
62
    assign FULL = reset_wr || FULL2;
63
    wire FULL2 = (WR_ADDR_NEXT==RD_ADDR_WR3) || (WR_ADDR_NEXT==RD_ADDR_WR2) || (WR_ADDR_NEXT==RD_ADDR_WR1);
64
 
65
    always @ (posedge WRCLK)
66
    begin
67
        RD_ADDR_WR1 <= RD_ADDR;
68
        RD_ADDR_WR2 <= RD_ADDR_WR1;
69
        RD_ADDR_WR3 <= RD_ADDR_WR2;
70
 
71
        reset_wr_buf <= { reset, reset_wr_buf[7:1] };
72
        reset_wr <= reset_wr_buf != 8'd0;
73
 
74
        if ( reset_wr )
75
        begin
76
            WR_ADDR <= ADDR_MAX;
77
            WR_ADDR_NEXT <= { (ADDR_WIDTH){1'b0} };
78
            WREN_BUF <= 1'b0;
79
        end else
80
        begin
81
            if ( WREN || WREN_BUF )             // process data
82
            begin
83
                if ( ! FULL2 )
84
                begin
85
                    BRAM[WR_ADDR] <= DI;
86
                    WR_ADDR <= WR_ADDR_NEXT;
87
                    WR_ADDR_NEXT <= WR_ADDR_NEXT == ADDR_MAX ? { ADDR_WIDTH{1'b0} } : WR_ADDR_NEXT + 1;
88
                end
89
                WREN_BUF <= FULL2;
90
            end
91
            WRERR <= WREN && WREN_BUF;
92
        end
93
    end
94
 
95
 
96
    always @ (posedge RDCLK)
97
    begin
98
        WR_ADDR_RD1 <= WR_ADDR;
99
        WR_ADDR_RD2 <= WR_ADDR_RD1;
100
        WR_ADDR_RD3 <= WR_ADDR_RD2;
101
 
102
        reset_rd_buf <= { reset, reset_rd_buf[7:1] };
103
        reset_rd <= reset_rd_buf != 8'd0;
104
 
105
        if ( reset_rd )
106
        begin
107
            RD_ADDR <= ADDR_MAX;
108
            RD_ADDR_NEXT <= { (ADDR_WIDTH){1'b0} };
109
            EMPTY <= 1'b1;
110
        end else
111
        begin
112
            RDERR <= RDEN && EMPTY;
113
 
114
            if ( RDEN || EMPTY )
115
            begin
116
                if ( (RD_ADDR_NEXT!=WR_ADDR_RD3) && (RD_ADDR_NEXT!=WR_ADDR_RD2) && (RD_ADDR_NEXT!=WR_ADDR_RD1) && (RD_ADDR!=WR_ADDR_RD3) && (RD_ADDR!=WR_ADDR_RD2) && (RD_ADDR!=WR_ADDR_RD1) )
117
                begin
118
                    EMPTY <= 1'b0;
119
                    DO <= BRAM[RD_ADDR];
120
//                  DO <= { BRAM[RD_ADDR][23:0], RD_ADDR[7:0] };
121
                    RD_ADDR <= RD_ADDR_NEXT;
122
                    RD_ADDR_NEXT <= RD_ADDR_NEXT == ADDR_MAX ? { ADDR_WIDTH{1'b0} } : RD_ADDR_NEXT + 1;
123
                end else
124
                begin
125
                    EMPTY <= 1'b1;
126
                end
127
            end
128
        end
129
    end
130
 
131
endmodule
132
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.