ラベル verilog の投稿を表示しています。 すべての投稿を表示
ラベル verilog の投稿を表示しています。 すべての投稿を表示

2020年8月11日火曜日

WSL : WSL に Vivado をインストールする

目的:

WSL (Debian) に Vivado をインストールする。
 

結果:

CUI でインストールすることで、Vivado をインストールすることができた。
但し、
  1. コンパイル時など、スタックサイズを変更できない旨の Warning が発生。
    ( WSL では スタックサイズの変更はできないらしい )
    ( WSL2 では Warning は発生しない ) * 2020/08/28 追記
  2. Debian は 公式サポートされていない。 できれば、Ubuntu 等の方が良いかも。
  3. 作業ディレクトリを NAS上にすると、ファイルがコピーできない、ファイルが無い等のエラーでコンパイルできない。Dドライブ等の内臓ディスク上は OK。

    (マウントの仕方が悪い ?  vi 等では普通に編集かのうだが、、)

インストール手順:

  1. インストーラをダウンロードする。(Windows)
    ダウンロードする為には、アカウントを作成する必要が有る。

GUIインストールの場合

  1. Xサーバを起動する。(Windows)
  2. ダウンロードしたインストーラを起動する。(WSL)
    (Windows で d:\download\xilinx に ダウンロードした場合の例)
    cd /mnt/d/download/xilinx
    ./Xilinx_Unified_2020.1_0602_1208_Lin64.bin

    自環境(Debian) では インストーラのGUI は開かず、下の様なメッセージが発生。
    Exception in thread "SPLASH_LOAD_MESSAGE" java.lang.IllegalStateException: no splash screen available
            at java.desktop/java.awt.SplashScreen.checkVisible(Unknown Source)
            at java.desktop/java.awt.SplashScreen.getBounds(Unknown Source)
            at java.desktop/java.awt.SplashScreen.getSize(Unknown Source)
            at com.xilinx.installer.gui.H.run(Unknown Source)
    Exception in thread "main" java.lang.IllegalStateException: no splash screen available
            at java.desktop/java.awt.SplashScreen.checkVisible(Unknown Source)
            at java.desktop/java.awt.SplashScreen.close(Unknown Source)
            at com.xilinx.installer.gui.G.b(Unknown Source)
            at com.xilinx.installer.gui.InstallerGUI.G(Unknown Source)
            at com.xilinx.installer.gui.InstallerGUI.e(Unknown Source)
            at com.xilinx.installer.api.InstallerLauncher.main(Unknown Source)
    
    この為、CUI でインストールを行った。
    また、Debianでのインストールの為、以下のメッセージ(ダイアログボックス)が表示された。
    尚、Ubuntu の WSL で試したところ、GUI のインストーラが起動した。
    ( インストーラが起動するまで 数分 かかった。)
    Ubuntu でのインストールは行わなかったが、インストーラに従えばGUIで インストールできると思われる。

CUIインストールの場合


  1. インストーラの抽出
    --noexec  --target <抽出ディレクトリ> のオプションを付けてインストーラを起動する。
    [Windows で d:\download\xilinx に ダウンロードした場合の例:]
    cd /mnt/d/download/xilinx
    ./Xilinx_Unified_2020.1_0602_1208_Lin64.bin --noexec --target ~/xilinx-installer
    これで、~/xilinx-installer ディレクトにインストール用ファイルが抽出される。
  2. ユーザ名、パスワードの入力
    抽出されたディレクトリに移動し、 ./xsetup -b AuthTokenGen を実行する。
    cd ~/xilinx-installer
    ./xsetup -b AuthTokenGen
    で、User ID, Password ( Xilinx のアカウント登録した ID(メールアドレス) と パスワード) を入力する。
    ( ./xsetup コマンド 実行してから UserID, Password 入力まで 数分 かかった。
     以降、コマンド入力後、気長に待つ必要あり。(環境に依存するかも) )
  3. 設定ファイルの作成
    ./xsetup -b ConfigGen
    で、インストール用の設定ファイルを作成する。
    実行すると以下の様な選択項目が表示されるため、選択する。
    Select a Product from the list: に Vivado (2) を選択
    Select an Edition from the list: に WebPACK (1) を選択
    選択後、設定ファイルのパス,ファイル名 が表示される。
  4. 設定ファイルの編集
    3. で生成された設定ファイル (テキストファイル) を編集する。
    ( 今回は、インストール先を  /tools/Xilinx  に修正した。 )
  5. インストールの実行
    sudo ./xsetup --agree XilinxEULA,3rdPartyEULA,WebTalkTerms --batch Install --config <設定ファイルのパス/ファイル名>
    で、Vivado のダウンロートとインストールを開始する。
    2020.1 での ダウンロードサイズ は 16.12GB だった。

    インストール終了後、Xilinx Information Center が起動したため、
     [File] → [Exit]  で、これを閉じた。

