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

Subversion Repositories openverifla

[/] [openverifla/] [trunk/] [openverifla_2.4/] [java/] [VeriFLA.java] - Rev 46

Compare with Previous | Blame | View Log

/*
VeriFLA.java
License: GNU GPL
 
Revision history:
revistion date: 2018/07/20; author: Laurentiu Duca
- port of SerialPort jssc instead of rxtx
- redesign of memory contents implied modification in the java source
revision date: 2007/Sep/03;  author: Laurentiu Duca
- sendRunCommand feature
- consider that the bt_queue_head_address is wrote at the end of the data capture.
- use HOUR_OF_DAY (0..23)
 
revision date: 2007/Jul/4; author: Laurentiu DUCA
- v01
*/
 
 
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.util.Properties;
import java.util.Enumeration;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.StringTokenizer;
 
import jssc.SerialPort;
import jssc.SerialPortException;
 
public class VeriFLA extends Object {
 
	// Data members are declared at the end.
 
	/**
	 * Creates a new object.
	 *
	 */	
	public VeriFLA() {
		this.serialPort = null;
		this.properties = new Properties();
	}
 
	/**
	 * Attaches the given serial serialPort to the device object.
	 * The method will try to open the serialPort.
	 */
	public boolean attach(String portName) {
		serialPort = new SerialPort(portName);
		try {
			int baudrate=Integer.parseInt(strBaudRate);
				//strBaudRate.equals("115200")?SerialPort.BAUDRATE_115200:
				//strBaudRate.equals("38400")?SerialPort.BAUDRATE_38400:SerialPort.BAUDRATE_9600;
			serialPort.openPort();//Open serial port
			serialPort.setParams(baudrate, 
                             SerialPort.DATABITS_8,
                             SerialPort.STOPBITS_1,
                             SerialPort.PARITY_NONE);
			//Set params. Also you can set params by this string: serialPort.setParams(9600, 8, 1, 0);
			//serialPort.writeBytes("This is a test string".getBytes());//Write data to port
		} catch (SerialPortException ex) {
			ex.printStackTrace(System.out);
			return false;
		}
 
		return true;
	}
 
	/**
	 * Detaches the currently attached serialPort, if one exists.
	 * This will close the serial port.
	 *
	 */
	public void detach() {
		if (serialPort != null) {
			try {
				serialPort.closePort();
			} catch (SerialPortException ex) {
				ex.printStackTrace(System.out);
			}
		}
	}
 
	public void run() throws IOException, SerialPortException {
		byte rawByte[]=new byte[1];
 
		if(sendRunCommand == 1) {
			// Send USERCMD_RESET command
			//rawByte[0]=USERCMD_RESET;
			//System.out.println("Sending USERCMD_RESET command");
			//serialPort.writeBytes(rawByte);
			//System.out.println("Done sending USERCMD_RESET command.");				
 
			// Send USERCMD_RUN command
			rawByte[0]=USERCMD_RUN;
			System.out.println("Sending user_run command..");
			serialPort.writeBytes(rawByte);
			System.out.println("Done sending user_run command.");	
		}
 
		// Read Captured data
		System.out.println("Waiting for data capture:");
		int i,j,ret;
		rawByte = new byte[memWords * octetsPerWord];
		rawByte = serialPort.readBytes(memWords * octetsPerWord);
		for(i=0; i<memWords; i++) {
			//rawByte = serialPort.readBytes(octetsPerWord);
			for(j=0; j<octetsPerWord; j++) {
				memoryLineBytes[memWords-1 - i][j]=rawByte[i* octetsPerWord + j];				
				//memoryLineBytes[memWords-1 - i][j]=rawByte[j];
			}
		}
		System.out.println("Data receive end.");
 
		// Debug
		if(!debugVeriFLA)
			return;
		System.out.println("Received data:");
		for(i=0; i<memWords; i++) {
			System.out.printf("%03d: ", i);
			for(j=octetsPerWord-1; j>=0; j--)
				System.out.printf("%02x ", memoryLineBytes[i][j]);
			System.out.println();
		}
 
		//System.exit(1);
	}
 
