视频教程
创建模块
#include <systemc.h>
// SC_MODULE声明模块,and2对应模块名
SC_MODULE(and2){
// sc_in声明输入端口,DT对应端口变量数据类型
sc_in<DT> a;
sc_in<DT> b;
// 声明时钟信号
sc_in<bool> clk;
// sc_out声明输出端口
sc_out<DT> f;
void func() {
// 输入端口读数据.read()
// 输出端口写数据.write()
f.write(a.read() & b.read());
}
// 模块构造函数
SC_CTOR(and2){
// 声明线程
SC_METHOD(func);
// 线程声明后紧接着声明敏感信号列表,以 << 号隔开
// 声明a和b为敏感信号
sensitive << a << b;
// 声明clk的上升沿为敏感信号,下降沿为.neg()
// sensitive << clk.pos();
}
}
Threads
-
A function made to act like a hardware process
- Run concurrently;
- Sensitive to signals, clock edges or fixed amounts of simulation time;
- Not called by the user, always active
-
支持三种threads
-
SC_METHOD()
-
Executes once every sensitive event
-
Run continuously
-
类似于Verilog @always block
-
可综合
- 组合逻辑或者简单时序逻辑
-
-
SC_THREAD()
-
只在simulation开始时运行一次
-
可以使用无限循环来以固定频率执行代码段
-
类似于Verilog @initial block
-
不可综合
- 在testbench中用于初始化、描述时钟等
-
-
SC_CTHREAD()
- “clocked thread”
- Run continuously
- References a clock edge
- 可综合
- Can take one or more clock cycles to execute a single iteration
-
-
Datatypes
-
SystemC has bit-accurate
-
Integer Datatypes
-
Unsigned and signed
sc_uint<N>- N是位宽
sc_int<N>
-
-
SC_CTHREAD Clocked Threads
-
SC_METHOD限制
- Limited to one cycle
- Fine for counters or simple sequential designs
- Not much different than hand coded RTL
- Can’t handle multi-cycle algorithms
-
SC_CTHREAD
-
Not limited to one cycle
-
Can contain continuous loops
-
Can contain large blocks of code with operations or control
-
Great for behavioral synthesis
-
SC_CTHREAD是SC_CTHREAD的一种特殊情况,SC_CTHREAD能产生更好的综合效果。SC_CTHREAD中可以使用wait()函数。
-
SC_CTHREAD中第二个参数需要传入时钟参数,(clk,pos()/clk.neg())
SC_CTHREAD(fir_main, clk.pos()); reset_signal_is(rst, true);
-
Testbench
-
Top level structural module
-
sc_main() funciton定义程序主函数
-
sc_signal<> 用于定义信号线连接模块之间的端口
-
sc_clock 定义clock信号
sc_clk clk_sig; // 构造函数中传入时钟信号,这里SC_NS指ns,10表示10ns为一个时钟周期 SC_CTOR(SYSTEM):clk_sig("clk_sig", 10, SC_NS)
-
-
sc_start()、sc_stop()开始和终止仿真
Handshaking
- valid/ready信号组
Latency
// 记录时间
sc_time start_time, end_time, clk_period;
start_time = sc_time_stamp();
// 获取时钟周期, clk是之前声明的时钟信号
sc_clock *clk_p = DCAST<sc_clock*>(clk.get_interface());
clock_period = clk_p -> period();