Vivado 実行:

以下の様に、インストールディレクトリの settings64.sh を ソースし、vivado を実行する。( インストール先 : /tools/Xilinx, Ver 2020.1 の場合 )
source /tools/Xilinx/Vivado/2020.1/settings64.sh
vivado

vivado の実行で、GUI で Vivado が起動する。

2020年7月18日土曜日

verilog : SVA の演算子

目的:

SVAの演算子等について記す。

各演算子:

(SVA の記述については、こちらを参照。
 下記 動作は、全てを確認した訳では無い為、使用時は注意して下さい。 )

主なシーケンス演算子:

  ( s, s1, s2 : シーケンス 、b : ブーリアン 、 x, y 等 : 信号名 )
演算子 説明
s1 ##n s2 s1 が成立してから nサイクル後に s2 が成立する時
 
s1 ##[n:m] s2 s1 が成立してから n~mサイクル後に s2 が成立する時
 
s [*n] s がnサイクル連続して繰り返された時
 
   
s [*n:m] s がn~mサイクル連続して繰り返された時
 
 
b[->n] b がnサイクル連続 又は 非連続 で繰り返された時
 
* ブーリアンのみ 
s1 intersect s2 s1, s2 の開始と終了が同じである時
 
b throughout s  s の継続中、 b が 真の時
 
s1 within s2  s2 の継続中 に s1 が 真になった場合の s2 終了時
 

主なプロパティ演算子:

演算子 説明
p1 and p2 p1, 2が共に成立するとき評価
   
p1 or p2 p1, 2どちらかが成立するとき評価
   
not p pが成立しないときに評価
   
if(b) p1 else p2 bが真ならp1を評価、偽ならp2を評価
   
disable iff(b) bが真の時は評価しない(Fail しない)
   
s |-> p s が成立した サイクルで p を評価
   
