import * as vscode from 'vscode'; import { ChildProcessWithoutNullStreams, exec, spawn } from 'child_process'; import * as fspath from 'path'; import * as fs from 'fs'; import { AbsPath, opeParam, PrjInfo } from '../../global'; import { hdlParam } from '../../hdlParser/core'; import { hdlFile, hdlDir, hdlPath } from '../../hdlFs'; import { PropertySchema } from '../../global/propertySchema'; import { XilinxIP } from '../../global/enum'; import { HardwareOutput, MainOutput, ReportType } from '../../global/outputChannel'; import { debounce, getPIDsWithName, killProcess } from '../../global/util'; import { t } from '../../i18n'; import { HdlFileProjectType } from '../../hdlParser/common'; const syn = ` `; const pnr = ` `; const bit = ` `; const debug = ` `; const security = ` `; export interface ePLContext { // 保留启动上下文 terminal? : vscode.Terminal, // 目前使用的启动上下文 process?: ChildProcessWithoutNullStreams, // 工具类型 tool? : string, // 第三方工具运行路径 path? : string, // 操作类 ope : EfinityOperation, }; export class EfinityOperation { script: string; efxPath: string; constructor() { this.script = ''; this.efxPath = hdlPath.join(opeParam.workspacePath, `${opeParam.prjInfo.prjName.PL}.xml`); } private getDeviceInfo(device: string): string { const deviceInfo = device.split('-'); let family = 'Trion'; if (device.slice(0, 2).toLowerCase() === 'ti') { family = 'Titanium'; } return ` `; } private getDesignInfo(): string { let designFile = ` \n`; for (const hdlFile of hdlParam.getAllHdlFiles()) { switch (hdlFile.projectType) { case HdlFileProjectType.Src: case HdlFileProjectType.LocalLib: case HdlFileProjectType.RemoteLib: case HdlFileProjectType.Sim: designFile += ` \n`; break; case HdlFileProjectType.IP: case HdlFileProjectType.Primitive: // IP 和 原语不用管 break; default: break; } } designFile += ` ` return ` \n${designFile} ` }; private getConstraintInfo(): string { let constraintFile = ''; hdlFile.pickFileRecursive(opeParam.prjInfo.arch.hardware.data, filePath => { if (filePath.endsWith('.sdc')) { constraintFile += ` \n`; } }); constraintFile += ` \n`; return ` \n${constraintFile} `; } public launch() { this.script = `\n${this.getDeviceInfo(opeParam.prjInfo.device)}\n${this.getDesignInfo()}\n${this.getConstraintInfo()}\n \n \n \n${syn}\n${pnr}\n${bit}\n${debug}\n${security}\n`; fs.writeFileSync(this.efxPath, this.script); } public build() { exec(`${this.updateEfinixPath()} ${this.efxPath} --flow compile --work_dir=${opeParam.workspacePath}/prj/efinix --output_dir ${opeParam.workspacePath}/prj/efinix/outflow --cleanup_work_dir work_pt`, (error, stdout, stderr) => { console.log(error); }) } public updateEfinixPath(): string { const efinixBinFolder = vscode.workspace.getConfiguration('digital-ide.prj.efinix.install').get('path') || ''; if (hdlFile.isDir(efinixBinFolder)) { let efinixPath = hdlPath.join(hdlPath.toSlash(efinixBinFolder), 'efx_run'); if (opeParam.os === 'win32') { efinixPath += '.bat'; } return efinixPath; } else { // 没有设置 Efinix bin 文件夹,就认为用户已经把对应的路径加入环境变量了 return 'efx_run'; } } }