本文主要记录由加拿大多伦多大学开发的开源高层次综合工具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
编译方法
make
make v
make p
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
则用来添加数据依赖(别名分析等)。