高級綜合工具Stratus學(xué)習(xí)筆記(1)

本次學(xué)習(xí)參考Stratus內(nèi)置的學(xué)習(xí)例程(simple_p2p)挠唆,學(xué)習(xí)內(nèi)容主要如下所示:

  • Stratus HLS軟件運行需要的必要文件及其寫法
  • Stratus HLS軟件操作方式
  • Stratus HLS內(nèi)置的p2p端口的基本使用(非流水線)
  • Stratus HLS自定義數(shù)據(jù)類型

1.Stratus HLS必要文件與寫法

Stratus工程所需要的文件如下圖所示:

文件 類型 說明
設(shè)計文件 cpp+h 描述設(shè)計的頭文件和cpp文件
TestBench cpp+h 描述測試平臺的頭文件和cpp文件
System cpp+h 連接設(shè)計文件和TestBench的頭文件和cpp文件
main.cpp cpp 整個仿真平臺的頂層文件
project.tcl tcl 指定工程配置(仿真選項和綜合選項)的tcl文件
Makefile makefile 由project.tcl生成的makefile文件

1.1.設(shè)計文件

設(shè)計文件的頭文件如下所示:

#ifndef __NEW1__H
#define __NEW1__H

#include "cynw_p2p.h"  // p2p端口的頭文件,如需使用cynw_p2p則需要引用該頭文件

#include "new1_input_type.h" // 類型new1_INPUT_DT的頭文件
#include "new1_output_type.h" // 類型new1_OUTPUT_DT的頭文件

SC_MODULE(new1) {  // 定義模塊new1
    public:
    cynw_p2p < new1_INPUT_DT  >::in     inputs;  // 一個p2p輸入端口
    cynw_p2p < new1_OUTPUT_DT >::out    outputs; // 一個p2p輸出端口
    
    // Declaration of clock and reset parameters
    sc_in_clk               clk;                 // 時鐘端口狈谊,類型為sc_in_clk
    sc_in < bool >          rst;                 // 復(fù)位端口
    SC_CTOR(new1):inputs("inputs"), outputs("outputs"), clk("clk"), rst("rst") {// 構(gòu)造函數(shù)
        SC_CTHREAD(thread1, clk.pos());          // 定義線程thread1,綁定時鐘上升沿
        reset_signal_is(rst,0);                  // 定義復(fù)位為0時有效
        
        // Connect the clk and rst signals to the metaports
        inputs.clk_rst(clk, rst);                // 綁定輸入端口的時鐘和復(fù)位
        outputs.clk_rst(clk, rst);               // 綁定輸出端口的時鐘和復(fù)位
    }
    void thread1();
    
    new1_OUTPUT_DT my_function(new1_INPUT_DT);
};

#endif

在設(shè)計頭文件中作瞄,定義了一個模塊new1美莫,具有一個p2p輸入端口和一個p2p輸出端口以及時鐘和復(fù)位端口,并聲明函數(shù)thread1為線程瓣窄,為其綁定了時鐘和復(fù)位,thread1的實現(xiàn)在cpp文件中如下所示:

#include "new1.h"

// The thread function for the design
void new1::thread1(){
    // Reset the interfaces
    { // 復(fù)位行為部分
        CYN_PROTOCOL("reset");
        
        inputs.reset();  // 輸入端口復(fù)位
        outputs.reset(); // 輸出端口復(fù)位
        
        wait();          // 復(fù)位行為以wait結(jié)束
    }
    
    // Main execution loop
    while (1){  // 模塊行為被包括在該無限循環(huán)中
        new1_INPUT_DT  input_val = inputs.get();   // get為阻塞的從input端口中獲取一個數(shù)據(jù)     
        new1_OUTPUT_DT output_val = my_function(input_val); // 執(zhí)行數(shù)據(jù)處理
        outputs.put(output_val);   // put為阻塞的發(fā)送一個數(shù)據(jù)
    }
}
//
//  User's computation function
//
new1_OUTPUT_DT new1::my_function(new1_INPUT_DT var){ // 進行數(shù)據(jù)處理纳鼎,處理方式為+1
    new1_OUTPUT_DT my_outputs;
    my_outputs.out1 = var.in1 + 1;
    return (my_outputs);
}

