VivadoのSystemVerilog対応状況(合成編) のバックアップソース(No.3)

更新

[[公開メモ]]

#contents

* Xilinx の最新開発環境 Vivado における System Verilog 対応状況を調べてみました [#y37e954e]

System Verilog を学ぶにあたって、とりあえず使える範囲から学ばないと無駄になりそうなので、
という意味合いで、対応状況を確認してみました。

[[電気回路/HDL/VivadoのSystemVerilog対応状況(シミュレーション編)]] もあります。

* 参考資料 [#d8b37531]

"Vivado Design Suite User Guide - Synthesis" UG901 (v2015.3) September 30, 2015 
の "Chapter 7: SystemVerilog Support" を参考にしています。

http://www.xilinx.com/support/documentation/sw_manuals/xilinx2015_3/ug901-vivado-synthesis.pdf

かなり頻繁に更新されているようなので、常に最新の情報を追う必要がありそうです。

- 2015/04/01 2015.1
- 2015/06/24 2015.2
- 2015/09/30 2015.3

同資料の、Chapter 3: HDL Coding Techniques も、非常に有用な内容が含まれているようですね。
別途熟読してみたいと思います。

* Data Type [#h09b1f12]

- integer_vector_type: bit, logic, or reg
- integer_atom_type: byte, shortint, int, longint, integer, or time
- non_integer_type: shortreal, real, or realtime
- struct
- enum

変数宣言の際の var は省略可能。

** Integer Data Types [#sf4cb9f7]

|~01 / 01XZ|~type|~bits|~default|h
|2-state|shortint|16-bit|signed|
|~|int     |32-bit|signed|
|~|longint |64-bit|signed|
|~|byte    |8-bit |signed|
|~|bit     |user defined vector size|unsigned|
|4-state|logic   |user defined vector size|unsigned|
|~|reg     |user-defined vector size|unsigned|
|~|integer |32-bit|signed|
|~|time    |64-bit|unsigned|

むむぅ。int と integer は違うのか・・・

** Real Numbers [#p438835e]

- real
- shortreal
- realtime

パラメータとして与えることはできても、計算する回路を生成することはできない。

** Void Data Type [#n6475c9c]

値を返さない function を定義する際にだけ使える。

** User-Defined Types [#ma695177]

typedef により定義可能。

 typedef data_type type_identifier {size};
 typedef [enum, struct, union] type_identifier;

** Enum Types [#wfffa2b9]

 enum [type] {enum_name1, enum_name2,...enum_namex} identifier

type のデフォルトは int なので、それ以外にしたい場合に指定する。

数字の割り当ては enum_name1 = 0 であり、それ以降1ずつ増える。

Cと同様に enum_name2=3 などとして数値を指定することも可能。

 enum {day[7]} day_of_week;  // これは次の行と同じ意味
 enum {day0, day1, day2, day3, day4, day5, day6} day_of_week;
 
 enum {day[1:7]} day_of_week; // creates day1,day2...day7
 enum {day[7] = 5} day_of_week; //creates day0=5, day1=6... day6=11

** Constants [#l9bceb27]

- parameter
- localparam
- specparam : Synthesis では無視される
- const

パラメータには type やビット幅、符号のありなしを指定できる。

** Casting [#lbcbc48e]

System Verilog では異なる type 間での代入はエラーになるので明示的にキャストしなければならない

 casting_type'(expression)

** Aggregate Data Types - structure [#r0b50799]

 struct {struct_member1; struct_member2;...struct_memberx;} structure_name;

** Aggregate Data Types - union [#p873ee2a]

 typedef union {int i; logic [7:0] j} my_union;
 my_union sig1;
 my_union sig2;
 sig1.i = 32; //sig1 gets the int format
 sig2.j = 8’b00001111; //sig2 get the 8bit logic format

レジスタのビットをばらばらにするのに使ったりする。

** Aggregate Data Types - Packed and Unpacked Arrays [#r7dc100f]

 logic [5:0] sig1; //packed array
 logic sig2 [5:0]; //unpacked array
 
 integer sig3; //equivalent to logic signed [31:0] sig3

* Processes [#g8c0288c]

** Always Procedures [#z401b4e0]

- always
- always_comb
- always_latch
- always_ff

 always_comb out1 = in1 & in2;
 //  always @(in1 or in2)
 //    out1 = in1 & in2;
 
 always_latch
   if(gate_en) q <= d;
 
 always_ff@(posedge clk)
   out1 <= in1;

** Block Statements [#i6b3e0fc]

begin ~ end で囲まれたブロックの中でローカル変数を定義可能。

 begin [: block name]
   [declarations]
   [statements]
 end [: block name]

 begin : my_block
   logic temp;
   temp = in1 & in2;
   out1 = temp;
 end : my_block

end の後のブロック名は省略可能

Parallel blocks (あるいは fork join blocks) は Vivado synthesis ではサポート外。

** Procedural Timing Controls [#m32f2054]

Delay Control は Synthesis では無視される

Event Control は always に与える形で使う。

 always@(posedge clk)
 always@(a or b or c)
 always@(a,b,c)
 always@*

** Operators [#ub24bb8c]

:代入演算子| =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, <<<=, >>>=
:単項演算子| +, -, !, ~, &, ~&, |, ~|, ^, ~^, ^~
:増減演算子| ++, --
:二項演算子| +, -, *, /, %, ==, ~=, ===, ~==, &&, ||, **, < , <=, >, >=, &, |, ^, ^~, ~^, >>, <<, >>>, <<<
:三項演算子| ? :
:連接演算子| { }

- 単項演算子の &, ~&, |, ~|, ^, ~^, ^~ はCには無いので注目に値する
- 二項演算子の ===, ~==, **, ^~, ~^, >>>, <<< も特殊
- A**B は A が 2 の累乗であるか、B が定数であるときに限り有効である
- 引数の type によって符号付き・符号なし演算が適切に行われる

* Procedural Programming Assignments [#ra619739]

** Conditional if-else Statement [#y4605dbe]

 If (expression1)
   command1;
 else if (expression2)
   command2;
 else if (expression3)
   command3;
 else
   command4;

** Case Statement [#qfcd2478]

 case (expression)
   value1: statement1;
   value2: statement2;
   value3: statement3;
   default: statement4;
 endcase

条件検査は順に行われる。~
つまり、value1 と value3 が両方 true でも statement1 のみが実行される。

if-else と case には parallel_case / full_case の属性を指定可能っぽい

** Loop Statements [#uc9785da]

for / repeat / for-each / while / do-while / forever が使える。

Verilog で for-each って見たこと無いかも。

* Tasks and Functions [#i25ae475]

** Task [#oa89e121]

 task [automatic/static] name (ports);
   [optional declarations];
   statements;
 endtask

static task というのは前回呼ばれた値を参照可能な task で、~
automatic task というのは毎回値が初期化される task、~
ということで合っている?

Vivado の synthesis ではすべての task は automatic として扱われる。

他の多くの simulator では static task がデフォルトなので気をつけること。

というか、常に "task automatic" と宣言しておくことにした方がよさそう。~
#エラーにはならないんだよね?→ 要チェック

** Functions (Automatic and Static) [#h7cb4585]

 function [automatic/static] data_type function_name(inputs);
   declarations;
   statements;
 endfunction [: function_name]

最後の function_name はオプション。enttask の後ろに task_name は書けないのかしら?

function_name = .... の形か、return で返り値を指定する。

Vivado の synthesis ではすべての function は automatic として扱われる。

simulator によっては static function がデフォルトなので気をつけること。

* Modules and Hierarchy [#ac0ff3ce]

** Connecting Modules [#r7629dcf]

宣言時と同じ名前の信号線を繋ぐ際には記述を省略できる。

 module lower (
   output [4:0] myout;
   input clk;
   input my_in;
   input [1:0] my_in2;
   ... ...
 endmodule
 
 // in the instantiating level.
 lower my_inst1 (.myout, .clk, .my_in, .my_in2);
 // works as same as below
 lower my_inst2 (.myout(myout), .clk(clk), .my_in(my_in), .my_in2(my_in2));

** Connecting Modules with Wildcard Ports [#yd4c4b29]

名前すら省略できる。

 // in the instantiating module
 lower my_inst3 (.*);
 
 lower my_inst4 (.myout(my_sig), .my_in(din), .*);

* Interfaces [#ad9d7346]

 // interface の宣言
 interface my_int
   logic sel;
   logic [9:0] data1, data2, result;
 endinterface : my_int
 
 // 下位モジュール1
 //    my_int.result を利用する
 module bottom1 (
   my_int int1,
   input clk,
   input [9:0] d1, d2,
   input s1,
   output logic equal
 );
   ...
 
 endmodule
 
 // 下位モジュール2
 //    my_int.result を設定する
 module bottom2 (
   my_int int1,
   input clk
 );
   
   ...
   if (int1.sel)
     int1.result <= int1.data1;
   ...
 
 endmodule
 
 // 上位モジュール
 module top(
   input clk,
   input s1,
   input [9:0] d1, d2,
   output equal
 );
   my_int int3(); // instantiation
   bottom1 u0 (int3, clk, d1, d2, s1, equal);
   bottom2 u1 (int3, clk);
 endmodule

** Modeports [#zc0e23f1]

普通に使うと interface に含まれる信号線はすべて inout になってしまうため、
方向を持たせたければ、

 interface my_int;
   logic sel;
   logic [9:0] data1, data2, result;
   modport b1 (input result, output sel, data1, data2);
   modport b2 (input sel, data1, data2, output result);
 endinterface : my_int
 
 module bottom1 (
   my_int.b1 int1,

のようにすれば良い。

あんまり分かりやすくはない気がするけれど、
名前を上手に付ければいいのかもしれない。

上記の例だと、set_result と use_result とか???

良い規約が欲しくなる。

** Miscellaneous Interface Features [#pae269fd]

interface に task, function を持たせることができる

interface に parameter を持たせることができる

* Packages [#g6faf2f5]

 package package_name;
   items
 endpackage : package_name

使うときは、

 import package_name::item or *;

* System Verilog に固有なものとして重要そうなのは [#h5e875cb]

- [[配線型>#sf4cb9f7]] (logic / bit など)
- [[enum>#wfffa2b9]] (ステートマシンのステートに使えそう)
- [[struct>>#r0b50799]] (interface との違いがよく分かっていない・・・)
- [[casting>#lbcbc48e]]
- [[Block内での変数定義>#i6b3e0fc]]
- [[モジュール配線名の省略>#r7629dcf]]
- [[Interface>#ad9d7346]] (優れた規約が欲しい)
- [[Packages>#g6faf2f5]] (優れた規約が欲しい)

くらいでしょうか。

* メモ [#tca3b327]

** interface のいけない使い方 [#w920e4ca]

各モジュールにデバッグ用の interface を配線しておくと、
どうしても覗いてみたい内部の信号線を一時的に interface に追加することで、
外まで引き出して観察するようなことができそう。

* コメント・質問 [#m43c3f84]

#article_kcaptcha


Counter: 11644 (from 2010/06/03), today: 3, yesterday: 2