UNPKG

edacation

Version:

Library and CLI for interacting with Yosys and nextpnr.

140 lines 6.23 kB
"use strict"; 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