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

Subversion Repositories usb_fpga_2_04

[/] [usb_fpga_2_04/] [trunk/] [examples/] [usb-fpga-2.13/] [2.13d/] [memfifo/] [MemFifo.java] - Rev 2

Compare with Previous | Blame | View Log

/*!
   memfifo -- implementation of EZ-USB slave FIFO's (input and output) a FIFO using the DDR3 SDRAM for ZTEX USB-FPGA Modules 2.13
   Copyright (C) 2009-2014 ZTEX GmbH.
   http://www.ztex.de
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3 as
   published by the Free Software Foundation.
 
   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program; if not, see http://www.gnu.org/licenses/.
!*/
 
import java.io.*;
import java.util.*;
import java.text.*;
 
import ch.ntb.usb.*;
 
import ztex.*;
 
// *****************************************************************************
// ******* ParameterException **************************************************
// *****************************************************************************
// Exception the prints a help message
class ParameterException extends Exception {
    public final static String helpMsg = new String (
		"Parameters:\n"+
		"    -d <number>       Device Number (default: 0)\n" +
		"    -f 	       Force uploads\n" +
		"    -p                Print bus info\n" +
		"    -h                This help" );
 
    public ParameterException (String msg) {
	super( msg + "\n" + helpMsg );
    }
}
 
// *****************************************************************************
// ******* USBReader ***********************************************************
// *****************************************************************************
class UsbReader extends Thread {
    private final int bufNum = 8;
    public final int bufSize = 512*1024;
    public byte[][] buf = new byte[bufNum][];
    public int[] bufBytes = new int[bufNum];
    private int readCount = -1;
    private int getCount = -1;
    public boolean terminate = false;
    private Ztex1v1 ztex;
 
    public UsbReader ( Ztex1v1 p_ztex ) {
        super ();
        ztex = p_ztex;
	for (int i=0; i<bufNum; i++) {
	    buf[i]=new byte[bufSize];
	}
    }
 
    public int getBuffer () {
	getCount += 1;
	while (getCount >= readCount) {
	    try {
		sleep(1);
            }
            catch ( InterruptedException e) {
            } 
	}
	return getCount % bufNum;
    }
 
    public void reset () {
	getCount = readCount + 1;
    }
 
    public void run() {
	setPriority(MAX_PRIORITY);
 
// reader loop
	while ( !terminate ) {
	    readCount += 1;
 
	    while ( readCount - bufNum >= getCount ) {
		try {
		    sleep(1);
        	}
    		catch ( InterruptedException e) {
        	} 
	    }
 
	    int i = readCount % bufNum;
	    bufBytes[i] = LibusbJava.usb_bulk_read(ztex.handle(), 0x82, buf[i], bufSize, 1000);
//	    System.out.println("Buffer " + i +": read " + bufBytes[i] + " bytes");
	}
 
    }
}
 
// *****************************************************************************
// ******* UsbWriter ***********************************************************
// *****************************************************************************
class UsbWriter extends Thread {
    private final int bufNum = 8;
    public final int bufSize = 512*1024;
    public byte[][] buf = new byte[bufNum][];
    private int writeCount = -1;
    private int getCount = -1;
    public boolean terminate = false;
    private Ztex1v1 ztex;
    public int errorBuffferCount = -1;		// buffer count if an error occurred; otherwise -1
    public int errorResult = 0;			// error code or number of bytes if an error occurred
 
    public UsbWriter ( Ztex1v1 p_ztex ) {
        super ();
        ztex = p_ztex;
	for (int i=0; i<bufNum; i++) {
	    buf[i]=new byte[bufSize];
	}
    }
 
    public int getBuffer () {
	getCount += 1;
	while (getCount - bufNum >= writeCount) {
	    try {
		sleep(1);
            }
            catch ( InterruptedException e) {
            } 
	}
	return getCount % bufNum;
    }
 
    public void reset () {
	getCount = writeCount + 1;
	errorBuffferCount = -1;
    }
 
