fixes #4
This commit is contained in:
parent
830fc367fd
commit
9a2434a43d
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ node_modules
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
*.dot
|
*.dot
|
||||||
tmp
|
tmp
|
||||||
|
vcd_parser.*
|
||||||
|
19
bin/build.js
19
bin/build.js
@ -14,15 +14,17 @@ p.property('i8', 'type');
|
|||||||
p.property('i32', 'size');
|
p.property('i32', 'size');
|
||||||
p.property('i32', 'time');
|
p.property('i32', 'time');
|
||||||
p.property('ptr', 'trigger');
|
p.property('ptr', 'trigger');
|
||||||
p.property('ptr', 'info');
|
|
||||||
p.property('ptr', 'triee');
|
p.property('ptr', 'triee');
|
||||||
p.property('ptr', 'lifee');
|
p.property('ptr', 'lifee');
|
||||||
p.property('ptr', 'hier');
|
p.property('ptr', 'info');
|
||||||
|
p.property('i32', 'stackPointer');
|
||||||
|
p.property('ptr', 'id');
|
||||||
p.property('ptr', 'napi_env');
|
p.property('ptr', 'napi_env');
|
||||||
|
|
||||||
const scopeIdentifierSpan = p.span(p.code.span('scopeIdentifierSpan'));
|
const scopeIdentifierSpan = p.span(p.code.span('scopeIdentifierSpan'));
|
||||||
const varSizeSpan = p.span(p.code.span('varSizeSpan'));
|
const varSizeSpan = p.span(p.code.span('varSizeSpan'));
|
||||||
const varIdSpan = p.span(p.code.span('varIdSpan'));
|
const varIdSpan = p.span(p.code.span('varIdSpan'));
|
||||||
|
const varNameSpan = p.span(p.code.span('varNameSpan'));
|
||||||
const idSpan = p.span(p.code.span('idSpan'));
|
const idSpan = p.span(p.code.span('idSpan'));
|
||||||
const commandSpan = p.span(p.code.span('commandSpan'));
|
const commandSpan = p.span(p.code.span('commandSpan'));
|
||||||
const timeSpan = p.span(p.code.span('timeSpan'));
|
const timeSpan = p.span(p.code.span('timeSpan'));
|
||||||
@ -45,6 +47,9 @@ const varSizeEnd = p.node('varSizeEnd');
|
|||||||
const varId = p.node('varId');
|
const varId = p.node('varId');
|
||||||
const varIdEnd = p.node('varIdEnd');
|
const varIdEnd = p.node('varIdEnd');
|
||||||
|
|
||||||
|
const varName = p.node('varName');
|
||||||
|
const varNameEnd = p.node('varNameEnd');
|
||||||
|
|
||||||
const inDeclaration = p.node('inDeclaration');
|
const inDeclaration = p.node('inDeclaration');
|
||||||
const enddefinitions = p.node('inDeclarationEnd');
|
const enddefinitions = p.node('inDeclarationEnd');
|
||||||
const simulation = p.node('simulation');
|
const simulation = p.node('simulation');
|
||||||
@ -155,9 +160,17 @@ varId
|
|||||||
.otherwise(varIdSpan.start(varIdEnd));
|
.otherwise(varIdSpan.start(varIdEnd));
|
||||||
|
|
||||||
varIdEnd
|
varIdEnd
|
||||||
.match(spaces, varIdSpan.end(inDeclaration))
|
.match(spaces, varIdSpan.end(varName))
|
||||||
.skipTo(varIdEnd);
|
.skipTo(varIdEnd);
|
||||||
|
|
||||||
|
varName
|
||||||
|
.match(spaces, varName)
|
||||||
|
.otherwise(varNameSpan.start(varNameEnd));
|
||||||
|
|
||||||
|
varNameEnd
|
||||||
|
.match(spaces, varNameSpan.end(inDeclaration))
|
||||||
|
.skipTo(varNameEnd);
|
||||||
|
|
||||||
// $end
|
// $end
|
||||||
|
|
||||||
inDeclaration
|
inDeclaration
|
||||||
|
19
bin/find.js
19
bin/find.js
@ -17,25 +17,26 @@ fs.readdir(dir).then(files => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const t0 = Date.now();
|
const t0 = Date.now();
|
||||||
|
const inst = lib.parser();
|
||||||
let inst = lib.parser();
|
|
||||||
|
|
||||||
const loads = lib.and();
|
const loads = lib.and();
|
||||||
const stores = lib.and();
|
const stores = lib.and();
|
||||||
const duration = lib.activity(10);
|
const duration = lib.activity(10);
|
||||||
|
|
||||||
inst.on('$enddefinitions', () => {
|
inst.on('$enddefinitions', () => {
|
||||||
// console.log(res);
|
const _ = inst.info.wires;
|
||||||
// console.log(inst.info);
|
inst.change.on(_.top.TestDriver.testHarness.system.tile.vpu.mem_i_load,
|
||||||
inst.change.on('D7', (time, cmd) => { // mem_i_load
|
(time, cmd) => {
|
||||||
loads.onA(time, cmd);
|
loads.onA(time, cmd);
|
||||||
stores.onNotA(time, cmd);
|
stores.onNotA(time, cmd);
|
||||||
});
|
}
|
||||||
inst.change.on('D1', (time, cmd) => { // mem_i_valid
|
);
|
||||||
|
inst.change.on(_.top.TestDriver.testHarness.system.tile.vpu.mem_i_valid,
|
||||||
|
(time, cmd) => {
|
||||||
loads.onB(time, cmd);
|
loads.onB(time, cmd);
|
||||||
stores.onB(time, cmd);
|
stores.onB(time, cmd);
|
||||||
duration.on(time);
|
duration.on(time);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
inst.on('finish', () => {
|
inst.on('finish', () => {
|
||||||
|
@ -6,7 +6,8 @@ let lib = require('bindings')('vcd.node');
|
|||||||
|
|
||||||
module.exports = () => {
|
module.exports = () => {
|
||||||
|
|
||||||
const info = {path: []};
|
const wires = {};
|
||||||
|
const info = {stack: [wires], wires: wires};
|
||||||
|
|
||||||
const s = new stream.Writable();
|
const s = new stream.Writable();
|
||||||
|
|
||||||
|
@ -50,6 +50,9 @@ $timescale 1ns $end
|
|||||||
$scope module leaf $end
|
$scope module leaf $end
|
||||||
$var wire 64 {u counter [63:0] $end
|
$var wire 64 {u counter [63:0] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
|
$scope module fruit $end
|
||||||
|
$var wire 4 {u point [3:0] $end
|
||||||
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
|
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
|
49
vcd.c
49
vcd.c
@ -11,7 +11,7 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define METHOD(name) napi_value name(napi_env env, napi_callback_info info)
|
#define METHOD(name) napi_value name(napi_env env, napi_callback_info cbInfo)
|
||||||
|
|
||||||
#define ASSERT(val, expr) \
|
#define ASSERT(val, expr) \
|
||||||
if (expr != napi_ok) { \
|
if (expr != napi_ok) { \
|
||||||
@ -22,7 +22,7 @@
|
|||||||
napi_value args[count]; \
|
napi_value args[count]; \
|
||||||
{ \
|
{ \
|
||||||
size_t argc = count; \
|
size_t argc = count; \
|
||||||
if (napi_get_cb_info(env, info, &argc, args, 0, 0) != napi_ok) { \
|
if (napi_get_cb_info(env, cbInfo, &argc, args, 0, 0) != napi_ok) { \
|
||||||
napi_throw_error(env, 0, "Error"); \
|
napi_throw_error(env, 0, "Error"); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
@ -120,7 +120,7 @@ METHOD(init) {
|
|||||||
ASSERT_ARGC(3)
|
ASSERT_ARGC(3)
|
||||||
ASSERT_FUNCTION(args[0], state->lifee)
|
ASSERT_FUNCTION(args[0], state->lifee)
|
||||||
ASSERT_FUNCTION(args[1], state->triee)
|
ASSERT_FUNCTION(args[1], state->triee)
|
||||||
ASSERT_OBJECT(args[2], state->hier)
|
ASSERT_OBJECT(args[2], state->info)
|
||||||
|
|
||||||
static char triggerString [4096] = " ";
|
static char triggerString [4096] = " ";
|
||||||
|
|
||||||
@ -130,13 +130,14 @@ METHOD(init) {
|
|||||||
|
|
||||||
napi_value status;
|
napi_value status;
|
||||||
ASSERT(status, napi_create_string_latin1(env, "declaration", NAPI_AUTO_LENGTH, &status))
|
ASSERT(status, napi_create_string_latin1(env, "declaration", NAPI_AUTO_LENGTH, &status))
|
||||||
ASSERT(state->hier, napi_set_named_property(env, state->hier, "status", status))
|
ASSERT(state->info, napi_set_named_property(env, state->info, "status", status))
|
||||||
|
// ASSERT(status, napi_get_named_property(env, state->info, "wires", &state->wires))
|
||||||
|
|
||||||
// napi_value hierObj;
|
// napi_value hierObj;
|
||||||
// ASSERT(hierObj, napi_create_object(env, &hierObj))
|
// ASSERT(hierObj, napi_create_object(env, &hierObj))
|
||||||
// state->hier = hierObj;
|
// state->info = hierObj;
|
||||||
|
|
||||||
// ASSERT(state->hier, napi_create_object(env, &state->hier))
|
// ASSERT(state->info, napi_create_object(env, &state->info))
|
||||||
|
|
||||||
ASSERT(res, napi_create_external(env, state, 0, 0, &res))
|
ASSERT(res, napi_create_external(env, state, 0, 0, &res))
|
||||||
return res;
|
return res;
|
||||||
@ -146,11 +147,11 @@ METHOD(done) {
|
|||||||
ASSERT_ARGC(4)
|
ASSERT_ARGC(4)
|
||||||
struct vcd_parser_s *state;
|
struct vcd_parser_s *state;
|
||||||
// last use of all external objects
|
// last use of all external objects
|
||||||
napi_value lifee, triee, hier;
|
napi_value lifee, triee, info;
|
||||||
ASSERT_EXTERNAL(args[0], state)
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
ASSERT_FUNCTION(args[1], lifee)
|
ASSERT_FUNCTION(args[1], lifee)
|
||||||
ASSERT_FUNCTION(args[2], triee)
|
ASSERT_FUNCTION(args[2], triee)
|
||||||
ASSERT_OBJECT(args[3], hier)
|
ASSERT_OBJECT(args[3], info)
|
||||||
|
|
||||||
// FIXME destroy parser state
|
// FIXME destroy parser state
|
||||||
|
|
||||||
@ -166,7 +167,7 @@ METHOD(execute) {
|
|||||||
ASSERT_EXTERNAL(args[0], state)
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
ASSERT_FUNCTION(args[1], state->lifee)
|
ASSERT_FUNCTION(args[1], state->lifee)
|
||||||
ASSERT_FUNCTION(args[2], state->triee)
|
ASSERT_FUNCTION(args[2], state->triee)
|
||||||
ASSERT_OBJECT(args[3], state->hier)
|
ASSERT_OBJECT(args[3], state->info)
|
||||||
ASSERT_BUFFER(args[4], p, plen)
|
ASSERT_BUFFER(args[4], p, plen)
|
||||||
|
|
||||||
state->napi_env = env;
|
state->napi_env = env;
|
||||||
@ -177,35 +178,6 @@ METHOD(execute) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(getInfo) {
|
|
||||||
ASSERT_ARGC(1)
|
|
||||||
struct vcd_parser_s *state;
|
|
||||||
ASSERT_EXTERNAL(args[0], state)
|
|
||||||
|
|
||||||
napi_value infObj, error, reason, command, type, size, time, trigger;
|
|
||||||
|
|
||||||
ASSERT(infObj, napi_create_object(env, &infObj))
|
|
||||||
ASSERT(error, napi_create_int32(env, state->error, &error))
|
|
||||||
ASSERT(reason, napi_create_string_latin1(env, state->reason, NAPI_AUTO_LENGTH, &reason))
|
|
||||||
ASSERT(command, napi_create_int32(env, state->command, &command))
|
|
||||||
ASSERT(type, napi_create_int32(env, state->type, &type))
|
|
||||||
ASSERT(size, napi_create_int32(env, state->size, &size))
|
|
||||||
ASSERT(time, napi_create_int32(env, state->time, &time))
|
|
||||||
ASSERT(trigger, napi_create_string_latin1(env, state->trigger, NAPI_AUTO_LENGTH, &trigger))
|
|
||||||
|
|
||||||
// ASSERT(state->hier, napi_create_object(env, &state->hier))
|
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "hier", state->hier))
|
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "error", error))
|
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "reason", reason))
|
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "command", command))
|
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "type", type))
|
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "size", size))
|
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "time", time))
|
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "trigger", trigger))
|
|
||||||
|
|
||||||
return infObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(setTrigger) {
|
METHOD(setTrigger) {
|
||||||
ASSERT_ARGC(2)
|
ASSERT_ARGC(2)
|
||||||
struct vcd_parser_s *state;
|
struct vcd_parser_s *state;
|
||||||
@ -221,7 +193,6 @@ napi_value Init(napi_env env, napi_value exports) {
|
|||||||
DECLARE_NAPI_METHOD("init", init)
|
DECLARE_NAPI_METHOD("init", init)
|
||||||
DECLARE_NAPI_METHOD("done", done)
|
DECLARE_NAPI_METHOD("done", done)
|
||||||
DECLARE_NAPI_METHOD("execute", execute)
|
DECLARE_NAPI_METHOD("execute", execute)
|
||||||
DECLARE_NAPI_METHOD("getInfo", getInfo)
|
|
||||||
DECLARE_NAPI_METHOD("setTrigger", setTrigger)
|
DECLARE_NAPI_METHOD("setTrigger", setTrigger)
|
||||||
return exports;
|
return exports;
|
||||||
}
|
}
|
||||||
|
2330
vcd_parser.c
2330
vcd_parser.c
File diff suppressed because it is too large
Load Diff
39
vcd_parser.h
39
vcd_parser.h
@ -1,39 +0,0 @@
|
|||||||
#ifndef INCLUDE_VCD_PARSER_H_
|
|
||||||
#define INCLUDE_VCD_PARSER_H_
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef struct vcd_parser_s vcd_parser_t;
|
|
||||||
struct vcd_parser_s {
|
|
||||||
int32_t _index;
|
|
||||||
void* _span_pos0;
|
|
||||||
void* _span_cb0;
|
|
||||||
void* _span_pos1;
|
|
||||||
void* _span_cb1;
|
|
||||||
int32_t error;
|
|
||||||
const char* reason;
|
|
||||||
const char* error_pos;
|
|
||||||
void* data;
|
|
||||||
void* _current;
|
|
||||||
uint8_t command;
|
|
||||||
uint8_t type;
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t time;
|
|
||||||
void* trigger;
|
|
||||||
void* info;
|
|
||||||
void* triee;
|
|
||||||
void* lifee;
|
|
||||||
void* hier;
|
|
||||||
void* napi_env;
|
|
||||||
};
|
|
||||||
|
|
||||||
int vcd_parser_init(vcd_parser_t* s);
|
|
||||||
int vcd_parser_execute(vcd_parser_t* s, const char* p, const char* endp);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
#endif /* INCLUDE_VCD_PARSER_H_ */
|
|
40
vcd_spans.c
40
vcd_spans.c
@ -8,6 +8,7 @@
|
|||||||
napi_throw(env, val); \
|
napi_throw(env, val); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME use a better structure to match strings
|
||||||
int stringEq (
|
int stringEq (
|
||||||
const unsigned char* gold, // search pattern
|
const unsigned char* gold, // search pattern
|
||||||
const unsigned char* p,
|
const unsigned char* p,
|
||||||
@ -39,17 +40,15 @@ 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) {
|
||||||
napi_env env = state->napi_env;
|
napi_env env = state->napi_env;
|
||||||
|
|
||||||
if (state->command == 5) {
|
if (state->command == 5) { // $upscope
|
||||||
// printf(")");
|
state->stackPointer -= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->command == 8) { // $enddefinitions
|
if (state->command == 8) { // $enddefinitions
|
||||||
napi_value status;
|
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))
|
||||||
ASSERT(state->hier, napi_set_named_property(env, state->hier, "status", status))
|
ASSERT(state->info, napi_set_named_property(env, state->info, "status", status))
|
||||||
|
|
||||||
napi_value undefined, eventName, eventPayload, return_val;
|
|
||||||
ASSERT(undefined, napi_get_undefined(env, &undefined))
|
ASSERT(undefined, napi_get_undefined(env, &undefined))
|
||||||
ASSERT(eventName, napi_create_string_latin1(env, "$enddefinitions", NAPI_AUTO_LENGTH, &eventName))
|
ASSERT(eventName, napi_create_string_latin1(env, "$enddefinitions", NAPI_AUTO_LENGTH, &eventName))
|
||||||
// ASSERT(eventPayload, napi_create_string_latin1(env, "payload", NAPI_AUTO_LENGTH, &eventPayload))
|
// ASSERT(eventPayload, napi_create_string_latin1(env, "payload", NAPI_AUTO_LENGTH, &eventPayload))
|
||||||
@ -61,8 +60,17 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, /* FIXME const */ unsigned char* endp) {
|
||||||
// printf("(%d:%d", state->type, state->size);
|
napi_env env = state->napi_env;
|
||||||
|
*(endp - 1) = 0; // FIXME NULL termination of ASCII string
|
||||||
|
napi_value name, obj, stack, top;
|
||||||
|
ASSERT(name, napi_create_string_latin1(env, (char*)p, (endp - p - 1), &name))
|
||||||
|
ASSERT(obj, napi_create_object(env, &obj))
|
||||||
|
ASSERT(state->info, napi_get_named_property(env, state->info, "stack", &stack))
|
||||||
|
ASSERT(top, napi_get_element(env, stack, state->stackPointer, &top))
|
||||||
|
ASSERT(top, napi_set_named_property(env, top, p, obj))
|
||||||
|
state->stackPointer += 1;
|
||||||
|
ASSERT(top, napi_set_element(env, stack, state->stackPointer, obj))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +80,19 @@ int varSizeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char
|
|||||||
}
|
}
|
||||||
|
|
||||||
int varIdSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
int varIdSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
// printf(" %d", state->type);
|
napi_env env = state->napi_env;
|
||||||
|
napi_value val;
|
||||||
|
ASSERT(state->id, napi_create_string_latin1(env, (char*)p, (endp - p - 1), &state->id))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int varNameSpan(vcd_parser_t* state, const unsigned char* p, /* FIXME const */ unsigned char* endp) {
|
||||||
|
napi_env env = state->napi_env;
|
||||||
|
*(endp - 1) = 0; // FIXME NULL termination of ASCII string
|
||||||
|
napi_value stack, top;
|
||||||
|
ASSERT(state->info, napi_get_named_property(env, state->info, "stack", &stack))
|
||||||
|
ASSERT(top, napi_get_element(env, stack, state->stackPointer, &top))
|
||||||
|
ASSERT(state->info, napi_set_named_property(env, top, p, state->id))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,13 +106,11 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end
|
|||||||
ASSERT(eventPayload2, napi_create_int32(env, state->command, &eventPayload2))
|
ASSERT(eventPayload2, napi_create_int32(env, state->command, &eventPayload2))
|
||||||
napi_value* argv[] = { &eventName, &eventPayload1, &eventPayload2 };
|
napi_value* argv[] = { &eventName, &eventPayload1, &eventPayload2 };
|
||||||
ASSERT(state->triee, napi_call_function(env, undefined, state->triee, 3, *argv, &return_val))
|
ASSERT(state->triee, napi_call_function(env, undefined, state->triee, 3, *argv, &return_val))
|
||||||
// printf("{%.*s}", (int)(endp - p - 1), p);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vectorSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
int vectorSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
// printf("{%.*s}", (int)(endp - p - 1), p);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user