OpenCores
URL https://opencores.org/ocsvn/usb_fpga_2_13/usb_fpga_2_13/trunk

Subversion Repositories usb_fpga_2_13

[/] [usb_fpga_2_13/] [trunk/] [examples/] [usb-fpga-2.13/] [2.13d/] [memfifo/] [fpga/] [memfifo.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
/*!
2
   memfifo -- implementation of EZ-USB slave FIFO's (input and output) a FIFO using the DDR3 SDRAM for ZTEX USB-FPGA Modules 2.13
3
   Copyright (C) 2009-2014 ZTEX GmbH.
4
   http://www.ztex.de
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License version 3 as
8
   published by the Free Software Foundation.
9
 
10
   This program is distributed in the hope that it will be useful, but
11
   WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
   General Public License for more details.
14
 
15
   You should have received a copy of the GNU General Public License
16
   along with this program; if not, see http://www.gnu.org/licenses/.
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
        input [1:0] mode,
29
        // debug
30
        output [9:0] led1,
31
        output [19:0] led2,
32
        input SW8,
33
        input SW10,
34
        // ddr3 
35
        inout [15:0] ddr3_dq,
36
        inout [1:0] ddr3_dqs_n,
37
        inout [1:0] ddr3_dqs_p,
38
        output [13:0] ddr3_addr,
39
        output [2:0] ddr3_ba,
40
        output ddr3_ras_n,
41
        output ddr3_cas_n,
42
        output ddr3_we_n,
43
        output ddr3_reset_n,
44
        output [0:0] ddr3_ck_p,
45
        output [0:0] ddr3_ck_n,
46
        output [0:0] ddr3_cke,
47
        output [1:0] ddr3_dm,
48
        output [0:0] ddr3_odt,
49
        // ez-usb
50
        inout [15:0] fd,
51
        output SLWR, SLRD,
52
        output SLOE, FIFOADDR0, FIFOADDR1, PKTEND,
53
        input FLAGA, FLAGB
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
    reg [1:0] mode_buf;
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
 
77
    // output fifo
78
    wire [127:0] DO;
79
    wire EMPTY, RDERR, USB_DI_ready;
80
    reg RDEN, rderr_buf, USB_DI_valid;
81
    reg [127:0] rd_buf;
82
    reg [2:0] rd_cnt;
83
 
84
    dram_fifo #(
85
        .FIRST_WORD_FALL_THROUGH("TRUE"),                       // Sets the FIFO FWFT to FALSE, TRUE
86
        .ALMOST_EMPTY_OFFSET2(13'h0008),
87
    ) dram_fifo_inst (
88
        .fxclk_in(fxclk_in),                                    // 48 MHz input clock pin
89
        .reset(reset || reset_usb),
90
        .reset_out(reset_mem),                                  // reset output
91
        .clkout2(),                                             // PLL clock outputs not used for memory interface
92
        .clkout3(),
93
        .clkout4(),
94
        .clkout5(),
95
        // Memory interface ports
96
        .ddr3_dq(ddr3_dq),
97
        .ddr3_dqs_n(ddr3_dqs_n),
98
        .ddr3_dqs_p(ddr3_dqs_p),
99
        .ddr3_addr(ddr3_addr),
100
        .ddr3_ba(ddr3_ba),
101
        .ddr3_ras_n(ddr3_ras_n),
102
        .ddr3_cas_n(ddr3_cas_n),
103
        .ddr3_we_n(ddr3_we_n),
104
        .ddr3_reset_n(ddr3_reset_n),
105
        .ddr3_ck_p(ddr3_ck_p),
106
        .ddr3_ck_n(ddr3_ck_n),
107
        .ddr3_cke(ddr3_cke),
108
        .ddr3_dm(ddr3_dm),
109
        .ddr3_odt(ddr3_odt),
110
        // input fifo interface, see "7 Series Memory Resources" user guide (ug743)
111
        .DI(DI),
112
        .FULL(FULL),                    // 1-bit output: Full flag
113
        .ALMOSTFULL1(),                 // 1-bit output: Almost full flag
114
        .ALMOSTFULL2(),                 // 1-bit output: Almost full flag
115
        .WRERR(WRERR),                  // 1-bit output: Write error
116
        .WREN(WREN),                    // 1-bit input: Write enable
117
        .WRCLK(ifclk),                  // 1-bit input: Rising edge write clock.
118
        // output fifo interface, see "7 Series Memory Resources" user guide (ug743)
119
        .DO(DO),
120
        .EMPTY(EMPTY),                  // 1-bit output: Empty flag
121
        .ALMOSTEMPTY1(),                // 1-bit output: Almost empty flag
122
        .ALMOSTEMPTY2(),                // 1-bit output: Almost empty flag
123
        .RDERR(RDERR),                  // 1-bit output: Read error
124
        .RDCLK(ifclk),                  // 1-bit input: Read clock
125
        .RDEN(RDEN),                    // 1-bit input: Read enable
126
        // free memory
127
        .mem_free_out(mem_free),
128
        // for debugging
129
        .status(status)
130
    );
131
 
132
    ezusb_io #(
133
        .OUTEP(2),                      // EP for FPGA -> EZ-USB transfers
134
        .INEP(6),                       // EP for EZ-USB -> FPGA transfers 
135
    ) ezusb_io_inst (
136
        .ifclk(ifclk),
137
        .reset(reset),                  // asynchronous reset input
138
        .reset_out(reset_usb),          // synchronous reset output
139
        // pins
140
        .ifclk_in(ifclk_in),
141
        .fd(fd),
142
        .SLWR(SLWR),
143
        .SLRD(SLRD),
144
        .SLOE(SLOE),
145
        .PKTEND(PKTEND),
146
        .FIFOADDR({FIFOADDR1, FIFOADDR0}),
147
        .EMPTY_FLAG(FLAGA),
148
        .FULL_FLAG(FLAGB),
149
        // signals for FPGA -> EZ-USB transfer
150
        .DI(rd_buf[15:0]),               // data written to EZ-USB
151
        .DI_valid(USB_DI_valid),        // 1 indicates data valid; DI and DI_valid must be hold if DI_ready is 0
152
        .DI_ready(USB_DI_ready),        // 1 if new data are accepted
153
        .DI_enable(1'b1),               // setting to 0 disables FPGA -> EZ-USB transfers
154
        .pktend_timeout(16'd73),        // timeout in multiples of 65536 clocks (approx. 0.1s @ 48 MHz) before a short packet committed
155
                                        // setting to 0 disables this feature
156
        // signals for EZ-USB -> FPGA transfer
157
        .DO(USB_DO),                    // data read from EZ-USB
158
        .DO_valid(USB_DO_valid),        // 1 indicated valid data
159
        .DO_ready((mode_buf==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
160
        // debug output
161
        .status(if_status)
162
    );
163
 
164
/*    BUFR ifclkin_buf (
165
        .I(ifclk_in),
166
        .O(ifclk)
167
    ); */
168
//    assign ifclk = ifclk_in;
169
 
170
    // debug board LEDs    
171
    assign led1 = SW10 ? status : { EMPTY, FULL, wrerr_buf, rderr_buf, if_status, FLAGB, FLAGA };
172
 
173
    assign led2[0] = mem_free != { 1'b1, 24'd0 };
174
    assign led2[1] = mem_free[23:19] < 5'd30;
175
    assign led2[2] = mem_free[23:19] < 5'd29;
176
    assign led2[3] = mem_free[23:19] < 5'd27;
177
    assign led2[4] = mem_free[23:19] < 5'd25;
178
    assign led2[5] = mem_free[23:19] < 5'd24;
179
    assign led2[6] = mem_free[23:19] < 5'd22;
180
    assign led2[7] = mem_free[23:19] < 5'd20;
181
    assign led2[8] = mem_free[23:19] < 5'd19;
182
    assign led2[9] = mem_free[23:19] < 5'd17;
183
    assign led2[10] = mem_free[23:19] < 5'd15;
184
    assign led2[11] = mem_free[23:19] < 5'd13;
185
    assign led2[12] = mem_free[23:19] < 5'd12;
186
    assign led2[13] = mem_free[23:19] < 5'd10;
187
    assign led2[14] = mem_free[23:19] < 5'd8;
188
    assign led2[15] = mem_free[23:19] < 5'd7;
189
    assign led2[16] = mem_free[23:19] < 5'd5;
190
    assign led2[17] = mem_free[23:19] < 5'd3;
191
    assign led2[18] = mem_free[23:19] < 5'd2;
192
    assign led2[19] = mem_free == 25'd0;
193
 
194
    assign test_sync = wr_cnt[0] || (wr_cnt == 4'd14);
195
 
196
    always @ (posedge ifclk)
197
    begin
198
        reset_ifclk <= reset || reset_usb || reset_mem;
199
 
200
        if ( reset_ifclk )
201
        begin
202
            rderr_buf <= 1'b0;
203
            wrerr_buf <= 1'b0;
204
        end else
205
        begin
206
            rderr_buf <= rderr_buf || RDERR;
207
            wrerr_buf <= wrerr_buf || WRERR;
208
        end
209
 
210
        // FPGA -> EZ-USB FIFO
211
        if ( reset_ifclk )
212
        begin
213
            rd_cnt <= 3'd0;
214
            USB_DI_valid <= 1'd0;
215
        end else if ( USB_DI_ready )
216
        begin
217
            USB_DI_valid <= !EMPTY;
218
            if ( !EMPTY )
219
            begin
220
                if ( rd_cnt == 3'd0 )
221
                begin
222
                    rd_buf <= DO;
223
                end else
224
                begin
225
                    rd_buf[111:0] <= rd_buf[127:16];
226
                end
227
                rd_cnt <= rd_cnt+1;
228
            end
229
        end
230
 
231
        RDEN <= !reset_ifclk && USB_DI_ready && !EMPTY && (rd_cnt==3'd0);
232
 
233
        if ( reset_ifclk )
234
        begin
235
            in_data <= 128'd0;
236
            in_valid <= 1'b0;
237
            wr_cnt <= 4'd0;
238
            test_cnt <= 7'd0;
239
            test_cs <= 12'd47;
240
            WREN <= 1'b0;
241
            clk_div <= 2'd3;
242
        end else if ( !FULL )
243
        begin
244
            if ( in_valid ) DI <= in_data;
245
 
246
            if ( mode_buf == 2'd0 )             // input from USB
247
            begin
248
                if ( USB_DO_valid )
249
                begin
250
                    in_data <= { USB_DO, in_data[127:16] };
251
                    in_valid <= wr_cnt[2:0] == 3'd7;
252
                    wr_cnt <= wr_cnt + 1;
253
                end else
254
                begin
255
                    in_valid <= 1'b0;
256
                end
257
            end else if ( clk_div == 2'd0 )     // test data generator
258
            begin
259
                if ( wr_cnt == 4'd15 )
260
                begin
261
                    test_cs <= 12'd47;
262
                    in_data[126:120] <= test_cs[6:0] ^ test_cs[13:7];
263
                    in_valid <= 1'b1;
264
                end else
265
                begin
266
                    test_cnt <= test_cnt + 7'd111;
267
                    test_cs <= test_cs + { test_sync, test_cnt };
268
                    in_data[126:120] <= test_cnt;
269
                    in_valid <= 1'b0;
270
                end
271
                in_data[127] <= test_sync;
272
                in_data[119:0] <= in_data[127:8];
273
                wr_cnt <= wr_cnt + 1;
274
            end else
275
            begin
276
                in_valid <= 1'b0;
277
            end
278
 
279
            if ( (mode_buf==2'd1) || ((mode_buf==2'd3) && SW8 ) )
280
            begin
281
                clk_div <= 2'd0;        // data rate: 48 MByte/s
282
            end else
283
            begin
284
                clk_div <= clk_div + 1; // data rate: 12 MByte/s
285
            end
286
        end
287
        WREN <= !reset_ifclk && in_valid && !FULL;
288
        mode_buf<=mode;
289
    end
290
 
291
endmodule
292
 

powered by: WebSVN 2.1.0

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