[TOC]
起因
最早的时候我在用SignalTap的时候,就发现Node Finder里面有Register这个选项,但是有些(其实可以算大部分)信号是没有的。后来网上找到的解释是这些没有输出到output的信号是会被综合工具优化掉的。
然后找到的解决方案是,把这些信号设置为输出,并在Assignment Editor里面设为virtual pin(因为没有这么多物理管脚的),这样就可以在Node Finder的Pins里面用了。
这个方法是有效的,主要我当时用的是Emacs。随着时间的推进,virtual pin自然是越来越多,今天翻看之前的一个工程,发现virtual pin就有2000多,很是骇人。
这个方法虽然有效,但是缺点也很是明显。首先就是麻烦,代码部分即使是有Emacs,还是容易有疏漏,层次越深的信号越是如此。然后就是这个显然是会对时序约束有影响。
之后我就又发现了另外的方案,就是在代码里设置Synthesis Attributes。Synthesis Attributes的作用不止是这样。
注释格式的Synthesis Attributes是不对的
在网上找到的就是这种Synthesis Attributes,出处可以搜《Altera的几个常用的Synthesis attributes》,格式为:
1
/* synthesis, <any_company_specific_attribute = value_or_optional_value */
还讲了例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Noprune
//A Verilog HDL synthesis attribute that prevents the Quartus II software from removing a register that does not directly or indirectly feed a top-level output or bidir pin.
//For example:
reg reg1 ;
//keep
//A Verilog HDL synthesis attribute that directs Analysis & Synthesis to not minimize or remove a particular net when optimizing combinational logic.
//For example:
wire keep_wire ;
//preserve
//A Verilog HDL synthesis attribute that directs Analysis & Synthesis to not minimize or remove a particular register when eliminating redundant registers or registers with constant drivers.
//For example:
reg reg1 ;
但我用的时候就是不对,在Node Finder里面,该找不到的还是找不到。
真正的Synthesis Attributes用法
我对这个其实也不是太执着,一方面是到后来项目的改动已经是很小了,该改的信号都改的差不多了,另一方面就是万一这个成功了,要把原来的都改回来那也不是个轻松的事情呵。
不过今天在Quartus ii里无意识的看verilog template的时候,意外的发现了竟然是有Synthesis Attributes这栏。激动的点开,一个个看了,之后就更激动了,我感觉我找到了真正的Synthesis Attributes的用法了。这个感觉非常强烈,搞的我都感觉不需要去确认了。
先来看看keep的:
1
2
3
4
5
6
wire <net_name>;
reg <variable_name>;
写法是完全不一样的。Quartus里面都这么写了,总不至于诓我把。刚好这几天要写一个新的工程,新的工程里就用这个方案试试了。
把template里面的全都贴出来好了:
full_case,用来应对case的default不知道怎么写的情况。
parallel_case,指示Quartus不生成优先逻辑,不过貌似case本来就不会生成优先逻辑的啊。
上面贴的keep,对wire和reg都是可以用的,这应该就是实现SignalTap观测内部信号的方法,要注意了。
1
2
3
4
5
6
wire <net_name>;
reg <variable_name>;
maxfan,指定最大扇出,这个应该是个综合约束。
preserve,针对寄存器的去优化策略。
1
2
3
4
5
6
<variable_declaration>;
module <module_name>(...);
noprune,防止无扇出的寄存器被优化。
1
2
3
4
5
<variable_declaration>;
1
2
3
4
5
<variable_declaration>;
module <module_name>(...);
1
2
3
4
<variable_declaration>;
module <module_name>(...);
1
2
3
4
<variable_declaration>;
module <module_name>(...);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<variable_or_net_declaration>;
variable e1;
reg e2;
reg q, data;
always@(posedge clk)
begin
if (e1 | e2)
begin
q <= data;
end
end
useioff,为I/O管脚添加寄存器(FF?),可以起到优化时序的作用。
1
2
3
4
5
6
7
output reg [7 :0 ] result ;
output reg [7 :0 ] result ;
ramstyle,指定使用的ram的类型,这个其实跟器件也有关系。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
reg [<msb>:<lsb>] <variable_name>[<msb>:<lsb>];
multstyle,指定乘法用逻辑资源实现还是DSP实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Controls the implementation of multiplication operators in your HDL
// source. Using this attribute, you can control whether the Quartus II
// software should preferentially implement a multiplication operation in
// general logic or dedicated hardware, if available in the target device.
// Legal values = "dsp" or "logic"
// Examples (in increasing order of priority)
// Control the implementation of all multiplications in a module
(* multstyle = "dsp" *) module foo(...);
// Control the implementation of all multiplications whose result is
// directly assigned to a variable
(* multstyle = "logic" *) wire signed [31 :0 ] result ;
assign result = a * b; // implement this multiplication in logic
// Control the implementation of a specific multiplication
wire signed [31 :0 ] result ;
assign result = a * (* multstyle = "dsp" ) b;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
reg [7 :0 ] state;
1
2
3
4
5
6
<io_declaration>;
input [2 :0 ] i;
1
2
3
4
5
6
7
8
9
module <name>(...);
reg q2;