H5W3
当前位置:H5W3 > 其他技术问题 > 正文

LegUp使用及源码分析

本文主要记录由加拿大多伦多大学开发的开源高层次综合工具LegUp HLS的编译、使用方法及源码分析。

安装及使用

需要先导入clang-3.5的位置

echo "alias clang-3.5='~/clang+llvm-3.5.0-x86_64-linux-gnu/bin/clang-3.5'" >> ~/.bash_aliases && source ~/.bash_aliases
echo "alias clang-3.5++='~/clang+llvm-3.5.0-x86_64-linux-gnu/bin/clang-3.5++'" >> ~/.bash_aliases && source ~/.bash_aliases
export PATH=~/clang+llvm-3.5.0-x86_64-linux-gnu/bin:$PATH

以及Quartus vsim的位置

export QUARTUS_ROOTDIR=~/altera/15.0/quartus/
export PATH=~/altera/15.0/quartus/sopc_builder/bin/:$PATH
export PATH=~/altera/15.0/modelsim_ase/bin/:$PATH
export PATH=~/altera/15.0/quartus/bin/:$PATH

编译方法

  • 硬件流生成Verilog:make
  • ModelSim仿真:make v
  • Quartus创建项目:make p
  • Quartus后端综合:make f

程序结构

没有主函数!没有主函数!没有主函数!因为是直接生成动态库文件.so,所以实际上编译是用llvm/clang进行编译,然后链接所需的库文件而已。

对于llvm来说,新增一个库,即写一个pass,所以Legup的核心即为LegupPass.cpp

该文件第210行的runOnModule可以看作是它的主函数。

bool LegupPass::runOnModule(Module &M){ // schedule each function
...
// Schedule the operations in each function
for (Allocation::hw_iterator i = allocation->hw_begin(), ie =
allocation->hw_end(); i != ie; ++i) {
GenerateRTL *HW = *i;
HW->scheduleOperations();
}
...
}

接着对应的是GenerateRTL.cpp中第6780行的scheduleOperations

void GenerateRTL::scheduleOperations(){
dag = new SchedulerDAG;
dag->runOnFunction(*Fp, alloc); // build DAG!
if (!LEGUP_CONFIG->getParameterInt("NO_DFG_DOT_FILES")) {
printSchedulingDFGDot(*dag);
}
sched = new SDCScheduler(alloc);
sched->schedule(Fp, dag); // schedule!
fsm = sched->getFSM(Fp);
}

建图的过程可见SchedulerDAG.cpp第291行的runOnFunction

bool SchedulerDAG::runOnFunction(Function &F, Allocation *_alloc) {
// read in function and iterate all its instructions
...
for (Function::iterator b = F.begin(), be = F.end(); b != be; b++) {
for (BasicBlock::iterator instr = b->begin(), ie = b->end();
instr != ie; ++instr) {
updateDAGwithInst(instr); // add nodes
}
}
for (Function::iterator b = F.begin(), be = F.end(); b != be; b++) {
for (BasicBlock::iterator instr = b->begin(), ie = b->end();
instr != ie; ++instr) {
generateDependencies(instr); // add edges
}
}
...
}

都是以指令为单位进行处理,一条指令(instruction)就是一个操作(operation)。
updateDAGwithInst用来添加每条指令的时延(delay),generateDependencies则用来添加数据依赖(别名分析等)。

Legup存在的问题

  • SDC的调度没有办法跨基本块,进而导致不同基本块之间的指令无法处于同个状态

本文地址:H5W3 » LegUp使用及源码分析