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.01b/] [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
   Implements a FWFT FIFO from all BRAM.
20
*/
21
 
22
 
23
module bram_fifo # (
24
        parameter BRAM_N = 32           // Number of BRAM blocks; 32 available on LX16
25
    ) (
26
        input reset,                    // reset
27
        // FIFO protocol equal to FWFT FIFO in "7 Series Memory Resources" user guide (ug743)
28
        // input fifo interface
29
        input [31:0] DI,                // must be hold while FULL is asserted
30
        output FULL,                    // 1-bit output: Full flag
31
        output reg WRERR,               // 1-bit output: Write error
32
        input WRCLK,                    // 1-bit input: Rising edge write clock.
33
        input WREN,                     // 1-bit input: Write enable
34
 
35
        // output fifo interface
36
        output reg [31:0] DO,
37
        output reg EMPTY,               // 1-bit output: Empty flag, can be used as data valid indicator
38
        output reg RDERR,               // 1-bit output: Read error
39
        input RDCLK,                    // 1-bit input: Read clock
40
        input RDEN                      // 1-bit input: Read enable
41
    );
42
 
43
    localparam ADDR_WIDTH = 15;
44
    localparam ADDR_MAX = 512*BRAM_N-1;
45
 
46
    reg [31:0] BRAM[0:ADDR_MAX];
47
 
48
    // DRAM controller: writing
49
    reg reset_wr, WREN_BUF;
50
    reg [7:0] reset_wr_buf = 8'd0;
51
    reg [ADDR_WIDTH-1:0] WR_ADDR, WR_ADDR_NEXT, RD_ADDR_WR1, RD_ADDR_WR2, RD_ADDR_WR3;
52
 
53
    // DRAM controller: reading
54
    reg reset_rd;
55
    reg [7:0] reset_rd_buf = 8'd0;
56
    reg [ADDR_WIDTH-1:0] RD_ADDR, RD_ADDR_NEXT, WR_ADDR_RD1, WR_ADDR_RD2, WR_ADDR_RD3;
57
 
58
    assign FULL = reset_wr || FULL2;
59
    wire FULL2 = (WR_ADDR_NEXT==RD_ADDR_WR3) || (WR_ADDR_NEXT==RD_ADDR_WR2) || (WR_ADDR_NEXT==RD_ADDR_WR1);
60
 
61
    always @ (posedge WRCLK)
62
    begin
63
        RD_ADDR_WR1 <= RD_ADDR;
64
        RD_ADDR_WR2 <= RD_ADDR_WR1;
65
        RD_ADDR_WR3 <= RD_ADDR_WR2;
66
 
67
        reset_wr_buf <= { reset, reset_wr_buf[7:1] };
68
        reset_wr <= reset_wr_buf != 8'd0;
69
 
70
        if ( reset_wr )
71
        begin
72
            WR_ADDR <= ADDR_MAX;
73
            WR_ADDR_NEXT <= { (ADDR_WIDTH){1'b0} };
74
            WREN_BUF <= 1'b0;
75
        end else
76
        begin
77
            if ( WREN || WREN_BUF )             // process data
78
            begin
79
                if ( ! FULL2 )
80
                begin
81
                    BRAM[WR_ADDR] <= DI;
82
                    WR_ADDR <= WR_ADDR_NEXT;
83
                    WR_ADDR_NEXT <= WR_ADDR_NEXT == ADDR_MAX ? { ADDR_WIDTH{1'b0} } : WR_ADDR_NEXT + 1;
84
                end
85
                WREN_BUF <= FULL2;
86
            end
87
            WRERR <= WREN && WREN_BUF;
88
        end
89
    end
90
 
91
 
92
    always @ (posedge RDCLK)
93
    begin
94
        WR_ADDR_RD1 <= WR_ADDR;
95
        WR_ADDR_RD2 <= WR_ADDR_RD1;
96
        WR_ADDR_RD3 <= WR_ADDR_RD2;
97
 
98
        reset_rd_buf <= { reset, reset_rd_buf[7:1] };
99
        reset_rd <= reset_rd_buf != 8'd0;
100
 
101
        if ( reset_rd )
102
        begin
103
            RD_ADDR <= ADDR_MAX;
104
            RD_ADDR_NEXT <= { (ADDR_WIDTH){1'b0} };
105
            EMPTY <= 1'b1;
106
        end else
107
        begin
108
            RDERR <= RDEN && EMPTY;
109
 
110
            if ( RDEN || EMPTY )
111
            begin
112
                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) )
113
                begin
114
                    EMPTY <= 1'b0;
115
                    DO <= BRAM[RD_ADDR];
116
//                  DO <= { BRAM[RD_ADDR][23:0], RD_ADDR[7:0] };
117
                    RD_ADDR <= RD_ADDR_NEXT;
118
                    RD_ADDR_NEXT <= RD_ADDR_NEXT == ADDR_MAX ? { ADDR_WIDTH{1'b0} } : RD_ADDR_NEXT + 1;
119
                end else
120
                begin
121
                    EMPTY <= 1'b1;
122
                end
123
            end
124
        end
125
    end
126
 
127
endmodule
128
 

powered by: WebSVN 2.1.0

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