	public void getCapturedData(String portName)
	{
		boolean found;
		found = attach(portName);
		if(!found) {
			System.out.println("Port " + portName + " not found.\n"+
				"\tPlease update the properties file.\n");
			System.exit(0);
		}		
		try {
			run();
		} catch (Exception ex) {
			ex.printStackTrace(System.out);
		}
		detach();				
	}
 
	public void saveCapturedData() throws IOException
	{
		// Create a new file with the name "capture_timestamp.v".
		String strTime=getTime();			
		String outputFileName, moduleName;
		moduleName="capture_"+strTime;
		outputFileName = moduleName+".v";
		File outputFile = new File(outputFileName);
		if (!outputFile.createNewFile()) {
			System.out.println("Error: Can not create file: " + outputFileName);
			System.exit(-1);
		}	
		OutputStream stream = new FileOutputStream(outputFile);
 
 
		// Write the timescale directive.
		String strLine;
		int i,j,k;
		strLine = "`timescale " + strTimescaleUnit + " / " + strTimescalePrecision + "\n\n";
		stream.write(strLine.getBytes());		
 
 
		// Write the module name and output params.
		strLine = "module " + moduleName + "(clk_of_verifla, la_trigger_matched, ";
		for (i = 0; i < signalGroups; i++) {
			strLine += groupName[i];
			if(i != (signalGroups - 1))
				strLine += ", ";
		}
		strLine += ", memory_line_id";
		strLine += ");\n\n";
		stream.write(strLine.getBytes());		
 
 
		// Write the declaration of signals
		strLine = "output clk_of_verifla;\n" + "output la_trigger_matched;\n" + "output ["+(memWords/4)+":0] memory_line_id;\n";
		stream.write(strLine.getBytes());
		for (k = 0; k < 2; k++) {
			for (i = 0; i < signalGroups; i++) {
				if(k == 0)
					strLine = "output ";
				else
					strLine = "reg ";
				if(groupSize[i] > 1) {
					if(groupEndian[i] != 0)
						strLine += "[0:"+(groupSize[i]-1)+"] ";
					else
						strLine += "["+(groupSize[i]-1)+":0] ";
				}
				strLine += groupName[i] + ";\n";
				stream.write(strLine.getBytes());	
			}
		}
		strLine =
			"reg ["+(memWords/4)+":0] memory_line_id;\n" +
			"reg la_trigger_matched;\n" +
			"reg clk_of_verifla;" + "\n\n" +
			"parameter PERIOD = " + clockPeriod + ";" + "\n";
		stream.write(strLine.getBytes());
 
 
		// Write the clock task.
		strLine =	 
		    "initial    // Clock process for clk_of_verifla" + "\n" +
		    "begin" + "\n" +
		    "    forever" + "\n" +
		    "    begin" + "\n" +
		    "        clk_of_verifla = 1'b0;" + "\n" +
		    "        #("+ (int)(clockPeriod / 2) + "); clk_of_verifla = 1'b1;" + "\n" +
		    "        #("+ (int)(clockPeriod / 2) + ");" + "\n" +
		    "    end" + "\n" +
		    "end" + "\n\n" ;
		stream.write(strLine.getBytes());		
 
 
		// Write captured data
		strLine = "initial begin\n";
		strLine += "#("+ (int)(clockPeriod / 2) + ");\n";
		strLine += "la_trigger_matched = 0;\n";
		stream.write(strLine.getBytes());
 
		// Compute the name of the signals
		String signalsToken;
		signalsToken = "{";
		for (i = signalGroups-1; i >= 0 ; i--) {
			signalsToken += groupName[i];
			if (i > 0)
				signalsToken += ",";
		}
		signalsToken += "} = ";
 
		// Write name of the signals, values and delays in the verilog file.
		String strWord;
		int currentTime=(clockPeriod / 2), delay;
 
		// compute the oldest wrote-info before trigger event
		int bt_queue_head_address=0, bt_queue_tail_address=0;
		// the word at address (memWords-1) represents bt_queue_tail_address.
		for(j = 0; j < (octetsPerWord-1); j++) {
			bt_queue_tail_address += ((0x000000FF) & (int) memoryLineBytes[memWords-1][j]) << (8*j);
		}
		System.out.println("bt_queue_tail_address=" + bt_queue_tail_address);
		// Find the first <efffective capture memory word>
		// before the trigger event (not an <emtpy-slot> memory word).
		if(bt_queue_tail_address == (triggerMatchMemAddr - 1))
			bt_queue_head_address = 0;
		else
			bt_queue_head_address = bt_queue_tail_address + 1;
		boolean before_trigger=true;
		boolean foundAnEffectiveCaptureWord=false, wentBack=false;
		i = bt_queue_head_address;
		do
		{
			for(j = 0; j < (octetsPerWord-1); j++) {
				if(memoryLineBytes[i][j] != 0)
					foundAnEffectiveCaptureWord = true;
			}
			if(foundAnEffectiveCaptureWord)
				break;
			i++;
			if(i >= triggerMatchMemAddr)
				if(!foundAnEffectiveCaptureWord && !wentBack) {
					i = 0;
					wentBack = true;
				}
		} while (i <= triggerMatchMemAddr);
		if(!foundAnEffectiveCaptureWord)
			fatalError("Could not find the first efffective capture before trigger match");
		if(i >= triggerMatchMemAddr)
			before_trigger=false;
 
		// Walk through the captured data and write it to capture.v	
		do {
			// Check if this is an empty line
			boolean allMemoryLineIsZero=true;
			for(j=octetsPerWord-1; j>=0; j--) {
				if(memoryLineBytes[i][j] != 0) {
					allMemoryLineIsZero = false;
					break;
				}			
			}
			if(allMemoryLineIsZero) {
				if(debugVeriFLA) {
					strLine = "// info: line "+i+" is empty.\n";
					System.out.println(strLine);
					stream.write(strLine.getBytes());
				}
			} else {
				// Write memory line index.
				strLine = "memory_line_id=" + i + ";\n";
				stream.write(strLine.getBytes());
				// Data capture
				strWord = totalSignals + "'b";
				for(j=octetsPerWord-1; j>=0; j--) {
					if((j * 8) < dataWordLenBits)
						for(k=7; k>=0; k--) {
							if((j*8+k) < totalSignals) {
								strWord += (memoryLineBytes[i][j] >> k) & 1;
							}
						}
				}
				strWord += ';';
				strLine = signalsToken + strWord + "\n";
				if(i == triggerMatchMemAddr)
					strLine += "la_trigger_matched = 1;\n";
				//strLine += "#" + clockPeriod + ";\n";
				// Write to file
				//System.out.println(strLine);
				stream.write(strLine.getBytes());
 
 
				// Time interval in which data is constant.
				delay=0;
				for(j = 0; j < octetsPerWord; j++) {
					if((j * 8) >= dataWordLenBits)
						delay += ((0x000000FF) & (int) memoryLineBytes[i][j]) << (8*j - dataWordLenBits);
				}
				currentTime += delay * clockPeriod;
				strLine = "#" + (delay * clockPeriod) + ";\n";
				// Write to file
				//System.out.println(strLine);
				stream.write(strLine.getBytes());
				// Also write the time stamp
				strLine = "// -------------  Current Time:  " + currentTime + "*(" + strTimescaleUnit + ") "+"\n";
				stream.write(strLine.getBytes());
			}
 
			// Compute the new value of i
			if(before_trigger) {
				i = (i+1) % triggerMatchMemAddr;
				if(i == bt_queue_head_address) {
					before_trigger = false;
					i = triggerMatchMemAddr;
				}
			}	
			else
				i = i + 1;
		} while (i < (memWords-1));
 
		strLine = "$stop;\nend\nendmodule\n";	
		stream.write(strLine.getBytes());	
 
		// Write raw memory information.		
		strLine = "/*\n"+STR_ORIGINAL_CAPTURE_DUMP+"\n";	
		for(i=0; i<memWords; i++) {
			strLine += "memory_line_id=" + i + ": ";
			for(j=octetsPerWord-1; j>=0; j--) {
				//strLine += "["+j+"]"+" " + Integer.toHexString(memoryLineBytes[i][j]) + " ";
				if((0x000000FF & (int) memoryLineBytes[i][j]) <= 0x0F)
					strLine += "0";
				strLine += Integer.toHexString(
					0x000000FF & (int) memoryLineBytes[i][j]).toUpperCase() + " ";
			}
			strLine += "\n";
		}
/*
		for(i=0; i<memWords; i++) {
			strLine = "";
			// Write the memory address of the word
			if(i <= 9)
				strLine += "0";
			strLine += i + " ";
			for(j=octetsPerWord-1; j>=0; j--) {
				if((0x000000FF & (int) memoryLineBytes[i][j]) <= 0x0F)
					strLine += "0";
				strLine += Integer.toHexString(
					0x000000FF & (int) memoryLineBytes[i][j]).toUpperCase() + " ";
			}
			strLine += "\n";
			stream.write(strLine.getBytes());	
		}
*/
		strLine += "*/\n";
		stream.write(strLine.getBytes());	
 
		stream.close();
		System.out.println("Job done. Please simulate " + outputFileName);
	}
 
