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

powered by: WebSVN 2.1.0

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