1 |
46 |
laurentiud |
/*
|
2 |
|
|
VeriFLA.java
|
3 |
|
|
License: GNU GPL
|
4 |
|
|
|
5 |
|
|
Revision history:
|
6 |
|
|
revistion date: 2018/07/20; author: Laurentiu Duca
|
7 |
|
|
- port of SerialPort jssc instead of rxtx
|
8 |
|
|
- redesign of memory contents implied modification in the java source
|
9 |
|
|
revision date: 2007/Sep/03; author: Laurentiu Duca
|
10 |
|
|
- sendRunCommand feature
|
11 |
|
|
- consider that the bt_queue_head_address is wrote at the end of the data capture.
|
12 |
|
|
- use HOUR_OF_DAY (0..23)
|
13 |
|
|
|
14 |
|
|
revision date: 2007/Jul/4; author: Laurentiu DUCA
|
15 |
|
|
- v01
|
16 |
|
|
*/
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
import java.io.IOException;
|
20 |
|
|
import java.io.InputStream;
|
21 |
|
|
import java.io.OutputStream;
|
22 |
|
|
import java.io.File;
|
23 |
|
|
import java.io.FileInputStream;
|
24 |
|
|
import java.io.FileOutputStream;
|
25 |
|
|
import java.io.FileNotFoundException;
|
26 |
|
|
import java.io.FileReader;
|
27 |
|
|
import java.io.BufferedReader;
|
28 |
|
|
import java.util.Properties;
|
29 |
|
|
import java.util.Enumeration;
|
30 |
|
|
import java.util.Calendar;
|
31 |
|
|
import java.util.GregorianCalendar;
|
32 |
|
|
import java.util.StringTokenizer;
|
33 |
|
|
|
34 |
|
|
import jssc.SerialPort;
|
35 |
|
|
import jssc.SerialPortException;
|
36 |
|
|
|
37 |
|
|
public class VeriFLA extends Object {
|
38 |
|
|
|
39 |
|
|
// Data members are declared at the end.
|
40 |
|
|
|
41 |
|
|
/**
|
42 |
|
|
* Creates a new object.
|
43 |
|
|
*
|
44 |
|
|
*/
|
45 |
|
|
public VeriFLA() {
|
46 |
|
|
this.serialPort = null;
|
47 |
|
|
this.properties = new Properties();
|
48 |
|
|
}
|
49 |
|
|
|
50 |
|
|
/**
|
51 |
|
|
* Attaches the given serial serialPort to the device object.
|
52 |
|
|
* The method will try to open the serialPort.
|
53 |
|
|
*/
|
54 |
|
|
public boolean attach(String portName) {
|
55 |
|
|
serialPort = new SerialPort(portName);
|
56 |
|
|
try {
|
57 |
|
|
int baudrate=Integer.parseInt(strBaudRate);
|
58 |
|
|
//strBaudRate.equals("115200")?SerialPort.BAUDRATE_115200:
|
59 |
|
|
//strBaudRate.equals("38400")?SerialPort.BAUDRATE_38400:SerialPort.BAUDRATE_9600;
|
60 |
|
|
serialPort.openPort();//Open serial port
|
61 |
|
|
serialPort.setParams(baudrate,
|
62 |
|
|
SerialPort.DATABITS_8,
|
63 |
|
|
SerialPort.STOPBITS_1,
|
64 |
|
|
SerialPort.PARITY_NONE);
|
65 |
|
|
//Set params. Also you can set params by this string: serialPort.setParams(9600, 8, 1, 0);
|
66 |
|
|
//serialPort.writeBytes("This is a test string".getBytes());//Write data to port
|
67 |
|
|
} catch (SerialPortException ex) {
|
68 |
|
|
ex.printStackTrace(System.out);
|
69 |
|
|
return false;
|
70 |
|
|
}
|
71 |
|
|
|
72 |
|
|
return true;
|
73 |
|
|
}
|
74 |
|
|
|
75 |
|
|
/**
|
76 |
|
|
* Detaches the currently attached serialPort, if one exists.
|
77 |
|
|
* This will close the serial port.
|
78 |
|
|
*
|
79 |
|
|
*/
|
80 |
|
|
public void detach() {
|
81 |
|
|
if (serialPort != null) {
|
82 |
|
|
try {
|
83 |
|
|
serialPort.closePort();
|
84 |
|
|
} catch (SerialPortException ex) {
|
85 |
|
|
ex.printStackTrace(System.out);
|
86 |
|
|
}
|
87 |
|
|
}
|
88 |
|
|
}
|
89 |
|
|
|
90 |
|
|
public void run() throws IOException, SerialPortException {
|
91 |
|
|
byte rawByte[]=new byte[1];
|
92 |
|
|
|
93 |
|
|
if(sendRunCommand == 1) {
|
94 |
|
|
// Send USERCMD_RESET command
|
95 |
|
|
//rawByte[0]=USERCMD_RESET;
|
96 |
|
|
//System.out.println("Sending USERCMD_RESET command");
|
97 |
|
|
//serialPort.writeBytes(rawByte);
|
98 |
|
|
//System.out.println("Done sending USERCMD_RESET command.");
|
99 |
|
|
|
100 |
|
|
// Send USERCMD_RUN command
|
101 |
|
|
rawByte[0]=USERCMD_RUN;
|
102 |
|
|
System.out.println("Sending user_run command..");
|
103 |
|
|
serialPort.writeBytes(rawByte);
|
104 |
|
|
System.out.println("Done sending user_run command.");
|
105 |
|
|
}
|
106 |
|
|
|
107 |
|
|
// Read Captured data
|
108 |
|
|
System.out.println("Waiting for data capture:");
|
109 |
|
|
int i,j,ret;
|
110 |
|
|
rawByte = new byte[memWords * octetsPerWord];
|
111 |
|
|
rawByte = serialPort.readBytes(memWords * octetsPerWord);
|
112 |
|
|
for(i=0; i<memWords; i++) {
|
113 |
|
|
//rawByte = serialPort.readBytes(octetsPerWord);
|
114 |
|
|
for(j=0; j<octetsPerWord; j++) {
|
115 |
|
|
memoryLineBytes[memWords-1 - i][j]=rawByte[i* octetsPerWord + j];
|
116 |
|
|
//memoryLineBytes[memWords-1 - i][j]=rawByte[j];
|
117 |
|
|
}
|
118 |
|
|
}
|
119 |
|
|
System.out.println("Data receive end.");
|
120 |
|
|
|
121 |
|
|
// Debug
|
122 |
|
|
if(!debugVeriFLA)
|
123 |
|
|
return;
|
124 |
|
|
System.out.println("Received data:");
|
125 |
|
|
for(i=0; i<memWords; i++) {
|
126 |
|
|
System.out.printf("%03d: ", i);
|
127 |
|
|
for(j=octetsPerWord-1; j>=0; j--)
|
128 |
|
|
System.out.printf("%02x ", memoryLineBytes[i][j]);
|
129 |
|
|
System.out.println();
|
130 |
|
|
}
|
131 |
|
|
|
132 |
|
|
//System.exit(1);
|
133 |
|
|
}
|
134 |
|
|
|
135 |
|
|
public void getCapturedData(String portName)
|
136 |
|
|
{
|
137 |
|
|
boolean found;
|
138 |
|
|
found = attach(portName);
|
139 |
|
|
if(!found) {
|
140 |
|
|
System.out.println("Port " + portName + " not found.\n"+
|
141 |
|
|
"\tPlease update the properties file.\n");
|
142 |
|
|
System.exit(0);
|
143 |
|
|
}
|
144 |
|
|
try {
|
145 |
|
|
run();
|
146 |
|
|
} catch (Exception ex) {
|
147 |
|
|
ex.printStackTrace(System.out);
|
148 |
|
|
}
|
149 |
|
|
detach();
|
150 |
|
|
}
|
151 |
|
|
|
152 |
|
|
public void saveCapturedData() throws IOException
|
153 |
|
|
{
|
154 |
|
|
// Create a new file with the name "capture_timestamp.v".
|
155 |
|
|
String strTime=getTime();
|
156 |
|
|
String outputFileName, moduleName;
|
157 |
|
|
moduleName="capture_"+strTime;
|
158 |
|
|
outputFileName = moduleName+".v";
|
159 |
|
|
File outputFile = new File(outputFileName);
|
160 |
|
|
if (!outputFile.createNewFile()) {
|
161 |
|
|
System.out.println("Error: Can not create file: " + outputFileName);
|
162 |
|
|
System.exit(-1);
|
163 |
|
|
}
|
164 |
|
|
OutputStream stream = new FileOutputStream(outputFile);
|
165 |
|
|
|
166 |
|
|
|
167 |
|
|
// Write the timescale directive.
|
168 |
|
|
String strLine;
|
169 |
|
|
int i,j,k;
|
170 |
|
|
strLine = "`timescale " + strTimescaleUnit + " / " + strTimescalePrecision + "\n\n";
|
171 |
|
|
stream.write(strLine.getBytes());
|
172 |
|
|
|
173 |
|
|
|
174 |
|
|
// Write the module name and output params.
|
175 |
|
|
strLine = "module " + moduleName + "(clk_of_verifla, la_trigger_matched, ";
|
176 |
|
|
for (i = 0; i < signalGroups; i++) {
|
177 |
|
|
strLine += groupName[i];
|
178 |
|
|
if(i != (signalGroups - 1))
|
179 |
|
|
strLine += ", ";
|
180 |
|
|
}
|
181 |
|
|
strLine += ", memory_line_id";
|
182 |
|
|
strLine += ");\n\n";
|
183 |
|
|
stream.write(strLine.getBytes());
|
184 |
|
|
|
185 |
|
|
|
186 |
|
|
// Write the declaration of signals
|
187 |
|
|
strLine = "output clk_of_verifla;\n" + "output la_trigger_matched;\n" + "output ["+(memWords/4)+":0] memory_line_id;\n";
|
188 |
|
|
stream.write(strLine.getBytes());
|
189 |
|
|
for (k = 0; k < 2; k++) {
|
190 |
|
|
for (i = 0; i < signalGroups; i++) {
|
191 |
|
|
if(k == 0)
|
192 |
|
|
strLine = "output ";
|
193 |
|
|
else
|
194 |
|
|
strLine = "reg ";
|
195 |
|
|
if(groupSize[i] > 1) {
|
196 |
|
|
if(groupEndian[i] != 0)
|
197 |
|
|
strLine += "[0:"+(groupSize[i]-1)+"] ";
|
198 |
|
|
else
|
199 |
|
|
strLine += "["+(groupSize[i]-1)+":0] ";
|
200 |
|
|
}
|
201 |
|
|
strLine += groupName[i] + ";\n";
|
202 |
|
|
stream.write(strLine.getBytes());
|
203 |
|
|
}
|
204 |
|
|
}
|
205 |
|
|
strLine =
|
206 |
|
|
"reg ["+(memWords/4)+":0] memory_line_id;\n" +
|
207 |
|
|
"reg la_trigger_matched;\n" +
|
208 |
|
|
"reg clk_of_verifla;" + "\n\n" +
|
209 |
|
|
"parameter PERIOD = " + clockPeriod + ";" + "\n";
|
210 |
|
|
stream.write(strLine.getBytes());
|
211 |
|
|
|
212 |
|
|
|
213 |
|
|
// Write the clock task.
|
214 |
|
|
strLine =
|
215 |
|
|
"initial // Clock process for clk_of_verifla" + "\n" +
|
216 |
|
|
"begin" + "\n" +
|
217 |
|
|
" forever" + "\n" +
|
218 |
|
|
" begin" + "\n" +
|
219 |
|
|
" clk_of_verifla = 1'b0;" + "\n" +
|
220 |
|
|
" #("+ (int)(clockPeriod / 2) + "); clk_of_verifla = 1'b1;" + "\n" +
|
221 |
|
|
" #("+ (int)(clockPeriod / 2) + ");" + "\n" +
|
222 |
|
|
" end" + "\n" +
|
223 |
|
|
"end" + "\n\n" ;
|
224 |
|
|
stream.write(strLine.getBytes());
|
225 |
|
|
|
226 |
|
|
|
227 |
|
|
// Write captured data
|
228 |
|
|
strLine = "initial begin\n";
|
229 |
|
|
strLine += "#("+ (int)(clockPeriod / 2) + ");\n";
|
230 |
|
|
strLine += "la_trigger_matched = 0;\n";
|
231 |
|
|
stream.write(strLine.getBytes());
|
232 |
|
|
|
233 |
|
|
// Compute the name of the signals
|
234 |
|
|
String signalsToken;
|
235 |
|
|
signalsToken = "{";
|
236 |
|
|
for (i = signalGroups-1; i >= 0 ; i--) {
|
237 |
|
|
signalsToken += groupName[i];
|
238 |
|
|
if (i > 0)
|
239 |
|
|
signalsToken += ",";
|
240 |
|
|
}
|
241 |
|
|
signalsToken += "} = ";
|
242 |
|
|
|
243 |
|
|
// Write name of the signals, values and delays in the verilog file.
|
244 |
|
|
String strWord;
|
245 |
|
|
int currentTime=(clockPeriod / 2), delay;
|
246 |
|
|
|
247 |
|
|
// compute the oldest wrote-info before trigger event
|
248 |
|
|
int bt_queue_head_address=0, bt_queue_tail_address=0;
|
249 |
|
|
// the word at address (memWords-1) represents bt_queue_tail_address.
|
250 |
|
|
for(j = 0; j < (octetsPerWord-1); j++) {
|
251 |
|
|
bt_queue_tail_address += ((0x000000FF) & (int) memoryLineBytes[memWords-1][j]) << (8*j);
|
252 |
|
|
}
|
253 |
|
|
System.out.println("bt_queue_tail_address=" + bt_queue_tail_address);
|
254 |
|
|
// Find the first <efffective capture memory word>
|
255 |
|
|
// before the trigger event (not an <emtpy-slot> memory word).
|
256 |
|
|
if(bt_queue_tail_address == (triggerMatchMemAddr - 1))
|
257 |
|
|
bt_queue_head_address = 0;
|
258 |
|
|
else
|
259 |
|
|
bt_queue_head_address = bt_queue_tail_address + 1;
|
260 |
|
|
boolean before_trigger=true;
|
261 |
|
|
boolean foundAnEffectiveCaptureWord=false, wentBack=false;
|
262 |
|
|
i = bt_queue_head_address;
|
263 |
|
|
do
|
264 |
|
|
{
|
265 |
|
|
for(j = 0; j < (octetsPerWord-1); j++) {
|
266 |
|
|
if(memoryLineBytes[i][j] != 0)
|
267 |
|
|
foundAnEffectiveCaptureWord = true;
|
268 |
|
|
}
|
269 |
|
|
if(foundAnEffectiveCaptureWord)
|
270 |
|
|
break;
|
271 |
|
|
i++;
|
272 |
|
|
if(i >= triggerMatchMemAddr)
|
273 |
|
|
if(!foundAnEffectiveCaptureWord && !wentBack) {
|
274 |
|
|
i = 0;
|
275 |
|
|
wentBack = true;
|
276 |
|
|
}
|
277 |
|
|
} while (i <= triggerMatchMemAddr);
|
278 |
|
|
if(!foundAnEffectiveCaptureWord)
|
279 |
|
|
fatalError("Could not find the first efffective capture before trigger match");
|
280 |
|
|
if(i >= triggerMatchMemAddr)
|
281 |
|
|
before_trigger=false;
|
282 |
|
|
|
283 |
|
|
// Walk through the captured data and write it to capture.v
|
284 |
|
|
do {
|
285 |
|
|
// Check if this is an empty line
|
286 |
|
|
boolean allMemoryLineIsZero=true;
|
287 |
|
|
for(j=octetsPerWord-1; j>=0; j--) {
|
288 |
|
|
if(memoryLineBytes[i][j] != 0) {
|
289 |
|
|
allMemoryLineIsZero = false;
|
290 |
|
|
break;
|
291 |
|
|
}
|
292 |
|
|
}
|
293 |
|
|
if(allMemoryLineIsZero) {
|
294 |
|
|
if(debugVeriFLA) {
|
295 |
|
|
strLine = "// info: line "+i+" is empty.\n";
|
296 |
|
|
System.out.println(strLine);
|
297 |
|
|
stream.write(strLine.getBytes());
|
298 |
|
|
}
|
299 |
|
|
} else {
|
300 |
|
|
// Write memory line index.
|
301 |
|
|
strLine = "memory_line_id=" + i + ";\n";
|
302 |
|
|
stream.write(strLine.getBytes());
|
303 |
|
|
// Data capture
|
304 |
|
|
strWord = totalSignals + "'b";
|
305 |
|
|
for(j=octetsPerWord-1; j>=0; j--) {
|
306 |
|
|
if((j * 8) < dataWordLenBits)
|
307 |
|
|
for(k=7; k>=0; k--) {
|
308 |
|
|
if((j*8+k) < totalSignals) {
|
309 |
|
|
strWord += (memoryLineBytes[i][j] >> k) & 1;
|
310 |
|
|
}
|
311 |
|
|
}
|
312 |
|
|
}
|
313 |
|
|
strWord += ';';
|
314 |
|
|
strLine = signalsToken + strWord + "\n";
|
315 |
|
|
if(i == triggerMatchMemAddr)
|
316 |
|
|
strLine += "la_trigger_matched = 1;\n";
|
317 |
|
|
//strLine += "#" + clockPeriod + ";\n";
|
318 |
|
|
// Write to file
|
319 |
|
|
//System.out.println(strLine);
|
320 |
|
|
stream.write(strLine.getBytes());
|
321 |
|
|
|
322 |
|
|
|
323 |
|
|
// Time interval in which data is constant.
|
324 |
|
|
delay=0;
|
325 |
|
|
for(j = 0; j < octetsPerWord; j++) {
|
326 |
|
|
if((j * 8) >= dataWordLenBits)
|
327 |
|
|
delay += ((0x000000FF) & (int) memoryLineBytes[i][j]) << (8*j - dataWordLenBits);
|
328 |
|
|
}
|
329 |
|
|
currentTime += delay * clockPeriod;
|
330 |
|
|
strLine = "#" + (delay * clockPeriod) + ";\n";
|
331 |
|
|
// Write to file
|
332 |
|
|
//System.out.println(strLine);
|
333 |
|
|
stream.write(strLine.getBytes());
|
334 |
|
|
// Also write the time stamp
|
335 |
|
|
strLine = "// ------------- Current Time: " + currentTime + "*(" + strTimescaleUnit + ") "+"\n";
|
336 |
|
|
stream.write(strLine.getBytes());
|
337 |
|
|
}
|
338 |
|
|
|
339 |
|
|
// Compute the new value of i
|
340 |
|
|
if(before_trigger) {
|
341 |
|
|
i = (i+1) % triggerMatchMemAddr;
|
342 |
|
|
if(i == bt_queue_head_address) {
|
343 |
|
|
before_trigger = false;
|
344 |
|
|
i = triggerMatchMemAddr;
|
345 |
|
|
}
|
346 |
|
|
}
|
347 |
|
|
else
|
348 |
|
|
i = i + 1;
|
349 |
|
|
} while (i < (memWords-1));
|
350 |
|
|
|
351 |
|
|
strLine = "$stop;\nend\nendmodule\n";
|
352 |
|
|
stream.write(strLine.getBytes());
|
353 |
|
|
|
354 |
|
|
// Write raw memory information.
|
355 |
|
|
strLine = "/*\n"+STR_ORIGINAL_CAPTURE_DUMP+"\n";
|
356 |
|
|
for(i=0; i<memWords; i++) {
|
357 |
|
|
strLine += "memory_line_id=" + i + ": ";
|
358 |
|
|
for(j=octetsPerWord-1; j>=0; j--) {
|
359 |
|
|
//strLine += "["+j+"]"+" " + Integer.toHexString(memoryLineBytes[i][j]) + " ";
|
360 |
|
|
if((0x000000FF & (int) memoryLineBytes[i][j]) <= 0x0F)
|
361 |
|
|
strLine += "0";
|
362 |
|
|
strLine += Integer.toHexString(
|
363 |
|
|
0x000000FF & (int) memoryLineBytes[i][j]).toUpperCase() + " ";
|
364 |
|
|
}
|
365 |
|
|
strLine += "\n";
|
366 |
|
|
}
|
367 |
|
|
/*
|
368 |
|
|
for(i=0; i<memWords; i++) {
|
369 |
|
|
strLine = "";
|
370 |
|
|
// Write the memory address of the word
|
371 |
|
|
if(i <= 9)
|
372 |
|
|
strLine += "0";
|
373 |
|
|
strLine += i + " ";
|
374 |
|
|
for(j=octetsPerWord-1; j>=0; j--) {
|
375 |
|
|
if((0x000000FF & (int) memoryLineBytes[i][j]) <= 0x0F)
|
376 |
|
|
strLine += "0";
|
377 |
|
|
strLine += Integer.toHexString(
|
378 |
|
|
0x000000FF & (int) memoryLineBytes[i][j]).toUpperCase() + " ";
|
379 |
|
|
}
|
380 |
|
|
strLine += "\n";
|
381 |
|
|
stream.write(strLine.getBytes());
|
382 |
|
|
}
|
383 |
|
|
*/
|
384 |
|
|
strLine += "*/\n";
|
385 |
|
|
stream.write(strLine.getBytes());
|
386 |
|
|
|
387 |
|
|
stream.close();
|
388 |
|
|
System.out.println("Job done. Please simulate " + outputFileName);
|
389 |
|
|
}
|
390 |
|
|
|
391 |
|
|
private void allocateMemory()
|
392 |
|
|
{
|
393 |
|
|
// Allocate memory
|
394 |
|
|
int i,j;
|
395 |
|
|
memoryLineBytes = new byte[memWords][];
|
396 |
|
|
for(i=0; i<memWords; i++)
|
397 |
|
|
memoryLineBytes[i] = new byte[octetsPerWord];
|
398 |
|
|
}
|
399 |
|
|
/*
|
400 |
|
|
private void simGetCapturedData()
|
401 |
|
|
{
|
402 |
|
|
// Init memory.
|
403 |
|
|
int i,j;
|
404 |
|
|
for(i=0; i < memWords; i++)
|
405 |
|
|
{
|
406 |
|
|
for(j=0; j < octetsPerWord; j++) {
|
407 |
|
|
memoryLineBytes[i][j]=(byte) i;
|
408 |
|
|
}
|
409 |
|
|
}
|
410 |
|
|
}
|
411 |
|
|
*/
|
412 |
|
|
public void rebuildCapturedDataFromFile(String fileName)
|
413 |
|
|
{
|
414 |
|
|
try {
|
415 |
|
|
String line;
|
416 |
|
|
File file;
|
417 |
|
|
file = new File(fileName);
|
418 |
|
|
if (!file.isFile())
|
419 |
|
|
fatalError("Error: File does not exist: " + fileName);
|
420 |
|
|
BufferedReader br = new BufferedReader(new FileReader(file));
|
421 |
|
|
|
422 |
|
|
boolean startOfMemory=false, allMemoryRead=false;
|
423 |
|
|
int i=0, j=0, tNo;
|
424 |
|
|
|
425 |
|
|
do {
|
426 |
|
|
line = br.readLine();
|
427 |
|
|
if (line == null)
|
428 |
|
|
fatalError("File " + fileName + " got null line while reading.");
|
429 |
|
|
//if(startOfMemory) {
|
430 |
|
|
StringTokenizer st;
|
431 |
|
|
st = new StringTokenizer(line," ");
|
432 |
|
|
tNo= st.countTokens();
|
433 |
|
|
if(tNo != (octetsPerWord+1))
|
434 |
|
|
fatalError("File " + fileName + " tNo != 2: " + tNo + " != 2" + (octetsPerWord+1));
|
435 |
|
|
st.nextToken();
|
436 |
|
|
for(j=octetsPerWord-1; j>=0; j--) {
|
437 |
|
|
memoryLineBytes[i][j] = (byte) Integer.parseInt(st.nextToken(), 16);
|
438 |
|
|
}
|
439 |
|
|
i++;
|
440 |
|
|
if(i >= memWords)
|
441 |
|
|
allMemoryRead = true;
|
442 |
|
|
//}
|
443 |
|
|
//else
|
444 |
|
|
//if (line.startsWith(STR_ORIGINAL_CAPTURE_DUMP)) {
|
445 |
|
|
// startOfMemory=true;
|
446 |
|
|
// i = 0;
|
447 |
|
|
//}
|
448 |
|
|
} while (!allMemoryRead);
|
449 |
|
|
} catch (Exception e) {
|
450 |
|
|
e.printStackTrace();
|
451 |
|
|
fatalError("rebuildCapturedDataFromFile exception");
|
452 |
|
|
}
|
453 |
|
|
}
|
454 |
|
|
|
455 |
|
|
public void job(String propertiesFileName, String strRebuildFileName)
|
456 |
|
|
{
|
457 |
|
|
getProperties(propertiesFileName);
|
458 |
|
|
allocateMemory();
|
459 |
|
|
if(strRebuildFileName == null)
|
460 |
|
|
getCapturedData(portName);
|
461 |
|
|
else
|
462 |
|
|
rebuildCapturedDataFromFile(strRebuildFileName);
|
463 |
|
|
try {
|
464 |
|
|
saveCapturedData();
|
465 |
|
|
} catch (IOException e) {
|
466 |
|
|
e.printStackTrace();
|
467 |
|
|
fatalError("Error saving Captured Data");
|
468 |
|
|
}
|
469 |
|
|
}
|
470 |
|
|
|
471 |
|
|
public static void fatalError(String errorName)
|
472 |
|
|
{
|
473 |
|
|
System.out.println("Fatal error: " + errorName);
|
474 |
|
|
System.exit(-1);
|
475 |
|
|
}
|
476 |
|
|
|
477 |
|
|
public void getProperties(String fileName)
|
478 |
|
|
{
|
479 |
|
|
File f;
|
480 |
|
|
f = new File(fileName);
|
481 |
|
|
if (!f.isFile()) {
|
482 |
|
|
System.out.println("Error: File does not exist: " + fileName);
|
483 |
|
|
System.exit(-1);
|
484 |
|
|
}
|
485 |
|
|
|
486 |
|
|
InputStream stream;
|
487 |
|
|
try {
|
488 |
|
|
stream = new FileInputStream(f);
|
489 |
|
|
try {
|
490 |
|
|
properties.load(stream);
|
491 |
|
|
} catch (IOException e) {
|
492 |
|
|
fatalError("IOException " + fileName);
|
493 |
|
|
}
|
494 |
|
|
} catch (FileNotFoundException e) {
|
495 |
|
|
fatalError("FileNotFoundException "+ fileName);
|
496 |
|
|
}
|
497 |
|
|
|
498 |
|
|
String strVal;
|
499 |
|
|
portName = properties.getProperty(NAME + ".portName");
|
500 |
|
|
if(portName == null)
|
501 |
|
|
fatalError("Properties: missing portName");
|
502 |
|
|
strBaudRate = properties.getProperty(NAME + ".baudRate");
|
503 |
|
|
if(strBaudRate == null)
|
504 |
|
|
fatalError("Properties: missing baudRate");
|
505 |
|
|
//if(!strBaudRate.equals("115200") && !strBaudRate.equals("38400") && !strBaudRate.equals("9600"))
|
506 |
|
|
//fatalError("Invalid baudRate (must be 115200 or 38400 or 9600)");
|
507 |
|
|
|
508 |
|
|
// time units
|
509 |
|
|
strTimescaleUnit=properties.getProperty(NAME + ".timescaleUnit");
|
510 |
|
|
strTimescalePrecision=properties.getProperty(NAME + ".timescalePrecision");
|
511 |
|
|
if(strTimescaleUnit == null || strTimescalePrecision == null)
|
512 |
|
|
fatalError("Properties: Not found timescale - unit or precision");
|
513 |
|
|
// clockPeriod
|
514 |
|
|
strVal=properties.getProperty(NAME + ".clockPeriod");
|
515 |
|
|
if(strVal != null)
|
516 |
|
|
clockPeriod=Integer.parseInt(strVal);
|
517 |
|
|
else
|
518 |
|
|
fatalError("Properties: clockPeriod not found");
|
519 |
|
|
|
520 |
|
|
// User signals
|
521 |
|
|
strVal=properties.getProperty(NAME + ".totalSignals");
|
522 |
|
|
if(strVal != null)
|
523 |
|
|
totalSignals=Integer.parseInt(strVal);
|
524 |
|
|
else
|
525 |
|
|
fatalError("Properties: endian not found");
|
526 |
|
|
// Groups of signals
|
527 |
|
|
strVal=properties.getProperty(NAME + ".signalGroups");
|
528 |
|
|
if(strVal != null)
|
529 |
|
|
signalGroups=Integer.parseInt(strVal);
|
530 |
|
|
else
|
531 |
|
|
fatalError("Properties: signalGroups not found");
|
532 |
|
|
groupName=new String[signalGroups];
|
533 |
|
|
groupSize=new int[signalGroups];
|
534 |
|
|
groupEndian=new int[signalGroups];
|
535 |
|
|
int i;
|
536 |
|
|
int sumOfSignals=0;
|
537 |
|
|
for (i=0; i < signalGroups; i++)
|
538 |
|
|
{
|
539 |
|
|
String strGroupName, strGroupSize, strGroupEndian;
|
540 |
|
|
strGroupName=properties.getProperty(NAME + ".groupName."+i);
|
541 |
|
|
strGroupSize=properties.getProperty(NAME + ".groupSize."+i);
|
542 |
|
|
strGroupEndian=properties.getProperty(NAME + ".groupEndian."+i);
|
543 |
|
|
if(strGroupName == null || strGroupSize == null || strGroupEndian == null)
|
544 |
|
|
fatalError("Properties: group " + i + " not found groupName or groupSize or groupEndian");
|
545 |
|
|
else {
|
546 |
|
|
groupName[i]=strGroupName;
|
547 |
|
|
groupSize[i]=Integer.parseInt(strGroupSize);
|
548 |
|
|
sumOfSignals += groupSize[i];
|
549 |
|
|
groupEndian[i]=Integer.parseInt(strGroupEndian);
|
550 |
|
|
}
|
551 |
|
|
}
|
552 |
|
|
if(sumOfSignals != totalSignals)
|
553 |
|
|
fatalError("Properties: totalSignals != sum of all group sizes: " + totalSignals + " != "+sumOfSignals);
|
554 |
|
|
|
555 |
|
|
|
556 |
|
|
// Memory
|
557 |
|
|
strVal=properties.getProperty(NAME + ".memWords");
|
558 |
|
|
if(strVal != null)
|
559 |
|
|
memWords=Integer.parseInt(strVal);
|
560 |
|
|
else
|
561 |
|
|
fatalError("Properties: memWords not found");
|
562 |
|
|
strVal=properties.getProperty(NAME + ".dataWordLenBits");
|
563 |
|
|
if(strVal != null)
|
564 |
|
|
dataWordLenBits=Integer.parseInt(strVal);
|
565 |
|
|
else
|
566 |
|
|
fatalError("Properties: dataWordLenBits not found");
|
567 |
|
|
if((dataWordLenBits % 8) != 0)
|
568 |
|
|
fatalError("Properties: dataWordLenBits is not multiple of 8");
|
569 |
|
|
if(dataWordLenBits != totalSignals)
|
570 |
|
|
fatalError("Properties: totalSignals != dataWordLenBits: " + totalSignals + " != "+dataWordLenBits);
|
571 |
|
|
strVal=properties.getProperty(NAME + ".clonesWordLenBits");
|
572 |
|
|
if(strVal != null)
|
573 |
|
|
clonesWordLenBits=Integer.parseInt(strVal);
|
574 |
|
|
else
|
575 |
|
|
fatalError("Properties: clonesWordLenBits not found");
|
576 |
|
|
if((clonesWordLenBits % 8) != 0)
|
577 |
|
|
fatalError("Properties: clonesWordLenBits is not multiple of 8");
|
578 |
|
|
memWordLenBits = dataWordLenBits + clonesWordLenBits;
|
579 |
|
|
// Compute sizes
|
580 |
|
|
// octetsPerWord
|
581 |
|
|
octetsPerWord = memWordLenBits / 8;
|
582 |
|
|
if (memWordLenBits % 8 > 0)
|
583 |
|
|
octetsPerWord++;
|
584 |
|
|
totalmemoryDataBytes = memWords*octetsPerWord;
|
585 |
|
|
// Trigger
|
586 |
|
|
strVal=properties.getProperty(NAME + ".triggerMatchMemAddr");
|
587 |
|
|
if(strVal != null)
|
588 |
|
|
triggerMatchMemAddr=Integer.parseInt(strVal);
|
589 |
|
|
else
|
590 |
|
|
fatalError("Properties: triggerMatchMemAddr not found");
|
591 |
|
|
/*
|
592 |
|
|
strVal=properties.getProperty(NAME + ".maxSamplesAfterTrigger");
|
593 |
|
|
if(strVal != null)
|
594 |
|
|
maxSamplesAfterTrigger=Integer.parseInt(strVal);
|
595 |
|
|
else
|
596 |
|
|
fatalError("Properties: maxSamplesAfterTrigger not found");
|
597 |
|
|
|
598 |
|
|
// triggerLastValue
|
599 |
|
|
strVal=properties.getProperty(NAME + ".triggerLastValue");
|
600 |
|
|
if(strVal != null) {
|
601 |
|
|
StringTokenizer st;
|
602 |
|
|
int j, tNo;
|
603 |
|
|
st = new StringTokenizer(strVal," ");
|
604 |
|
|
tNo= st.countTokens();
|
605 |
|
|
if(tNo != octetsPerWord)
|
606 |
|
|
fatalError("triggerLastValue " + " tNo != octetsPerWord: " + tNo + " != " + octetsPerWord);
|
607 |
|
|
triggerLastValue = new int[octetsPerWord];
|
608 |
|
|
for(j=octetsPerWord-1; j>=0; j--) {
|
609 |
|
|
triggerLastValue[j] = (byte) Integer.parseInt(st.nextToken(), 16);
|
610 |
|
|
}
|
611 |
|
|
}
|
612 |
|
|
else
|
613 |
|
|
fatalError("Properties: triggerLastValue not found");
|
614 |
|
|
*/
|
615 |
|
|
}
|
616 |
|
|
|
617 |
|
|
public String getTime()
|
618 |
|
|
{
|
619 |
|
|
Calendar calendar=new GregorianCalendar();
|
620 |
|
|
String strTime;
|
621 |
|
|
int field;
|
622 |
|
|
strTime = "" + calendar.get(Calendar.YEAR);
|
623 |
|
|
field = 1 + calendar.get(Calendar.MONTH);
|
624 |
|
|
if(field < 10)
|
625 |
|
|
strTime += "0";
|
626 |
|
|
strTime += field;
|
627 |
|
|
if(calendar.get(Calendar.DAY_OF_MONTH) < 10)
|
628 |
|
|
strTime += "0";
|
629 |
|
|
strTime += calendar.get(Calendar.DAY_OF_MONTH) + "_" ;
|
630 |
|
|
if(calendar.get(Calendar.HOUR_OF_DAY) < 10)
|
631 |
|
|
strTime += "0";
|
632 |
|
|
strTime += calendar.get(Calendar.HOUR_OF_DAY);
|
633 |
|
|
if(calendar.get(Calendar.MINUTE) < 10)
|
634 |
|
|
strTime += "0";
|
635 |
|
|
strTime += calendar.get(Calendar.MINUTE) + "_";
|
636 |
|
|
if(calendar.get(Calendar.SECOND) < 10)
|
637 |
|
|
strTime += "0";
|
638 |
|
|
strTime += calendar.get(Calendar.SECOND) ;
|
639 |
|
|
System.out.println("date and time: "+strTime);
|
640 |
|
|
return strTime;
|
641 |
|
|
}
|
642 |
|
|
|
643 |
|
|
public static void main(String[] args) throws Exception
|
644 |
|
|
{
|
645 |
|
|
if(args.length < 1)
|
646 |
|
|
VeriFLA.fatalError("Too few arguments: "+args.length+
|
647 |
|
|
"\nSintax is:\n\tjava VeriFLA <propertiesFileName> [<sendRunCommand>=0/1 (default 0)] [sourceToRebuild_capture]\n"+
|
648 |
|
|
"Examples:\n1. Wait for FPGA to send capture:\n\tjava VeriFLA verifla_properties_keyboard.txt\n"+
|
649 |
|
|
"2. Send to the monitor the run command and wait for FPGA to send capture:\n\tjava VeriFLA verifla_properties_keyboard.txt 1\n"
|
650 |
|
|
);
|
651 |
|
|
// 1st arg.
|
652 |
|
|
System.out.println("propertiesFileName = " + args[0]);
|
653 |
|
|
// 2nd arg.
|
654 |
|
|
sendRunCommand = 0;
|
655 |
|
|
if(args.length >= 2) {
|
656 |
|
|
System.out.println(" sendRunCommand = " + args[1]);
|
657 |
|
|
sendRunCommand = Integer.parseInt(args[1]);
|
658 |
|
|
}
|
659 |
|
|
// 3rd arg.
|
660 |
|
|
String sourceToRebuildCaptureFile=null;
|
661 |
|
|
if(args.length >= 3) {
|
662 |
|
|
System.out.println(" sourceToRebuild_capture = " + args[2]);
|
663 |
|
|
sourceToRebuildCaptureFile = args[2];
|
664 |
|
|
}
|
665 |
|
|
VeriFLA verifla;
|
666 |
|
|
verifla = new VeriFLA();
|
667 |
|
|
verifla.job(args[0], sourceToRebuildCaptureFile);
|
668 |
|
|
}
|
669 |
|
|
|
670 |
|
|
// This java app. data members
|
671 |
|
|
boolean debugVeriFLA=true;
|
672 |
|
|
|
673 |
|
|
String propertiesFileName;
|
674 |
|
|
Properties properties;
|
675 |
|
|
SerialPort serialPort;
|
676 |
|
|
String strBaudRate;
|
677 |
|
|
final static String NAME = "LA";
|
678 |
|
|
final static String STR_ORIGINAL_CAPTURE_DUMP = "ORIGINAL CAPTURE DUMP";
|
679 |
|
|
final static int USERCMD_RESET=0x00, USERCMD_RUN = 0x01;
|
680 |
|
|
byte [][] memoryLineBytes;
|
681 |
|
|
int octetsPerWord, totalmemoryDataBytes;
|
682 |
|
|
int totalSignals;
|
683 |
|
|
public static int sendRunCommand=0;
|
684 |
|
|
int clockPeriod;
|
685 |
|
|
|
686 |
|
|
// Properties file members
|
687 |
|
|
String portName;
|
688 |
|
|
int memWords, memWordLenBits, dataWordLenBits, clonesWordLenBits,
|
689 |
|
|
triggerMatchMemAddr, maxSamplesAfterTrigger;
|
690 |
|
|
//int [] triggerLastValue;
|
691 |
|
|
String strTimescaleUnit, strTimescalePrecision;
|
692 |
|
|
int signalGroups;
|
693 |
|
|
String [] groupName;
|
694 |
|
|
int [] groupSize, groupEndian;
|
695 |
|
|
}
|