    public void run() {
	setPriority(MAX_PRIORITY);
 
// writer loop
	while ( !terminate ) {
	    writeCount += 1;
 
	    while ( writeCount >= getCount ) {
		try {
		    sleep(1);
        	}
    		catch ( InterruptedException e) {
        	} 
	    }
 
	    int i = writeCount % bufNum;
	    int j = LibusbJava.usb_bulk_write(ztex.handle(), 0x06, buf[i], bufSize, 1000);
	    if ( j != bufSize ) {
		errorBuffferCount = writeCount;
		errorResult = j;
	    }
//	    System.out.println("Buffer " + i +": wrote " + j + " bytes");
	}
 
    }
}
 
// *****************************************************************************
// ******* UsbTestWriter *******************************************************
// *****************************************************************************
class UsbTestWriter extends Thread {
    public boolean terminate = false;
    private UsbWriter writer;
 
    public UsbTestWriter ( Ztex1v1 p_ztex ) {
        super ();
	writer = new UsbWriter( p_ztex );
    }
 
    public boolean error () {
	return writer.errorBuffferCount >= 0;
    }
 
    public void run() {
	writer.start();
 
	int k = 0;
	int cs = 47;
	int sync;
	Random random = new Random();
	while ( !terminate ) {
	    byte[] b = writer.buf[writer.getBuffer()];
	    for ( int i=0; i<writer.bufSize; i++ ) {
		int j = k & 15;
		sync = ( ((j & 1)==1) || (j==14) ) ? 128 : 0;
		if ( j == 15 ) {
		    b[i] = (byte) (sync | ((cs & 127) ^ (cs>>7)));
		    cs = 47;
		}
		else {
//		    b[i] = (byte) ( (j==0 ? (k>>4) & 127 : random.nextInt(128)) | sync );
		    b[i] = (byte) ( (((k>>4)+j) & 127) | sync );
		    cs += (b[i] & 255);
		}
		k=(k+1) & 65535;
	    }
	}
 
        writer.terminate=true;
    }
}
 
 
// *****************************************************************************
// ******* MemFifo *************************************************************
// *****************************************************************************
class MemFifo extends Ztex1v1 {
 
    // constructor
    public MemFifo ( ZtexDevice1 pDev ) throws UsbException {
	super ( pDev );
    }
 
    // set mode
    public void setMode( int i ) throws UsbException {
	i = i & 3;
	vendorCommand (0x80, "Set test mode", i, 0);
    }
 
    // reset
    public void reset( ) throws UsbException {
	vendorCommand (0x81, "Reset:", 0, 0);
	try {
	    Thread.sleep(300);
        }
        catch ( InterruptedException e) {
        } 
	byte[] buf = new byte[4096];
	while ( LibusbJava.usb_bulk_read(handle(), 0x82, buf, buf.length, 100) == buf.length ) { };  // empties buffers
    }
 
