蜂鸟 E200
使用标准 DFF 模块例化生成寄存器
1
2
3
4
5 // 例化
wire flg_r;
wire fkg_nxt = ~flg_r;
wire flg_ena = (ptr_r == ('E203_OITF_DEPTH-q') & ptr_ena)
sirv_gnrl_fddlr #(1) flg_dfflrs(flg_ena, flg_nxt, flg_r, clk, rst_n);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 // DFF
// DFF with Load-enable and Reset, Default reset value is 0
module sirv_gnrl_dfflr # (
parameter DW = 32
) (
input lden,
input [DW-1:0] dnxt,
output [DW-1:0] qout,
input clk,
input rst_n
);
reg [DW-1:0] qout_r;
// 使用 always 块编写寄存器逻辑
always @(posedge clk or negedge rst_n)
begin : DFFLR_PROC
if (rst_n == 1'b0)
qout_r <= {DW{1'b0}};
else if (lden == 1'b1)
qout_r <= #1 dnxt;
end
assign qout = qout_r;
// 使用 assertion 捕捉 lden 信号的不定态
//{
//{
//synopsys translate_off
sirv_gnrl_xchecker # (
.DW(1)
) sirv_gnrl_xchecker(
.i_dat(lden),
.clk (clk)
);
//synopsys translate_on
//}
//}
endmodule
优点
便于全局替换寄存器类型。
例:带有 reset 的寄存器面积和时序会差一些,因此在数据通路上可以使用不带 reset 的寄存器,而只在控制通路上使用。
便于在寄存器中全局插入延迟。
明确的 load-enable 使能信号,方便综合工具自动插入寄存器级别的门控时钟,以降低动态功耗。
便于规避 if-else 不能传播不定态的问题。
使用 assign 语法代替 if-else 和 case 语法
if-else 和 case 不能传播不定态。
if-else 和case
1
2
3
4if(a)
out = in1;
else
out = in2;若a为不定态,会等效于0,输出等于in2,没有将不定态传播出去。
可能会在仿真阶段(综合结果应该是一样的)掩盖某些致命的错误,造成芯片功能错误。
assign
1
assign out = a ? in1:in2;
out = x,能够将不定态传播出去。
if-else 和 case 会产生优先级的选择电路(级联)而非并行选择电路,不利于时序和面积。
if-else 和case
1
2
3
4
5
6
7
8if(sel1)
out = in1;
else if (sel2)
out = in2;
else if (sel3)
out = in3;
else
out = 4'b0;会被综合成优先级选择电路,面积和时序均不够优化。
case?
assign
优先级选择:规避不定态 X 传播的问题。
1
2
3
4assign out = sel1 ? in1[3:0] :
sel2 ? in2[3:0] :
sel3 ? in3[3:0] :
4'b0;并行选择:
1
2
3assign out = ({4{sel1}} & in1[3:0])
|({4{sel2}} & in2[3:0])
|({4{sel3}} & in3[3:0]);
数据通路和控制通路的寄存器
带有 reset 的寄存器面积和时序会差一些,因此在数据通路上可以使用不带 reset 的寄存器,而只在控制通路上使用。
Clock 和 Reset 信号
Clock 和 Reset 信号只能接入 DFF 作为其时钟和复位信号,不能用于其他逻辑功能。