增加对于开头存在 #0 这样例子的解析支持

This commit is contained in:
锦恢 2024-09-05 15:08:46 +08:00
parent f10bd6dce6
commit 2eda8afff7
11 changed files with 219 additions and 79 deletions

View File

@ -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

View File

@ -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)))

View File

@ -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

View File

@ -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;

View File

@ -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());

View File

@ -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
View 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

View File

@ -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;

View File

@ -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);