增加对于开头存在 #0 这样例子的解析支持
This commit is contained in:
parent
f10bd6dce6
commit
2eda8afff7
19
README.md
19
README.md
@ -6,25 +6,34 @@ Value Change Dump ([VCD](https://en.wikipedia.org/wiki/Value_change_dump)) parse
|
|||||||
|
|
||||||
2. clone https://github.com/Digital-EDA/digital-vcd-parser
|
2. clone https://github.com/Digital-EDA/digital-vcd-parser
|
||||||
|
|
||||||
## Build
|
## 构建
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
source $EMCC_HOME/emsdk_env.sh
|
source $EMCC_HOME/emsdk_env.sh
|
||||||
# once only
|
|
||||||
|
# 只需要运行一次
|
||||||
npm install browserify terser node-gyp -g
|
npm install browserify terser node-gyp -g
|
||||||
# once only
|
# 只需要运行一次
|
||||||
npm i
|
npm i
|
||||||
|
|
||||||
|
# 构建左推解析器代码(每次修改 ./bin/build.js 都需要重新运行)
|
||||||
|
node bin/build.js
|
||||||
|
|
||||||
# build
|
# build
|
||||||
make -j 12
|
make -j 12
|
||||||
```
|
```
|
||||||
|
|
||||||
production are :
|
生成 :
|
||||||
|
|
||||||
- `./out/vcd.js`
|
- `./out/vcd.js`
|
||||||
- `./out/vcd.wasm`
|
- `./out/vcd.wasm`
|
||||||
|
|
||||||
move them to your development worksapce.
|
部署代码:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 将生成的 wasm 通过 浏览器化和特殊处理后部署到 render 项目中
|
||||||
|
source deploy.sh /mnt/c/Users/11934/Project/Digital-IDE/digital-vcd-render
|
||||||
|
```
|
||||||
|
|
||||||
## Test
|
## Test
|
||||||
|
|
||||||
|
@ -125,7 +125,8 @@ const generate = (cb) => {
|
|||||||
$dumpon: 11,
|
$dumpon: 11,
|
||||||
$dumpvars: 12,
|
$dumpvars: 12,
|
||||||
'#': 13,
|
'#': 13,
|
||||||
'0': 14, '1': 15,
|
'0': 14,
|
||||||
|
'1': 15,
|
||||||
x: 16, X: 17,
|
x: 16, X: 17,
|
||||||
z: 18, Z: 19,
|
z: 18, Z: 19,
|
||||||
u: 20, U: 21, // VHDL states
|
u: 20, U: 21, // VHDL states
|
||||||
@ -136,9 +137,12 @@ const generate = (cb) => {
|
|||||||
b: 30, B: 31, r: 32, R: 33
|
b: 30, B: 31, r: 32, R: 33
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(cmd);
|
||||||
|
|
||||||
|
// p.code.store('command') 的具体执行逻辑移步 command-handler.js 中的 commandHandler
|
||||||
declaration
|
declaration
|
||||||
.match(spaces, declaration)
|
.match(spaces, declaration)
|
||||||
.select(cmd('$scope $var $upscope $comment $date $timescale $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)))
|
||||||
|
@ -5,9 +5,13 @@ const createVCD = require('../out/vcd.js');
|
|||||||
const webVcdParser = require('../lib/web-vcd-parser.js');
|
const webVcdParser = require('../lib/web-vcd-parser.js');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{ maxChunkLength: number, useGcd: boolean }} consumeConfig
|
* @typedef {Object} consumeConfig
|
||||||
|
* @property {number} maxChunkLength
|
||||||
|
* @property {boolean} useGcd
|
||||||
*
|
*
|
||||||
* @typedef {{ kind: string, wave: number[] }} vcdValue
|
* @typedef {Object} vcdValue
|
||||||
|
* @property {string} kind
|
||||||
|
* @property {number[]} wave
|
||||||
*
|
*
|
||||||
* @typedef {Object} VarSignal
|
* @typedef {Object} VarSignal
|
||||||
* @property { 'var' } kind
|
* @property { 'var' } kind
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
source $EMCC_HOME/emsdk_env.sh
|
source $EMCC_HOME/emsdk_env.sh
|
||||||
npm install browserify terser node-gyp -g
|
npm install browserify terser node-gyp -g
|
||||||
npm i
|
npm i
|
||||||
|
@ -3,72 +3,79 @@
|
|||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
const handleScope = (info, str) => {
|
const handleScope = (info, str) => {
|
||||||
const [type, name] = str.split(/\s+/);
|
const [type, name] = str.split(/\s+/);
|
||||||
const ero = {kind: 'scope', type, name, body: []};
|
const ero = { kind: 'scope', type, name, body: [] };
|
||||||
const current = info.stack[info.stack.length - 1];
|
const current = info.stack[info.stack.length - 1];
|
||||||
current.body.push(ero);
|
current.body.push(ero);
|
||||||
info.stack.push(ero);
|
info.stack.push(ero);
|
||||||
// console.log(ero);
|
// console.log(ero);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpScope = (info /* , str */) => {
|
const handleUpScope = (info /* , str */) => {
|
||||||
info.stack.pop();
|
info.stack.pop();
|
||||||
// console.log(['upscope', str]);
|
// console.log(['upscope', str]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleVar = (info, str) => {
|
const handleVar = (info, str) => {
|
||||||
// reg 3 ( r_reg [2:0]
|
// reg 3 ( r_reg [2:0]
|
||||||
// 0 1 2 3+
|
// 0 1 2 3+
|
||||||
const eroj = str.split(/\s+/);
|
const eroj = str.split(/\s+/);
|
||||||
const ero = {
|
const ero = {
|
||||||
kind: 'var',
|
kind: 'var',
|
||||||
type: eroj[0],
|
type: eroj[0],
|
||||||
size: parseInt(eroj[1]),
|
size: parseInt(eroj[1]),
|
||||||
link: eroj[2],
|
link: eroj[2],
|
||||||
name: eroj.slice(3).join('')
|
name: eroj.slice(3).join('')
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
const m = ero.name.match('^(?<name>\\w+)\\[' + (ero.size - 1) + ':0]$');
|
const m = ero.name.match('^(?<name>\\w+)\\[' + (ero.size - 1) + ':0]$');
|
||||||
if (m) {
|
if (m) {
|
||||||
ero.name = m.groups.name;
|
ero.name = m.groups.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
const current = info.stack[info.stack.length - 1];
|
||||||
const current = info.stack[info.stack.length - 1];
|
current.body.push(ero);
|
||||||
current.body.push(ero);
|
// console.log(ero);
|
||||||
// console.log(ero);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 处理 C++ 中的 on_command 函数,也就是 llparse 框架中的 p.code.store('command') 触发的函数
|
||||||
|
* @param {} info
|
||||||
|
* @param {*} cmd
|
||||||
|
* @param {*} str
|
||||||
|
*/
|
||||||
const commandHandler = (info, cmd, str) => {
|
const commandHandler = (info, cmd, str) => {
|
||||||
str = str.trim();
|
str = str.trim();
|
||||||
switch(cmd) {
|
|
||||||
case 1:
|
switch (cmd) {
|
||||||
info.comment = str;
|
case 1:
|
||||||
// console.log(['comment', str]);
|
info.comment = str;
|
||||||
break;
|
// console.log(['comment', str]);
|
||||||
case 2:
|
break;
|
||||||
info.date = str;
|
case 2:
|
||||||
// console.log(['date', str]);
|
info.date = str;
|
||||||
break;
|
// console.log(['date', str]);
|
||||||
case 3:
|
break;
|
||||||
handleScope(info, str);
|
case 3:
|
||||||
break;
|
handleScope(info, str);
|
||||||
case 4:
|
break;
|
||||||
info.timescale = str;
|
case 4:
|
||||||
// console.log(['timescale', str]);
|
info.timescale = str;
|
||||||
break;
|
// console.log(['timescale', str]);
|
||||||
case 5:
|
break;
|
||||||
handleUpScope(info, str);
|
case 5:
|
||||||
break;
|
handleUpScope(info, str);
|
||||||
case 6:
|
break;
|
||||||
handleVar(info, str);
|
case 6:
|
||||||
break;
|
handleVar(info, str);
|
||||||
case 7:
|
break;
|
||||||
info.version = str;
|
case 7:
|
||||||
// console.log(['version', str]);
|
info.version = str;
|
||||||
break;
|
// console.log(['version', str]);
|
||||||
default:
|
break;
|
||||||
console.log([cmd, str]);
|
default:
|
||||||
}
|
console.log([cmd, str]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = commandHandler;
|
module.exports = commandHandler;
|
||||||
|
@ -86,7 +86,7 @@ module.exports = async (deso, inst, done) => {
|
|||||||
inst.change.any(onAnyChange);
|
inst.change.any(onAnyChange);
|
||||||
|
|
||||||
inst.on('finish', () => {
|
inst.on('finish', () => {
|
||||||
console.log((Date.now() - t0) / 1000);
|
// console.log((Date.now() - t0) / 1000);
|
||||||
deso.tgcd = tgcd;
|
deso.tgcd = tgcd;
|
||||||
deso.t0 = (inst.info.t0 || 0);
|
deso.t0 = (inst.info.t0 || 0);
|
||||||
// console.log(inst.getTime());
|
// console.log(inst.getTime());
|
||||||
|
@ -145,7 +145,7 @@ const getWrapper = wasm => {
|
|||||||
* @param {*} chunk
|
* @param {*} chunk
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
execute: (ctx, cb0, cb1, info, chunk) => {
|
execute: (ctx, cb0, cb1, info, chunk) => {
|
||||||
boundInfo = info;
|
boundInfo = info;
|
||||||
ee[0] = cb0;
|
ee[0] = cb0;
|
||||||
ee[1] = cb1;
|
ee[1] = cb1;
|
||||||
|
@ -8,12 +8,11 @@ const fs = require('fs');
|
|||||||
const { makeVcdStream } = require('../../bin/vcd');
|
const { makeVcdStream } = require('../../bin/vcd');
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const arraybuffer = fs.readFileSync('./test/debug/pe_tb.vcd');
|
const arraybuffer = fs.readFileSync('./test/debug/small.vcd');
|
||||||
const vcdstream = await makeVcdStream();
|
const vcdstream = await makeVcdStream();
|
||||||
vcdstream.consume(arraybuffer);
|
vcdstream.consume(arraybuffer);
|
||||||
const info = vcdstream.getBasicInfo();
|
const info = vcdstream.getBasicInfo();
|
||||||
console.log(info.signalValues['*']);
|
console.log(info);
|
||||||
console.log(info.signalValues['+']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
114
test/debug/la0_waveform.vcd
Normal file
114
test/debug/la0_waveform.vcd
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#0 $dumpon
|
||||||
|
$date today $end
|
||||||
|
$timescale 1 ns $end
|
||||||
|
$scope module top $end
|
||||||
|
$var wire 1 0 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/line1_debounced $end
|
||||||
|
$var wire 1 1 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/line2_debounced $end
|
||||||
|
$var wire 4 2 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/trigger_line $end
|
||||||
|
$var wire 2 3 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/encoder_trigger_mode $end
|
||||||
|
$var wire 2 4 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/encoder_sourceA_sel $end
|
||||||
|
$var wire 2 5 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/encoder_sourceB_sel $end
|
||||||
|
$var wire 1 6 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/encoder_counter_rst $end
|
||||||
|
$var wire 32 7 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/encoder_counter $end
|
||||||
|
$var wire 2 8 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/encoder_counter_mode $end
|
||||||
|
$var wire 1 9 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_trigger_out $end
|
||||||
|
$var wire 1 a ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/encoder_sourceA $end
|
||||||
|
$var wire 1 b ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/encoder_sourceB $end
|
||||||
|
$var wire 1 c ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/trigger_forward $end
|
||||||
|
$var wire 1 d ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/trigger_backward $end
|
||||||
|
$var wire 2 e ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/encoder_sourceA_dly $end
|
||||||
|
$var wire 2 f ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/encoder_sourceB_dly $end
|
||||||
|
$var wire 1 10 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/encoder_sourceA_pos $end
|
||||||
|
$var wire 1 11 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/encoder_sourceA_neg $end
|
||||||
|
$var wire 1 12 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/encoder_sourceB_neg $end
|
||||||
|
$var wire 1 13 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/trigger_forward0 $end
|
||||||
|
$var wire 1 14 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/trigger_forward1 $end
|
||||||
|
$var wire 1 15 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/trigger_forward2 $end
|
||||||
|
$var wire 1 16 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/trigger_forward3 $end
|
||||||
|
$var wire 1 17 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/trigger_backward0 $end
|
||||||
|
$var wire 1 18 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/trigger_backward1 $end
|
||||||
|
$var wire 1 19 ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/trigger_backward3 $end
|
||||||
|
$var wire 1 1a ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encoder_control_top_inst/u1_encoder2trigger/trigger_backward2 $end
|
||||||
|
$var wire 32 1b ins_top_s4/inst_apb3_device/extern_trigger_top_inst/encode_rcounter $end
|
||||||
|
$upscope $end
|
||||||
|
$enddefinitions $end
|
||||||
|
#0
|
||||||
|
$dumpvars
|
||||||
|
00
|
||||||
|
11
|
||||||
|
b1110 2
|
||||||
|
b00 3
|
||||||
|
b00 4
|
||||||
|
b01 5
|
||||||
|
06
|
||||||
|
b00000000000000000010000111001101 7
|
||||||
|
b00 8
|
||||||
|
09
|
||||||
|
0a
|
||||||
|
1b
|
||||||
|
0c
|
||||||
|
0d
|
||||||
|
b00 e
|
||||||
|
b11 f
|
||||||
|
010
|
||||||
|
011
|
||||||
|
012
|
||||||
|
013
|
||||||
|
014
|
||||||
|
015
|
||||||
|
016
|
||||||
|
017
|
||||||
|
018
|
||||||
|
019
|
||||||
|
01a
|
||||||
|
b00000000000000000000000000000000 1b
|
||||||
|
$end
|
||||||
|
#1021
|
||||||
|
10
|
||||||
|
b1111 2
|
||||||
|
#1022
|
||||||
|
1a
|
||||||
|
#1023
|
||||||
|
b01 e
|
||||||
|
110
|
||||||
|
117
|
||||||
|
#1024
|
||||||
|
1d
|
||||||
|
b11 e
|
||||||
|
010
|
||||||
|
017
|
||||||
|
#1025
|
||||||
|
b00000000000000000010000111001110 7
|
||||||
|
19
|
||||||
|
0d
|
||||||
|
#1026
|
||||||
|
09
|
||||||
|
#2047
|
||||||
|
10
|
||||||
|
11
|
||||||
|
b1111 2
|
||||||
|
b00 3
|
||||||
|
b00 4
|
||||||
|
b01 5
|
||||||
|
06
|
||||||
|
b00000000000000000010000111001110 7
|
||||||
|
b00 8
|
||||||
|
09
|
||||||
|
1a
|
||||||
|
1b
|
||||||
|
0c
|
||||||
|
0d
|
||||||
|
b11 e
|
||||||
|
b11 f
|
||||||
|
010
|
||||||
|
011
|
||||||
|
012
|
||||||
|
013
|
||||||
|
014
|
||||||
|
015
|
||||||
|
016
|
||||||
|
017
|
||||||
|
018
|
||||||
|
019
|
||||||
|
01a
|
||||||
|
b00000000000000000000000000000000 1b
|
@ -77,6 +77,7 @@ int stringEq(const unsigned char* i, // search pattern
|
|||||||
int commandSpan(vcd_parser_t* state, const unsigned char* p,
|
int commandSpan(vcd_parser_t* state, const unsigned char* p,
|
||||||
const unsigned char* endp) {
|
const unsigned char* endp) {
|
||||||
const uint8_t command = state->command;
|
const uint8_t command = state->command;
|
||||||
|
|
||||||
#ifndef VCDWASM
|
#ifndef VCDWASM
|
||||||
napi_env env = state->napi_env;
|
napi_env env = state->napi_env;
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ int commandSpan(vcd_parser_t* state, const unsigned char* p,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if ((command > 0) && (command < 8)) {
|
if ((command > 0) && (command < 8)) {
|
||||||
const int len = endp - p;
|
const int len = endp - p;
|
||||||
int tailLen = 3;
|
int tailLen = 3;
|
||||||
if (len < 4) {
|
if (len < 4) {
|
||||||
|
@ -133,15 +133,17 @@ int init(externalJsMethodZero* f0, externalJsMethodOne* f1,
|
|||||||
int32_t execute(const int context, externalJsMethodZero* f0,
|
int32_t execute(const int context, externalJsMethodZero* f0,
|
||||||
externalJsMethodOne* f1, externalJsSetProperty* sfn,
|
externalJsMethodOne* f1, externalJsSetProperty* sfn,
|
||||||
externalJsGetProperty* gfn, char* p, const int plen) {
|
externalJsGetProperty* gfn, char* p, const int plen) {
|
||||||
// cout << "execute got " << p << "\n";
|
// 详见 web-vcd-parser.js 中的 boundSet
|
||||||
// cout << "execute " << (int)sfn << " and got " << p << "\n";
|
|
||||||
bound_set_property = sfn;
|
bound_set_property = sfn;
|
||||||
bound_get_property = gfn;
|
|
||||||
externalZero = f0;
|
|
||||||
externalOne = f1;
|
|
||||||
|
|
||||||
// const size_t plen = strlen(p);
|
// 详见 web-vcd-parser.js 中的 boundGet
|
||||||
// printf("<chunk len|%d>\n", plen);
|
bound_get_property = gfn;
|
||||||
|
|
||||||
|
// 详见 web-vcd-parser.js 中的 boundEE0
|
||||||
|
externalZero = f0;
|
||||||
|
|
||||||
|
// 详见 web-vcd-parser.js 中的 boundEE1
|
||||||
|
externalOne = f1;
|
||||||
|
|
||||||
const int32_t error = vcd_parser_execute(state, p, p + plen);
|
const int32_t error = vcd_parser_execute(state, p, p + plen);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user