	private void allocateMemory()
	{
		// Allocate memory
		int i,j;
		memoryLineBytes = new byte[memWords][];
		for(i=0; i<memWords; i++)
			memoryLineBytes[i] = new byte[octetsPerWord];
	}
/*	
	private void simGetCapturedData() 
	{	
		// Init memory.	
		int i,j;
		for(i=0; i < memWords; i++)
		{
			for(j=0; j < octetsPerWord; j++) {
					memoryLineBytes[i][j]=(byte) i;
			}
		}
	}
*/
	public void rebuildCapturedDataFromFile(String fileName) 
	{
		try {
			String line;
			File file;		
			file = new File(fileName);
			if (!file.isFile())
				fatalError("Error: File does not exist: " + fileName);
			BufferedReader br = new BufferedReader(new FileReader(file));
 
			boolean startOfMemory=false, allMemoryRead=false;
			int i=0, j=0, tNo;
 
			do {
				line = br.readLine();
				if (line == null)
					fatalError("File " + fileName + " got null line while reading.");
				//if(startOfMemory) {
					StringTokenizer st;
					st = new StringTokenizer(line," ");
					tNo= st.countTokens();
					if(tNo != (octetsPerWord+1))
						fatalError("File " + fileName + " tNo != 2: " + tNo + " != 2" + (octetsPerWord+1));
					st.nextToken();
					for(j=octetsPerWord-1; j>=0; j--) {
						memoryLineBytes[i][j] = (byte) Integer.parseInt(st.nextToken(), 16);
					}
					i++;
					if(i >= memWords)
						allMemoryRead = true;
				//}
				//else
				//if (line.startsWith(STR_ORIGINAL_CAPTURE_DUMP)) {
				//	startOfMemory=true;
				//	i = 0;
				//}
			} while (!allMemoryRead);
		} catch (Exception e) {
			e.printStackTrace();
			fatalError("rebuildCapturedDataFromFile exception");
		}
	}
 