s |=> p s が成立した 次のサイクルで p を評価 ( s |-> ##1 p と同じ )
   


主な関数:

$rose( 信号 )  信号の最下位ビットが '1' に変化した時に 真
   
$fell( 信号 )  信号の最下位ビットが '0' に変化した時に 真
   
$stable( 信号 )  信号が 1サイクル前から変化しなければ 真
   
$past( 信号 , n )  信号のnサイクル前の値,  nが省略された場合は n=1
   
$onehot( 信号 )  信号の'H' のビット数が 1 の時に 真
   
$onehot0( 信号 )  信号の'H' のビット数が 1 又は 0 の時に 真
   
$isunknown(信号)  信号に 'x' や 'z' が含まれる場合に 真
   
$countones(信号)  信号の'H' のビット数
   



2020年6月21日日曜日

verilog : SVA の property 記述概要

目的:

SVA の property 記述について 理解した内容を 記す

property 記述 :

検証の動作を定義する。
property 記述のみでは アサーションを生成できず、 assertion 記述が必用。

記述方法:




プロパティ表現:

プロパティ表現で 検証の動作内容を定義する。

インプリケーション演算子を使用する場合。


前提条件が 成立した後、 1 クロック後に 帰結部 を 評価する。
上の例では、 X が 立ち上がった後、1クロック後に Y が 立ち下がる事 を確認する。
シーケンスについては、下記参照。
インプリケーション演算子 には次の 2種類がある。
  • オーバーラップ・インプリケーション演算子  ( |-> )
      前提部終了と帰結部開始が同じクロック
  • ノン・オーバーラップ・インプリケーション演算子 ( |=> )
      前提部終了の 1クロック後に帰結部開始。 |-> ##1  と同じになる。

プロパティ否定演算子を使用する場合。






クロック毎に x と y が 等しくない事を確認する。

演算子を使用しない場合。





クロック毎に x と y が 同じであることを確認する。

その他、プロパティ演算子 として and, or, if else を使用して複数のプロパティ表現を組み合わせる事が可能。

シーケンス:

シーケンスは、信号の一連の動作を表す。
例えは、 信号 A, B, C が 1クロック毎に 立ち上がる場合は、
  a ##1 b ##1 c
の様に記述する。
1つの信号が立ち上がるだけでも シーケンス である。
  a
シーケンスは、シーケンス記述で 名前を付けて プロパティ記述の中で使用することができる。

シーケンス演算子 の 詳細は こちら を参照。

システム関数:

システム関数として、以下の関数があり、シーケンス記述等で使用できる。
$rose( 信号 )
 信号の最下位ビットが '1' に変化した時に 真
$fell( 信号 )
 信号の最下位ビットが '0' に変化した時に 真
$stable( 信号 )
 信号が 1サイクル前から変化しなければ 真
$past( 信号 , n )
 信号のnサイクル前の値,  nが省略された場合は n=1
$onehot( 信号 )
 信号の'H' のビット数が 1 の時に 真
$onehot0( 信号 )
 信号の'H' のビット数が 1 又は 0 の時に 真
$isunknown(信号)
 信号に 'x' や 'z' が含まれる場合に 真
$countones(信号)
 信号の'H' のビット数

2020年6月20日土曜日

verilog : SVA による検証概要

目的:

SVA の概要について 理解した内容を 記す

SVA とは:

System Verilog Assertion の略。
System Verilog の アサーション記述言語。
内部論理の期待動作の検知 や 禁止動作を監視する。
 ( 期待通りに動作しない場合等を検出する )

SVA 適用手順:

SVA を適用するには、以下の記述を行う。
  1. SVA ファイル記述
    SVA 用のモジュールを作成する。
    SVAは、通常のRTL内にも記述できるが、
    1. ifdef などで合成時に無視できるようにする必要がある。
    2. module が system veerilog として扱われるため、RTL に system verilog の記述が混ざっても検証時には気づけない。 
      ( RTL を verilog で記述する場合 )
    等の注意が必要な為、SVA用のモジュールにした方が良いと感じる。
  2. bind ファイル記述
    SVA ファイル を RTL の信号 に紐づける。
    SVA ファイルで 直接 RTLの信号を記述することもできるが、bind ファイルを 使用することで複数の信号に同じ SVA を適用できる。

SVA ファイルの記述:

SVA のファイルは、通常の module と同様に作成する。
但し、output ポートは無い。(必要無い)
SVA の module には、
 通常の rtl 記述
 property 記述
 assertion 記述
 を行う。
例 : sva_test.sv
module sva_test ( clk, rst_n, sig1, sig2) ;
  input clk ;
  input rst_n ;
  input sig1 ;
  input sig2 ;

  // property 記述
  property p_test1(x, y) ;
    @(posedge clk ) disable iff(~rst_n)
        $rose(x) |-> ##1 fell(y) ;
  endproperty

  // assertion 記述
  a_test1 : assert property ( p_test1 ( sig1, sig2) ) ;

endmodule

property 記述 と assertion 記述 を 1つ にして
a_test1 : assert property (
    @(posedge clk ) disable iff(rst)
        $rose(sig1) |-> ##1 fell(sig2)
) ;


の様にも記述できるが、property 記述 と assertion 記述 を 分けると、1つのproperty 記述を 複数の asertion 記述で使用できる。

property 記述 については、SVA の property 記述概要 を参照

bind ファイルの記述:

アサーションの バインディングは 以下の様に行う。
 bind <bind先モジュール名> <アサーションモジュール名>  <インスタンス名> (
   ポート 接続 記述
) ;

bind DUT sva_test  sva_test1 (
  .clk    (clock),
  .rst_n (reset_n) ,
  .sig1   (signal_1) ,
  .sig2   (signal_2) ,
) ;




2020年4月19日日曜日

verilog : 多ビット信号の配列 (二次元配列)

目的:

多ビット信号の配列(二次元配列)を使用する。

宣言:

レジスタ(メモリ)
reg  [7:0] r_data[0:127]    // 8bit幅 128 個のレジスタ宣言

信号(Wire)
wire [7:0] w_data[0:127]    // 8bit幅 128 組の ワイヤ宣言

Verilog では ポートに二次元配列は使用できない。

代入:

wire       sig_1b ;
wire [7:0] sig_8b ;
assign w_data[14] = sig ;        // 8bit 幅の信号を 15番目の 8bit信号 に代入
assign sig_1b = w_data[127][7] ; // 1bit 幅の信号に 127番目の bit7(MSB)を代入

例:

回路図

 ( 各BIT_WIDTH 幅の FF の MSB を 束ねて dt_msb 信号として出力 )

verilog (モジュール)
FF は generate 文を使用して for - next で 記述。
ポートは二次元配列で記述できない為、内部で宣言した wire に 1つづつ assign 。
二次元配列から一次元配列へのアサインは「多ビット信号の配列(二次元配列)と入出力ポート 」を参照。
// -----------------------------------------------------
//   Sample module
//
//   Module Name : test_md1
//   Version     : 0.00
// -----------------------------------------------------
 
module test_md1 #(                      // Module name : test
  parameter BIT_WIDTH = 4 ,             // parameter list
  parameter DATA_NUM  = 8               // parameter list
) (                                     //
  clr,                                  // port list
  clk,
  enable,
  set,
  data_1,
  data_2,
  data_3,
  data_4,
  data_5,
  data_6,
  data_7,
  data_8,
  out_dt1,
  out_dt2,
  out_dt3,
  out_dt4,
  out_dt5,
  out_dt6,
  out_dt7,
  out_dt8,
  dt_msb
) ;
 
