学习目标为:
Stratus允许指定一个主循环(while(1)
)中的内容为流水线方式实现,即每个时钟周期均可以进入数据执行,需要在主循环开始时添加如下语句指定使用流水线实现:
HLS_PIPELINE_LOOP(<STALL_TYPE>, <cycle>, <name>);
上述指定该loop为流水线实现,具有三个参数,分别如下所示:
HARD_STALL
和SOFT_STALL
两种对于STALL_TYPE中的两种,具有以下的区别:
HARD_STALL
:当流水线的某一级阻塞时,整条流水线停止运行SOFT_STALL
:当流水线的某一级阻塞时,仅阻塞级之前的流水线停止运行,阻塞级之后的流水线继续运行对于要生成流水线的代码片(循环体),Stratus有以下的要求:
Unable to satisfy HLS_HLS_PIPELINE_LOOP directive "main_pipeline",possibly because of a statement in this line.
Pipelining forces multiple assignments to output data_out
学习过程使用上一次使用的+1功能电路,将其执行线程改为以下按流水线展开:
void dut_template::t() {
{
HLS_DEFINE_PROTOCOL("reset");
x_in.reset();
y_out.reset();
wait();
}
while(1) {
// HLS_PIPELINE_LOOP(HARD_STALL, 1, "main_loop");
HLS_PIPELINE_LOOP(SOFT_STALL, 1, "main_loop");
DT x_val = x_in.get();
DT out_val = x_val + 1;
y_out.put(out_val);
}
}
这里使用了输入间隔为1个周期(每个周期均可输入)的SOFT_STALL形式的流水线。
为了观察流水线功能,这次将两个+1功能模块dut_template
连在一起进行仿真,顶层为pipeline_test
,代码如下所所示:
#ifndef _DUT_PIPE
#define _DUT_PIPE
#include "cynw_p2p.h"
#include "cynw_fifo.h"
#include "defines.h"
#include "dut_template_wrap.h"
SC_MODULE(pipeline_test) {
public:
cynw_p2p<DT, ioConfig>::base_in x_in;
cynw_p2p<DT, ioConfig>::base_out y_out;
cynw_p2p<DT, ioConfig> tmp;
sc_in_clk clk;
sc_in<bool> rst;
dut_template_wrapper *ut0;
dut_template_wrapper *ut1;
SC_CTOR(pipeline_test):
x_in("x_in"),y_out("y_out"),tmp("tmp"),
clk("clk"),rst("rst") {
ut0 = new dut_template_wrapper("ut0");
ut0->clk(clk);
ut0->rst(rst);
ut0->x_in(x_in);
ut0->y_out(tmp);
ut1 = new dut_template_wrapper("ut1");
ut1->clk(clk);
ut1->rst(rst);
ut1->x_in(tmp);
ut1->y_out(y_out);
}
// void t(); 不可调用函数进行连线!!!
};
#endif
首先关注使用的p2p接口如下所示:
cynw_p2p<DT, ioConfig>::base_in x_in;
cynw_p2p<DT, ioConfig>::base_out y_out;
需要注意的是本次使用了base_in
和base_out
而不是in
和out
(参考笔记1),因为这两个端口的目的仅仅为连接使用,相当于连线,因此不需要使用in
和out
,也不需要指定时钟与复位信号。随后关注调用部分:
dut_template_wrapper *ut0;
dut_template_wrapper *ut1;
这里的调用方式为调用dut_template_wrapper
而不是dut_template
,这是Stratus的区别,若要在高级综合中保留层次结构,则需要在这里调用wrapper
而不是本身,对应的,也需要在tcl中指定子模块dut_template
为待综合模块。最后一点需要注意的是,SC_CTOR
中连线部分需要在本函数中编写,不可像system中一样调用函数进行连线,否则会在仿真过程中产生问题。该设计对应的project.tcl如下所示:
...
use_tech_lib "$LIB_PATH/$LIB_LEAF"
set_attr clock_period 10.0
set_attr message_detail 3
set_attr default_input_delay 0.1
set_attr cc_options " -g --std=c++0x"
enable_waveform_logging -vcd
set_attr end_of_sim_command "make saySimPassed"
define_system_module basic_ut/main.cpp
define_system_module basic_ut/system.cpp
define_system_module basic_ut/tb.cpp
define_hls_module pipeline_test dut_module/pipeline_test.cpp
define_hls_module dut_template dut_module/dut_template.cpp # 子模块也需要指定为待综合模块
define_io_config * TLM
define_io_config * PIN
define_hls_config pipeline_test BASIC
define_hls_config dut_template BASIC # 子模块也需要指定综合等级
define_sim_config T -io_config TLM
define_sim_config B -io_config PIN
define_sim_config H {pipeline_test RTL_V BASIC}
仿真结束后使用verdi查看波形,未添加流水线的波形如下所示:
可以发现这种情况下每两个周期才能输入一个数据,添加了流水线的波形如下所示:
添加了流水线展开后,可以发现每个时钟周期均可输入新的数据。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有