    // reads data and verifies them. 
    // returns true if errors occurred
    // rate is data rate in kBytes; <=0 means unlimited
    public boolean verify ( UsbReader reader, int iz, int rate ) {
    	boolean valid = false;
	int byte_cnt = 0, sync_cnt = 0, cs = 47, first = 255, prev_first = 255;
	boolean memError = false;
 
	for (int i=0; i<iz; i++) {
	    if ( i>0 && rate>0 ) {
		try {
		    Thread.sleep(reader.bufSize/rate);
        	}
        	catch ( InterruptedException e) {
        	} 
	    }
	    int j = reader.getBuffer();
	    int bb = reader.bufBytes[j];
	    byte[] b = reader.buf[j];
	    int merrors = 0;
	    int ferrors = 0;
	    int serrors = 0;
	    boolean prev_sync = false;
 
	    if ( bb != reader.bufSize ) {
		System.out.println("Data read error");
		memError = true;
		break;
	    }
 
/*	    for ( int l=0; l<512; l+=1) {
		System.out.print("   " + (b[l] & 255) );
		if ( (l & 15) == 15 ) System.out.println();
	    } */
 
	    for (int k=0; k<bb; k++ ) {
		byte_cnt++;
		sync_cnt++;
		if ( (b[k] & 128) == 0 ) sync_cnt=0;
		if ( byte_cnt == 1 ) {
		    prev_first = first;
    		    first = b[k] & 255;
		} 
// 		if ( k<40 ) System.out.println(k + ": " + (b[k] & 255) + "  " + (b[k] & 127) + "   " + ((cs & 127) ^ (cs>>7)) + "  " + byte_cnt + "  " + sync_cnt +"	" + prev_first + "  " + first );
		if ( sync_cnt == 3 ) {
		    boolean serror = byte_cnt != 16;
		    boolean merror = ( b[k] & 127 ) != ((cs & 127) ^ (cs>>7));
		    boolean ferror = prev_sync && ( first != ((prev_first + 1) & 127) );
		    prev_sync = byte_cnt == 16;
//		    valid = valid || ( !serror && !merror && !ferror );
		    valid = valid || ( !serror && !merror );
		    if ( valid ) {
			if ( serror ) serrors += 1;
			else if ( merror ) merrors += 1;
			else if ( ferror ) ferrors += 1;
			if ( serror && (serrors <= 2) && (k>=byte_cnt-1) && (k+1<bb)  ) {
			    System.out.print( "Sync Error: " + byte_cnt + " at " + k + ": " );
			    for ( int l=1; l<=byte_cnt+1; l++ ) System.out.print((b[k-byte_cnt+l] < 0 ? "*" : "" ) + (b[k-byte_cnt+l] & 127) + " ");
			}
//			if ( ferror && (ferrors == 1) && (k+1<bb) ) System.out.println( "Fifo error: " + prev_first + " " + first + " " +  ( b[k+1] & 127 ) + ":    ");
		    }
		    cs=47;
		    byte_cnt = 0;
		} else {
		    cs += ( b[k] & 255);
		}
	    }
 
	    if ( ! valid ) {
		System.out.println("Invalid data");
		return true;
	    }
 
	    System.out.print("Buffer " + i + ": " + serrors + " sync errors, 	" + merrors + " memory or transfer errors,  " + ferrors + " FIFO errors    \r");
	    if ( merrors + ferrors + serrors > (i==0 ? 1 : 0 ) ) { // one error in first buffer may occurs ofter changing mode
	        System.out.println();
	        memError = true;
	    }
	}
        System.out.println();
	return memError;
    }
 
// ******* main ****************************************************************
    public static void main (String args[]) {
 
	int devNum = 0;
	boolean force = false;
 
	try {
// init USB stuff
	    LibusbJava.usb_init();
 
// scan the USB bus
	    ZtexScanBus1 bus = new ZtexScanBus1( ZtexDevice1.ztexVendorId, ZtexDevice1.ztexProductId, true, false, 1);
	    if ( bus.numberOfDevices() <= 0) {
		System.err.println("No devices found");
	        System.exit(0);
	    }
 
// scan the command line arguments
    	    for (int i=0; i<args.length; i++ ) {
	        if ( args[i].equals("-d") ) {
	    	    i++;
		    try {
			if (i>=args.length) throw new Exception();
    			devNum = Integer.parseInt( args[i] );
		    } 
		    catch (Exception e) {
		        throw new ParameterException("Device number expected after -d");
		    }
		}
		else if ( args[i].equals("-f") ) {
		    force = true;
		}
		else if ( args[i].equals("-p") ) {
	    	    bus.printBus(System.out);
		    System.exit(0);
		}
		else if ( args[i].equals("-p") ) {
	    	    bus.printBus(System.out);
		    System.exit(0);
		}
		else if ( args[i].equals("-h") ) {
		        System.err.println(ParameterException.helpMsg);
	    	        System.exit(0);
		}
		else throw new ParameterException("Invalid Parameter: "+args[i]);
	    }
 
	    String errStr = "";
 
// create the main class	    
	    MemFifo ztex = new MemFifo ( bus.device(devNum) );
 
// upload the firmware if necessary
	    if ( force || ! ztex.valid() || ! ztex.dev().productString().equals("memfifo for UFM 2.13") ) {
		System.out.println("Firmware upload time: " + ztex.uploadFirmware( "memfifo.ihx", force ) + " ms");
		force = true;
	    }
 
// upload the bitstream if necessary
	    if ( force || ! ztex.getFpgaConfiguration() ) {
		System.out.println("FPGA configuration time: " + ztex.configureFpga( "fpga/memfifo.runs/impl_1/memfifo.bit" , force, -1 ) + " ms");
	    } 
 
// claim tnterface
    	    ztex.trySetConfiguration ( 1 );
    	    ztex.claimInterface ( 0 );
 
// reset FIFO's 
	    if ( !force ) {
		System.out.println("Resetting  FIFO's");
		ztex.reset();
	    }
 
// PKTEND test
/*	    {
		byte[] buf = new byte[65536];
	        int i = LibusbJava.usb_bulk_write(ztex.handle(), 0x06, buf, buf.length, 1000);
//	        System.out.println("PKTEND test: wrote "+i+" bytes");
		// number of read bytes is usually less than number written bytes because DRAM FIFO is usually never completely emptied in order to avoid small transactions
	        i=LibusbJava.usb_bulk_read(ztex.handle(), 0x82, buf, buf.length, 1000); 
	        // 
	        int j = i & 511;
	        System.out.println("PKTEND test: read "+i+" bytes, last paket: " + (j == 0 ? 512 : j) + " bytes" );
	    } */
 
// start traffic reader
	    UsbReader reader = new UsbReader( ztex );
	    reader.start();
 
// Mode 1: 48 MByte/s Test data generator: used for speed test
	    ztex.setMode(1);
	    System.out.println("48 MByte/s test data generator: ");
	    long t0 = new Date().getTime();
	    ztex.verify(reader, 2000, 0);
	    System.out.println("Read data rate: " + Math.round(reader.bufSize*2000.0/((new Date().getTime()-t0)*100.0)*0.1) + " MByte/s");
 
 
// Mode 2: 12 MByte/s Test data generator: tests flow control
	    ztex.setMode(2);
	    System.out.println("12 MByte/s test data generator: ");
	    ztex.verify(reader, 2000, 0);
 
// PKTEND test
	    {
		byte[] buf = new byte[65536];
	        int i;
	        while ( (i = LibusbJava.usb_bulk_write(ztex.handle(), 0x06, buf, buf.length, 1000)) == buf.length ) { }
	        int j = i & 511;
	        System.out.println("PKTEND test: last paket size: " + (j == 0 ? 512 : j) + " bytes" );
	    } 
 
// Mode 0: write+read mode
	    ztex.reset();
	    UsbTestWriter writer = new UsbTestWriter( ztex );
	    writer.start();
	    reader.reset();
 
	    System.out.println("USB write + read mode: speed test");
	    t0 = new Date().getTime();
	    ztex.verify(reader, 1000, 0);
	    System.out.println("Read data rate: " + Math.round(reader.bufSize*1000.0/((new Date().getTime()-t0)*100.0)*0.1) + " MByte/s");
 
	    System.out.println("USB write + read mode: 5 MByte/s read rate");
	    ztex.verify(reader, 1000, 5000);
 
	    if ( writer.error() ) System.out.println("Write errors occured");
 
// Terminating threads
	    writer.terminate=true; 	// stop the writer
	    reader.terminate=true;  	// stop the reader
/*	    for (int i=0; i<10000 &&  writer.isAlive() && reader.isAlive(); i++ ) { 
		if ( ( i % 1000 ) == 999 ) System.out.print(".");
		try {
		    Thread.sleep(1);
        	}
    		catch ( InterruptedException e) {
        	} 
	    }
	    System.out.println();
 
// releases interface	    
    	    ztex.releaseInterface( 0 );	 */
 
	}
	catch (Exception e) {
	    System.out.println("Error: "+e.getLocalizedMessage() );
	} 
 
   } 
 
}
 

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.