1.2.TB文件

TestBench的頭文件如下所示俺夕,其定義了一個模塊tb,其他部分預(yù)設(shè)計文件類似

#ifndef __TB__H
#define __TB__H

#include "cynw_p2p.h"

#include "new1_input_type.h"
#include "new1_output_type.h"

SC_MODULE(tb)
{
    public:
    cynw_p2p < new1_OUTPUT_DT >::base_in    inputs;
    cynw_p2p < new1_INPUT_DT >::base_out    outputs;
    
    // Declaration of clock and reset parameters
    sc_in_clk                   clk;
    sc_out < bool >             rst;
    sc_in < bool >              rst_in; // sampling version of "rst"
    
    SC_CTOR(tb)
    {
        SC_CTHREAD(source, clk.pos());
        SC_CTHREAD(sink, clk.pos());
        reset_signal_is(rst_in,0);
        rst_in(rst);
    }
    void source();
    void sink();
};

#endif

tb定義了source和sink兩個線程贱鄙,線程描述如下所示:

#include "tb.h"

// Source thread
void tb::source(){
    // Reset the output metaport and cycle the design's reset
    outputs.reset();    // 輸出端口復(fù)位
    
    // 端口復(fù)位劝贸,拉低rst兩個時鐘周期后拉高
    rst = 0;
    wait(2);
    rst = 1;
    wait();
    
    // 輸入激勵,這里的激勵是從0發(fā)到9
    for (int i = 0; i < 10; i++){
        // Write values to the DUT
        new1_INPUT_DT tmp;
        tmp.in1 = i;
        outputs.put(tmp);
    }
}

// Read all the expected values from the design
void tb::sink() {
    inputs.reset();      // 復(fù)位行為
    wait();                     // to synchronize with reset

    // 接收10個輸出后結(jié)束
    for (int i = 0; i < 10; i++) {
        // Read values from the DUT
        new1_OUTPUT_DT input_val = inputs.get();
        // printf("%d\n", input_val);
        cerr << "Read " << input_val.out1 << "\n";
    }
    esc_stop();
}

可以發(fā)現(xiàn)TB的行為沒有按設(shè)計文件編寫逗宁,因為TB并需要綜合映九,所以可以用更符合C的方式編寫。

1.3.system文件

system文件用于連接TB和設(shè)計瞎颗,頭文件如下所示:

#ifndef SYSTEM_H_INCLUDED
#define SYSTEM_H_INCLUDED

#include <systemc.h>
#include <esc.h>
#include "cynw_p2p.h"

#include "tb.h"
#include "new1_input_type.h"
#include "new1_output_type.h"
#include "new1_wrap.h"

SC_MODULE(TOP)
{
    public:
    // cynw_p2p channels
    cynw_p2p < new1_INPUT_DT >      inputs_chan;
    cynw_p2p < new1_OUTPUT_DT >     outputs_chan;
    
    // clock and reset signals
    sc_clock            clk;
    sc_signal < bool >  rst;
    // The testbench and DUT modules.
    new1_wrapper *m_dut;  // 聲明指向設(shè)計的指針
    tb   *m_tb;           // 聲明指向tb的指針
    
    void initInstances();
    void deleteInstances();
    
    SC_CTOR(TOP): clk("clk", 5, SC_NS, 0.5, 0, SC_NS, true),  // 定義時鐘
        inputs_chan("inputs_chan"),
        outputs_chan("outputs_chan"),
        rst("rst")
    {
        initInstances();
    }
    
    ~TOP()
    {
        deleteInstances();
    }
};

#endif // SYSTEM_H_INCLUDED

system定義了模塊TOP件甥,即整個仿真系統(tǒng)的頂層,使用指針的方式聲明子模塊哼拔,需要注意的是引有,Stratus會自動為設(shè)計的模塊添加wrapper,因此設(shè)計指針的類型為new1_wrapper而不是new管挟,連線的部分在cpp文件中如下所示:

