如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II)

时间:2023-12-24 12:43:55

Abstract
撰寫Verilog時,雖然每個module都會先用ModelSim或Quartus II自帶的simulator仿真過,但真的將每個module合併時,一些不可預期的『run-time』問題可能才一一浮現,這時得靠SignalTap II來幫忙debug。

Introduction
使用環境:Quartus II 8.0 + DE2-70 (Cyclone II EP2C70F896C6N)

實際使用SignalTap II時,會發現有些reg與wire可以觀察,有些又無法觀察,在(原創) 如何使用SignalTap II觀察reg值? (IC Design) (Quartus II) (SignalTap II) (Verilog)中,我利用將reg接到top module的方式來觀察reg,雖然可行,但老實說並不是很好的方式。當初有網友發表評論,說這是因為reg被Quartus II優化掉不見了,導致無法使用SignalTap II觀察,本文整理出完整的reg與wire觀察方法。

觀察reg
如同(原創) 如何使用SignalTap II觀察reg值? (IC Design) (Quartus II) (SignalTap II) (Verilog)的範例,我再重複一次。

SSignalTapII_register_not_preserve.v / Verilog


1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com

4 Filename    : SignalTapII_register_not_preserve.v
5 Compiler    : Quartus II 8.0
6 Description : Demo how to preserve register with SingalTap II
7 Release     : 10/17/2008 1.0
8 */

10 module SignalTapII_register_not_preserve (
11   input iCLK,
12   input iRST_N
13 );
14 
15 reg [3:0] cnt;
16 
17 always@(posedge iCLK, negedge iRST_N) begin
18   if (!iRST_N)
19     cnt <= 4'h0;
20   else
21     cnt <= cnt + 4'h1;
22 end
23 
24 endmodule

這是個很簡單的計數器,我故意讓cnt不做output,而想用SignalTap II去觀察cnt這個reg的值。

如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II)

cnt都是0,顯然不合理,表示SignalTap II無法capture cnt這個reg的值。為什麼會這樣呢?

若我們將SignalTap II拿掉,重新用Quartus II編譯,觀察其compilation report,顯示register為0

如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II)

觀察RTL Viewer的合成結果,真的沒有register!!

如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II)

這證明了一件事情,Quartus II在合成時,發現cnt並沒有需要output,而自動最佳化不合成cnt,導致SignalTap II無法觀察reg,不過有時為了debug方便,我們就是想觀察這種reg,有辦法讓Quartus II暫時不要啟動最佳化嗎?

使用Synthesis Attribute避免最佳化

SignalTapII_register_preserve.v / Verilog


1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com

4 Filename    : SignalTapII_register_preserve.v
5 Compiler    : Quartus II 8.0
6 Description : Demo how to preserve register in SignalTap II
7 Release     : 10/17/2008 1.0
8 */

10 module SignalTapII_register_preserve (
11   input iCLK,
12   input iRST_N
13 )
14 
15 reg [3:0] cnt /*synthesis noprune*/;
16 
17 always@(posedge iCLK, negedge iRST_N) begin
18   if (!iRST_N)
19     cnt <= 4'h0;
20   else
21     cnt <= cnt + 4'h1;
22 end
23 
24 endmodule

15行

reg [3:0] cnt /*synthesis noprune*/;

多了/*synthesis noprune*/這個synthesis attribute,指示Quartus II不要對cnt做最佳化,保留此register以供SignalTap II觀察注意必須寫在分號前面,不能如下寫在分號後面

reg [3:0] cnt;/*synthesis noprune*/ //錯!!

編譯後,SignalTap II就能順利的觀察到cnt的值!!重點是不需改top module的interface,只需對想觀察的reg加上synthesis attribute即可。

如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II)

Quartus II也支援Verilog 2001的語法


1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com

4 Filename    : SignalTapII_register_preserve.v
5 Compiler    : Quartus II 8.0
6 Description : Demo how to preserve register in SignalTap II
7 Release     : 10/17/2008 1.0
8 */

10 module SignalTapII_register_preserve (
11   input iCLK,
12   input iRST_N
13 );
14 
15 // Verilog 2001
16 //(*noprune*) reg [3:0] cnt;
17 
18 always@(posedge iCLK, negedge iRST_N) begin
19   if (!iRST_N)
20     cnt <= 4'h0;
21   else
22     cnt <= cnt + 4'h1;
23 end
24 
25 endmodule

16行

(*noprune*) reg [3:0] cnt;

這是Verilog 2001的語法,Quartus II 8.0也能看得懂。

若希望整個module的reg都不被最佳化,可將synthesis attribute放在module。


1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com

4 Filename    : SignalTapII_register_preserve.v
5 Compiler    : Quartus II 8.0
6 Description : Demo how to preserve register in SignalTap II
7 Release     : 10/17/2008 1.0
8 */

10 module SignalTapII_register_preserve (
11   input iCLK,
12   input iRST_N
13 ) /*synthesis noprune*/;
14 
15 reg [3:0] cnt;
16 
17 always@(posedge iCLK, negedge iRST_N) begin
18   if (!iRST_N)
19     cnt <= 4'h0;
20   else
21     cnt <= cnt + 4'h1;
22 end
23 
24 endmodule

13行

module SignalTapII_register_preserve (
  input iCLK,
  input iRST_N
//);
) /*synthesis noprune*/;

將/*synthesis noprune*/放在module,這樣整個module的reg將不被最佳化,不用再一一指定。

