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

powered by: WebSVN 2.1.0

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