edacation
Version:
Library and CLI for interacting with Yosys and nextpnr.
140 lines • 6.23 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateYosysSynthCommands = exports.generateYosysSynthPrepareCommands = exports.generateYosysRTLCommands = exports.getYosysWorkerOptions = exports.generateYosysWorkerOptions = exports.getYosysOptions = exports.getYosysDefaultOptions = void 0;
const path_1 = __importDefault(require("path"));
const util_js_1 = require("../util.js");
const devices_js_1 = require("./devices.js");
const target_js_1 = require("./target.js");
const DEFAULT_OPTIONS = {
optimize: true
};
const getFileIngestCommands = (inputFiles, options) => {
const commands = [];
// Load vhdl files
const vhdlFiles = inputFiles.filter((file) => util_js_1.FILE_EXTENSIONS_VHDL.includes(path_1.default.extname(file).substring(1)));
if (vhdlFiles.length) {
if (!options.topLevelModule) {
throw new Error('Top level module must be defined when synthesizing VHDL');
}
commands.push('plugin -i ghdl', `ghdl ${vhdlFiles.join(' ')} -e ${options.topLevelModule}`);
}
// Load verilog files
const verilogFiles = inputFiles.filter((file) => util_js_1.FILE_EXTENSIONS_VERILOG.includes(path_1.default.extname(file).substring(1)));
if (verilogFiles.length) {
commands.push(...verilogFiles.map((file) => `read_verilog -sv "${file}"`));
}
// (auto-)set top-level module
if (options.topLevelModule) {
commands.push(`hierarchy -top ${options.topLevelModule}`);
}
else {
commands.push('hierarchy -auto-top');
}
return commands;
};
const getSynthCommands = (arch, outFile) => {
const commands = [];
if (arch === 'generic') {
commands.push('synth;');
commands.push(`write_json "${outFile}";`);
}
else {
commands.push(`synth_${arch} -json "${outFile}";`);
}
return commands;
};
const getYosysDefaultOptions = (configuration) => (0, target_js_1.getDefaultOptions)(configuration, 'yosys', DEFAULT_OPTIONS);
exports.getYosysDefaultOptions = getYosysDefaultOptions;
const getYosysOptions = (configuration, targetId) => (0, target_js_1.getOptions)(configuration, targetId, 'yosys', DEFAULT_OPTIONS);
exports.getYosysOptions = getYosysOptions;
const generateYosysWorkerOptions = (configuration, projectInputFiles, targetId) => {
const target = (0, target_js_1.getTarget)(configuration, targetId);
const options = (0, exports.getYosysOptions)(configuration, targetId);
const vendor = devices_js_1.VENDORS[target.vendor];
const family = vendor.families[target.family];
const inputFiles = projectInputFiles
.filter((inputFile) => inputFile.type === 'design' && util_js_1.FILE_EXTENSIONS_HDL.includes(path_1.default.extname(inputFile.path).substring(1)))
.map((file) => file.path);
const outputFiles = [(0, target_js_1.getTargetFile)(target, `${family.architecture}.json`)];
const tool = 'yosys';
const commands = [...getFileIngestCommands(inputFiles, options), 'proc;'];
if (options.optimize) {
commands.push('opt;');
}
commands.push(...getSynthCommands(family.architecture, outputFiles[0]));
return {
inputFiles,
outputFiles,
target,
options,
steps: [
{
tool,
arguments: [],
commands
}
]
};
};
exports.generateYosysWorkerOptions = generateYosysWorkerOptions;
const getYosysWorkerOptions = (project, targetId) => {
const generated = (0, exports.generateYosysWorkerOptions)(project.getConfiguration(), project.getInputFiles(), targetId);
const inputFiles = (0, target_js_1.getCombined)(project.getConfiguration(), targetId, 'yosys', 'inputFiles', generated.inputFiles).filter((f) => !!f);
const outputFiles = (0, target_js_1.getCombined)(project.getConfiguration(), targetId, 'yosys', 'outputFiles', generated.outputFiles).filter((f) => !!f);
const target = generated.target;
const options = generated.options;
const steps = generated.steps.map((step) => {
const tool = step.tool;
const args = step.arguments;
const commands = (0, target_js_1.getCombined)(project.getConfiguration(), targetId, 'yosys', 'commands', step.commands);
return { tool, arguments: args, commands };
});
return {
inputFiles,
outputFiles,
target,
options,
steps
};
};
exports.getYosysWorkerOptions = getYosysWorkerOptions;
const generateYosysRTLCommands = (workerOptions) => {
// Yosys commands taken from yosys2digitaljs (https://github.com/tilk/yosys2digitaljs/blob/1b4afeae61/src/index.js#L1225)
return [
...getFileIngestCommands(workerOptions.inputFiles, workerOptions.options),
'proc;',
'opt;',
'memory -nomap;',
'wreduce -memx;',
'opt -full;',
`tee -q -o ${(0, target_js_1.getTargetFile)(workerOptions.target, 'stats.yosys.json')} stat -json -width *;`,
`write_json "${(0, target_js_1.getTargetFile)(workerOptions.target, 'rtl.yosys.json')}";`,
''
];
};
exports.generateYosysRTLCommands = generateYosysRTLCommands;
const generateYosysSynthPrepareCommands = (workerOptions) => {
return [
...getFileIngestCommands(workerOptions.inputFiles, workerOptions.options),
'proc;',
'opt;',
`write_json "${(0, target_js_1.getTargetFile)(workerOptions.target, 'presynth.yosys.json')}";`,
''
];
};
exports.generateYosysSynthPrepareCommands = generateYosysSynthPrepareCommands;
const generateYosysSynthCommands = (workerOptions) => {
const target = workerOptions.target;
const vendor = devices_js_1.VENDORS[target.vendor];
const family = vendor.families[target.family];
return [
`read_json "${(0, target_js_1.getTargetFile)(workerOptions.target, 'presynth.yosys.json')}"`,
...getSynthCommands(family.architecture, workerOptions.outputFiles[0]),
''
];
};
exports.generateYosysSynthCommands = generateYosysSynthCommands;
//# sourceMappingURL=yosys.js.map