// port declaration ----------------
input                  clr ;
input                  clk ;
input                  enable ;
input                  set ;
input  [BIT_WIDTH-1:0] data_1 ;
input  [BIT_WIDTH-1:0] data_2 ;
input  [BIT_WIDTH-1:0] data_3 ;
input  [BIT_WIDTH-1:0] data_4 ;
input  [BIT_WIDTH-1:0] data_5 ;
input  [BIT_WIDTH-1:0] data_6 ;
input  [BIT_WIDTH-1:0] data_7 ;
input  [BIT_WIDTH-1:0] data_8 ;
output [BIT_WIDTH-1:0] out_dt1 ;
output [BIT_WIDTH-1:0] out_dt2 ;
output [BIT_WIDTH-1:0] out_dt3 ;
output [BIT_WIDTH-1:0] out_dt4 ;
output [BIT_WIDTH-1:0] out_dt5 ;
output [BIT_WIDTH-1:0] out_dt6 ;
output [BIT_WIDTH-1:0] out_dt7 ;
output [BIT_WIDTH-1:0] out_dt8 ;
output [DATA_NUM-1:0]  dt_msb ;
 
// parameter declaration -----------
parameter DLY = 1 ;
 
// internal signal declaration -----
wire                 set_enable ;

wire [BIT_WIDTH-1:0] in_data[1:DATA_NUM] ;
reg  [BIT_WIDTH-1:0] lt_data[1:DATA_NUM] ;
 
// logical description -------------
assign set_enable = enable & set ;

assign in_data[1] = data_1 ;
assign in_data[2] = data_2 ;
assign in_data[3] = data_3 ;
assign in_data[4] = data_4 ;
assign in_data[5] = data_5 ;
assign in_data[6] = data_6 ;
assign in_data[7] = data_7 ;
assign in_data[8] = data_8 ;

generate
  genvar i ;
  for (i=1; i<DATA_NUM+1; i=i+1) 
    begin : dtlatch
      always @(posedge clk or posedge clr)
        if (clr) 
          lt_data[i]  <= #DLY  {BIT_WIDTH{1'b0}} ;
        else if (set_enable)
            lt_data[i]  <= #DLY  in_data[i] ;

      assign dt_msb[i-1] = lt_data[i][BIT_WIDTH-1] ;
    end

