fixed issues with cross chunk Spans, chunk string->array, and better tests
This commit is contained in:
parent
afbee0d083
commit
1d920a3e08
@ -37,6 +37,8 @@ const properties = {
|
|||||||
mask: 'ptr', // mask (x, z) of the signal on change event
|
mask: 'ptr', // mask (x, z) of the signal on change event
|
||||||
digitCount: 'i32',
|
digitCount: 'i32',
|
||||||
tmpStr: 'ptr',
|
tmpStr: 'ptr',
|
||||||
|
timeStampStr: 'ptr',
|
||||||
|
idStr: 'ptr',
|
||||||
tmpStr2: 'ptr',
|
tmpStr2: 'ptr',
|
||||||
stackPointer: 'i32',
|
stackPointer: 'i32',
|
||||||
id: 'ptr',
|
id: 'ptr',
|
||||||
@ -255,7 +257,7 @@ const generate = (cb) => {
|
|||||||
.skipTo(inSimulation);
|
.skipTo(inSimulation);
|
||||||
|
|
||||||
simulationTime
|
simulationTime
|
||||||
.match(spaces, timeSpan.end(simulation))
|
.match(spaces, timeSpan.end(p.invoke(p.code.span('onTime'), simulation)))
|
||||||
.skipTo(simulationTime);
|
.skipTo(simulationTime);
|
||||||
|
|
||||||
simulationVector
|
simulationVector
|
||||||
@ -298,7 +300,7 @@ const generate = (cb) => {
|
|||||||
.skipTo(simulationVectorRecovery);
|
.skipTo(simulationVectorRecovery);
|
||||||
|
|
||||||
simulationId
|
simulationId
|
||||||
.match(spaces, idSpan.end(simulation))
|
.match(spaces, idSpan.end(p.invoke(p.code.span('onId'), simulation)))
|
||||||
.skipTo(simulationId);
|
.skipTo(simulationId);
|
||||||
|
|
||||||
const artifacts = p.build(declaration);
|
const artifacts = p.build(declaration);
|
||||||
|
35
lib/chopper.js
Normal file
35
lib/chopper.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
function xoshiro128ss(a, b, c, d) {
|
||||||
|
return function() {
|
||||||
|
var t = b << 9, r = a * 5; r = (r << 7 | r >>> 25) * 9;
|
||||||
|
c ^= a; d ^= b;
|
||||||
|
b ^= c; a ^= d; c ^= t;
|
||||||
|
d = d << 11 | d >>> 21;
|
||||||
|
return (r >>> 0) / 4294967296;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function * chopper (src, step) {
|
||||||
|
|
||||||
|
const chunker = len => {
|
||||||
|
const chunk = src.slice(0, len);
|
||||||
|
src = src.slice(chunk.length);
|
||||||
|
return chunk;
|
||||||
|
};
|
||||||
|
|
||||||
|
const random = xoshiro128ss(1134534345, 2145245245624, 313442566456, 4245642456456);
|
||||||
|
// const random = Math.random;
|
||||||
|
// const random = () => 0;
|
||||||
|
// yield(chunker(395));
|
||||||
|
// yield(chunker(145));
|
||||||
|
while(true) {
|
||||||
|
if (src.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
yield(chunker(random() * step + step));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = chopper;
|
@ -31,15 +31,21 @@ module.exports = () => {
|
|||||||
const cxt = lib.init(lifemit, triemit, info);
|
const cxt = lib.init(lifemit, triemit, info);
|
||||||
|
|
||||||
s._write = function (chunk, encoding, callback) {
|
s._write = function (chunk, encoding, callback) {
|
||||||
lib.execute(cxt, lifemit, triemit2, info, chunk);
|
const err = lib.execute(cxt, lifemit, triemit2, info, chunk);
|
||||||
|
if (err) {
|
||||||
|
// console.log(info);
|
||||||
|
console.log(err);
|
||||||
|
// throw new Error(err);
|
||||||
|
}
|
||||||
callback();
|
callback();
|
||||||
};
|
};
|
||||||
|
|
||||||
s.change = {
|
s.change = {
|
||||||
on: (id, fn) => {
|
on: (id, fn) => {
|
||||||
|
// console.log(id);
|
||||||
triemit2 = triemit;
|
triemit2 = triemit;
|
||||||
triee.on(id, fn);
|
triee.on(id, fn);
|
||||||
const triggerString = triee.eventNames().join(' ') + ' ';
|
const triggerString = triee.eventNames().join('\0') + '\0\0';
|
||||||
lib.setTrigger(cxt, triggerString);
|
lib.setTrigger(cxt, triggerString);
|
||||||
},
|
},
|
||||||
any: fn => {
|
any: fn => {
|
||||||
|
@ -11,26 +11,36 @@ const dotProp = require('dot-prop');
|
|||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
function u8ToBn(u8) {
|
// function u8ToBn(u8) {
|
||||||
var hex = [];
|
// let str = '';
|
||||||
// let u8 = Uint8Array.from(buf);
|
// for (let i = 0; i < u8.length; i++) {
|
||||||
|
// const val = u8[i];
|
||||||
|
// str = val.toString(16) + str;
|
||||||
|
// if (val < 16) {
|
||||||
|
// str = '0' + str;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return BigInt('0x' + str);
|
||||||
|
// }
|
||||||
|
|
||||||
u8.forEach(function (i) {
|
function h8ToBn(HEAPU8, start, len) {
|
||||||
var h = i.toString(16);
|
let str = '';
|
||||||
if (h.length % 2) { h = '0' + h; }
|
const fin = start + len;
|
||||||
hex.push(h);
|
for (let i = start; i < fin; i++) {
|
||||||
});
|
const val = HEAPU8[i];
|
||||||
|
str = val.toString(16) + str;
|
||||||
hex.reverse();
|
if (val < 16) {
|
||||||
|
str = '0' + str;
|
||||||
return BigInt('0x' + hex.join(''));
|
}
|
||||||
|
}
|
||||||
|
return BigInt('0x' + str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// let startCalled = 0;
|
// let startCalled = 0;
|
||||||
|
|
||||||
const bindCWrap = (c, wasm) => {
|
const bindCWrap = (c, wasm) => {
|
||||||
const w = wasm.cwrap;
|
const w = wasm.cwrap;
|
||||||
c.execute = w('execute', 'number', ['number', 'number', 'number', 'number', 'number', 'string']);
|
c.execute = w('execute', 'number', ['number', 'number', 'number', 'number', 'number', 'array', 'number']);
|
||||||
c.init = w('init', 'number', ['number', 'number', 'number', 'number']);
|
c.init = w('init', 'number', ['number', 'number', 'number', 'number']);
|
||||||
c.getTime = w('getTime', 'number', ['number']);
|
c.getTime = w('getTime', 'number', ['number']);
|
||||||
c.setTrigger = w('setTrigger', 'number', ['number', 'string']);
|
c.setTrigger = w('setTrigger', 'number', ['number', 'string']);
|
||||||
@ -57,13 +67,21 @@ const getWrapper = wasm => {
|
|||||||
|
|
||||||
// gets a string from a c heap pointer and length
|
// gets a string from a c heap pointer and length
|
||||||
const getString = (name, len) => {
|
const getString = (name, len) => {
|
||||||
const view = wasm.HEAPU8.subarray(name, name+len);
|
|
||||||
|
// const view = wasm.HEAPU8.subarray(name, name+len);
|
||||||
|
// let string = '';
|
||||||
|
// for (let i = 0; i < len; i++) {
|
||||||
|
// string += String.fromCharCode(view[i]);
|
||||||
|
// }
|
||||||
|
// return string;
|
||||||
|
|
||||||
let string = '';
|
let string = '';
|
||||||
for (let i = 0; i < len; i++) {
|
const end = name + len;
|
||||||
string += String.fromCharCode(view[i]);
|
for (let i = name; i < end; i++) {
|
||||||
|
string += String.fromCharCode(wasm.HEAPU8[i]);
|
||||||
}
|
}
|
||||||
return string;
|
return string;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let boundInfo;
|
let boundInfo;
|
||||||
@ -137,16 +155,19 @@ const getWrapper = wasm => {
|
|||||||
boundEE1 = wasm.addFunction(function(eventName, l0, time, command, valueWords, value, mask) {
|
boundEE1 = wasm.addFunction(function(eventName, l0, time, command, valueWords, value, mask) {
|
||||||
const name = getString(eventName, l0);
|
const name = getString(eventName, l0);
|
||||||
// console.log(`event name`);
|
// console.log(`event name`);
|
||||||
// console.log(`event ${name} time ${time} cmd ${command} wrds ${valueWords}`);
|
// console.log({name, time, command, valueWords});
|
||||||
|
|
||||||
|
|
||||||
const view0 = wasm.HEAPU8.subarray(value, value+(valueWords*8));
|
// const view0 = wasm.HEAPU8.subarray(value, value+(valueWords*8));
|
||||||
const view1 = wasm.HEAPU8.subarray(mask, mask+(valueWords*8));
|
// const view1 = wasm.HEAPU8.subarray(mask, mask+(valueWords*8));
|
||||||
|
|
||||||
let bigValue = u8ToBn(view0);
|
// let bigValue = u8ToBn(view0);
|
||||||
let bigMask = u8ToBn(view1);
|
// let bigMask = u8ToBn(view1);
|
||||||
|
// let bigValue = 0n;
|
||||||
|
|
||||||
// console.log(bigValue.toString(16));
|
// console.log(bigValue.toString(16));
|
||||||
|
const bigValue = h8ToBn(wasm.HEAPU8, value, valueWords * 8);
|
||||||
|
const bigMask = h8ToBn(wasm.HEAPU8, mask, valueWords * 8);
|
||||||
|
|
||||||
ee[1](name, time, command, bigValue, bigMask);
|
ee[1](name, time, command, bigValue, bigMask);
|
||||||
}, 'viijiiii');
|
}, 'viijiiii');
|
||||||
@ -167,7 +188,7 @@ const getWrapper = wasm => {
|
|||||||
boundInfo = info;
|
boundInfo = info;
|
||||||
ee[0] = cb0;
|
ee[0] = cb0;
|
||||||
ee[1] = cb1;
|
ee[1] = cb1;
|
||||||
c.execute(ctx, boundEE0, boundEE1, boundSet, boundGet, chunk.toString());
|
return c.execute(ctx, boundEE0, boundEE1, boundSet, boundGet, chunk, chunk.length);
|
||||||
},
|
},
|
||||||
setTrigger: (ctx, triggerString) => {
|
setTrigger: (ctx, triggerString) => {
|
||||||
return c.setTrigger(ctx, triggerString);
|
return c.setTrigger(ctx, triggerString);
|
||||||
@ -208,8 +229,11 @@ module.exports = async wasm => {
|
|||||||
const cxt = lib.init(lifemit, triemit, info);
|
const cxt = lib.init(lifemit, triemit, info);
|
||||||
|
|
||||||
s._write = function (chunk, encoding, callback) {
|
s._write = function (chunk, encoding, callback) {
|
||||||
// console.log('about to write', chunk);
|
// console.log(cxt, info);
|
||||||
lib.execute(cxt, lifemit, triemit2, info, chunk);
|
const err = lib.execute(cxt, lifemit, triemit2, info, chunk);
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
// console.log(util.inspect(info, {showHidden: true, depth : null, colorize: true}));
|
// console.log(util.inspect(info, {showHidden: true, depth : null, colorize: true}));
|
||||||
// console.log(info.stack[0].top);
|
// console.log(info.stack[0].top);
|
||||||
// console.log(info.stack[1]);
|
// console.log(info.stack[1]);
|
||||||
@ -220,9 +244,9 @@ module.exports = async wasm => {
|
|||||||
s.change = {
|
s.change = {
|
||||||
on: (id, fn) => {
|
on: (id, fn) => {
|
||||||
triemit2 = triemit;
|
triemit2 = triemit;
|
||||||
// console.log(id, fn);
|
|
||||||
triee.on(id, fn);
|
triee.on(id, fn);
|
||||||
const triggerString = triee.eventNames().join(' ') + ' ';
|
const triggerString = triee.eventNames().join(' ') + ' ';
|
||||||
|
// console.log(id, Buffer.from(triggerString));
|
||||||
lib.setTrigger(cxt, triggerString);
|
lib.setTrigger(cxt, triggerString);
|
||||||
},
|
},
|
||||||
any: fn => {
|
any: fn => {
|
||||||
@ -239,5 +263,3 @@ module.exports = async wasm => {
|
|||||||
|
|
||||||
return s;
|
return s;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* global BigInt */
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/* global BigInt */
|
|
||||||
|
|
||||||
const dotProp = require('dot-prop');
|
const dotProp = require('dot-prop');
|
||||||
|
|
||||||
function _waitForStart(mod) {
|
function _waitForStart(mod) {
|
||||||
|
File diff suppressed because one or more lines are too long
BIN
out/vcd.wasm
BIN
out/vcd.wasm
Binary file not shown.
72
test/dump.vcd
Normal file
72
test/dump.vcd
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
$version Generated by VerilatedVcd $end
|
||||||
|
$date Wed Sep 18 22:59:07 2019
|
||||||
|
$end
|
||||||
|
$timescale 1ns $end
|
||||||
|
|
||||||
|
$scope module top $end
|
||||||
|
$var wire 1 "}G clock $end
|
||||||
|
$scope module leaf $end
|
||||||
|
$var wire 64 {u counter [63:0] $end
|
||||||
|
$upscope $end
|
||||||
|
$scope module fruit $end
|
||||||
|
$var wire 4 u) point [3:0] $end
|
||||||
|
$upscope $end
|
||||||
|
$upscope $end
|
||||||
|
|
||||||
|
$enddefinitions $end
|
||||||
|
#100
|
||||||
|
0"}G
|
||||||
|
#200
|
||||||
|
1"}G
|
||||||
|
bzzzzxxxx11110000ZZZZXXXX11110000zzzzxxxx11110000zzzzxxxx11110000 {u
|
||||||
|
#300
|
||||||
|
0"}G
|
||||||
|
b1111000000000000000000000000000000000000000000000000000000000000 {u
|
||||||
|
b0000 u)
|
||||||
|
#301
|
||||||
|
b0000111100000000000000000000000000000000000000000000000000000000 {u
|
||||||
|
b0001 u)
|
||||||
|
#302
|
||||||
|
b0000000011110000000000000000000000000000000000000000000000000000 {u
|
||||||
|
b0010 u)
|
||||||
|
#303
|
||||||
|
b0000000000001111000000000000000000000000000000000000000000000000 {u
|
||||||
|
b0011 u)
|
||||||
|
#304
|
||||||
|
b0000000000000000111100000000000000000000000000000000000000000000 {u
|
||||||
|
b0100 u)
|
||||||
|
#305
|
||||||
|
b0000000000000000000011110000000000000000000000000000000000000000 {u
|
||||||
|
b0101 u)
|
||||||
|
#306
|
||||||
|
b0000000000000000000000001111000000000000000000000000000000000000 {u
|
||||||
|
b0110 u)
|
||||||
|
#307
|
||||||
|
b0000000000000000000000000000111100000000000000000000000000000000 {u
|
||||||
|
b0111 u)
|
||||||
|
#308
|
||||||
|
B0000000000000000000000000000000011110000000000000000000000000000 {u
|
||||||
|
b1000 u)
|
||||||
|
#309
|
||||||
|
b0000000000000000000000000000000000001111000000000000000000000000 {u
|
||||||
|
b1001 u)
|
||||||
|
#310
|
||||||
|
b0000000000000000000000000000000000000000111100000000000000000000 {u
|
||||||
|
b1010 u)
|
||||||
|
#311
|
||||||
|
b0000000000000000000000000000000000000000000011110000000000000000 {u
|
||||||
|
b1011 u)
|
||||||
|
#312
|
||||||
|
b0000000000000000000000000000000000000000000000001111000000000000 {u
|
||||||
|
b1100 u)
|
||||||
|
#313
|
||||||
|
b0000000000000000000000000000000000000000000000000000111100000000 {u
|
||||||
|
b1101 u)
|
||||||
|
#314
|
||||||
|
b0000000000000000000000000000000000000000000000000000000011110000 {u
|
||||||
|
b1110 u)
|
||||||
|
#315
|
||||||
|
b0000000000000000000000000000000000000000000000000000000000001111 {u
|
||||||
|
b1111 u)
|
||||||
|
#316
|
||||||
|
1"}G
|
@ -17,7 +17,9 @@ describe('basic', () => {
|
|||||||
|
|
||||||
it('fail: foo bar', done => {
|
it('fail: foo bar', done => {
|
||||||
const inst = parser();
|
const inst = parser();
|
||||||
expect(inst.write(Buffer.from(' foo bar ???'))).to.eq(true);
|
expect(() => {
|
||||||
|
inst.write(Buffer.from(' foo bar ???'));
|
||||||
|
}).not.to.throw();
|
||||||
expect(inst.info).to.deep.eq({
|
expect(inst.info).to.deep.eq({
|
||||||
stack: [{}],
|
stack: [{}],
|
||||||
status: 'declaration',
|
status: 'declaration',
|
||||||
@ -26,11 +28,13 @@ describe('basic', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('$comment', done => {
|
it('fail: $comment', done => {
|
||||||
const inst = parser();
|
const inst = parser();
|
||||||
expect(inst.write(Buffer.from(
|
expect(() => {
|
||||||
' \n $comment some text $end $comment more text $end ???'
|
inst.write(Buffer.from(
|
||||||
))).to.eq(true);
|
' \n $comment some text $end $comment more text $end ???'
|
||||||
|
));
|
||||||
|
}).not.to.throw();
|
||||||
expect(inst.info).to.deep.eq({
|
expect(inst.info).to.deep.eq({
|
||||||
comment: ' more text ',
|
comment: ' more text ',
|
||||||
stack: [{}],
|
stack: [{}],
|
||||||
|
@ -1,118 +1,87 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
const expect = require('chai').expect;
|
const expect = require('chai').expect;
|
||||||
const parser = require('../lib/parser.js');
|
const parser = require('../lib/parser.js');
|
||||||
|
const chopper = require('../lib/chopper.js');
|
||||||
|
|
||||||
describe('dump', () => {
|
const expectaitions = [
|
||||||
|
{ id: '"}G', time: 100n, cmd: 14, value: 0n, mask: 0n },
|
||||||
|
{ id: '"}G', time: 200n, cmd: 15, value: 1n, mask: 0n },
|
||||||
|
{ id: '{u', time: 200n, cmd: 30, value: 0xf0f0f0f0f0f0f0f0n, mask: 0xff00ff00ff00ff00n },
|
||||||
|
{ id: '"}G', time: 300n, cmd: 14, value: 0n, mask: 0n },
|
||||||
|
{ id: '{u', time: 300n, cmd: 30, value: 0xf000000000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 300n, cmd: 30, value: 0n, mask: 0n },
|
||||||
|
{ id: '{u', time: 301n, cmd: 30, value: 0x0f00000000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 301n, cmd: 30, value: 1n, mask: 0n },
|
||||||
|
{ id: '{u', time: 302n, cmd: 30, value: 0x00f0000000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 302n, cmd: 30, value: 2n, mask: 0n },
|
||||||
|
{ id: '{u', time: 303n, cmd: 30, value: 0x000f000000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 303n, cmd: 30, value: 3n, mask: 0n },
|
||||||
|
{ id: '{u', time: 304n, cmd: 30, value: 0x0000f00000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 304n, cmd: 30, value: 4n, mask: 0n },
|
||||||
|
{ id: '{u', time: 305n, cmd: 30, value: 0x00000f0000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 305n, cmd: 30, value: 5n, mask: 0n },
|
||||||
|
{ id: '{u', time: 306n, cmd: 30, value: 0x000000f000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 306n, cmd: 30, value: 6n, mask: 0n },
|
||||||
|
{ id: '{u', time: 307n, cmd: 30, value: 0x0000000f00000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 307n, cmd: 30, value: 7n, mask: 0n },
|
||||||
|
{ id: '{u', time: 308n, cmd: 31, value: 0x00000000f0000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 308n, cmd: 30, value: 8n, mask: 0n },
|
||||||
|
{ id: '{u', time: 309n, cmd: 30, value: 0x000000000f000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 309n, cmd: 30, value: 9n, mask: 0n },
|
||||||
|
{ id: '{u', time: 310n, cmd: 30, value: 0x0000000000f00000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 310n, cmd: 30, value: 10n, mask: 0n },
|
||||||
|
{ id: '{u', time: 311n, cmd: 30, value: 0x00000000000f0000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 311n, cmd: 30, value: 11n, mask: 0n },
|
||||||
|
{ id: '{u', time: 312n, cmd: 30, value: 0x000000000000f000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 312n, cmd: 30, value: 12n, mask: 0n },
|
||||||
|
{ id: '{u', time: 313n, cmd: 30, value: 0x0000000000000f00n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 313n, cmd: 30, value: 13n, mask: 0n },
|
||||||
|
{ id: '{u', time: 314n, cmd: 30, value: 0x00000000000000f0n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 314n, cmd: 30, value: 14n, mask: 0n },
|
||||||
|
{ id: '{u', time: 315n, cmd: 30, value: 0x000000000000000fn, mask: 0n },
|
||||||
|
{ id: 'u)', time: 315n, cmd: 30, value: 15n, mask: 0n },
|
||||||
|
{ id: '"}G', time: 316n, cmd: 15, value: 1n, mask: 0n }
|
||||||
|
];
|
||||||
|
|
||||||
it('simple', done => {
|
describe('napi dump', function () {
|
||||||
const inst = parser();
|
it('simple napi', done => {
|
||||||
const dump = [];
|
fs.readFile(path.join(__dirname, 'dump.vcd'), function (err, src) {
|
||||||
['"}G', '{u', 'u)'] // array of all signal ids
|
if (err) {
|
||||||
.map(id =>
|
throw new Error(err);
|
||||||
inst.change.on(id, (time, cmd, value, mask) => {
|
}
|
||||||
dump.push({
|
const inst = parser();
|
||||||
id,
|
const dump = [];
|
||||||
time,
|
['"}G', '{u', 'u)'] // array of all signal ids
|
||||||
cmd,
|
.map(id =>
|
||||||
value,
|
inst.change.on(id, (time, cmd, value, mask) => {
|
||||||
mask
|
const row = {
|
||||||
});
|
id,
|
||||||
})
|
time: BigInt(time),
|
||||||
);
|
cmd,
|
||||||
|
value,
|
||||||
|
mask
|
||||||
|
};
|
||||||
|
dump.push(row);
|
||||||
|
// console.log(row);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
inst.on('finish', () => {
|
inst.on('finish', () => {
|
||||||
expect(inst.getTime()).to.eq(316n);
|
expect(inst.getTime()).to.eq(316n);
|
||||||
expect(dump).to.deep.eq([
|
expect(dump).to.deep.eq(expectaitions);
|
||||||
{ id: '"}G', time: 100, cmd: 14, value: 0n, mask: 0n },
|
done();
|
||||||
{ id: '"}G', time: 200, cmd: 15, value: 1n, mask: 0n },
|
});
|
||||||
{ id: '{u', time: 200, cmd: 30, value: 0xf0f0f0f0f0f0f0f0n, mask: 0xff00ff00ff00ff00n },
|
|
||||||
{ id: '"}G', time: 300, cmd: 14, value: 0n, mask: 0n },
|
for (const chunk of chopper(src, 100)) {
|
||||||
{ id: '{u', time: 300, cmd: 30, value: 0xf000000000000000n, mask: 0n },
|
// console.log('\u001b[31m[\u001b[0m' + chunk.toString() + '\u001b[31m]\u001b[0m');
|
||||||
{ id: '{u', time: 301, cmd: 30, value: 0x0f00000000000000n, mask: 0n },
|
inst.write(chunk);
|
||||||
{ id: '{u', time: 302, cmd: 30, value: 0x00f0000000000000n, mask: 0n },
|
}
|
||||||
{ id: '{u', time: 303, cmd: 30, value: 0x000f000000000000n, mask: 0n },
|
inst.end();
|
||||||
{ id: '{u', time: 304, cmd: 30, value: 0x0000f00000000000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 305, cmd: 30, value: 0x00000f0000000000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 306, cmd: 30, value: 0x000000f000000000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 307, cmd: 30, value: 0x0000000f00000000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 308, cmd: 31, value: 0x00000000f0000000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 309, cmd: 30, value: 0x000000000f000000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 310, cmd: 30, value: 0x0000000000f00000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 311, cmd: 30, value: 0x00000000000f0000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 312, cmd: 30, value: 0x000000000000f000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 313, cmd: 30, value: 0x0000000000000f00n, mask: 0n },
|
|
||||||
{ id: '{u', time: 314, cmd: 30, value: 0x00000000000000f0n, mask: 0n },
|
|
||||||
{ id: '{u', time: 315, cmd: 30, value: 0x000000000000000fn, mask: 0n },
|
|
||||||
{ id: '"}G', time: 316, cmd: 15, value: 1n, mask: 0n }
|
|
||||||
]);
|
|
||||||
// console.log(dump);
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
inst.write(`
|
|
||||||
$version Generated by VerilatedVcd $end
|
|
||||||
$date Wed Sep 18 22:59:07 2019
|
|
||||||
$end
|
|
||||||
$timescale 1ns $end
|
|
||||||
|
|
||||||
$scope module top $end
|
|
||||||
$var wire 1 "}G clock $end
|
|
||||||
$scope module leaf $end
|
|
||||||
$var wire 64 {u counter [63:0] $end
|
|
||||||
$upscope $end
|
|
||||||
$scope module fruit $end
|
|
||||||
$var wire 4 u) point [3:0] $end
|
|
||||||
$upscope $end
|
|
||||||
$upscope $end
|
|
||||||
|
|
||||||
$enddefinitions $end
|
|
||||||
#100
|
|
||||||
0"}G
|
|
||||||
#200
|
|
||||||
1"}G
|
|
||||||
bzzzzxxxx11110000ZZZZXXXX11110000zzzzxxx`);
|
|
||||||
|
|
||||||
// break in the middle of the number scan
|
|
||||||
|
|
||||||
inst.write(`x11110000zzzzxxxx11110000 {u
|
|
||||||
#300
|
|
||||||
0"}G
|
|
||||||
b1111000000000000000000000000000000000000000000000000000000000000 {u
|
|
||||||
#301
|
|
||||||
b0000111100000000000000000000000000000000000000000000000000000000 {u
|
|
||||||
#302
|
|
||||||
b0000000011110000000000000000000000000000000000000000000000000000 {u
|
|
||||||
#303
|
|
||||||
b0000000000001111000000000000000000000000000000000000000000000000 {u
|
|
||||||
#304
|
|
||||||
b0000000000000000111100000000000000000000000000000000000000000000 {u
|
|
||||||
#305
|
|
||||||
b0000000000000000000011110000000000000000000000000000000000000000 {u
|
|
||||||
#306
|
|
||||||
b0000000000000000000000001111000000000000000000000000000000000000 {u
|
|
||||||
#307
|
|
||||||
b0000000000000000000000000000111100000000000000000000000000000000 {u
|
|
||||||
#308
|
|
||||||
B0000000000000000000000000000000011110000000000000000000000000000 {u
|
|
||||||
#309
|
|
||||||
b0000000000000000000000000000000000001111000000000000000000000000 {u
|
|
||||||
#310
|
|
||||||
b0000000000000000000000000000000000000000111100000000000000000000 {u
|
|
||||||
#311
|
|
||||||
b0000000000000000000000000000000000000000000011110000000000000000 {u
|
|
||||||
#312
|
|
||||||
b0000000000000000000000000000000000000000000000001111000000000000 {u
|
|
||||||
#313
|
|
||||||
b0000000000000000000000000000000000000000000000000000111100000000 {u
|
|
||||||
#314
|
|
||||||
b0000000000000000000000000000000000000000000000000000000011110000 {u
|
|
||||||
#315
|
|
||||||
b0000000000000000000000000000000000000000000000000000000000001111 {u
|
|
||||||
#316
|
|
||||||
1"}G
|
|
||||||
`);
|
|
||||||
inst.end();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,120 +1,92 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
const expect = require('chai').expect;
|
const expect = require('chai').expect;
|
||||||
const createVCD = require('../out/vcd.js');
|
const createVCD = require('../out/vcd.js');
|
||||||
const webVcdParser = require('../lib/web-vcd-parser.js');
|
const webVcdParser = require('../lib/web-vcd-parser.js');
|
||||||
|
const chopper = require('../lib/chopper.js');
|
||||||
|
|
||||||
describe('wasm dump', function () {
|
const expectaitions = [
|
||||||
|
{ id: '"}G', time: 100n, cmd: 14, value: 0n, mask: 0n },
|
||||||
|
{ id: '"}G', time: 200n, cmd: 15, value: 1n, mask: 0n },
|
||||||
|
{ id: '{u', time: 200n, cmd: 30, value: 0xf0f0f0f0f0f0f0f0n, mask: 0xff00ff00ff00ff00n },
|
||||||
|
{ id: '"}G', time: 300n, cmd: 14, value: 0n, mask: 0n },
|
||||||
|
{ id: '{u', time: 300n, cmd: 30, value: 0xf000000000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 300n, cmd: 30, value: 0n, mask: 0n },
|
||||||
|
{ id: '{u', time: 301n, cmd: 30, value: 0x0f00000000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 301n, cmd: 30, value: 1n, mask: 0n },
|
||||||
|
{ id: '{u', time: 302n, cmd: 30, value: 0x00f0000000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 302n, cmd: 30, value: 2n, mask: 0n },
|
||||||
|
{ id: '{u', time: 303n, cmd: 30, value: 0x000f000000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 303n, cmd: 30, value: 3n, mask: 0n },
|
||||||
|
{ id: '{u', time: 304n, cmd: 30, value: 0x0000f00000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 304n, cmd: 30, value: 4n, mask: 0n },
|
||||||
|
{ id: '{u', time: 305n, cmd: 30, value: 0x00000f0000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 305n, cmd: 30, value: 5n, mask: 0n },
|
||||||
|
{ id: '{u', time: 306n, cmd: 30, value: 0x000000f000000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 306n, cmd: 30, value: 6n, mask: 0n },
|
||||||
|
{ id: '{u', time: 307n, cmd: 30, value: 0x0000000f00000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 307n, cmd: 30, value: 7n, mask: 0n },
|
||||||
|
{ id: '{u', time: 308n, cmd: 31, value: 0x00000000f0000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 308n, cmd: 30, value: 8n, mask: 0n },
|
||||||
|
{ id: '{u', time: 309n, cmd: 30, value: 0x000000000f000000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 309n, cmd: 30, value: 9n, mask: 0n },
|
||||||
|
{ id: '{u', time: 310n, cmd: 30, value: 0x0000000000f00000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 310n, cmd: 30, value: 10n, mask: 0n },
|
||||||
|
{ id: '{u', time: 311n, cmd: 30, value: 0x00000000000f0000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 311n, cmd: 30, value: 11n, mask: 0n },
|
||||||
|
{ id: '{u', time: 312n, cmd: 30, value: 0x000000000000f000n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 312n, cmd: 30, value: 12n, mask: 0n },
|
||||||
|
{ id: '{u', time: 313n, cmd: 30, value: 0x0000000000000f00n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 313n, cmd: 30, value: 13n, mask: 0n },
|
||||||
|
{ id: '{u', time: 314n, cmd: 30, value: 0x00000000000000f0n, mask: 0n },
|
||||||
|
{ id: 'u)', time: 314n, cmd: 30, value: 14n, mask: 0n },
|
||||||
|
{ id: '{u', time: 315n, cmd: 30, value: 0x000000000000000fn, mask: 0n },
|
||||||
|
{ id: 'u)', time: 315n, cmd: 30, value: 15n, mask: 0n },
|
||||||
|
{ id: '"}G', time: 316n, cmd: 15, value: 1n, mask: 0n }
|
||||||
|
];
|
||||||
|
|
||||||
it('simple wasm', function (done) {
|
describe('wasm dump', () => {
|
||||||
createVCD().then(function (mod) {
|
it('simple wasm', done => {
|
||||||
webVcdParser(mod).then(function (inst) {
|
fs.readFile(path.join(__dirname, 'dump.vcd'), function (err, src) {
|
||||||
const dump = [];
|
if (err) {
|
||||||
['"}G', '{u', 'u)'] // array of all signal ids
|
throw new Error(err);
|
||||||
.map(id =>
|
}
|
||||||
inst.change.on(id, (time, cmd, value, mask) => {
|
createVCD().then((mod) => {
|
||||||
dump.push({
|
webVcdParser(mod).then((inst) => {
|
||||||
id,
|
const dump = [];
|
||||||
time,
|
['"}G', '{u', 'u)'] // array of all signal ids
|
||||||
cmd,
|
.map(id =>
|
||||||
value,
|
inst.change.on(id, (time, cmd, value, mask) => {
|
||||||
mask
|
const row = {
|
||||||
});
|
id,
|
||||||
})
|
time,
|
||||||
);
|
cmd,
|
||||||
|
value,
|
||||||
|
mask
|
||||||
|
};
|
||||||
|
dump.push(row);
|
||||||
|
// console.log(row);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
inst.on('finish', () => {
|
inst.on('finish', () => {
|
||||||
// expect(inst.getTime()).to.eq(316n);
|
expect(inst.getTime()).to.eq(316n);
|
||||||
expect(dump).to.deep.eq([
|
// console.log(dump);
|
||||||
{ id: '"}G', time: 100n, cmd: 14, value: 0n, mask: 0n },
|
// expect(dump.length).to.eq(expectaitions.length);
|
||||||
{ id: '"}G', time: 200n, cmd: 15, value: 1n, mask: 0n },
|
expect(dump).to.deep.eq(expectaitions);
|
||||||
{ id: '{u', time: 200n, cmd: 30, value: 0xf0f0f0f0f0f0f0f0n, mask: 0xff00ff00ff00ff00n },
|
done();
|
||||||
{ id: '"}G', time: 300n, cmd: 14, value: 0n, mask: 0n },
|
});
|
||||||
{ id: '{u', time: 300n, cmd: 30, value: 0xf000000000000000n, mask: 0n },
|
const step = (Math.random() * 500) |0;
|
||||||
{ id: '{u', time: 301n, cmd: 30, value: 0x0f00000000000000n, mask: 0n },
|
for (const chunk of chopper(src, step)) {
|
||||||
{ id: '{u', time: 302n, cmd: 30, value: 0x00f0000000000000n, mask: 0n },
|
// console.log('\n\u001b[31m[\u001b[0m' + chunk.toString() + '\u001b[31m](\u001b[0m\n' + chunk.length + '\u001b[31m)\u001b[0m\n');
|
||||||
{ id: '{u', time: 303n, cmd: 30, value: 0x000f000000000000n, mask: 0n },
|
inst.write(chunk);
|
||||||
{ id: '{u', time: 304n, cmd: 30, value: 0x0000f00000000000n, mask: 0n },
|
}
|
||||||
{ id: '{u', time: 305n, cmd: 30, value: 0x00000f0000000000n, mask: 0n },
|
inst.end();
|
||||||
{ id: '{u', time: 306n, cmd: 30, value: 0x000000f000000000n, mask: 0n },
|
// console.log(step);
|
||||||
{ id: '{u', time: 307n, cmd: 30, value: 0x0000000f00000000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 308n, cmd: 31, value: 0x00000000f0000000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 309n, cmd: 30, value: 0x000000000f000000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 310n, cmd: 30, value: 0x0000000000f00000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 311n, cmd: 30, value: 0x00000000000f0000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 312n, cmd: 30, value: 0x000000000000f000n, mask: 0n },
|
|
||||||
{ id: '{u', time: 313n, cmd: 30, value: 0x0000000000000f00n, mask: 0n },
|
|
||||||
{ id: '{u', time: 314n, cmd: 30, value: 0x00000000000000f0n, mask: 0n },
|
|
||||||
{ id: '{u', time: 315n, cmd: 30, value: 0x000000000000000fn, mask: 0n },
|
|
||||||
{ id: '"}G', time: 316n, cmd: 15, value: 1n, mask: 0n }
|
|
||||||
]);
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
inst.write(`
|
|
||||||
$version Generated by VerilatedVcd $end
|
|
||||||
$date Wed Sep 18 22:59:07 2019
|
|
||||||
$end
|
|
||||||
$timescale 1ns $end
|
|
||||||
|
|
||||||
$scope module top $end
|
|
||||||
$var wire 1 "}G clock $end
|
|
||||||
$scope module leaf $end
|
|
||||||
$var wire 64 {u counter [63:0] $end
|
|
||||||
$upscope $end
|
|
||||||
$scope module fruit $end
|
|
||||||
$var wire 4 u) point [3:0] $end
|
|
||||||
$upscope $end
|
|
||||||
$upscope $end
|
|
||||||
|
|
||||||
$enddefinitions $end
|
|
||||||
#100
|
|
||||||
0"}G
|
|
||||||
#200
|
|
||||||
1"}G
|
|
||||||
bzzzzxxxx11110000ZZZZXXXX11110000zzzzxxx`);
|
|
||||||
|
|
||||||
// break in the middle of the number scan
|
|
||||||
|
|
||||||
inst.write(`x11110000zzzzxxxx11110000 {u
|
|
||||||
#300
|
|
||||||
0"}G
|
|
||||||
b1111000000000000000000000000000000000000000000000000000000000000 {u
|
|
||||||
#301
|
|
||||||
b0000111100000000000000000000000000000000000000000000000000000000 {u
|
|
||||||
#302
|
|
||||||
b0000000011110000000000000000000000000000000000000000000000000000 {u
|
|
||||||
#303
|
|
||||||
b0000000000001111000000000000000000000000000000000000000000000000 {u
|
|
||||||
#304
|
|
||||||
b0000000000000000111100000000000000000000000000000000000000000000 {u
|
|
||||||
#305
|
|
||||||
b0000000000000000000011110000000000000000000000000000000000000000 {u
|
|
||||||
#306
|
|
||||||
b0000000000000000000000001111000000000000000000000000000000000000 {u
|
|
||||||
#307
|
|
||||||
b0000000000000000000000000000111100000000000000000000000000000000 {u
|
|
||||||
#308
|
|
||||||
B0000000000000000000000000000000011110000000000000000000000000000 {u
|
|
||||||
#309
|
|
||||||
b0000000000000000000000000000000000001111000000000000000000000000 {u
|
|
||||||
#310
|
|
||||||
b0000000000000000000000000000000000000000111100000000000000000000 {u
|
|
||||||
#311
|
|
||||||
b0000000000000000000000000000000000000000000011110000000000000000 {u
|
|
||||||
#312
|
|
||||||
b0000000000000000000000000000000000000000000000001111000000000000 {u
|
|
||||||
#313
|
|
||||||
b0000000000000000000000000000000000000000000000000000111100000000 {u
|
|
||||||
#314
|
|
||||||
b0000000000000000000000000000000000000000000000000000000011110000 {u
|
|
||||||
#315
|
|
||||||
b0000000000000000000000000000000000000000000000000000000000001111 {u
|
|
||||||
#316
|
|
||||||
1"}G
|
|
||||||
`);
|
|
||||||
inst.end();
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
10
vcd.c
10
vcd.c
@ -123,9 +123,11 @@ METHOD(init) {
|
|||||||
ASSERT_FUNCTION(args[1], state->triee)
|
ASSERT_FUNCTION(args[1], state->triee)
|
||||||
ASSERT_OBJECT(args[2], state->info)
|
ASSERT_OBJECT(args[2], state->info)
|
||||||
|
|
||||||
static char triggerString [4096] = " ";
|
static char triggerString [4096] = {0};
|
||||||
static char tmpStr [4096] = " ";
|
static char tmpStr [4096] = {0};
|
||||||
static char tmpStr2 [4096] = " ";
|
static char tmpStr2 [4096] = {0};
|
||||||
|
static char timeStampStr [4096] = {0};
|
||||||
|
static char idStr [4096] = {0};
|
||||||
static uint64_t valueBuf [4096] = {};
|
static uint64_t valueBuf [4096] = {};
|
||||||
static uint64_t maskBuf [4096] = {};
|
static uint64_t maskBuf [4096] = {};
|
||||||
|
|
||||||
@ -134,6 +136,8 @@ METHOD(init) {
|
|||||||
state->napi_env = env;
|
state->napi_env = env;
|
||||||
state->tmpStr = tmpStr;
|
state->tmpStr = tmpStr;
|
||||||
state->tmpStr2 = tmpStr2;
|
state->tmpStr2 = tmpStr2;
|
||||||
|
state->timeStampStr = timeStampStr;
|
||||||
|
state->idStr = idStr;
|
||||||
state->value = valueBuf;
|
state->value = valueBuf;
|
||||||
state->mask = maskBuf;
|
state->mask = maskBuf;
|
||||||
state->time = INT64_MAX;
|
state->time = INT64_MAX;
|
||||||
|
75
vcd_spans.c
75
vcd_spans.c
@ -25,7 +25,7 @@ typedef void* napi_env;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void strcopy(const unsigned char* p, const unsigned char* endp, unsigned char* dst) {
|
void strcopy(const unsigned char* p, const unsigned char* endp, unsigned char* dst) {
|
||||||
unsigned char* src;
|
const unsigned char* src;
|
||||||
src = p;
|
src = p;
|
||||||
while (src < (endp - 1)) {
|
while (src < (endp - 1)) {
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
@ -35,40 +35,52 @@ void strcopy(const unsigned char* p, const unsigned char* endp, unsigned char* d
|
|||||||
*dst = 0;
|
*dst = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void strconcat(const unsigned char* p, const unsigned char* endp, unsigned char* dst) {
|
||||||
|
// printf("<len:%d>", endp - p);
|
||||||
|
dst += strlen((char *)dst); // go to the end of string
|
||||||
|
while (p < endp) {
|
||||||
|
*dst = *p;
|
||||||
|
p++;
|
||||||
|
dst++;
|
||||||
|
}
|
||||||
|
*dst = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME use a better structure to match strings
|
// FIXME use a better structure to match strings
|
||||||
int stringEq (
|
int stringEq (
|
||||||
const unsigned char* gold, // search pattern
|
const unsigned char* i, // search pattern
|
||||||
const unsigned char* p,
|
const unsigned char* p,
|
||||||
const unsigned char* endp
|
const unsigned char* endp
|
||||||
) {
|
) {
|
||||||
if (gold[0] == 0) {
|
if (*i == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
unsigned char* i;
|
const unsigned char* j;
|
||||||
unsigned char* j;
|
|
||||||
i = gold;
|
|
||||||
j = p;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (*i == ' ') { // end of search pattern
|
j = p;
|
||||||
|
// printf("(%s|%s)", (char *)i, (char *)j);
|
||||||
|
if (*i == 0) { // end of search pattern
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
while (*i == *j) { // follow matching trail
|
while (*i == *j) { // follow matching trail
|
||||||
|
if (*i == 0 && *j == 0) { // match zeros
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
if ((*i == ' ') && (j == (endp - 1))) { // exact match
|
while (*i != 0) { // skip to the end of pattern word
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
while (*i != ' ') { // skip to the end of pattern word
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
j = p; // try another word
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
|
|
||||||
|
#ifndef VCDWASM
|
||||||
napi_env env = state->napi_env;
|
napi_env env = state->napi_env;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (state->command == 5) { // $upscope
|
if (state->command == 5) { // $upscope
|
||||||
state->stackPointer -= 1;
|
state->stackPointer -= 1;
|
||||||
@ -100,6 +112,8 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state->command == 8) { // $enddefinitions
|
if (state->command == 8) { // $enddefinitions
|
||||||
|
*(char *)state->idStr = 0;
|
||||||
|
*(char *)state->timeStampStr = 0;
|
||||||
#ifndef VCDWASM
|
#ifndef VCDWASM
|
||||||
napi_value status, undefined, eventName, eventPayload, return_val;
|
napi_value status, undefined, eventName, eventPayload, return_val;
|
||||||
ASSERT(status, napi_create_string_latin1(env, "simulation", NAPI_AUTO_LENGTH, &status))
|
ASSERT(status, napi_create_string_latin1(env, "simulation", NAPI_AUTO_LENGTH, &status))
|
||||||
@ -191,15 +205,27 @@ int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char
|
|||||||
}
|
}
|
||||||
|
|
||||||
int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
|
strconcat(p, endp, state->idStr);
|
||||||
|
// printf("<idSpan|%s>\n", (char *)state->idStr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int onId (vcd_parser_t* state, const unsigned char* _p, const unsigned char* _endp) {
|
||||||
#ifndef VCDWASM
|
#ifndef VCDWASM
|
||||||
napi_env env = state->napi_env;
|
napi_env env = state->napi_env;
|
||||||
#endif
|
#endif
|
||||||
|
const unsigned char* p = (char *)state->idStr;
|
||||||
|
const unsigned int plen = strlen((char *)p) - 1;
|
||||||
|
*(char *)(p + plen) = 0; // null instead of space
|
||||||
|
const unsigned char* endp = p + plen - 1;
|
||||||
|
// printf("<onId|%s>\n", (char *)state->idStr);
|
||||||
|
|
||||||
const int valueWords = (state->digitCount >> 6) + 1;
|
const int valueWords = (state->digitCount >> 6) + 1;
|
||||||
uint64_t* value = state->value;
|
uint64_t* value = state->value;
|
||||||
uint64_t* mask = state->mask;
|
uint64_t* mask = state->mask;
|
||||||
if (stringEq((state->trigger), p, endp)) {
|
if (stringEq((state->trigger), p, endp)) {
|
||||||
const uint8_t command = state->command;
|
const uint8_t command = state->command;
|
||||||
|
// printf("{id:'%s',cmd:%d}", (char *)p, command);
|
||||||
if (command == 14) {
|
if (command == 14) {
|
||||||
value[0] = 0;
|
value[0] = 0;
|
||||||
mask[0] = 0;
|
mask[0] = 0;
|
||||||
@ -211,17 +237,17 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end
|
|||||||
#ifndef VCDWASM
|
#ifndef VCDWASM
|
||||||
napi_value undefined, eventName, aTime, aCommand, aValue, aMask, return_val;
|
napi_value undefined, eventName, aTime, aCommand, aValue, aMask, return_val;
|
||||||
ASSERT(undefined, napi_get_undefined(env, &undefined))
|
ASSERT(undefined, napi_get_undefined(env, &undefined))
|
||||||
ASSERT(eventName, napi_create_string_latin1(env, (char*)p, (endp - p - 1), &eventName))
|
ASSERT(eventName, napi_create_string_latin1(env, (char*)p, NAPI_AUTO_LENGTH, &eventName))
|
||||||
ASSERT(aTime, napi_create_int64(env, state->time, &aTime))
|
ASSERT(aTime, napi_create_int64(env, state->time, &aTime))
|
||||||
ASSERT(aCommand, napi_create_int32(env, command, &aCommand))
|
ASSERT(aCommand, napi_create_int32(env, command, &aCommand))
|
||||||
ASSERT(aValue, napi_create_bigint_words(env, 0, valueWords, value, &aValue))
|
ASSERT(aValue, napi_create_bigint_words(env, 0, valueWords, value, &aValue))
|
||||||
ASSERT(aMask, napi_create_bigint_words(env, 0, valueWords, mask, &aMask))
|
ASSERT(aMask, napi_create_bigint_words(env, 0, valueWords, mask, &aMask))
|
||||||
napi_value* argv[] = {&eventName, &aTime, &aCommand, &aValue, &aMask};
|
napi_value* argv[] = {&eventName, &aTime, &aCommand, &aValue, &aMask};
|
||||||
ASSERT(state->triee, napi_call_function(env, undefined, state->triee, 5, *argv, &return_val))
|
ASSERT(state->triee, napi_call_function(env, undefined, state->triee, 5, *argv, &return_val))
|
||||||
|
// printf("<id='%s'>", (char *)p);
|
||||||
#else
|
#else
|
||||||
strcopy(p, endp, state->tmpStr);
|
// strcopy(p, endp, state->tmpStr);
|
||||||
emit_triee(state->tmpStr, state->time, command, valueWords, value, mask);
|
emit_triee((char *)p, state->time, command, valueWords, value, mask);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
for (int i = 0; i < valueWords; i++) {
|
for (int i = 0; i < valueWords; i++) {
|
||||||
@ -229,9 +255,12 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end
|
|||||||
mask[i] = 0;
|
mask[i] = 0;
|
||||||
}
|
}
|
||||||
state->digitCount = 0;
|
state->digitCount = 0;
|
||||||
|
*(char *)state->idStr = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int onDigit(
|
int onDigit(
|
||||||
vcd_parser_t* state,
|
vcd_parser_t* state,
|
||||||
const unsigned char* p,
|
const unsigned char* p,
|
||||||
@ -270,8 +299,17 @@ int onRecover(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int timeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
int timeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
int64_t time = strtoul((const char *)p, (char **)&endp, 10);
|
strconcat(p, endp, state->timeStampStr);
|
||||||
|
// printf("<timeSpan|%s>\n", (char *)state->timeStampStr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int onTime (vcd_parser_t* state, const unsigned char* _p, const unsigned char* _endp) {
|
||||||
|
char *end;
|
||||||
|
const int64_t time = strtoul(state->timeStampStr, &end, 10);
|
||||||
|
// printf("<onTime|%lu>\n", time);
|
||||||
if (state->time == INT64_MAX) {
|
if (state->time == INT64_MAX) {
|
||||||
#ifndef VCDWASM
|
#ifndef VCDWASM
|
||||||
napi_env env = state->napi_env;
|
napi_env env = state->napi_env;
|
||||||
@ -283,5 +321,6 @@ int timeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* e
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
state->time = time;
|
state->time = time;
|
||||||
|
*(char *)state->timeStampStr = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -123,9 +123,11 @@ int init(
|
|||||||
state->lifee = 0;
|
state->lifee = 0;
|
||||||
state->triee = 0;
|
state->triee = 0;
|
||||||
|
|
||||||
static char triggerString [4096] = " ";
|
static char triggerString [4096] = {0};
|
||||||
static char tmpStr [4096] = " ";
|
static char tmpStr [4096] = {0};
|
||||||
static char tmpStr2 [4096] = " ";
|
static char tmpStr2 [4096] = {0};
|
||||||
|
static char timeStampStr [4096] = {0};
|
||||||
|
static char idStr [4096] = {0};
|
||||||
static uint64_t valueBuf [4096] = {};
|
static uint64_t valueBuf [4096] = {};
|
||||||
static uint64_t maskBuf [4096] = {};
|
static uint64_t maskBuf [4096] = {};
|
||||||
|
|
||||||
@ -134,10 +136,12 @@ int init(
|
|||||||
state->napi_env = 0;
|
state->napi_env = 0;
|
||||||
state->tmpStr = tmpStr;
|
state->tmpStr = tmpStr;
|
||||||
state->tmpStr2 = tmpStr2;
|
state->tmpStr2 = tmpStr2;
|
||||||
|
state->timeStampStr = timeStampStr;
|
||||||
|
state->idStr = idStr;
|
||||||
state->value = valueBuf;
|
state->value = valueBuf;
|
||||||
state->mask = maskBuf;
|
state->mask = maskBuf;
|
||||||
state->digitCount = 0;
|
|
||||||
state->time = INT64_MAX;
|
state->time = INT64_MAX;
|
||||||
|
state->digitCount = 0;
|
||||||
|
|
||||||
set_property_string("status", "declaration");
|
set_property_string("status", "declaration");
|
||||||
|
|
||||||
@ -157,7 +161,8 @@ int32_t execute(
|
|||||||
externalJsMethodOne* f1,
|
externalJsMethodOne* f1,
|
||||||
externalJsSetProperty* sfn,
|
externalJsSetProperty* sfn,
|
||||||
externalJsGetProperty* gfn,
|
externalJsGetProperty* gfn,
|
||||||
char* p
|
char* p,
|
||||||
|
const int plen
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// cout << "execute got " << p << "\n";
|
// cout << "execute got " << p << "\n";
|
||||||
@ -167,7 +172,9 @@ int32_t execute(
|
|||||||
externalZero = f0;
|
externalZero = f0;
|
||||||
externalOne = f1;
|
externalOne = f1;
|
||||||
|
|
||||||
const size_t plen = strlen(p);
|
// const size_t plen = strlen(p);
|
||||||
|
// printf("<chunk len|%d>\n", plen);
|
||||||
|
|
||||||
|
|
||||||
const int32_t error = vcd_parser_execute(state, p, p + plen);
|
const int32_t error = vcd_parser_execute(state, p, p + plen);
|
||||||
|
|
||||||
@ -175,9 +182,18 @@ int32_t execute(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int setTrigger(const int context, char* triggerString) {
|
int setTrigger(const int context, char* triggerString) {
|
||||||
state->trigger = malloc(strlen(triggerString));
|
int triggerStringLen = strlen((char *)triggerString) - 1;
|
||||||
strcpy((char*)state->trigger, triggerString);
|
// state->trigger = malloc(strlen(triggerString));
|
||||||
// cout << "setTrigger() got " << triggerString << "\n";
|
char* p = (char *)state->tmpStr;
|
||||||
|
for (int i = 0; i < triggerStringLen; i++) {
|
||||||
|
char c = *(triggerString + i);
|
||||||
|
if (c == 32) {
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
*(p + i) = c;
|
||||||
|
}
|
||||||
|
// strcpy((char*)state->trigger, triggerString);
|
||||||
|
// cout << "[" << triggerString << "|" << p << "\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user