	public void job(String propertiesFileName, String strRebuildFileName)
	{
		getProperties(propertiesFileName);
		allocateMemory();
		if(strRebuildFileName == null)
			getCapturedData(portName);
		else
			rebuildCapturedDataFromFile(strRebuildFileName);
		try {
			saveCapturedData();
		} catch (IOException e) {
			e.printStackTrace();
			fatalError("Error saving Captured Data");
		}
	}
 
	public static void fatalError(String errorName)
	{
		System.out.println("Fatal error: " + errorName);
		System.exit(-1);
	}
 
	public void getProperties(String fileName)
	{
		File f;
		f = new File(fileName);
		if (!f.isFile()) {
			System.out.println("Error: File does not exist: " + fileName);
			System.exit(-1);
		}
 
		InputStream stream;
		try {
			stream = new FileInputStream(f);
			try {
				properties.load(stream);
			} catch (IOException e) {
				fatalError("IOException " + fileName);
			} 
		} catch (FileNotFoundException e) {
			fatalError("FileNotFoundException "+ fileName);
		}
 
		String strVal;
		portName = properties.getProperty(NAME + ".portName");
		if(portName == null)
			fatalError("Properties: missing portName");
		strBaudRate = properties.getProperty(NAME + ".baudRate");
		if(strBaudRate == null)
			fatalError("Properties: missing baudRate");
		//if(!strBaudRate.equals("115200") && !strBaudRate.equals("38400") && !strBaudRate.equals("9600"))
			//fatalError("Invalid baudRate (must be 115200 or 38400 or 9600)");
 
		// time units
		strTimescaleUnit=properties.getProperty(NAME + ".timescaleUnit");
		strTimescalePrecision=properties.getProperty(NAME + ".timescalePrecision");
		if(strTimescaleUnit == null || strTimescalePrecision == null) 
			fatalError("Properties: Not found timescale - unit or precision");
		// clockPeriod
		strVal=properties.getProperty(NAME + ".clockPeriod");
		if(strVal != null)
			clockPeriod=Integer.parseInt(strVal);
		else
			fatalError("Properties: clockPeriod not found");					
 
		// User signals
		strVal=properties.getProperty(NAME + ".totalSignals");
		if(strVal != null)
			totalSignals=Integer.parseInt(strVal);
		else
			fatalError("Properties: endian not found");		
		// Groups of signals
		strVal=properties.getProperty(NAME + ".signalGroups");
		if(strVal != null)
			signalGroups=Integer.parseInt(strVal);
		else
			fatalError("Properties: signalGroups not found");
		groupName=new String[signalGroups];
		groupSize=new int[signalGroups];
		groupEndian=new int[signalGroups];
		int i;
		int sumOfSignals=0;
		for (i=0; i < signalGroups; i++)
		{
			String strGroupName, strGroupSize, strGroupEndian;
			strGroupName=properties.getProperty(NAME + ".groupName."+i);
			strGroupSize=properties.getProperty(NAME + ".groupSize."+i);
			strGroupEndian=properties.getProperty(NAME + ".groupEndian."+i);
			if(strGroupName == null || strGroupSize == null || strGroupEndian == null)
				fatalError("Properties: group " + i + " not found groupName or groupSize or groupEndian");
			else {
				groupName[i]=strGroupName;
				groupSize[i]=Integer.parseInt(strGroupSize);
				sumOfSignals += groupSize[i];
				groupEndian[i]=Integer.parseInt(strGroupEndian);
			}	
		}
		if(sumOfSignals != totalSignals)
			fatalError("Properties: totalSignals != sum of all group sizes: " + totalSignals + " != "+sumOfSignals);
 
 
		// Memory
		strVal=properties.getProperty(NAME + ".memWords");
		if(strVal != null)
			memWords=Integer.parseInt(strVal);
		else
			fatalError("Properties: memWords not found");
		strVal=properties.getProperty(NAME + ".dataWordLenBits");
		if(strVal != null)
			dataWordLenBits=Integer.parseInt(strVal);
		else
			fatalError("Properties: dataWordLenBits not found");
		if((dataWordLenBits % 8) != 0)
			fatalError("Properties: dataWordLenBits is not multiple of 8");
		if(dataWordLenBits != totalSignals)
			fatalError("Properties: totalSignals != dataWordLenBits: " + totalSignals + " != "+dataWordLenBits);
		strVal=properties.getProperty(NAME + ".clonesWordLenBits");
		if(strVal != null)
			clonesWordLenBits=Integer.parseInt(strVal);
		else
			fatalError("Properties: clonesWordLenBits not found");
		if((clonesWordLenBits % 8) != 0)
			fatalError("Properties: clonesWordLenBits is not multiple of 8");
		memWordLenBits = dataWordLenBits + clonesWordLenBits;
		// Compute sizes
		// octetsPerWord
		octetsPerWord = memWordLenBits / 8;
		if (memWordLenBits % 8 > 0)
			octetsPerWord++;
		totalmemoryDataBytes = memWords*octetsPerWord;
		// Trigger
		strVal=properties.getProperty(NAME + ".triggerMatchMemAddr");
		if(strVal != null)
			triggerMatchMemAddr=Integer.parseInt(strVal);
		else
			fatalError("Properties: triggerMatchMemAddr not found");
/*
		strVal=properties.getProperty(NAME + ".maxSamplesAfterTrigger");
		if(strVal != null)
			maxSamplesAfterTrigger=Integer.parseInt(strVal);
		else
			fatalError("Properties: maxSamplesAfterTrigger not found");
 
		// triggerLastValue
		strVal=properties.getProperty(NAME + ".triggerLastValue");
		if(strVal != null) {
			StringTokenizer st;
			int j, tNo;
			st = new StringTokenizer(strVal," ");
			tNo= st.countTokens();
			if(tNo != octetsPerWord)
				fatalError("triggerLastValue " + " tNo != octetsPerWord: " + tNo + " != " + octetsPerWord);	
			triggerLastValue = new int[octetsPerWord];
			for(j=octetsPerWord-1; j>=0; j--) {
				triggerLastValue[j] = (byte) Integer.parseInt(st.nextToken(), 16);
			}
		}
		else
			fatalError("Properties: triggerLastValue not found");
*/			
	}
 