endgenerate
 
assign out_dt1 = lt_data[1] ;
assign out_dt2 = lt_data[2] ;
assign out_dt3 = lt_data[3] ;
assign out_dt4 = lt_data[4] ;
assign out_dt5 = lt_data[5] ;
assign out_dt6 = lt_data[6] ;
assign out_dt7 = lt_data[7] ;
assign out_dt8 = lt_data[8] ;
 
endmodule

verilog (上位階層)
//   Sample test
//
//   Module Name : test
//   Version     : 0.00
// -----------------------------------------------------
 
module test(
  clr,                                  // port list
  clk,
  enable,
  set,
  data_1,
  data_2,
  data_3,
  data_4,
  data_5,
  data_6,
  data_7,
  data_8,
  out_dt1,
  out_dt2,
  out_dt3,
  out_dt4,
  out_dt5,
  out_dt6,
  out_dt7,
  out_dt8,
  dt_msb
) ;
 
// port declaration ----------------
input        clr ;
input        clk ;
input        enable ;
input        set ;
input  [7:0] data_1 ;
input  [7:0] data_2 ;
input  [7:0] data_3 ;
input  [7:0] data_4 ;
input  [7:0] data_5 ;
input  [7:0] data_6 ;
input  [7:0] data_7 ;
input  [7:0] data_8 ;
output [7:0] out_dt1 ;
output [7:0] out_dt2 ;
output [7:0] out_dt3 ;
output [7:0] out_dt4 ;
output [7:0] out_dt5 ;
output [7:0] out_dt6 ;
output [7:0] out_dt7 ;
output [7:0] out_dt8 ;
output [7:0]  dt_msb ;
 
test_md1 #(
  .BIT_WIDTH (8) 
)i_test(
  .clr      (clr),
  .clk      (clk),
  .enable   (enable),
  .set      (set),
  .data_1   (data_1),
  .data_2   (data_2),
  .data_3   (data_3),
  .data_4   (data_4),
  .data_5   (data_5),
  .data_6   (data_6),
  .data_7   (data_7),
  .data_8   (data_8),
  .out_dt1  (out_dt1),
  .out_dt2  (out_dt2),
  .out_dt3  (out_dt3),
  .out_dt4  (out_dt4),
  .out_dt5  (out_dt5),
  .out_dt6  (out_dt6),
  .out_dt7  (out_dt7),
  .out_dt8  (out_dt8),
  .dt_msb   (dt_msb)
) ;

endmodule


verilog (テストベンチ, 呼び出し側)
// ----------------------------------------------------------
//   test bench
//
//     for test.v
// ----------------------------------------------------------

