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.13/] [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 fxclk_in,
24
        input ifclk_in,
25
        input reset,
26
        // debug
27
        output [9:0] led1,
28
        output [19:0] led2,
29
        input SW8,
30
        input SW10,
31
        // ddr3 
32
        inout [15:0] ddr3_dq,
33
        inout [1:0] ddr3_dqs_n,
34
        inout [1:0] ddr3_dqs_p,
35
        output [13:0] ddr3_addr,
36
        output [2:0] ddr3_ba,
37
        output ddr3_ras_n,
38
        output ddr3_cas_n,
39
        output ddr3_we_n,
40
        output ddr3_reset_n,
41
        output [0:0] ddr3_ck_p,
42
        output [0:0] ddr3_ck_n,
43
        output [0:0] ddr3_cke,
44
        output [1:0] ddr3_dm,
45
        output [0:0] ddr3_odt,
46
        // ez-usb
47
        inout [15:0] fd,
48
        output SLWR, SLRD,
49
        output SLOE, FIFOADDR0, FIFOADDR1, PKTEND,
50
        input FLAGA, FLAGB,
51
        // GPIO
52
        input gpio_clk, gpio_dir,
53
        inout gpio_dat
54
    );
55
 
56
    wire reset_mem, reset_usb;
57
    wire ifclk;
58
    reg reset_ifclk;
59
    wire [24:0] mem_free;
60
    wire [9:0] status;
61
    wire [3:0] if_status;
62
    wire [3:0] mode;
63
 
64
    // input fifo
65
    reg [127:0] DI;
66
    wire FULL, WRERR, USB_DO_valid;
67
    reg WREN, wrerr_buf;
68
    wire [15:0] USB_DO;
69
    reg [127:0] in_data;
70
    reg [3:0] wr_cnt;
71
    reg [6:0] test_cnt;
72
    reg [13:0] test_cs;
73
    reg in_valid;
74
    wire test_sync;
75
    reg [1:0] clk_div;
76
    reg DI_run;
77
 
78
    // output fifo
79
    wire [127:0] DO;
80
    wire EMPTY, RDERR, USB_DI_ready;
81
    reg RDEN, rderr_buf, USB_DI_valid;
82
    reg [127:0] rd_buf;
83
    reg [2:0] rd_cnt;
84
 
85
    dram_fifo #(
86
        .FIRST_WORD_FALL_THROUGH("TRUE"),                       // Sets the FIFO FWFT to FALSE, TRUE
87
        .ALMOST_EMPTY_OFFSET2(13'h0008)
88
    ) dram_fifo_inst (
89
        .fxclk_in(fxclk_in),                                    // 48 MHz input clock pin
90
        .reset(reset || reset_usb),
91
        .reset_out(reset_mem),                                  // reset output
92
        .clkout2(),                                             // PLL clock outputs not used for memory interface
93
        .clkout3(),
94
        .clkout4(),
95
        .clkout5(),
96
        // Memory interface ports
97
        .ddr3_dq(ddr3_dq),
98
        .ddr3_dqs_n(ddr3_dqs_n),
99
        .ddr3_dqs_p(ddr3_dqs_p),
100
        .ddr3_addr(ddr3_addr),
101
        .ddr3_ba(ddr3_ba),
102
        .ddr3_ras_n(ddr3_ras_n),
103
        .ddr3_cas_n(ddr3_cas_n),
104
        .ddr3_we_n(ddr3_we_n),
105
        .ddr3_reset_n(ddr3_reset_n),
106
        .ddr3_ck_p(ddr3_ck_p),
107
        .ddr3_ck_n(ddr3_ck_n),
108
        .ddr3_cke(ddr3_cke),
109
        .ddr3_dm(ddr3_dm),
110
        .ddr3_odt(ddr3_odt),
111
        // input fifo interface, see "7 Series Memory Resources" user guide (ug743)
112
        .DI(DI),
113
        .FULL(FULL),                    // 1-bit output: Full flag
114
        .ALMOSTFULL1(),                 // 1-bit output: Almost full flag
115
        .ALMOSTFULL2(),                 // 1-bit output: Almost full flag
116
        .WRERR(WRERR),                  // 1-bit output: Write error
117
        .WREN(WREN),                    // 1-bit input: Write enable
118
        .WRCLK(ifclk),                  // 1-bit input: Rising edge write clock.
119
        // output fifo interface, see "7 Series Memory Resources" user guide (ug743)
120
        .DO(DO),
121
        .EMPTY(EMPTY),                  // 1-bit output: Empty flag
122
        .ALMOSTEMPTY1(),                // 1-bit output: Almost empty flag
123
        .ALMOSTEMPTY2(),                // 1-bit output: Almost empty flag
124
        .RDERR(RDERR),                  // 1-bit output: Read error
125
        .RDCLK(ifclk),                  // 1-bit input: Read clock
126
        .RDEN(RDEN),                    // 1-bit input: Read enable
127
        // free memory
128
        .mem_free_out(mem_free),
129
        // for debugging
130
        .status(status)
131
    );
