yosys2digitaljs 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core.d.ts +2 -0
- package/dist/core.js +46 -0
- package/dist/index.js +2 -36
- package/package.json +1 -1
- package/src/core.ts +50 -0
- package/src/index.ts +4 -41
package/dist/core.d.ts
CHANGED
|
@@ -135,4 +135,6 @@ export type ConvertOptions = {
|
|
|
135
135
|
};
|
|
136
136
|
export declare function yosys2digitaljs(obj: Yosys.Output, options?: ConvertOptions): Digitaljs.TopModule;
|
|
137
137
|
export declare function io_ui(output: Digitaljs.Module): void;
|
|
138
|
+
export declare function prepare_yosys_script(filenames: string[], options: Options): string;
|
|
139
|
+
export declare function prepare_verilator_args(filenames: string[]): string[];
|
|
138
140
|
export {};
|
package/dist/core.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.yosys2digitaljs = yosys2digitaljs;
|
|
5
5
|
exports.io_ui = io_ui;
|
|
6
|
+
exports.prepare_yosys_script = prepare_yosys_script;
|
|
7
|
+
exports.prepare_verilator_args = prepare_verilator_args;
|
|
6
8
|
const HashMap = require("hashmap");
|
|
7
9
|
const bigInt = require("big-integer");
|
|
8
10
|
const _3vl_1 = require("3vl");
|
|
@@ -1034,3 +1036,47 @@ function io_ui(output) {
|
|
|
1034
1036
|
}
|
|
1035
1037
|
}
|
|
1036
1038
|
}
|
|
1039
|
+
function ansi_c_escape_contents(cmd) {
|
|
1040
|
+
function func(ch) {
|
|
1041
|
+
if (ch == '\t')
|
|
1042
|
+
return '\\t';
|
|
1043
|
+
if (ch == '\r')
|
|
1044
|
+
return '\\r';
|
|
1045
|
+
if (ch == '\n')
|
|
1046
|
+
return '\\n';
|
|
1047
|
+
return '\\x' + ch.charCodeAt(0).toString(16).padStart(2, '0');
|
|
1048
|
+
}
|
|
1049
|
+
return cmd.replace(/(["'\\])/g, '\\$1')
|
|
1050
|
+
.replace(/[\x00-\x1F\x7F-\x9F]/g, func);
|
|
1051
|
+
}
|
|
1052
|
+
function ansi_c_escape(cmd) {
|
|
1053
|
+
return '"' + ansi_c_escape_contents(cmd) + '"';
|
|
1054
|
+
}
|
|
1055
|
+
function shell_escape_contents(cmd) {
|
|
1056
|
+
return cmd.replace(/(["\r\n$`\\])/g, '\\$1');
|
|
1057
|
+
}
|
|
1058
|
+
function shell_escape(cmd) {
|
|
1059
|
+
return '"' + shell_escape_contents(cmd) + '"';
|
|
1060
|
+
}
|
|
1061
|
+
function process_filename(filename) {
|
|
1062
|
+
const flags = /\.sv$/.test(filename) ? "-sv" : "";
|
|
1063
|
+
return `read_verilog ${flags} ${ansi_c_escape(filename)}`;
|
|
1064
|
+
}
|
|
1065
|
+
function prepare_yosys_script(filenames, options) {
|
|
1066
|
+
const optimize_simp = options.optimize ? "opt" : "opt_clean";
|
|
1067
|
+
const optimize = options.optimize ? "opt -full" : "opt_clean";
|
|
1068
|
+
const fsmexpand = options.fsmexpand ? " -expand" : "";
|
|
1069
|
+
const fsmpass = options.fsm == "nomap"
|
|
1070
|
+
? "fsm -nomap" + fsmexpand
|
|
1071
|
+
: options.fsm
|
|
1072
|
+
? "fsm" + fsmexpand
|
|
1073
|
+
: "";
|
|
1074
|
+
const readVerilogFilesScript = filenames
|
|
1075
|
+
.map((filename) => process_filename(filename));
|
|
1076
|
+
const yosysScript = [...readVerilogFilesScript, 'hierarchy -auto-top', 'proc', optimize_simp, fsmpass, 'memory -nomap', 'wreduce -memx', optimize];
|
|
1077
|
+
return yosysScript.join('; ');
|
|
1078
|
+
}
|
|
1079
|
+
function prepare_verilator_args(filenames) {
|
|
1080
|
+
const processed_filenames = filenames.map(shell_escape);
|
|
1081
|
+
return ['-lint-only', '-Wall', '-Wno-DECLFILENAME', '-Wno-UNOPT', '-Wno-UNOPTFLAT', ...processed_filenames];
|
|
1082
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -12,37 +12,11 @@ const path = require("path");
|
|
|
12
12
|
const util_1 = require("util");
|
|
13
13
|
const core_1 = require("./core");
|
|
14
14
|
const sanitize = require('sanitize-filename');
|
|
15
|
-
function ansi_c_escape_contents(cmd) {
|
|
16
|
-
function func(ch) {
|
|
17
|
-
if (ch == '\t')
|
|
18
|
-
return '\\t';
|
|
19
|
-
if (ch == '\r')
|
|
20
|
-
return '\\r';
|
|
21
|
-
if (ch == '\n')
|
|
22
|
-
return '\\n';
|
|
23
|
-
return '\\x' + ch.charCodeAt(0).toString(16).padStart(2, '0');
|
|
24
|
-
}
|
|
25
|
-
return cmd.replace(/(["'\\])/g, '\\$1')
|
|
26
|
-
.replace(/[\x00-\x1F\x7F-\x9F]/g, func);
|
|
27
|
-
}
|
|
28
|
-
function ansi_c_escape(cmd) {
|
|
29
|
-
return '"' + ansi_c_escape_contents(cmd) + '"';
|
|
30
|
-
}
|
|
31
|
-
function shell_escape_contents(cmd) {
|
|
32
|
-
return cmd.replace(/(["\r\n$`\\])/g, '\\$1');
|
|
33
|
-
}
|
|
34
|
-
function shell_escape(cmd) {
|
|
35
|
-
return '"' + shell_escape_contents(cmd) + '"';
|
|
36
|
-
}
|
|
37
|
-
function process_filename(filename) {
|
|
38
|
-
const flags = /\.sv$/.test(filename) ? " -sv" : "";
|
|
39
|
-
return "read_verilog" + flags + " " + ansi_c_escape(filename);
|
|
40
|
-
}
|
|
41
15
|
const verilator_re = /^%(Warning|Error)[^:]*: ([^:]*):([0-9]+):([0-9]+): (.*)$/;
|
|
42
16
|
async function verilator_lint(filenames, dirname, options = {}) {
|
|
43
17
|
try {
|
|
44
18
|
const output = [];
|
|
45
|
-
const verilator_result = await (0, util_1.promisify)(child_process.exec)(
|
|
19
|
+
const verilator_result = await (0, util_1.promisify)(child_process.exec)(`timeout -k10s 40s verilator ${(0, core_1.prepare_verilator_args)(filenames).join(' ')}`, { maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000 })
|
|
46
20
|
.catch(exc => exc);
|
|
47
21
|
for (const line of verilator_result.stderr.split('\n')) {
|
|
48
22
|
const result = line.match(verilator_re);
|
|
@@ -63,17 +37,9 @@ async function verilator_lint(filenames, dirname, options = {}) {
|
|
|
63
37
|
}
|
|
64
38
|
}
|
|
65
39
|
async function process(filenames, dirname, options = {}) {
|
|
66
|
-
const optimize_simp = options.optimize ? "; opt" : "; opt_clean";
|
|
67
|
-
const optimize = options.optimize ? "; opt -full" : "; opt_clean";
|
|
68
|
-
const fsmexpand = options.fsmexpand ? " -expand" : "";
|
|
69
|
-
const fsmpass = options.fsm == "nomap" ? "; fsm -nomap" + fsmexpand
|
|
70
|
-
: options.fsm ? "; fsm" + fsmexpand
|
|
71
|
-
: "";
|
|
72
40
|
const tmpjson = await tmp.tmpName({ postfix: '.json' });
|
|
73
41
|
let obj = undefined;
|
|
74
|
-
const yosys_result = await (0, util_1.promisify)(child_process.exec)(
|
|
75
|
-
'; hierarchy -auto-top; proc' + optimize_simp + fsmpass + '; memory -nomap; wreduce -memx' +
|
|
76
|
-
optimize + '" -o "' + tmpjson + '"', { maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000 })
|
|
42
|
+
const yosys_result = await (0, util_1.promisify)(child_process.exec)(`timeout -k10s 40s yosys -p "${(0, core_1.prepare_yosys_script)(filenames, options)}" -o ${tmpjson}`, { maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000 })
|
|
77
43
|
.catch(exc => exc);
|
|
78
44
|
try {
|
|
79
45
|
if (yosys_result instanceof Error) {
|
package/package.json
CHANGED
package/src/core.ts
CHANGED
|
@@ -1158,3 +1158,53 @@ export function io_ui(output: Digitaljs.Module) {
|
|
|
1158
1158
|
}
|
|
1159
1159
|
}
|
|
1160
1160
|
}
|
|
1161
|
+
|
|
1162
|
+
function ansi_c_escape_contents(cmd: string): string {
|
|
1163
|
+
function func(ch: string) {
|
|
1164
|
+
if (ch == '\t') return '\\t';
|
|
1165
|
+
if (ch == '\r') return '\\r';
|
|
1166
|
+
if (ch == '\n') return '\\n';
|
|
1167
|
+
return '\\x' + ch.charCodeAt(0).toString(16).padStart(2, '0');
|
|
1168
|
+
}
|
|
1169
|
+
return cmd.replace(/(["'\\])/g,'\\$1')
|
|
1170
|
+
.replace(/[\x00-\x1F\x7F-\x9F]/g, func);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
function ansi_c_escape(cmd: string): string {
|
|
1174
|
+
return '"' + ansi_c_escape_contents(cmd) + '"';
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
function shell_escape_contents(cmd: string): string {
|
|
1178
|
+
return cmd.replace(/(["\r\n$`\\])/g,'\\$1');
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
function shell_escape(cmd: string): string {
|
|
1182
|
+
return '"' + shell_escape_contents(cmd) + '"';
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
function process_filename(filename: string): string {
|
|
1186
|
+
const flags = /\.sv$/.test(filename) ? "-sv" : "";
|
|
1187
|
+
return `read_verilog ${flags} ${ansi_c_escape(filename)}`;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
export function prepare_yosys_script(filenames: string[], options: Options): string {
|
|
1191
|
+
const optimize_simp = options.optimize ? "opt" : "opt_clean";
|
|
1192
|
+
const optimize = options.optimize ? "opt -full" : "opt_clean";
|
|
1193
|
+
const fsmexpand = options.fsmexpand ? " -expand" : "";
|
|
1194
|
+
const fsmpass = options.fsm == "nomap"
|
|
1195
|
+
? "fsm -nomap" + fsmexpand
|
|
1196
|
+
: options.fsm
|
|
1197
|
+
? "fsm" + fsmexpand
|
|
1198
|
+
: "";
|
|
1199
|
+
|
|
1200
|
+
const readVerilogFilesScript = filenames
|
|
1201
|
+
.map((filename) => process_filename(filename))
|
|
1202
|
+
|
|
1203
|
+
const yosysScript = [...readVerilogFilesScript, 'hierarchy -auto-top', 'proc', optimize_simp, fsmpass, 'memory -nomap', 'wreduce -memx', optimize]
|
|
1204
|
+
return yosysScript.join('; ');
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
export function prepare_verilator_args(filenames: string[]): string[] {
|
|
1208
|
+
const processed_filenames = filenames.map(shell_escape);
|
|
1209
|
+
return ['-lint-only', '-Wall', '-Wno-DECLFILENAME', '-Wno-UNOPT', '-Wno-UNOPTFLAT', ...processed_filenames];
|
|
1210
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ import * as child_process from 'child_process';
|
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
8
|
import { promisify } from 'util';
|
|
9
|
-
import { yosys2digitaljs, ConvertOptions, Digitaljs } from './core';
|
|
9
|
+
import { prepare_yosys_script, prepare_verilator_args, yosys2digitaljs, ConvertOptions, Digitaljs } from './core';
|
|
10
10
|
const sanitize = require('sanitize-filename');
|
|
11
11
|
|
|
12
12
|
type Options = ConvertOptions & {
|
|
@@ -33,42 +33,13 @@ type LintMessage = {
|
|
|
33
33
|
message: string
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
function ansi_c_escape_contents(cmd: string): string {
|
|
38
|
-
function func(ch: string) {
|
|
39
|
-
if (ch == '\t') return '\\t';
|
|
40
|
-
if (ch == '\r') return '\\r';
|
|
41
|
-
if (ch == '\n') return '\\n';
|
|
42
|
-
return '\\x' + ch.charCodeAt(0).toString(16).padStart(2, '0');
|
|
43
|
-
}
|
|
44
|
-
return cmd.replace(/(["'\\])/g,'\\$1')
|
|
45
|
-
.replace(/[\x00-\x1F\x7F-\x9F]/g, func);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function ansi_c_escape(cmd: string): string {
|
|
49
|
-
return '"' + ansi_c_escape_contents(cmd) + '"';
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function shell_escape_contents(cmd: string): string {
|
|
53
|
-
return cmd.replace(/(["\r\n$`\\])/g,'\\$1');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function shell_escape(cmd: string): string {
|
|
57
|
-
return '"' + shell_escape_contents(cmd) + '"';
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function process_filename(filename: string): string {
|
|
61
|
-
const flags = /\.sv$/.test(filename) ? " -sv" : "";
|
|
62
|
-
return "read_verilog" + flags + " " + ansi_c_escape(filename);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
36
|
const verilator_re = /^%(Warning|Error)[^:]*: ([^:]*):([0-9]+):([0-9]+): (.*)$/;
|
|
66
37
|
|
|
67
38
|
export async function verilator_lint(filenames: string[], dirname?: string, options: Options = {}): Promise<LintMessage[]> {
|
|
68
39
|
try {
|
|
69
40
|
const output: LintMessage[] = [];
|
|
70
41
|
const verilator_result: {stdout: string, stderr: string} = await promisify(child_process.exec)(
|
|
71
|
-
|
|
42
|
+
`timeout -k10s 40s verilator ${prepare_verilator_args(filenames).join(' ')}`,
|
|
72
43
|
{maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000})
|
|
73
44
|
.catch(exc => exc);
|
|
74
45
|
for (const line of verilator_result.stderr.split('\n')) {
|
|
@@ -89,23 +60,15 @@ export async function verilator_lint(filenames: string[], dirname?: string, opti
|
|
|
89
60
|
}
|
|
90
61
|
|
|
91
62
|
export async function process(filenames: string[], dirname?: string, options: Options = {}): Promise<Output> {
|
|
92
|
-
const optimize_simp = options.optimize ? "; opt" : "; opt_clean";
|
|
93
|
-
const optimize = options.optimize ? "; opt -full" : "; opt_clean";
|
|
94
|
-
const fsmexpand = options.fsmexpand ? " -expand" : "";
|
|
95
|
-
const fsmpass = options.fsm == "nomap" ? "; fsm -nomap" + fsmexpand
|
|
96
|
-
: options.fsm ? "; fsm" + fsmexpand
|
|
97
|
-
: "";
|
|
98
63
|
const tmpjson = await tmp.tmpName({ postfix: '.json' });
|
|
99
64
|
let obj = undefined;
|
|
100
65
|
const yosys_result: {stdout: string, stderr: string, killed?: boolean, code?: number} = await promisify(child_process.exec)(
|
|
101
|
-
|
|
102
|
-
'; hierarchy -auto-top; proc' + optimize_simp + fsmpass + '; memory -nomap; wreduce -memx' +
|
|
103
|
-
optimize + '" -o "' + tmpjson + '"',
|
|
66
|
+
`timeout -k10s 40s yosys -p "${prepare_yosys_script(filenames, options)}" -o ${tmpjson}`,
|
|
104
67
|
{maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000})
|
|
105
68
|
.catch(exc => exc);
|
|
106
69
|
try {
|
|
107
70
|
if (yosys_result instanceof Error) {
|
|
108
|
-
if (yosys_result.killed)
|
|
71
|
+
if (yosys_result.killed)
|
|
109
72
|
yosys_result.message = "Yosys killed"
|
|
110
73
|
else if (yosys_result.code)
|
|
111
74
|
yosys_result.message = "Yosys failed with code " + yosys_result.code;
|