`timescale 1ns / 1ps

module testbench ;

// testbench logic -------------------
reg   clr;
reg   clk;
reg   [7:0] in_data_1 ;
reg   [7:0] in_data_2 ;
reg   [7:0] in_data_3 ;
reg   [7:0] in_data_4 ;
reg   [7:0] in_data_5 ;
reg   [7:0] in_data_6 ;
reg   [7:0] in_data_7 ;
reg   [7:0] in_data_8 ;
reg   enable ;
reg   set ;
wire  [7:0] out_data_1 ;
wire  [7:0] out_data_2 ;
wire  [7:0] out_data_3 ;
wire  [7:0] out_data_4 ;
wire  [7:0] out_data_5 ;
wire  [7:0] out_data_6 ;
wire  [7:0] out_data_7 ;
wire  [7:0] out_data_8 ;

wire  [7:0] data_msb ;

test  i_test(
  .clr      (clr),
  .clk      (clk),
  .enable   (enable),
  .set      (set),
  .data_1   (in_data_1),
  .data_2   (in_data_2),
  .data_3   (in_data_3),
  .data_4   (in_data_4),
  .data_5   (in_data_5),
  .data_6   (in_data_6),
  .data_7   (in_data_7),
  .data_8   (in_data_8),
  .out_dt1  (out_data_1),
  .out_dt2  (out_data_2),
  .out_dt3  (out_data_3),
  .out_dt4  (out_data_4),
  .out_dt5  (out_data_5),
  .out_dt6  (out_data_6),
  .out_dt7  (out_data_7),
  .out_dt8  (out_data_8),
  .dt_msb   (data_msb)
) ;

initial begin
  clk = 0 ;
  clr = 1 ;
  #10 clr = 0 ;
  forever begin
    #10 clk = ~clk ;
  end
end

// scenario --------------------------
initial begin
  $dumpfile("tb.vcd");
  $dumpvars(0,testbench) ;

  enable    = 1'b0 ;
  set       = 1'b0 ;
  in_data_1 = 8'd0 ;
  in_data_2 = 8'd0 ;
  in_data_3 = 8'd0 ;
  in_data_4 = 8'd0 ;
  in_data_5 = 8'd0 ;
  in_data_6 = 8'd0 ;
  in_data_7 = 8'd0 ;
  in_data_8 = 8'd0 ;

  #200 enable    = 1'b1 ;
       in_data_1 = 8'h01 ;
       in_data_2 = 8'h92 ;
       in_data_3 = 8'h23 ;
       in_data_4 = 8'hb4 ;
       in_data_5 = 8'hc5 ;
       in_data_6 = 8'h56 ;
       in_data_7 = 8'he7 ;
       in_data_8 = 8'h78 ;
  #101 set       = 1'b1 ;
  #20  set       = 1'b0 ; 
  #100 enable    = 1'b0 ;
       in_data_1 = 8'hff ;
       in_data_2 = 8'hff ;
       in_data_3 = 8'hff ;
       in_data_4 = 8'hff ;
       in_data_5 = 8'hff ;
       in_data_6 = 8'hff ;
       in_data_7 = 8'hff ;
       in_data_8 = 8'hff ;
  #101 set       = 1'b1 ;
  #20  set       = 1'b0 ; 
  #200 ;
  $finish;
  end

endmodule

シミュレーション結果


2020年4月18日土曜日

verilog : module のパラメタライズ

目的:

ビット幅等をパラメータ化してmoduleを再利用しやすいようにする。

構造:


module側

module <モジュール名> #(
 パラメータリスト
) (
 ポートリスト
) ;
 パラメータ宣言 (PARAMETER)
 ネット宣言 (wire, reg)
 論理記述
  ( assign, always, module接続, 等)
endmodule

 呼び出し側


 <モジュール名>  #(
 パラメータリスト
) <インスタンス名> (
 ポートリスト
) ;

呼び出し側の #( パラメータリスト) は省略可能。
省略時は、モジュールで設定したデフォルト値を使用。
 

パラメータ化された reg への固定値代入


固定値の代入は、連接を使用して以下の様に書ける。
parameter  WID = 8 ;
reg [WID-1:0]  data ;
( all '1' を代入 )
 data <= {WID{1'b1}} ;
( 下位 4bit に 0x7 を大入)
 data <= {{(WID-4){1'b0}}, {4'h7}} ;

例:

ビット幅をパラメータ化した例を示す。
回路図
 verilog (モジュール)
モジュールは、デフォルト 4bit 幅で記述
// -----------------------------------------------------
//   Sample module
//
//   Module Name : test_md1
//   Version     : 0.00
// -----------------------------------------------------
 
module test_md1 #(                      // Module name : test
  parameter BIT_WIDTH = 4               // parameter list
) (                                     //
  clr,                                  // port list
  clk,
  enable,
  set,
  data,
  out_dt
) ;
 
// port declaration ----------------
input                  clr ;
input                  clk ;
input                  enable ;
input                  set ;
input  [BIT_WIDTH-1:0] data ;
output [BIT_WIDTH-1:0] out_dt ;
 
// parameter declaration -----------
parameter DLY = 1 ;
 
// internal signal declaration -----
wire                 set_enable ;

reg  [BIT_WIDTH-1:0] lt_data ;
 
// logical description -------------
assign set_enable = enable & set ;
 
always @(posedge clk or posedge clr)
  if (clr) 
    lt_data  <= #DLY  {BIT_WIDTH{1'b0}} ;
//  lt_data  <= #DLY {{(BIT_WIDTH-4){1'b0}},{4'h7}} ;
else if (set_enable)
    lt_data  <= #DLY  data ;
 
assign out_dt = lt_data ;
 
endmodule

 verilog (上位階層)
// -----------------------------------------------------
//   Sample test
//
//   Module Name : test
//   Version     : 0.00
// -----------------------------------------------------
 
module test (
  clr,
  clk,
  enable,
  set,
  data,
  out_dt
) ;

// port declaration ----------------
input        clr ;
input        clk ;
input        enable ;
input        set ;
input  [7:0] data ;
output [7:0] out_dt ;
 
// testbench logic -------------------

test_md1 #(
  .BIT_WIDTH (8) 
)i_test_md1(
  .clr    (clr),
  .clk    (clk),
  .enable (enable),
  .set    (set),
  .data   (data),
  .out_dt (out_dt)
) ;

endmodule

 verilog (テストベンチ, 呼び出し側)
// ----------------------------------------------------------
//   test bench
//
//     for test.v
// ----------------------------------------------------------

`timescale 1ns / 1ps

