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/] [memfifo.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
   Top level module: glues everything together.
20
*/
21
 
22
module memfifo (
23
        input ifclk_in,
24
        input reset,
25
        // debug
26
        output [9:0] led1,
27
        input SW8,
28
        // ez-usb
29
        inout [15:0] fd,
30
        output SLWR, SLRD,
31
        output SLOE, FIFOADDR0, FIFOADDR1, PKTEND,
32
        input FLAGA, FLAGB,
33
        // GPIO
34
        input gpio_clk, gpio_dir,
35
        inout gpio_dat
36
    );
37
 
38
    wire reset_usb;
39
    wire ifclk;
40
    reg reset_ifclk;
41
    wire [9:0] status;
42
    wire [3:0] if_status;
43
    wire [3:0] mode;
44
 
45
    // input fifo
46
    reg [31:0] DI;
47
    wire FULL, WRERR, USB_DO_valid;
48
    reg WREN, wrerr_buf;
49
    wire [15:0] USB_DO;
50
    reg [31:0] in_data;
51
    reg [3:0] wr_cnt;
52
    reg [6:0] test_cnt;
53
    reg [13:0] test_cs;
54
    reg in_valid;
55
    wire test_sync;
56
    reg [1:0] clk_div;
57
    reg DI_run;
58
 
59
    // output fifo
60
    wire [31:0] DO;
61
    wire EMPTY, RDERR, USB_DI_ready;
62
    reg RDEN, rderr_buf, USB_DI_valid;
63
    reg [31:0] rd_buf;
64
    reg rd_cnt;
65
 
66
    bram_fifo bram_fifo_inst (
67
        .reset(reset || reset_usb),
68
        // input fifo interface
69
        .DI(DI),                        // must be hold while FULL is asserted
70
        .FULL(FULL),                    // 1-bit output: Full flag
71
        .WRERR(WRERR),                  // 1-bit output: Write error
72
        .WREN(WREN),                    // 1-bit input: Write enable
73
        .WRCLK(ifclk),                  // 1-bit input: Rising edge write clock.
74
        // output fifo interface
75
        .DO(DO),
76
        .EMPTY(EMPTY),                  // 1-bit output: Empty flag
77
        .RDERR(RDERR),                  // 1-bit output: Read error
78
        .RDCLK(ifclk),                  // 1-bit input: Read clock
79
        .RDEN(RDEN)                     // 1-bit input: Read enable
80
        // for debugging
81
    );
82
 
83
    ezusb_gpio gpio_inst (
84
        .clk(ifclk),                    // system clock, minimum frequency is 24 MHz
85
        // hardware pins
86
        .gpio_clk(gpio_clk),            // data clock; data sent on both edges
87
        .gpio_dir(gpio_dir),            // 1: output, 0->1 transition latches input data and starts writing
88
        .gpio_dat(gpio_dat),
89
        // interface
90
        .in(mode),
91
        .out(4'd0)                      // wired or: GPIO's not used for output should be 0
92
    );
93
 
94
    ezusb_io #(
95
        .OUTEP(2),                      // EP for FPGA -> EZ-USB transfers
96
        .INEP(6),                       // EP for EZ-USB -> FPGA transfers 
97
        .TARGET("A7")                   // "A4" for Artix 7
98
    ) ezusb_io_inst (
99
        .ifclk(ifclk),
100
        .reset(reset),                  // asynchronous reset input
101
        .reset_out(reset_usb),          // synchronous reset output
102
        // pins
103
        .ifclk_in(ifclk_in),
104
        .fd(fd),
105
        .SLWR(SLWR),
106
        .SLRD(SLRD),
107
        .SLOE(SLOE),
108
        .PKTEND(PKTEND),
109
        .FIFOADDR({FIFOADDR1, FIFOADDR0}),
110
        .EMPTY_FLAG(FLAGA),
111
        .FULL_FLAG(FLAGB),
112
        // signals for FPGA -> EZ-USB transfer
113
        .DI(rd_buf[15:0]),               // data written to EZ-USB
114
        .DI_valid(USB_DI_valid),        // 1 indicates data valid; DI and DI_valid must be hold if DI_ready is 0
115
        .DI_ready(USB_DI_ready),        // 1 if new data are accepted
116
        .DI_enable(1'b1),               // setting to 0 disables FPGA -> EZ-USB transfers
117
        .pktend_arm(mode[2]),           // 0->1 transition enables the manual PKTEND mechanism:
118
                                        // PKTEND is asserted as soon output becomes idle
119
                                        // recommended procedure for accurate packet transfers:
120
                                        //   * DI_validgoes low after last data of package
121
                                        //   * monitor PKTEND and hold DI_valid until PKTEND is asserted (PKTEND = 0)
122
        .pktend_timeout(16'd366),       // automatic PKTEN assertation after pktend_timeout*65536 (approx. 0.5s) clocks of no
123
                                        // output data. Setting to 0 disables this feature.
124
        // signals for EZ-USB -> FPGA transfer
125
        .DO(USB_DO),                    // data read from EZ-USB
126
        .DO_valid(USB_DO_valid),        // 1 indicated valid data
127
        .DO_ready((mode[1:0]==2'd0) && !reset_ifclk && !FULL),   // setting to 1 enables writing new data to DO in next clock; DO and DO_valid are hold if DO_ready is 0
128
        // debug output
129
        .status(if_status)
130
    );
131
 
132
    // debug board LEDs    
133
//    assign led1 =  { EMPTY, FULL, wrerr_buf, rderr_buf, if_status, FLAGB, FLAGA };
134
    assign led1 =  { EMPTY, FULL, mode[1:0], if_status, FLAGB, FLAGA };
135
 
136
    assign test_sync = wr_cnt[0] || (wr_cnt == 4'd14);
137
 
138
    always @ (posedge ifclk)
139
    begin
140
        reset_ifclk <= reset || reset_usb;
141
 
142
        if ( reset_ifclk )
143
        begin
144
            rderr_buf <= 1'b0;
145
            wrerr_buf <= 1'b0;
146
        end else
147
        begin
148
            rderr_buf <= rderr_buf || RDERR;
149
            wrerr_buf <= wrerr_buf || WRERR;
150
        end
151
 
152
        // FPGA -> EZ-USB FIFO
153
        DI_run <= !mode[2];
154
        if ( reset_ifclk )
155
        begin
156
            rd_cnt <= 1'd0;
157
            USB_DI_valid <= 1'd0;
158
        end else if ( USB_DI_ready )
159
        begin
160
            USB_DI_valid <= !EMPTY && DI_run;
161
            if ( !EMPTY && DI_run )
162
            begin
163
                if ( rd_cnt == 1'd0 )
164
                begin
165
                    rd_buf <= DO;
166
                end else
167
                begin
168
                    rd_buf[15:0] <= rd_buf[31:16];
169
                end
170
                rd_cnt <= rd_cnt + 1'd1;
171
            end
172
        end
173
        RDEN <= !reset_ifclk && USB_DI_ready && !EMPTY && (rd_cnt==1'd0) && DI_run;
174
 
175
        // data source
176
        if ( reset_ifclk )
177
        begin
178
            in_data <= 31'd0;
179
            in_valid <= 1'b0;
180
            wr_cnt <= 4'd0;
181
            test_cnt <= 7'd0;
182
            test_cs <= 12'd47;
183
            WREN <= 1'b0;
184
            clk_div <= 2'd3;
185
            DI <= 32'h05040302;
186
        end else if ( !FULL )
187
        begin
188
            if ( in_valid ) DI <= in_data;
189
//          DI <= DI + 32'h03030303;
190
 
191
            if ( mode[1:0] == 2'd0 )             // input from USB
192
            begin
193
                if ( USB_DO_valid )
194
                begin
195
                    in_data <= { USB_DO, in_data[31:16] };
196
                    in_valid <= wr_cnt[0];
197
                    wr_cnt <= wr_cnt + 4'd1;
198
                end else
199
                begin
200
                    in_valid <= 1'b0;
201
                end
202
            end else if ( clk_div == 2'd0 )     // test data generator 
203
            begin
204
                if ( wr_cnt == 4'd15 )
205
                begin
206
                    test_cs <= 12'd47;
207
                    in_data[30:24] <= test_cs[6:0] ^ test_cs[13:7];
208
                end else
209
                begin
210
                    test_cnt <= test_cnt + 7'd111;
211
                    test_cs <= test_cs + { test_sync, test_cnt };
212
                    in_data[30:24] <= test_cnt;
213
                end
214
                in_data[31] <= test_sync;
215
                in_data[23:0] <= in_data[31:8];
216
                in_valid <= wr_cnt[1:0] == 2'd3;
217
                wr_cnt <= wr_cnt + 4'd1;
218
            end else
219
            begin
220
                in_valid <= 1'b0;
221
            end
222
 
223
            if ( (mode[1:0]==2'd1) || ((mode[1:0]==2'd3) && SW8 ) )
224
            begin
225
                clk_div <= 2'd0;        // data rate: 48 MByte/s
226
            end else
227
            begin
228
                clk_div <= clk_div + 2'd1;      // data rate: 12 MByte/s
229
            end
230
        end
231
        WREN <= !reset_ifclk && in_valid && !FULL;
232
//      WREN <= !reset_ifclk && !FULL;
233
    end
234
 
235
endmodule
236
 

powered by: WebSVN 2.1.0

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