#include "system.h"

void TOP::initInstances()
{
    m_dut = new new1_wrapper("new1_wrapper");
    
    // Connect the design module
    m_dut->clk(clk);
    m_dut->rst(rst);
    m_dut->inputs(inputs_chan);
    m_dut->outputs(outputs_chan);
    
    
    // Connect the testbench
    m_tb = new tb("tb");
    m_tb->clk(clk);
    m_tb->rst(rst);
    m_tb->outputs(inputs_chan);
    m_tb->inputs(outputs_chan);
}

void TOP::deleteInstances()
{
    delete m_tb;
    delete m_dut;
}

1.4.main

main文件用于啟動仿真轿曙、連接設(shè)計和連接聯(lián)合仿真等功能,一般不需要修改僻孝,main.cpp文件如下所示:

#include "system.h"

TOP *top = NULL;

extern void esc_elaborate() {
    top = new TOP("top");
}

extern void  esc_cleanup() {
    delete top;
}

int sc_main(int argc, char *argv[]) {
    esc_initialize(argc, argv);
    esc_elaborate();
    sc_start();
    return 0;
}

1.5.project.tcl

project.tcl用于指定綜合信息和仿真信息,其主體主要需要執(zhí)行以下步驟:

  • 指定庫信息
  • 指定時鐘信息
  • 設(shè)置仿真信息守谓,包括仿真工具信息和仿真平臺信息
  • 設(shè)置高級綜合信息
  • 設(shè)置物理綜合信息(如果需要)
# 設(shè)置物理庫信息穿铆,這里的寫法可以照抄,調(diào)用的是Stratus內(nèi)置的一個庫
set LIB_PATH "[get_install_path]/share/stratus/techlibs/GPDK045/gsclib045_svt_v4.4/gsclib045/timing"
set LIB_LEAF "slow_vdd1v2_basicCells.lib"
use_tech_lib    "$LIB_PATH/$LIB_LEAF" # 設(shè)置物理庫

# set clock:設(shè)置時鐘庫
set_attr clock_period 5.0 # 設(shè)置時鐘周期為5ns
set_attr default_input_delay 0.1 # 設(shè)置輸入delay為0.1ns

# message level
set_attr message_detail 2 # 設(shè)置信息等級為2

# set dump setting:設(shè)置仿真工具信息
use_verilog_simulator incisive # 使用仿真器incisive(Stratus內(nèi)置斋荞,其實為ncverilog)
set_attr cc_options             " -g"  # 仿真后選項荞雏,可直接照抄
enable_waveform_logging -vcd  # 設(shè)置輸出波形文件為vcd,還可以選擇fsdb
set_attr end_of_sim_command "make saySimPassed" # 仿真后執(zhí)行的命令

# system config:設(shè)置仿真平臺信息,這一步需要設(shè)置所有描述不需要進行綜合部分的文件為system_module
define_system_module main.cpp  # 設(shè)置main為system_module
define_system_module system.cpp # 設(shè)置system部分為system_module
define_system_module tb.cpp # 設(shè)置仿真平臺tb為system_module

# hls config:設(shè)置高級綜合信息
define_hls_module new1 new1.cpp # 設(shè)置hls_module為new1
define_hls_config new1 BASIC    # 設(shè)置hls_config為BASIC
# define_hls_config new1 DPA --dpopt_auto=op,expr

# 設(shè)置仿真信息
define_sim_config B "new1 RTL_V BASIC" # 定義仿真目標(biāo)凤优,仿真目標(biāo)為RTL_V級

設(shè)置物理庫到設(shè)置仿真平臺信息都比較容易理解悦陋,比較復(fù)雜的是設(shè)置高級綜合信息這個部分。高級綜合信息的設(shè)置分為兩個部分筑辨,分別是設(shè)置待綜合的模塊和綜合等級俺驶,分別對應(yīng)define_hls_moduledefine_hls_config命令。define_hls_module用于指定高級綜合的對象棍辕,即指定待綜合的模塊和描述該模塊的文件指令如下所示:

