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] - Rev 2

Compare with Previous | Blame | View Log

/*%
   memfifo -- Connects the bi-directional high speed interface of default firmware to a FIFO built of on-board SDRAM or on-chip BRAM
   Copyright (C) 2009-2017 ZTEX GmbH.
   http://www.ztex.de
 
   Copyright and related rights are licensed under the Solderpad Hardware
   License, Version 0.51 (the "License"); you may not use this file except
   in compliance with the License. You may obtain a copy of the License at
 
       http://solderpad.org/licenses/SHL-0.51.
 
   Unless required by applicable law or agreed to in writing, software, hardware
   and materials distributed under this License is distributed on an "AS IS"
   BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   implied. See the License for the specific language governing permissions
   and limitations under the License.
%*/
/* 
   Top level module: glues everything together.    
*/  
 
module memfifo (
	input fxclk_in,
	input ifclk_in,
	input reset,
	inout [3:0] gpio_n,
	// debug
	output led,
	output [9:0] led1,
	output [19:0] led2,
	input SW10,
	// ddr3 
	inout [15:0] ddr3_dq,
	inout [1:0] ddr3_dqs_n,
	inout [1:0] ddr3_dqs_p,
	output [13:0] ddr3_addr,
	output [2:0] ddr3_ba,
	output ddr3_ras_n,
	output ddr3_cas_n,
	output ddr3_we_n,
        output ddr3_reset_n,
	output [0:0] ddr3_ck_p,
        output [0:0] ddr3_ck_n,
	output [0:0] ddr3_cke,
        output [1:0] ddr3_dm,
	output [0:0] ddr3_odt,
	// ez-usb
        inout [15:0] fd,
	output SLWR, SLRD,
	output SLOE, PKTEND,
	input EMPTY_FLAG, FULL_FLAG
    );
 
    wire reset_mem, reset_usb;
    wire ifclk;
    reg reset_ifclk;
    wire [24:0] mem_free;
    wire [9:0] status;
    wire [6:0] if_status;
    wire [3:0] gpio_in;
 
    // input fifo
    reg [127:0] DI;
    wire FULL, WRERR, USB_DO_valid;
    reg WREN, wrerr_buf, USB_DO_ready, FULL_buf1, FULL_buf2;
    wire [15:0] USB_DO;
    reg [127:0] in_data;
    reg [2:0] wr_cnt;
    reg [6:0] test_cnt0, test_cnt1;
    reg [13:0] test_cs;
    wire [13:0] test_cs_w;
    reg in_valid;
    reg [3:0] clk_div;
    reg DI_run;
 
    // output fifo
    wire [127:0] DO;
    wire EMPTY, RDERR, USB_DI_ready;
    reg RDEN, rderr_buf, USB_DI_valid;
    reg [127:0] rd_buf;
    reg [2:0] rd_cnt;
 
    dram_fifo #(
        .FIRST_WORD_FALL_THROUGH("TRUE"),  			// Sets the FIFO FWFT to FALSE, TRUE
	.ALMOST_EMPTY_OFFSET2(13'h0008)
    ) dram_fifo_inst (
	.fxclk_in(fxclk_in),					// 26 MHz input clock pin
        .reset(reset || reset_usb),
        .reset_out(reset_mem),					// reset output
      	.clkout2(),	 					// PLL clock outputs not used for memory interface
      	.clkout3(),	
      	.clkout4(),	
      	.clkout5(),	
	// Memory interface ports
	.ddr3_dq(ddr3_dq),
        .ddr3_dqs_n(ddr3_dqs_n),
        .ddr3_dqs_p(ddr3_dqs_p),
        .ddr3_addr(ddr3_addr),
        .ddr3_ba(ddr3_ba),
        .ddr3_ras_n(ddr3_ras_n),
        .ddr3_cas_n(ddr3_cas_n),
        .ddr3_we_n(ddr3_we_n),
        .ddr3_reset_n(ddr3_reset_n),
        .ddr3_ck_p(ddr3_ck_p),
        .ddr3_ck_n(ddr3_ck_n),
        .ddr3_cke(ddr3_cke),
	.ddr3_dm(ddr3_dm),
        .ddr3_odt(ddr3_odt),
	// input fifo interface, see "7 Series Memory Resources" user guide (ug743)
	.DI(DI),
        .FULL(FULL),                    // 1-bit output: Full flag
        .ALMOSTFULL1(),  	     	// 1-bit output: Almost full flag
        .ALMOSTFULL2(),  	     	// 1-bit output: Almost full flag
        .WRERR(WRERR),                  // 1-bit output: Write error
        .WREN(WREN),                    // 1-bit input: Write enable
        .WRCLK(ifclk),                  // 1-bit input: Rising edge write clock.
	// output fifo interface, see "7 Series Memory Resources" user guide (ug743)
	.DO(DO),
	.EMPTY(EMPTY),                  // 1-bit output: Empty flag
        .ALMOSTEMPTY1(),                // 1-bit output: Almost empty flag
        .ALMOSTEMPTY2(),                // 1-bit output: Almost empty flag
        .RDERR(RDERR),                  // 1-bit output: Read error
        .RDCLK(ifclk),                  // 1-bit input: Read clock
        .RDEN(RDEN),                    // 1-bit input: Read enable
	// free memory
	.mem_free_out(mem_free),
	// for debugging
	.status(status)
    );
 
    ezusb_io ezusb_io_inst (
        .ifclk(ifclk),
        .reset(reset),   		// asynchronous reset input
        .reset_out(reset_usb),		// synchronous reset output
        // pins
        .ifclk_in(ifclk_in),
        .fd(fd),
	.SLWR(SLWR),
	.SLRD(SLRD),
	.SLOE(SLOE), 
	.PKTEND(PKTEND),
	.EMPTY_FLAG(EMPTY_FLAG),
	.FULL_FLAG(FULL_FLAG),
	// signals for FPGA -> EZ-USB transfer
	.DI(rd_buf[15:0]),		// data written to EZ-USB
	.DI_valid(USB_DI_valid),	// 1 indicates data valid; DI and DI_valid must be hold if DI_ready is 0
	.DI_ready(USB_DI_ready),	// 1 if new data are accepted
	.DI_enable(1'b1),		// setting to 0 disables FPGA -> EZ-USB transfers
    	.pktend_arm(gpio_in[2]),	// 0->1 transition enables the manual PKTEND mechanism:
    	                                // PKTEND is asserted as soon output becomes idle
    	                                // recommended procedure for accurate packet transfers:
    	                                //   * DI_validgoes low after last data of package
    	                                //   * monitor PKTEND and hold DI_valid until PKTEND is asserted (PKTEND = 0)
        .pktend_timeout(16'd793),	// automatic PKTEN assertation after pktend_timeout*65536 (approx. 0.5s) clocks of no
                                        // output data. Setting to 0 disables this feature.
//        .pktend_timeout(16'd0),
	// signals for EZ-USB -> FPGA transfer
	.DO(USB_DO),			// data read from EZ-USB
	.DO_valid(USB_DO_valid),	// 1 indicated valid data
	.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
        // debug output
	.status(if_status)	
    );
 
    ezusb_gpio ezusb_gpio_inst (
	.clk(ifclk),
	.gpio_n(gpio_n),
	.in(gpio_in),
	.out(4'd0)
    );
 
/*    BUFR ifclkin_buf (
	.I(ifclk_in),
	.O(ifclk) 
    ); */
//    assign ifclk = ifclk_in;
 
    // FPGA Board led
    assign led = !if_status[6]; // led is inverted
 
    // debug board LEDs    
    assign led1 = SW10 ? status : { EMPTY, FULL, wrerr_buf, rderr_buf, if_status[5:0] };
 
    assign led2[0] = mem_free != { 1'b1, 24'd0 };
    assign led2[1] = mem_free[23:19] < 5'd30;
    assign led2[2] = mem_free[23:19] < 5'd29;
    assign led2[3] = mem_free[23:19] < 5'd27;
    assign led2[4] = mem_free[23:19] < 5'd25;
    assign led2[5] = mem_free[23:19] < 5'd24;
    assign led2[6] = mem_free[23:19] < 5'd22;
    assign led2[7] = mem_free[23:19] < 5'd20;
    assign led2[8] = mem_free[23:19] < 5'd19;
    assign led2[9] = mem_free[23:19] < 5'd17;
    assign led2[10] = mem_free[23:19] < 5'd15;
    assign led2[11] = mem_free[23:19] < 5'd13;
    assign led2[12] = mem_free[23:19] < 5'd12;
    assign led2[13] = mem_free[23:19] < 5'd10;
    assign led2[14] = mem_free[23:19] < 5'd8;
    assign led2[15] = mem_free[23:19] < 5'd7;
    assign led2[16] = mem_free[23:19] < 5'd5;
    assign led2[17] = mem_free[23:19] < 5'd3;
    assign led2[18] = mem_free[23:19] < 5'd2;
    assign led2[19] = mem_free == 25'd0;
 
    assign test_cs_w = test_cs + {1'b1, test_cnt0};
 
    always @ (posedge ifclk)
    begin
	reset_ifclk <= reset || reset_usb || reset_mem;
 
	if ( reset_ifclk ) 
	begin
	    rderr_buf <= 1'b0;
	    wrerr_buf <= 1'b0;
	end else
	begin
	    rderr_buf <= rderr_buf || RDERR;
	    wrerr_buf <= wrerr_buf || WRERR;
	end
 
	// FPGA -> EZ-USB FIFO
	DI_run <= !gpio_in[2];
        if ( reset_ifclk )
        begin
	    rd_cnt <= 3'd0;
	    USB_DI_valid <= 1'd0;
	end else if ( USB_DI_ready )
	begin
	    USB_DI_valid <= !EMPTY && DI_run;
	    if ( !EMPTY && DI_run )
	    begin
	        if ( rd_cnt == 3'd0 )
	        begin
	    	    rd_buf <= DO;
		end else
	    	begin
	    	    rd_buf[111:0] <= rd_buf[127:16];
		end
		rd_cnt <= rd_cnt+1;
	    end
	end
	RDEN <= !reset_ifclk && USB_DI_ready && !EMPTY && (rd_cnt==3'd0) && DI_run;
 
	// data source
	USB_DO_ready = !reset_ifclk && ((gpio_in[1:0]==2'd0 && !FULL) || (gpio_in[1:0]==2'd3));
	FULL_buf1 <= FULL;
	FULL_buf2 <= FULL_buf1;
 
	if ( reset_ifclk ) 
	begin
	    in_data <= 128'd0;
	    in_valid <= 1'b0;
	    wr_cnt <= 3'd0;
	    test_cnt0 <= 7'd0;
	    test_cnt1 <= 7'd111;
	    test_cs <= 12'd47;
	    WREN <= 1'b0;
	    clk_div <= 4'd15;
	end else if ( !FULL_buf2 )		// FULL can be processed delayed because data is buffered 
	begin
	    if ( in_valid ) DI <= in_data;
 
    	    if ( gpio_in[1:0] == 2'd0 )		// input from USB
    	    begin
    		if ( USB_DO_valid )
    		begin
		    in_data <= { USB_DO, in_data[127:16] };
		    in_valid <= wr_cnt == 3'd7;
	    	    wr_cnt <= wr_cnt + 1;
	    	end else
	    	begin
		    in_valid <= 1'b0;
		end
    	    end else if ( clk_div == 2'd0 )	// test data generator
	    begin
	        if ( wr_cnt == 3'd7 )
	        begin
		    in_data[127:112] <= { 1'b1, test_cs_w[6:0] ^ test_cs_w[13:7], 1'b1, test_cnt0 };
		    test_cnt0 <= test_cnt1;
		    test_cnt1 <= test_cnt1 + 7'd111;
	    	    test_cs <= 14'd47;
		    in_valid <= 1'b1;
		end else
		begin
		    test_cnt0 <= test_cnt0 + 7'd94;  // (111*2) & 127
		    test_cnt1 <= test_cnt1 + 7'd94;  // (111*2) & 127
		    test_cs <= test_cs + { 1'b1, test_cnt1 } + { 1'b0, test_cnt0 };
		    in_data[127:112] <= { 1'b1, test_cnt1, 1'b0, test_cnt0 };
		    in_valid <= 1'b0;
		end
		in_data[111:0] <= in_data[127:16];
	    	wr_cnt <= wr_cnt + 1;
	    end else 
	    begin
	        in_valid <= 1'b0;
	    end
 
	    // mode 3 is a debug mode: dummy read from USB, write test data
	    if ( gpio_in[0]==1'd1 ) 
//	    if ( gpio_in[1:0]==2'd1 ) 
	    begin
	        clk_div <= 4'd0;	// data rate: 208 MByte/s
	    end else 
	    begin
	        clk_div <= clk_div + 1;	// data rate: 13 MByte/s
	    end
	end
	WREN <= !reset_ifclk && in_valid && !FULL;
    end
 
endmodule
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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