|
|
|
Verilog HDL 簡易マニュアル
|
|
|
|
========
|
|
|
|
|
|
|
|
## 数値
|
|
|
|
|
|
|
|
```
|
|
|
|
8'b1111_0000 // 8bitの数値、二進法(b)で11110000
|
|
|
|
16'hfae3 // 16bitの数値、十六進法(h)でfae3
|
|
|
|
4'd12 // 4bitの数値、十進法(d)で12
|
|
|
|
2389 // 十進法で2389、ビット数は暗黙で32bitになる
|
|
|
|
```
|
|
|
|
|
|
|
|
## 演算子
|
|
|
|
|
|
|
|
### 算術演算
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
a <= a + 1; // 二進法で加算
|
|
|
|
a <= a - 1; // 二進法で減算
|
|
|
|
a <= a * 3; // 二進法で乗算
|
|
|
|
a <= a / 3; // 二進法で除算
|
|
|
|
a <= a % 5; // 二進法で剰余演算
|
|
|
|
```
|
|
|
|
|
|
|
|
C言語と同じ。
|
|
|
|
|
|
|
|
### 論理演算
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
if (!a || b && c) // もし aが0 または (bが1 かつ cが1) ならば
|
|
|
|
```
|
|
|
|
|
|
|
|
C言語と同じ。
|
|
|
|
|
|
|
|
### ビットごと (bit-wise) の論理演算
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
a <= ~a; // 全ビットを反転
|
|
|
|
a <= a & b; // ビットごとに論理積
|
|
|
|
a <= a | b; // ビットごとに論理和
|
|
|
|
a <= a ^ b; // ビットごとに排他的論理和
|
|
|
|
a <= a ~& b; // ビットごとにNAND
|
|
|
|
a <= a ~| b; // ビットごとにNOR
|
|
|
|
```
|
|
|
|
|
|
|
|
C言語と同じ。NANDやNORはC言語にはないが。
|
|
|
|
|
|
|
|
### シフト演算
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
a <= a >> 3; // 3bit論理右シフト
|
|
|
|
a <= a << 3; // 3bit論理左シフト
|
|
|
|
a <= a >>> 3; // 3bit算術右シフト
|
|
|
|
```
|
|
|
|
|
|
|
|
C言語だと算術右シフトを選ぶ方法はないが、Verilog HDLでは`>>>`で書ける。
|
|
|
|
|
|
|
|
### 比較演算子
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
if (a == 1'b1) ...; // もしaが1と等しかったら
|
|
|
|
if (a != 1'b1) ...; // もしaが1ではなかったら
|
|
|
|
if (a < 2'b10) ...; // もしaを符号なし整数として解釈して2よりも小さかったら
|
|
|
|
if (a > 2'b01) ...; // もしaを符号なし整数として解釈して1よりも大きかったら
|
|
|
|
```
|
|
|
|
|
|
|
|
C言語と同じ。つまり、`a == b&c`は、`(a==b) & c`と解釈されるので注意が必要!
|
|
|
|
|
|
|
|
### 条件演算子(選択)
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
a <= a ? b : c; // aが0でなければb、0ならばc
|
|
|
|
```
|
|
|
|
|
|
|
|
C言語と同じ。
|
|
|
|
|
|
|
|
### ビットの取り出し
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
wire [31:0] x;
|
|
|
|
wire msb;
|
|
|
|
wire [2:0] offset;
|
|
|
|
|
|
|
|
assign msb = x[31];
|
|
|
|
assign offset = x[12:10];
|
|
|
|
```
|
|
|
|
|
|
|
|
C言語だと配列の宣言は`int array[32]`のようになるが、Verilog HDL では`wire [31:0] x;`のように逆順になる。取り出すときは同じ。
|
|
|
|
|
|
|
|
### 連結と複製
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
{{16{x[15]}}, x} // 16bit の値 x を 32bit に符号拡張
|
|
|
|
{{11{ins[31]}}, ins[31], ins[19:12], ins[20], ins[30:21], {1'b0}} // RISC-V の JAL 命令の即値のデコード
|
|
|
|
```
|
|
|
|
|
|
|
|
## 構文
|
|
|
|
|
|
|
|
### if
|
|
|
|
C言語では`{`から`}`がブロックになりましたが、Verilog HDL では Pascal 風に`begin`から`end`でブロックを作ります。一文だけならばぶら下げることも可能です。
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
if (条件式1)
|
|
|
|
式1;
|
|
|
|
else if (条件式2)
|
|
|
|
begin
|
|
|
|
式2;
|
|
|
|
式3;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
式4;
|
|
|
|
```
|
|
|
|
|
|
|
|
### for
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
for (i = 0; i < N; i = i + 1) 式;
|
|
|
|
```
|
|
|
|
|
|
|
|
C言語と同じ。
|
|
|
|
|
|
|
|
### case
|
|
|
|
|
|
|
|
C言語の`switch`文に相当します。
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
case (信号名)
|
|
|
|
値1: 式1;
|
|
|
|
値2: 式2;
|
|
|
|
値3: begin
|
|
|
|
式3;
|
|
|
|
式4;
|
|
|
|
end
|
|
|
|
default: 式5;
|
|
|
|
endcase
|
|
|
|
```
|
|
|
|
### casex
|
|
|
|
|
|
|
|
`x`を don't care として使用可能です。
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
casex (ins[31:24])
|
|
|
|
8'b1000_00xx: d <= 3'b001; // 8'b1000_0000, 8'b1000_0001, 8'b1000_0010, 8'b1000_0011 の四種にマッチ
|
|
|
|
8'b0100_xxxx: d <= 3'b010; // 十六通りの値にマッチ
|
|
|
|
default : d <= 3'b000;
|
|
|
|
endcase
|
|
|
|
```
|
|
|
|
|
|
|
|
### function
|
|
|
|
|
|
|
|
構文は以下のようになる。
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
function 返り値の型 関数名;
|
|
|
|
引数1;
|
|
|
|
引数2;
|
|
|
|
|
|
|
|
関数名 = 式;
|
|
|
|
endfunction
|
|
|
|
```
|
|
|
|
|
|
|
|
例えば、
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
function [7:0] dec38;
|
|
|
|
input [2:0] x;
|
|
|
|
|
|
|
|
dec38 = 0;
|
|
|
|
dec38[x] = 1;
|
|
|
|
endfunction
|
|
|
|
```
|
|
|
|
|
|
|
|
## 組み合わせ回路を作るときの注意
|
|
|
|
|
|
|
|
組み合わせ回路を作るために`if`文や`case`文を使う場合、**必ず全パターンを記述してください**。つまり、`else`や`default`を必ず書いてくださいということです。
|
|
|
|
|
|
|
|
これは、特定の条件の時に代入されない → その場合信号が変化しない → 信号を記憶しなければ と解釈されるためで、ラッチが生成されてしまいます。
|
|
|
|
|
|
|
|
命令セットにないから来ないはず、という発想で書かないのは**間違いです**。C言語等では、本当に来ないなら記述しなくても問題なく動作しますが、HDL の場合はそうではありません。論理合成ツールからは、回路の入力として何が来るか把握できないため、何が来ても大丈夫なように回路を構成しようとします。そのため、不要なラッチができてしまいます。
|
|
|
|
|
|
|
|
## コンパイラ指示子
|
|
|
|
|
|
|
|
### マクロ
|
|
|
|
|
|
|
|
C言語の`#define`のようなことができます。
|
|
|
|
|
|
|
|
#### 定義の仕方
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
`define シンボル 値
|
|
|
|
```
|
|
|
|
|
|
|
|
#### 参照の仕方
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
`シンボル
|
|
|
|
```
|
|
|
|
|
|
|
|
#### 例
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
`define sign 1
|
|
|
|
|
|
|
|
// ...
|
|
|
|
|
|
|
|
line = `sign; // line = 1 と同じ。
|
|
|
|
```
|
|
|
|
|
|
|
|
`` `define ``による定義は、モジュール定義内でも行えます。
|
|
|
|
|
|
|
|
### インクルード
|
|
|
|
|
|
|
|
C言語の`#include`のようなことができます。
|
|
|
|
|
|
|
|
```verilog
|
|
|
|
`include "ファイル名"
|
|
|
|
```
|
|
|
|
|
|
|
|
複数の`.v`ファイルに分割して設計するときには、C言語のヘッダファイルのように、マクロ定義だけ集めたファイルを作り、インクルードするとよいでしょう。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|