	public String getTime()
	{
		Calendar calendar=new GregorianCalendar();
		String strTime;
		int field;
		strTime = "" + calendar.get(Calendar.YEAR);
		field = 1 + calendar.get(Calendar.MONTH);
		if(field < 10)
			strTime += "0";
		strTime += field;
		if(calendar.get(Calendar.DAY_OF_MONTH) < 10)
			strTime += "0";
		strTime += calendar.get(Calendar.DAY_OF_MONTH) + "_" ;
		if(calendar.get(Calendar.HOUR_OF_DAY) < 10)
			strTime += "0";
		strTime += calendar.get(Calendar.HOUR_OF_DAY);
		if(calendar.get(Calendar.MINUTE) < 10)
			strTime += "0";
		strTime += calendar.get(Calendar.MINUTE) + "_";
		if(calendar.get(Calendar.SECOND) < 10)
			strTime += "0";
		strTime += calendar.get(Calendar.SECOND) ;
		System.out.println("date and time: "+strTime);
		return strTime;		
	}	
 
	public static void main(String[] args) throws Exception
	{
		if(args.length < 1)
			VeriFLA.fatalError("Too few arguments: "+args.length+
				"\nSintax is:\n\tjava VeriFLA <propertiesFileName> [<sendRunCommand>=0/1 (default 0)] [sourceToRebuild_capture]\n"+
				"Examples:\n1. Wait for FPGA to send capture:\n\tjava VeriFLA verifla_properties_keyboard.txt\n"+
				"2. Send to the monitor the run command and wait for FPGA to send capture:\n\tjava VeriFLA verifla_properties_keyboard.txt 1\n"
				);
		// 1st arg.
		System.out.println("propertiesFileName = " + args[0]);
		// 2nd arg.
		sendRunCommand = 0;
		if(args.length >= 2) {
			System.out.println(" sendRunCommand = " + args[1]);
			sendRunCommand = Integer.parseInt(args[1]);
		}
		// 3rd arg.
		String sourceToRebuildCaptureFile=null;
		if(args.length >= 3) {
			System.out.println(" sourceToRebuild_capture = " + args[2]);
			sourceToRebuildCaptureFile = args[2];
		}
		VeriFLA verifla;
		verifla = new VeriFLA();
		verifla.job(args[0], sourceToRebuildCaptureFile);
	}
 
	// This java app. data members				
	boolean debugVeriFLA=true;
 
	String propertiesFileName;
	Properties properties;
	SerialPort serialPort;
	String strBaudRate;
	final static String NAME = "LA";
	final static String STR_ORIGINAL_CAPTURE_DUMP = "ORIGINAL CAPTURE DUMP";
	final static int USERCMD_RESET=0x00, USERCMD_RUN = 0x01;
	byte [][] memoryLineBytes;
	int octetsPerWord, totalmemoryDataBytes;
	int totalSignals;
	public static int sendRunCommand=0;
	int clockPeriod;
 
	// Properties file members
	String portName;
	int memWords, memWordLenBits, dataWordLenBits, clonesWordLenBits,
		triggerMatchMemAddr, maxSamplesAfterTrigger;
	//int [] triggerLastValue;
	String strTimescaleUnit, strTimescalePrecision;
	int signalGroups;
	String [] groupName;
	int [] groupSize, groupEndian;
}
 

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.