new way of handling scope/vars
This commit is contained in:
parent
f9d7687532
commit
5c5126c019
118
bin/build.js
118
bin/build.js
@ -58,13 +58,12 @@ const generate = (cb) => {
|
|||||||
Object.keys(properties).map(key => p.property(properties[key], key));
|
Object.keys(properties).map(key => p.property(properties[key], key));
|
||||||
|
|
||||||
const {
|
const {
|
||||||
scopeIdentifierSpan,
|
// scopeIdentifierSpan,
|
||||||
varSizeSpan, varIdSpan, varNameSpan,
|
varSizeSpan, varIdSpan, varNameSpan,
|
||||||
idSpan,
|
idSpan,
|
||||||
commandSpan,
|
commandSpan,
|
||||||
timeSpan
|
timeSpan
|
||||||
} = `
|
} = `
|
||||||
scopeIdentifierSpan
|
|
||||||
varSizeSpan varIdSpan varNameSpan
|
varSizeSpan varIdSpan varNameSpan
|
||||||
idSpan
|
idSpan
|
||||||
commandSpan
|
commandSpan
|
||||||
@ -73,10 +72,12 @@ const generate = (cb) => {
|
|||||||
.trim().split(/\s+/)
|
.trim().split(/\s+/)
|
||||||
.reduce((res, n) => Object.assign(res, {[n]: p.span(p.code.span(n))}), {});
|
.reduce((res, n) => Object.assign(res, {[n]: p.span(p.code.span(n))}), {});
|
||||||
|
|
||||||
|
// scopeIdentifierSpan
|
||||||
|
|
||||||
const {
|
const {
|
||||||
declaration,
|
declaration,
|
||||||
scopeType, scopeTypeEnd,
|
// scopeType, scopeTypeEnd,
|
||||||
scopeIdentifier, scopeIdentifierEnd,
|
// scopeIdentifier, scopeIdentifierEnd,
|
||||||
varType, varTypeEnd,
|
varType, varTypeEnd,
|
||||||
varSize, varSizeEnd,
|
varSize, varSizeEnd,
|
||||||
varId, varIdEnd,
|
varId, varIdEnd,
|
||||||
@ -89,8 +90,6 @@ const generate = (cb) => {
|
|||||||
simulationId
|
simulationId
|
||||||
} = `
|
} = `
|
||||||
declaration
|
declaration
|
||||||
scopeType scopeTypeEnd
|
|
||||||
scopeIdentifier scopeIdentifierEnd
|
|
||||||
varType varTypeEnd
|
varType varTypeEnd
|
||||||
varSize varSizeEnd
|
varSize varSizeEnd
|
||||||
varId varIdEnd
|
varId varIdEnd
|
||||||
@ -105,6 +104,9 @@ const generate = (cb) => {
|
|||||||
.trim().split(/\s+/)
|
.trim().split(/\s+/)
|
||||||
.reduce((res, n) => Object.assign(res, {[n]: p.node(n)}), {});
|
.reduce((res, n) => Object.assign(res, {[n]: p.node(n)}), {});
|
||||||
|
|
||||||
|
// scopeType scopeTypeEnd
|
||||||
|
// scopeIdentifier scopeIdentifierEnd
|
||||||
|
|
||||||
const enddefinitions = p.node('inDeclarationEnd');
|
const enddefinitions = p.node('inDeclarationEnd');
|
||||||
|
|
||||||
const cmd = objection({
|
const cmd = objection({
|
||||||
@ -134,56 +136,50 @@ const generate = (cb) => {
|
|||||||
|
|
||||||
declaration
|
declaration
|
||||||
.match(spaces, declaration)
|
.match(spaces, declaration)
|
||||||
.select(cmd('$scope'),
|
// .select(cmd('$scope'),
|
||||||
p.invoke(p.code.store('command'), commandSpan.start(scopeType)))
|
// p.invoke(p.code.store('command'), commandSpan.start(scopeType)))
|
||||||
.select(cmd('$var'),
|
// .select(cmd('$var'),
|
||||||
p.invoke(p.code.store('command'), commandSpan.start(varType)))
|
// p.invoke(p.code.store('command'), commandSpan.start(varType)))
|
||||||
.select(cmd('$comment $date $timescale $upscope $version'),
|
.select(cmd('$scope $var $upscope $comment $date $timescale $version'),
|
||||||
p.invoke(p.code.store('command'), commandSpan.start(inDeclaration)))
|
p.invoke(p.code.store('command'), commandSpan.start(inDeclaration)))
|
||||||
.select(cmd('$enddefinitions'),
|
.select(cmd('$enddefinitions'),
|
||||||
p.invoke(p.code.store('command'), commandSpan.start(enddefinitions)))
|
p.invoke(p.code.store('command'), commandSpan.start(enddefinitions)))
|
||||||
.otherwise(p.error(1, 'Expected declaration command'));
|
.otherwise(p.error(1, 'Expected declaration command'));
|
||||||
|
|
||||||
// $scope
|
// $scope module clkdiv2n_tb $end
|
||||||
|
// ^^^^^^
|
||||||
|
|
||||||
scopeType
|
// scopeType.match(spaces, scopeType).otherwise(scopeTypeEnd);
|
||||||
.match(spaces, scopeType)
|
// scopeTypeEnd
|
||||||
.otherwise(scopeTypeEnd);
|
// .select(
|
||||||
|
// {
|
||||||
|
// module: 0,
|
||||||
|
// task: 1,
|
||||||
|
// function: 2,
|
||||||
|
// begin: 3,
|
||||||
|
// fork: 4,
|
||||||
|
// // extra scopes from Verilator
|
||||||
|
// generate: 5,
|
||||||
|
// struct: 6,
|
||||||
|
// union: 7,
|
||||||
|
// class: 8,
|
||||||
|
// interface: 9,
|
||||||
|
// package: 10,
|
||||||
|
// program: 11
|
||||||
|
// },
|
||||||
|
// p.invoke(p.code.store('type'), scopeIdentifier))
|
||||||
|
// .otherwise(p.error(2, 'Expected scope type'));
|
||||||
|
|
||||||
scopeTypeEnd
|
// $scope module clkdiv2n_tb $end
|
||||||
.select(
|
// ^^^^^^^^^^^
|
||||||
{
|
|
||||||
module: 0,
|
|
||||||
task: 1,
|
|
||||||
function: 2,
|
|
||||||
begin: 3,
|
|
||||||
fork: 4,
|
|
||||||
// extra scopes from Verilator
|
|
||||||
generate: 5,
|
|
||||||
struct: 6,
|
|
||||||
union: 7,
|
|
||||||
class: 8,
|
|
||||||
interface: 9,
|
|
||||||
package: 10,
|
|
||||||
program: 11
|
|
||||||
},
|
|
||||||
p.invoke(p.code.store('type'), scopeIdentifier))
|
|
||||||
.otherwise(p.error(2, 'Expected scope type'));
|
|
||||||
|
|
||||||
scopeIdentifier
|
// scopeIdentifier.match(spaces, scopeIdentifier).otherwise(scopeIdentifierSpan.start(scopeIdentifierEnd));
|
||||||
.match(spaces, scopeIdentifier)
|
// scopeIdentifierEnd.match(spaces, scopeIdentifierSpan.end(inDeclaration)).skipTo(scopeIdentifierEnd);
|
||||||
.otherwise(scopeIdentifierSpan.start(scopeIdentifierEnd));
|
|
||||||
|
|
||||||
scopeIdentifierEnd
|
// $var reg 3 ( r_reg [2:0] $end
|
||||||
.match(spaces, scopeIdentifierSpan.end(inDeclaration))
|
// ^^^
|
||||||
.skipTo(scopeIdentifierEnd);
|
|
||||||
|
|
||||||
// $var
|
|
||||||
|
|
||||||
varType
|
|
||||||
.match(spaces, varType)
|
|
||||||
.otherwise(varTypeEnd);
|
|
||||||
|
|
||||||
|
varType.match(spaces, varType).otherwise(varTypeEnd);
|
||||||
varTypeEnd
|
varTypeEnd
|
||||||
.select({
|
.select({
|
||||||
event: 1,
|
event: 1,
|
||||||
@ -207,29 +203,23 @@ const generate = (cb) => {
|
|||||||
}, p.invoke(p.code.store('type'), varSize))
|
}, p.invoke(p.code.store('type'), varSize))
|
||||||
.otherwise(p.error(3, 'Expected var type'));
|
.otherwise(p.error(3, 'Expected var type'));
|
||||||
|
|
||||||
varSize
|
// $var reg 3 ( r_reg [2:0] $end
|
||||||
.match(spaces, varSize)
|
// ^
|
||||||
.otherwise(varSizeSpan.start(varSizeEnd));
|
|
||||||
|
|
||||||
varSizeEnd
|
varSize.match(spaces, varSize).otherwise(varSizeSpan.start(varSizeEnd));
|
||||||
.match(spaces, varSizeSpan.end(varId))
|
varSizeEnd.match(spaces, varSizeSpan.end(varId)).skipTo(varSizeEnd);
|
||||||
.skipTo(varSizeEnd);
|
|
||||||
|
|
||||||
varId
|
// $var reg 3 ( r_reg [2:0] $end
|
||||||
.match(spaces, varId)
|
// ^
|
||||||
.otherwise(varIdSpan.start(varIdEnd));
|
|
||||||
|
|
||||||
varIdEnd
|
varId.match(spaces, varId).otherwise(varIdSpan.start(varIdEnd));
|
||||||
.match(spaces, varIdSpan.end(varName))
|
varIdEnd.match(spaces, varIdSpan.end(varName)).skipTo(varIdEnd);
|
||||||
.skipTo(varIdEnd);
|
|
||||||
|
|
||||||
varName
|
// $var reg 3 ( r_reg [2:0] $end
|
||||||
.match(spaces, varName)
|
// ^^^^^
|
||||||
.otherwise(varNameSpan.start(varNameEnd));
|
|
||||||
|
|
||||||
varNameEnd
|
varName.match(spaces, varName).otherwise(varNameSpan.start(varNameEnd));
|
||||||
.match(spaces, varNameSpan.end(inDeclaration))
|
varNameEnd.match('$end', commandSpan.end(varNameSpan.end(declaration))).skipTo(varNameEnd);
|
||||||
.skipTo(varNameEnd);
|
|
||||||
|
|
||||||
// $end
|
// $end
|
||||||
|
|
||||||
|
72
lib/command-handler.js
Normal file
72
lib/command-handler.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const handleScope = (info, str) => {
|
||||||
|
const [type, name] = str.split(/\s+/);
|
||||||
|
const ero = {kind: 'scope', type, name, body: []};
|
||||||
|
const current = info.stack[info.stack.length - 1];
|
||||||
|
current.body.push(ero);
|
||||||
|
info.stack.push(ero);
|
||||||
|
// console.log(ero);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpScope = (info /* , str */) => {
|
||||||
|
info.stack.pop();
|
||||||
|
// console.log(['upscope', str]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleVar = (info, str) => {
|
||||||
|
// reg 3 ( r_reg [2:0]
|
||||||
|
// 0 1 2 3+
|
||||||
|
const eroj = str.split(/\s+/);
|
||||||
|
const ero = {
|
||||||
|
kind: 'var',
|
||||||
|
type: eroj[0],
|
||||||
|
size: parseInt(eroj[1]),
|
||||||
|
link: eroj[2],
|
||||||
|
name: eroj.slice(3).join('')
|
||||||
|
};
|
||||||
|
{
|
||||||
|
const m = ero.name.match('^(?<name>\\w+)\\[' + (ero.size - 1) + ':0]$');
|
||||||
|
if (m) {
|
||||||
|
ero.name = m.groups.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const current = info.stack[info.stack.length - 1];
|
||||||
|
current.body.push(ero);
|
||||||
|
// console.log(ero);
|
||||||
|
};
|
||||||
|
|
||||||
|
const commandHandler = (info, cmd, str) => {
|
||||||
|
str = str.trim();
|
||||||
|
switch(cmd) {
|
||||||
|
case 1:
|
||||||
|
info.comment = str;
|
||||||
|
// console.log(['comment', str]);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
info.date = str;
|
||||||
|
// console.log(['date', str]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
handleScope(info, str);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
info.timescale = str;
|
||||||
|
// console.log(['timescale', str]);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
handleUpScope(info, str);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
handleVar(info, str);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
info.version = str;
|
||||||
|
// console.log(['version', str]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log([cmd, str]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = commandHandler;
|
@ -5,6 +5,8 @@ const EventEmitter = require('events').EventEmitter;
|
|||||||
|
|
||||||
const dotProp = require('dot-prop');
|
const dotProp = require('dot-prop');
|
||||||
|
|
||||||
|
const commandHandler = require('./command-handler.js');
|
||||||
|
|
||||||
// function _waitForStart(mod) {
|
// function _waitForStart(mod) {
|
||||||
// return new Promise((resolve)=>{
|
// return new Promise((resolve)=>{
|
||||||
// mod.addOnPostRun(resolve);
|
// mod.addOnPostRun(resolve);
|
||||||
@ -50,6 +52,7 @@ const bindCWrap = (c, wasm) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getWrapper = wasm => {
|
const getWrapper = wasm => {
|
||||||
|
// console.log(wasm);
|
||||||
|
|
||||||
const c = {};
|
const c = {};
|
||||||
|
|
||||||
@ -115,6 +118,7 @@ const getWrapper = wasm => {
|
|||||||
// console.log({name, time, command, 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));
|
||||||
|
|
||||||
@ -159,8 +163,13 @@ const getWrapper = wasm => {
|
|||||||
break;
|
break;
|
||||||
// path to path (any type)
|
// path to path (any type)
|
||||||
case 3:
|
case 3:
|
||||||
tmp = dotProp.get(boundInfo, getString(v0, v1));
|
tmp = getString(v0, v1)
|
||||||
// console.log(`for ${getString(v0, v1)} got ${tmp}, set to ${prop}`);
|
.split(',')
|
||||||
|
.map(e => dotProp.get(boundInfo, e));
|
||||||
|
if (tmp.length === 1) {
|
||||||
|
dotProp.set(boundInfo, prop, tmp[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
dotProp.set(boundInfo, prop, tmp);
|
dotProp.set(boundInfo, prop, tmp);
|
||||||
break;
|
break;
|
||||||
// create empty object at path
|
// create empty object at path
|
||||||
@ -168,7 +177,9 @@ const getWrapper = wasm => {
|
|||||||
// console.log(`${prop} is new {}`);
|
// console.log(`${prop} is new {}`);
|
||||||
dotProp.set(boundInfo, prop, {});
|
dotProp.set(boundInfo, prop, {});
|
||||||
break;
|
break;
|
||||||
|
case 5:
|
||||||
|
commandHandler(boundInfo, v0, prop);
|
||||||
|
break;
|
||||||
default: throw new Error();
|
default: throw new Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,9 +232,8 @@ module.exports = async wasm => {
|
|||||||
// console.log('getWrapper', lib);
|
// console.log('getWrapper', lib);
|
||||||
await lib.start();
|
await lib.start();
|
||||||
// console.log('vcd wasm srarted');
|
// console.log('vcd wasm srarted');
|
||||||
|
const wires = {kind: 'scope', type: '.', name: '.', body: []};
|
||||||
const wires = {};
|
const info = {stack: [wires], wires};
|
||||||
const info = {stack: [wires], wires: wires};
|
|
||||||
|
|
||||||
const s = new stream.Writable();
|
const s = new stream.Writable();
|
||||||
|
|
||||||
@ -245,7 +255,7 @@ 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(cxt, info);
|
// console.log('chunk:', chunk.length);
|
||||||
const err = lib.execute(cxt, lifemit, triemit2, info, chunk);
|
const err = lib.execute(cxt, lifemit, triemit2, info, chunk);
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
File diff suppressed because one or more lines are too long
BIN
out/vcd.wasm
BIN
out/vcd.wasm
Binary file not shown.
56
vcd_spans.c
56
vcd_spans.c
@ -77,41 +77,53 @@ int stringEq (
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
const uint8_t command = state->command;
|
||||||
#ifndef VCDWASM
|
#ifndef VCDWASM
|
||||||
napi_env env = state->napi_env;
|
napi_env env = state->napi_env;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (state->command == 5) { // $upscope
|
// if (command == 5) { // $upscope
|
||||||
state->stackPointer -= 1;
|
// state->stackPointer -= 1;
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(state->command == 1) || // $comment
|
(command == 1) || // $comment
|
||||||
(state->command == 2) || // $date
|
(command == 2) || // $date
|
||||||
(state->command == 4) || // $timescale
|
(command == 3) || // $scope
|
||||||
(state->command == 7) // $version
|
(command == 4) || // $timescale
|
||||||
|
(command == 5) || // $upscope
|
||||||
|
(command == 6) || // $var
|
||||||
|
(command == 7) // $version
|
||||||
) {
|
) {
|
||||||
char* key;
|
char* key;
|
||||||
switch(state->command) {
|
switch(command) {
|
||||||
case 1: key = "comment"; break;
|
case 1: key = "comment"; break;
|
||||||
case 2: key = "date"; break;
|
case 2: key = "date"; break;
|
||||||
case 4: key = "timescale"; break;
|
case 4: key = "timescale"; break;
|
||||||
|
// case 6: key = "var"; break;
|
||||||
case 7: key = "version"; break;
|
case 7: key = "version"; break;
|
||||||
}
|
}
|
||||||
#ifndef VCDWASM
|
|
||||||
napi_value val;
|
napi_value val;
|
||||||
ASSERT(val, napi_create_string_latin1(env, (char*)p, (endp - p - 4), &val))
|
ASSERT(val, napi_create_string_latin1(env, (char*)p, (endp - p - 4), &val))
|
||||||
ASSERT(state->info, napi_set_named_property(env, state->info, key, val))
|
ASSERT(state->info, napi_set_named_property(env, state->info, key, val))
|
||||||
#else
|
|
||||||
strcopy(p, endp - 3, state->tmpStr);
|
|
||||||
set_property_string(key, state->tmpStr);
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if ((command > 0) && (command < 8)) {
|
||||||
|
const int len = endp - p;
|
||||||
|
int tailLen = 3;
|
||||||
|
if (len < 4) {
|
||||||
|
tailLen = len;
|
||||||
|
}
|
||||||
|
strcopy(p, endp - tailLen, state->tmpStr);
|
||||||
|
// set_property_string(key, state->tmpStr);
|
||||||
|
on_command(state->tmpStr, command);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (state->command == 8) { // $enddefinitions
|
if (command == 8) { // $enddefinitions
|
||||||
*(char *)state->idStr = 0;
|
*(char *)state->idStr = 0;
|
||||||
*(char *)state->timeStampStr = 0;
|
*(char *)state->timeStampStr = 0;
|
||||||
#ifndef VCDWASM
|
#ifndef VCDWASM
|
||||||
@ -167,7 +179,13 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig
|
|||||||
}
|
}
|
||||||
|
|
||||||
int varSizeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
int varSizeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
state->size = strtol((const char *)p, (char **)&endp, 10);
|
const int32_t size = strtol((const char *)p, (char **)&endp, 10);
|
||||||
|
state->size = size;
|
||||||
|
#ifndef VCDWASM
|
||||||
|
#else
|
||||||
|
set_property_int("varType", state->type);
|
||||||
|
set_property_int("varSize", size);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +217,7 @@ int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char
|
|||||||
// set
|
// set
|
||||||
// info.stack[sp].`tmpStr` = info.varId
|
// info.stack[sp].`tmpStr` = info.varId
|
||||||
snprintf(state->tmpStr2, 4096, "stack.%d.%s", state->stackPointer, state->tmpStr);
|
snprintf(state->tmpStr2, 4096, "stack.%d.%s", state->stackPointer, state->tmpStr);
|
||||||
set_path_to_path(state->tmpStr2, "varId");
|
set_path_to_path(state->tmpStr2, "varType,varSize,varId");
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,10 @@ void new_object_path(const char* name) {
|
|||||||
bound_set_property(name, strlen(name), 4, 0, 0);
|
bound_set_property(name, strlen(name), 4, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void on_command(const char* body, const int command) {
|
||||||
|
bound_set_property(body, strlen(body), 5, command, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int get_property_int(const char* name) {
|
int get_property_int(const char* name) {
|
||||||
return bound_get_property(name, strlen(name));
|
return bound_get_property(name, strlen(name));
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ void set_property_string(const char* name, const char* value);
|
|||||||
void set_path_string(const char* name, const char* value);
|
void set_path_string(const char* name, const char* value);
|
||||||
void set_path_to_path(const char* name, const char* value);
|
void set_path_to_path(const char* name, const char* value);
|
||||||
void new_object_path(const char* name);
|
void new_object_path(const char* name);
|
||||||
|
void on_command(const char* body, const int command);
|
||||||
int get_property_int(const char* name);
|
int get_property_int(const char* name);
|
||||||
void emit_lifee(const char* name);
|
void emit_lifee(const char* name);
|
||||||
void emit_triee(
|
void emit_triee(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user