module testbench ;

// testbench logic -------------------
reg   clr;
reg   clk;
reg   [7:0] in_data ;
reg   enable ;
reg   set ;
wire  [7:0] out_data ;

test  i_test(
  .clr    (clr),
  .clk    (clk),
  .enable (enable),
  .set    (set),
  .data   (in_data),
  .out_dt (out_data)
) ;

initial begin
  clk = 0 ;
  clr = 1 ;
  #10 clr = 0 ;
  forever begin
    #10 clk = ~clk ;
  end
end

// scenario --------------------------
initial begin
  $dumpfile("tb.vcd");
  $dumpvars(0,testbench) ;

  enable  = 1'b0 ;
  set     = 1'b0 ;
  in_data = 8'd0 ;

  #200 enable  = 1'b1 ;
       in_data = 8'h55 ;
  #101 set     = 1'b1 ;
  #20  set     = 1'b0 ; 
  #100 enable  = 1'b0 ;
       in_data = 8'haa ;
  #101 set     = 1'b1 ;
  #20  set     = 1'b0 ; 
  #200 ;
  $finish;
  end

endmodule

シミュレーション結果




2019年6月16日日曜日

verilog : よく使用する RTL 記述

目的:

通常、よく使用する RTL記述 (論理合成可能な 論理記述) について記す。

RTL記述例:

assign 文 : 組み合わせ回路の記述を行う。

assing out = in1 & in2 ;    // 演算子 : (ビット)  & (and), | (or), ^ (xor), ~(not)
                                      //              (算術)   +, -
                                      //              (比較)   <, <=, >=, >, ==, !=, ===, !==
                                      //              (論理)   &&, ||, !
                                      //              (シフト)  >>, <<, <<<, >>>
                                      //              (条件(3項))  <条件> ? <真> : <偽> 
                                      //              (連接)   {<信号>,<信号>, ... }

連接 : 記述の仕方いろいろ。

