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

powered by: WebSVN 2.1.0

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