学习目标:
- 学习如何使用Stratus IDE生成存储器模型
- 学习如何在代码中使用存储器模型
1.存储器生成
存储器生成使用Stratus IDE内置的存储器模型生成器,首先使用Stratus IDE打开工程,在左侧边栏中打开project选项卡,打开libraries,右键Memories,选择New Memory Library
新建存储器库,新建后可以在工程下发现同名文件夹
/1.png)
随后,右击新建的库memlib选择新建存储器,可以打开如下的界面进行配置:
- Memory name:存储器名称,使用存储器时使用该名称进行调用
- Word size:数据位宽,即每个地址存储多少个bit
- Number of words:地址数量,即有多少个word,存储容量为$Word size \times Number of words$bit
- Latency:从地址输入到数据输出消耗的时钟周期数量
- Setup time:通常意义的建立时间加保持时间,即控制信号需要在时钟沿附近保持的长度,不要写0。
- Output delay:输出延迟,即从时钟沿或数据输入到数据输出的延迟时间,不要写0。
- Area:面积,HLS将在综合报告中使用该面积(如果填写)
中间的Option部分可以选择时序的方式,时序有以下几种:
- Allow chaining:使用左侧的Setup time和Output delay计入延迟估算,在必要时插入寄存器
- Disallow chaining:不计入延迟估算,等效于Setup time和Output delay都填写0
- Registers at memories:强制插入寄存器
/2.png)
在这个页面填写常规信息后,点击上方的Port端口添加或编辑端口信息,该界面如下所示。可以通过编辑端口数量、选择端口类型和编辑端口名称,这些端口名称将在波形中体现。
/3.png)
随后点击OK即可生成存储器模型,生成的存储器模型文件结构如下所示:
/4.png)
在调用存储器模型的文件中,需要引用头文件memlib.h
2.存储器使用
在高级综合中使用存储器通过wrapper和port构成:
- wrapper:存储器模块,通过调用该模块生成存储器
- port:访问接口,在一个模块中声明一个存储器的port并将该port和wrapper指针连接即可进行存储器访问
对于wrapper,其声明方式为<memory name>::wrapper<ioConfig> * point
,例如声明一个名称为RAM的wrapper,命名为m_mem如下所示:
1 | RAM::wrapper<ioConfig> * m_mem; |
定义后需要在构造函数(SC_CTOR)中对其进行实例化和绑定clk和rst端口,如下所示:
1 | m_mem = new RAM::wrapper<ioConfig>("ram_wrapper"); |
对于port,声明方式为<memory name>::port<ioConfig> port
,例如声明一个名称为RAM的port,命名为ram_port如下所示:
1 | RAM::port<ioConfig> ram_port; |
同样的,需要在构造函数中绑定clk和rst端口:
1 | ram_port.clk_rst(clk, rst); |
并且需要在顶层将wrapper绑定到端口上,如下所示(m_dut为ram_port所属的模块):
1 | m_dut->ram_port(*m_mem); |
随后可以使用类似数组的方式对存储进行访问,访问方式如下所示:
1 | read_data = ram_port[i] // 从i地址读取数据 |
最后,需要在project.tcl中添加存储器库,使用use_hls_lib
指令,写法如下所示:
1 | use_hls_lib "./memlib" |
另外,对于一个存储器模型,具有以下的参数可以方便代码的编写:
名称 | 说明 |
---|---|
\ |
存储器word数量(Number of words) |
\ |
存储器地址位宽 |
\ |
存储器数据位宽 |
3.实际工程
这里实现了一个将memory集成的加法器功能,功能为输入一个数据i,从存储器的地址i获取数据并与i相加,加法部分模块如下所示:
1 |
|
1 |
|
顶层模块如下所示:
1 |
|
对于以上工程,project.tcl中的库部分如下所示:
1 | set LIB_PATH "[get_install_path]/share/stratus/techlibs/GPDK045/gsclib045_svt_v4.4/gsclib045/timing" |
除此之外,基本与之前的工程相同,进行仿真,不带流水线的结果如下所示:
/5.png)
带流水线的结果如下所示:
/6.png)
可以发现流水线有三级,分别是输入地址、获取输出和计算和。