3.7 KiB
3.7 KiB
@TOC
1 function中的automatic VS static
在SV/Verilog中的的function声明动态automatic使用场景; automatic关键字主要是用于解决递归调用和并发执行时候的变量存储问题; 首先可综合与不可综合等是和这个automatic关键字是没有关系的;该关键字只是用于跑仿真时的函数体变量存储位置情况;
1.0 关键特性对比
存储类型:Auto: 动态分配栈存储 Static:静态存储--类似全局变量; 递归支持:Auto:支持 Static:不支持 并发调用安全:线程安全; Static:可能数据竞争 初始化行为:每次调用独立初始化; Static:保持上次调用状态 典型应用场景:递归/冲入调用; Static:状态保持的计算;
1.1 可综合function
原则:可综合function一般是只能综合成纯组合逻辑; 因此: 1.仅包含纯计算逻辑; 2.不包含时序语句(综合和仿真的时序语句:@(posedge),wati,#delay等) 3.不包含时序控制语句;
好的实践:
// 标注可综合属性
(* synthesize *)
function automatic checksum;
input xxx;
input xxx;
return checksum;
endfunction
1.2 使用场景
必须使用auto情况: 1.函数会被多个并行进程调用; 2.需要保证每次调用独立性的计算逻辑; 使用Static情况: 1.需要保持调用间状态的计算; 2.对仿真性能要求高的简单计算;
1.3 Demo
1.递归函数调用
// 计算阶乘的递归函数
function automatic integer factorial;
input integer n;
if (n <= 1)
factorial = 1;
else
factorial = n * factorial(n-1); // 递归调用
endfunction
2.在多处并行调用的函数
// 在多处并行调用的函数
function automatic int count_ones;
input [31:0] data;
count_ones = 0;
for (int i=0; i<32; i++)
if (data[i]) count_ones++;
endfunction
fork
a_out = count_ones(a_in); // 可能同时多处调用
b_out = count_ones(b_in);
join
1.4 小结
- automatic函数会占用更多内存,因为每次调用都会创建新的变量副本;
- SystemVerilog中默认所有函数都是automatic的;
- 在Verilog-2001中需要显式声明automatic; 当需要递归调用、并行安全或独立变量存储时使用automatic函数,简单无状态的操作使用普通函数即可。
2 不适用异步复位或完全不适用复位的场景及优势
一般来说这不使用异步复位,是需要特别关注的,否则真的是把握不住,容易出问题 但是经常会在IP上看到过,比如S家,C家和ARM的IP就经常会遇到;
2.1 适用场景
2.1.1 数据通路寄存器
// 流水线中间级寄存器,不需要复位
always @(posedge clk)
data_stage2 <= data_stage1; // 仅时钟驱动
2.1.2 时钟使能控制的寄存器
// 仅通过时钟使能控制
always @(posedge clk) begin
if (clk_en)
data_reg <= new_data; // 不需要复位
end
2.1.3 状态保持寄存器
(* no_reset *)
reg [3:0] history; // 历史记录寄存器
always @(posedge clk) begin
history <= {history[2:0], current_bit};
end
// 通过初始化赋值实现状态机复位(FPGA适用)
logic [3:0] state = 4'b0001; // 初始状态
always_ff @(posedge clk) begin
state <= next_state;
end
2.2 收益
1.时序收敛 减少复位信号带来的布线压力,消除复位释放的恢复时间(Recovery/Removal)检查;时序裕量提升10-15%; 2.面设优化 减少复位树缓冲器(Buffer)和时钟门控单元; 3.功耗降低 复位网络通常具有高负载,去除后可降低动态功耗; 3.减少复位毛刺引发的亚稳态