{ sig1 , sig2, sig3 }     // 信号を連接
{ 7{1'b0},sig1}           //  sig1 の前に 7bit の'0' を付加
{{(P_BW-1){1'b0}},sig1}   //  sig1(1bit 信号) を bit幅 P_BW に 0拡張

bit幅が パラメータ になっている場合の 固定値('1') 代入の例
reg  [P_BW-1:0] sig ;
reg  [P_BW-1:0] sig2 ;

always @(posedge clk or posedge clr)
  if (clr )
    sig <= {{(P_BW-1){1'b0}},1'b1} ;   // P_BW'h1 とは 書けない為
  else
    sig  <= sig2 ;

always 文 : 順序回路 (FF) の記述を行う。

always @(posedge clk or negedge rst)  // rst は 非同期リセット(負極性)
  if (~rst)                           // リセット 時 (rst が '0' の時)
    q <= #1 1'b0 ;                    //   出力を 'L' にする
  else                                // 非リセット時

    q <= #1 d ;                       //   出力に入力を伝搬させる

function 文:if文 や case文 を使用した組み合わせ回路の記述を行う。
       複数の組み合わせ回路を 1組にして記述して使い回す時にも使用。

function [7:0] sel;
  input [1:0] in1 ;
  input [7:0] in2 ;
  begin
    case(in1)
      2'b00 : sel = 8'd0 ;
      2'b01 : sel = in2 ;
      2'b10 : sel = ~in2 ;
      default : sel = 8'hff ;
      endcase
  end
endfunction

assign out = sel(i1,i2) ;

 module 呼び出し : 下位 module を呼び出す。

test test1(           // <module名:test>  <インスタンス名:test1> (
  .in1 (sig1),        //    .<ポート名:in1>  (<接続信号名:sig1>),
  .in2 (sig2),        //    .<ポート名:in2>  (<接続信号名:sig2>),
  .out (sig3)         //    .<ポート名:out>  (<接続信号名:sig3>),
) ;                   //


3項演算子 : セレクタの記述等に使用


assign out = (i1 == 2'b00) ? 8'd0 :
             (i1 == 2'b01) ? in2   :
             (i1 == 2'b10) ? ~in2  :
                             8'hff  ;

( 上記 function 文の例と同じ回路 )

 genarete文 : 大量の assign 記述等を for 文を使用して記述する場合に使用。

wire [9:0] bus1 ;
wire [9:0] bus2 ;

genvar i;
generate 
  for(i=0; i<10; i=i+1) 
    begin : Gen1                         // begin の後に ラベルが必用 ?
      assign bus2[i] = bus1 [9 - i] ;  
    end
endgenerate

verilog : 基本構造

目的:

verilog記述の基本構造を記す。

基本構造:


module <モジュール名> (
  ポートリスト
) ;

パラメータ宣言 (PARAMETER)
ネット宣言 (wire, reg)

論理記述
 ( assign, always, module接続, 等)

endmodule

1つのモジュール で 1つのファイル(*.v) とするのが良い様に思う。

例:

2つの入力信号 の AND を 2段の FF を通して出力。

// 
// Sample module
//
// Module Name : test
// Version     : 0.00
//

module test(            // Module name : test
  rst,                  // port list
  clk,
  in1,
  in2,
  out
) ;

// port declaration ----------------
input rst ;
input clk ;
input in1 ;
input in2 ;
output out ;

// parameter declaration -----------
parameter DLY = 1 ;

// internal signal declaration -----
wire  w_and ;
reg   r_and_lt ;
reg   r_and_lt2 ;

// logical description -------------
assign w_and = in1 & in2 ;

always @(posedge clk or posedge rst)
  if (rst) begin
    r_and_lt  <= #DLY 1'b0 ;
    r_and_lt2 <= #DLY 1'b0 ;
    end
  else begin
    r_and_lt  <= #DLY w_and ;
    r_and_lt2 <= #DLY r_and_lt ;
    end

assign out = r_and_lt ;

endmodule

verilog : コンパイル/シミュレーション環境のインストール (WSL)

目的: 

PC(WSL) 上で Verilog の コンパイル、シミュレーションができる様にする。

インストール内容:

WSL (Debian) 上に Icarus Verilog と gtkwave をインストール。
gtkwave は、GUI の為、事前に Xサーバーのインストールが必要。

インストール手順:

以下を実行する。
sudo apt-get update
sudo apt-get install iverilog
sudo apt-get install gtkwave

gtkwave のインストールに少し時間がかかるが、特に問題なくインストール完了。

実行手順:

以下にコンパイルから波形表示までの手順を簡単に記す。
  • コンパイル
    iverilog -o <出力ファイル名> <Verilog ファイル名>


    iverilog -o test testbench.v test.v
  • シミュレーション実行
    vvp <出力ファイル名>


    vvp test
  • 波形表示
    gtkwave <vcdファイル名>


    gtkwave test.vcd

その他:

gtkwave を実行すると、

(gtkwave:656): GConf-WARNING **: Client failed to connect to the D-BUS daemon:
/usr/bin/dbus-launch terminated abnormally without any error message
GConf Error: No D-BUS daemon running
 

が発生するが、取り敢えず波形は見れそう。