另外一個與reg相關的Synthesis Attribute:/*synthesis preserve*/
跟reg相關的attribute,除了/*synthesis noprune*/可用,還有一個/*synthesis preserve*/可用,兩者的差異在於:

/*synthesis noprune*/ 避免Quartus II優化掉沒output的reg。

/*synthesis preserve*/ 避免Quartus II將reg優化為常數,或者合併重複的reg。

也可以使用Verilog 2001的寫法

//(*preserve*) reg [3:0] cnt;

或者整個module的寫法

module SignalTapII_register_preserve (
  input iCLK,
  input iRST_N
) /*synthesis preserve*/;

觀察wire
同樣的,在SignalTap II觀察wire時,有時也會因為被Quartus II優化掉而無法用SignalTap II觀察。

SignalTapII_wire_not_keep.v / Verilog


1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com

4 Filename    : SignalTapII_wire_not_keep.v
5 Compiler    : Quartus II 8.0
6 Description : Demo how to keep wire
7 Release     : 10/17/2008 1.0
8 */

10 module SignalTapII_wire_not_keep (
11   input        iCLK,
12   input        iRST_N,
13   output [3:0] oCNT
14 );
15 
16 wire [3:0] Cnt;  
17 reg  [3:0] cnt;
18 
19 assign Cnt = cnt;
20 assign oCNT = Cnt;
21 
22 always@(posedge iCLK, negedge iRST_N) begin
23   if (!iRST_N)
24     cnt <= 4'h0;
25   else
26     cnt <= cnt + 4'h1;
27 end
28 
29 endmodule

16行

wire [3:0] Cnt;

假設我想用SignalTap II去觀察Cnt這個wire。

如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II)

Cnt都是0,顯然不合理,表示SignalTap II無法capture cnt這個wire的值。為什麼會這樣呢?

因為Cnt這個wire已經被Quartus II優化不見了!!

不過有時為了debug方便,我們就是想觀察這種wire,有辦法讓Quartus II暫時不要啟動最佳化嗎?

SignalTapII_wire_keep.v / Verilog


1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com

4 Filename    : SignalTapII_wire_keep.v
5 Compiler    : Quartus II 8.0
6 Description : Demo how to keep wire
7 Release     : 10/17/2008 1.0
8 */

10 module SignalTapII_wire_keep (
11   input        iCLK,
12   input        iRST_N,
13   output [3:0] oCNT
14 );
15 
16 wire [3:0] Cnt /*synthesis keep*/;  
17 reg  [3:0] cnt;
18 
19 assign Cnt = cnt;
20 assign oCNT = Cnt;
21 
22 always@(posedge iCLK, negedge iRST_N) begin
23   if (!iRST_N)
24     cnt <= 4'h0;
25   else
26     cnt <= cnt + 4'h1;
27 end
28 
29 endmodule

16行

wire [3:0] Cnt /*synthesis keep*/; 

多了/*synthesis keep*/這個synthesis attribute,指示Quartus II不要對Cnt做最佳化,保留此wire以供SignalTap II觀察注意必須寫在分號前面,不能如下寫在分號後面

wire [3:0] Cnt;/*synthesis keep*/ //錯 

編譯後,SignalTap II就能順利的觀察到Cnt的值!!重點是不需改top module的interface,只需對想觀察的wire加上synthesis attribute即可。

如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II)

Quartus II也支援Verilog 2001的語法


1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com

4 Filename    : SignalTapII_wire_keep.v
5 Compiler    : Quartus II 8.0
6 Description : Demo how to keep wire
7 Release     : 10/17/2008 1.0
8 */

10 module SignalTapII_wire_keep (
11   input        iCLK,
12   input        iRST_N,
13   output [3:0] oCNT
14 );
15 
16 // Verilog 2001
17 (*keep*) wire [3:0] Cnt;
18 reg  [3:0] cnt;
19 
20 assign Cnt = cnt;
21 assign oCNT = Cnt;
22 
23 always@(posedge iCLK, negedge iRST_N) begin
24   if (!iRST_N)
25     cnt <= 4'h0;
26   else
27     cnt <= cnt + 4'h1;
28 end
29 
30 endmodule

17行

(*keep*) wire [3:0] Cnt;

這是Verilog 2001的語法,Quartus II 8.0也能看得懂。

不過目前Quartus II 8.0並不支援對整個module下/*synthesis keep*/,原因不明,我實際用Quartus II 8.0測試,SignalTap II並無反應,且Quartus II的help也沒說可以對整個module下/*synthesis keep*/。

完整程式碼下載
SignalTapII_register_not_preserve.7z (不使用synthesis noprune)
SignalTapII_register_preserve.7z (使用synthesis noprune
SignalTapII_wire_not_keep.7z (不使用synthesis keep)
SignalTapII_wire_keep.7z (使用synthesis keep)

Conclusion
關於避免Quartus II優化reg,/*synthesis noprune*/與/*synthesis preserve*/還是有些差異,程式寫到很大時,可能一時很難決定要用哪一個attribute,可以交替試試看,反正1/2的機會,總會對一個。

會使用synthesis attribute之後,總算解掉長久以來,無法用SignalTap II觀察reg與wire的老問題,感謝網友們的指導。

See Also
(原創) 如何使用SignalTap II觀察reg值? (IC Design) (Quartus II) (SignalTap II) (Verilog)
(筆記) 如何增加SignalTap II能觀察的reg與wire數量? (SOC) (Quartus II) (SignalTap II)

转载自:http://www.cnblogs.com/oomusou/archive/2008/10/17/signaltap_ii_reg_wire.html