132
 
133
    ezusb_gpio gpio_inst (
134
        .clk(ifclk),                    // system clock, minimum frequency is 24 MHz
135
        // hardware pins
136
        .gpio_clk(gpio_clk),            // data clock; data sent on both edges
137
        .gpio_dir(gpio_dir),            // 1: output, 0->1 transition latches input data and starts writing
138
        .gpio_dat(gpio_dat),
139
        // interface
140
        .in(mode),
141
        .out(4'd0)                      // wired or: GPIO's not used for output should be 0
142
    );
143
 
144
    ezusb_io #(
145
        .OUTEP(2),                      // EP for FPGA -> EZ-USB transfers
146
        .INEP(6),                       // EP for EZ-USB -> FPGA transfers 
147
        .TARGET("A7")                   // "A4" for Artix 7
148
    ) ezusb_io_inst (
149
        .ifclk(ifclk),
150
        .reset(reset),                  // asynchronous reset input
151
        .reset_out(reset_usb),          // synchronous reset output
152
        // pins
153
        .ifclk_in(ifclk_in),
154
        .fd(fd),
155
        .SLWR(SLWR),
156
        .SLRD(SLRD),
157
        .SLOE(SLOE),
158
        .PKTEND(PKTEND),
159
        .FIFOADDR({FIFOADDR1, FIFOADDR0}),
160
        .EMPTY_FLAG(FLAGA),
161
        .FULL_FLAG(FLAGB),
162
        // signals for FPGA -> EZ-USB transfer
163
        .DI(rd_buf[15:0]),               // data written to EZ-USB
164
        .DI_valid(USB_DI_valid),        // 1 indicates data valid; DI and DI_valid must be hold if DI_ready is 0
165
        .DI_ready(USB_DI_ready),        // 1 if new data are accepted
166
        .DI_enable(1'b1),               // setting to 0 disables FPGA -> EZ-USB transfers
167
        .pktend_arm(mode[2]),           // 0->1 transition enables the manual PKTEND mechanism:
168
                                        // PKTEND is asserted as soon output becomes idle
169
                                        // recommended procedure for accurate packet transfers:
170
                                        //   * DI_validgoes low after last data of package
171
                                        //   * monitor PKTEND and hold DI_valid until PKTEND is asserted (PKTEND = 0)
172
        .pktend_timeout(16'd366),       // automatic PKTEN assertation after pktend_timeout*65536 (approx. 0.5s) clocks of no
173
                                        // output data. Setting to 0 disables this feature.
174
        // signals for EZ-USB -> FPGA transfer
175
        .DO(USB_DO),                    // data read from EZ-USB
176
        .DO_valid(USB_DO_valid),        // 1 indicated valid data
177
        .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
178
        // debug output
179
        .status(if_status)
180
    );
181
 
182
/*    BUFR ifclkin_buf (
183
        .I(ifclk_in),
184
        .O(ifclk)
185
    ); */
186
//    assign ifclk = ifclk_in;
187
 
188
    // debug board LEDs    
189
    assign led1 = SW10 ? status : { EMPTY, FULL, wrerr_buf, rderr_buf, if_status, FLAGB, FLAGA };
190
 
191
    assign led2[0] = mem_free != { 1'b1, 24'd0 };
192
    assign led2[1] = mem_free[23:19] < 5'd30;
193
    assign led2[2] = mem_free[23:19] < 5'd29;
194
    assign led2[3] = mem_free[23:19] < 5'd27;
195
    assign led2[4] = mem_free[23:19] < 5'd25;
196
    assign led2[5] = mem_free[23:19] < 5'd24;
197
    assign led2[6] = mem_free[23:19] < 5'd22;
198
    assign led2[7] = mem_free[23:19] < 5'd20;
199
    assign led2[8] = mem_free[23:19] < 5'd19;
200
    assign led2[9] = mem_free[23:19] < 5'd17;
201
    assign led2[10] = mem_free[23:19] < 5'd15;
202
    assign led2[11] = mem_free[23:19] < 5'd13;
203
    assign led2[12] = mem_free[23:19] < 5'd12;
204
    assign led2[13] = mem_free[23:19] < 5'd10;
205
    assign led2[14] = mem_free[23:19] < 5'd8;
206
    assign led2[15] = mem_free[23:19] < 5'd7;
207
    assign led2[16] = mem_free[23:19] < 5'd5;
208
    assign led2[17] = mem_free[23:19] < 5'd3;
209
    assign led2[18] = mem_free[23:19] < 5'd2;
210
    assign led2[19] = mem_free == 25'd0;
211
 
212
    assign test_sync = wr_cnt[0] || (wr_cnt == 4'd14);
213
 
214
    always @ (posedge ifclk)
215
    begin
216
        reset_ifclk <= reset || reset_usb || reset_mem;
217
 
218
        if ( reset_ifclk )
219
        begin
220
            rderr_buf <= 1'b0;
221
            wrerr_buf <= 1'b0;
222
        end else
223
        begin
224
            rderr_buf <= rderr_buf || RDERR;
225
            wrerr_buf <= wrerr_buf || WRERR;
226
        end
227
 
228
        // FPGA -> EZ-USB FIFO
229
        DI_run <= !mode[2];
230
        if ( reset_ifclk )
231
        begin
232
            rd_cnt <= 3'd0;
233
            USB_DI_valid <= 1'd0;
234
        end else if ( USB_DI_ready )
235
        begin
236
            USB_DI_valid <= !EMPTY && DI_run;
237
            if ( !EMPTY && DI_run )
238
            begin
239
                if ( rd_cnt == 3'd0 )
240
                begin
241
                    rd_buf <= DO;
242
                end else
243
                begin
244
                    rd_buf[111:0] <= rd_buf[127:16];
245
                end
246
                rd_cnt <= rd_cnt+1;
247
            end
248
        end
249
        RDEN <= !reset_ifclk && USB_DI_ready && !EMPTY && (rd_cnt==3'd0) && DI_run;
250
 
251
        // data source
252
        if ( reset_ifclk )
253
        begin
254
            in_data <= 128'd0;
255
            in_valid <= 1'b0;
256
            wr_cnt <= 4'd0;
257
            test_cnt <= 7'd0;
258
            test_cs <= 12'd47;
259
            WREN <= 1'b0;
260
            clk_div <= 2'd3;
261
        end else if ( !FULL )
262
        begin
263
            if ( in_valid ) DI <= in_data;
264
 
265
            if ( mode[1:0] == 2'd0 )             // input from USB
266
            begin
267
                if ( USB_DO_valid )
268
                begin
269
                    in_data <= { USB_DO, in_data[127:16] };
270
                    in_valid <= wr_cnt[2:0] == 3'd7;
271
                    wr_cnt <= wr_cnt + 1;
272
                end else
273
                begin
274
                    in_valid <= 1'b0;
275
                end
276
            end else if ( clk_div == 2'd0 )     // test data generator
277
            begin
278
                if ( wr_cnt == 4'd15 )
279
                begin
280
                    test_cs <= 12'd47;
281
                    in_data[126:120] <= test_cs[6:0] ^ test_cs[13:7];
282
                    in_valid <= 1'b1;
283
                end else
284
                begin
285
                    test_cnt <= test_cnt + 7'd111;
286
                    test_cs <= test_cs + { test_sync, test_cnt };
287
                    in_data[126:120] <= test_cnt;
288
                    in_valid <= 1'b0;
289
                end
290
                in_data[127] <= test_sync;
291
                in_data[119:0] <= in_data[127:8];
292
                wr_cnt <= wr_cnt + 1;
293
            end else
294
            begin
295
                in_valid <= 1'b0;
296
            end
297
 
298
            if ( (mode[1:0]==2'd1) || ((mode[1:0]==2'd3) && SW8 ) )
299
            begin
300
                clk_div <= 2'd0;        // data rate: 48 MByte/s
301
            end else
302
            begin
303
                clk_div <= clk_div + 1; // data rate: 12 MByte/s
304
            end
305
        end
306
        WREN <= !reset_ifclk && in_valid && !FULL;
307
    end
308
 
309
endmodule
310
 

powered by: WebSVN 2.1.0

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