UNPKG

edacation

Version:

Library and CLI for interacting with Yosys and nextpnr.

157 lines 7.08 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getYosysSynthesisWorkerOptions = exports.getYosysRTLWorkerOptions = exports.getYosysOptions = 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, topLevelModule: undefined, synthArguments: undefined, }; const getYosysOptions = (configuration, targetId) => (0, target_js_1.getOptions)(configuration, targetId, 'yosys', DEFAULT_OPTIONS); exports.getYosysOptions = getYosysOptions; 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 getInputFiles = (project, targetId) => { const generatedInputFiles = project.getInputFiles() .filter((inputFile) => inputFile.type === 'design' && util_js_1.FILE_EXTENSIONS_HDL.includes(path_1.default.extname(inputFile.path).substring(1))) .map((file) => file.path); return (0, target_js_1.getCombined)(project.getConfiguration(), targetId, 'yosys', 'inputFiles', generatedInputFiles).filter((f) => !!f); }; const getOutputFiles = (project, targetId, files) => { const target = project.getTarget(targetId); if (target === null) throw new Error('Target not found'); const generatedOutputFiles = files.map(f => (0, target_js_1.getTargetFile)(target.config, f)); return (0, target_js_1.getCombined)(project.getConfiguration(), targetId, 'yosys', 'outputFiles', generatedOutputFiles).filter((f) => !!f); }; const getYosysRTLWorkerOptions = (project, targetId) => { const configuration = project.getConfiguration(); const target = (0, target_js_1.getTarget)(configuration, targetId); const options = (0, exports.getYosysOptions)(configuration, targetId); // Input files const inputFiles = getInputFiles(project, targetId); // Output files const outputFiles = getOutputFiles(project, targetId, ["stats.yosys.json", "rtl.yosys.json"]); // Commands const generatedCommands = [ ...getFileIngestCommands(inputFiles, options), 'proc;', ]; if (options.optimize) generatedCommands.push('opt;'); generatedCommands.push('memory -nomap;'); if (options.optimize) generatedCommands.push('wreduce -memx;', 'opt -full;'); generatedCommands.push(`tee -q -o "${(0, target_js_1.getTargetFile)(target, 'stats.yosys.json')}" stat -json -width *;`, `write_json "${(0, target_js_1.getTargetFile)(target, 'rtl.yosys.json')}";`, ''); const commands = (0, target_js_1.getCombined)(configuration, targetId, 'yosys', 'rtlCommands', generatedCommands); const encoder = new TextEncoder(); return { inputFiles, outputFiles, target, options, steps: [ { id: 'rtl', tool: 'yosys', arguments: ['rtl.ys'], generatedInputFiles: [ { name: 'rtl.ys', content: encoder.encode(commands.join('\n')) } ], commands, } ] }; }; exports.getYosysRTLWorkerOptions = getYosysRTLWorkerOptions; const getYosysSynthesisWorkerOptions = (project, targetId) => { const configuration = project.getConfiguration(); 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]; // Input files const inputFiles = getInputFiles(project, targetId); // Output files const outputFiles = getOutputFiles(project, targetId, [`${family.architecture}.json`]); // Commands (preparation) const generatedPrepareCommands = [ ...getFileIngestCommands(inputFiles, options), 'proc;', ]; if (options.optimize) generatedPrepareCommands.push('opt;'); generatedPrepareCommands.push(`write_json "${(0, target_js_1.getTargetFile)(target, 'presynth.yosys.json')}";`, ''); const prepareCommands = (0, target_js_1.getCombined)(configuration, targetId, 'yosys', 'synthPrepareCommands', generatedPrepareCommands); // Commands (synthesis) const generatedSynthCommands = [ `read_json "${(0, target_js_1.getTargetFile)(target, 'presynth.yosys.json')}";`, ]; const synthArgs = options.synthArguments || ''; if (family.architecture === 'generic') { generatedSynthCommands.push(`synth ${synthArgs};`); generatedSynthCommands.push(`write_json "${(0, target_js_1.getTargetFile)(target, family.architecture)}.json";`); } else { generatedSynthCommands.push(`synth_${family.architecture} -json "${(0, target_js_1.getTargetFile)(target, family.architecture)}.json" ${synthArgs};`); } generatedSynthCommands.push(''); const synthCommands = (0, target_js_1.getCombined)(configuration, targetId, 'yosys', 'synthCommands', generatedSynthCommands); const encoder = new TextEncoder(); return { inputFiles, outputFiles, target, options, steps: [ { id: 'prepare', tool: 'yosys', arguments: ['synth-prepare.ys'], generatedInputFiles: [ { name: 'synth-prepare.ys', content: encoder.encode(prepareCommands.join('\n')) } ], commands: prepareCommands, }, { id: 'synth', tool: 'yosys', arguments: ['synth.ys'], generatedInputFiles: [ { name: 'synth.ys', content: encoder.encode(synthCommands.join('\n')) } ], commands: synthCommands, } ] }; }; exports.getYosysSynthesisWorkerOptions = getYosysSynthesisWorkerOptions; //# sourceMappingURL=yosys.js.map