define_hls_module 模塊名 文件名

一個例子如下所示暮现,指定需要對new1.cpp的中包含的new1模塊進行高級綜合:

define_hls_module new1 new1.cpp

第二個部分為指定高級綜合等級,高級綜合具有多個等級楚昭,對應(yīng)不同的性能和面積的折中栖袋,這里使用BASIC,指定指令如下所示:

define_hls_config 模塊名 綜合等級
define_hls_config new1 BASIC # 指定模塊new1高級綜合等級為BASIC

隨后需要設(shè)置仿真信息抚太,只能對一個高級綜合對象進行仿真塘幅,每次進行高級綜合,生成3個模型尿贫,RTL_V是其中的一種晌块,設(shè)置仿真信息需要指定對哪一個高級綜合等級的哪一個高級綜合對象中的哪一個模型進行仿真,仿真指令如下所示:

define_sim_config 配置名稱 "模塊名稱 模型類型 綜合等級"
define_sim_config B "new1 RTL_V BASIC" # 定義仿真目標(biāo)帅霜,仿真目標(biāo)為RTL_V級

1.6.Makefile

Makefile由project.tcl直接生成匆背,不需要手動編寫

2.操作方式

2.1.makefile生成

Makefile通過project.tcl自動生成,指令如下所指示:

bdw_makegen project.tcl

2.2.進行高級綜合

高級綜合指令如下所示:

make hls_配置名稱

例如上述腳本身冀,高級綜合指令為:

make hls_B

生成的文件位于bdw_work/modules文件夾下

2.3.進行仿真

進行仿真指令的命令如下所示:

make sim_配置名稱

例如上述腳本钝尸,進行仿真指令為:

make sim_B

生成的波形文件位于bdw_work/sim文件夾下

3.debug

當(dāng)dump fsdb波形時,會發(fā)生fsdb連接的錯誤搂根,此時解決方法為:

  • 進行make clean操作
  • 將dump的波形類型改為vcd并重新生成Makefile
  • 進行仿真
  • 將dump類型的模型改為fsdb并重新生成Makefile
  • 進行仿真即可
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末珍促,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子剩愧,更是在濱河造成了極大的恐慌猪叙,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仁卷,死亡現(xiàn)場離奇詭異穴翩,居然都是意外死亡,警方通過查閱死者的電腦和手機锦积,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門芒帕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丰介,你說我怎么就攤上這事背蟆〖郑” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵带膀,是天一觀的道長志珍。 經(jīng)常有香客問我,道長垛叨,這世上最難降的妖魔是什么伦糯? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮点额,結(jié)果婚禮上舔株,老公的妹妹穿的比我還像新娘。我一直安慰自己还棱,他們只是感情好载慈,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著珍手,像睡著了一般办铡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上琳要,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天寡具,我揣著相機與錄音,去河邊找鬼稚补。 笑死童叠,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的课幕。 我是一名探鬼主播厦坛,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼乍惊!你這毒婦竟也來了杜秸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤润绎,失蹤者是張志新(化名)和其女友劉穎撬碟,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體莉撇,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡呢蛤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了稼钩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顾稀。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖坝撑,靈堂內(nèi)的尸體忽然破棺而出静秆,到底是詐尸還是另有隱情,我是刑警寧澤巡李,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布抚笔,位于F島的核電站,受9級特大地震影響侨拦,放射性物質(zhì)發(fā)生泄漏殊橙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一狱从、第九天 我趴在偏房一處隱蔽的房頂上張望膨蛮。 院中可真熱鬧,春花似錦季研、人聲如沸敞葛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惹谐。三九已至,卻和暖如春驼卖,著一層夾襖步出監(jiān)牢的瞬間氨肌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工酌畜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怎囚,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓桥胞,卻偏偏與公主長得像恳守,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子埠戳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容