Processing math: 100%

2019/09/08

VHDL/Verilog-HDL差分

VHDLとVerilog-HDLの記述方法についてメモ.

VHDLとVerilog-HDLではほとんど記号的な記述方法に差があるのみで, ほとんどが機械的に可換である. 以下では機械的には置き換えられない記述方法についてメモしておく. ほとんどは書き方の問題で実装時に有利・不利があるかは考えていない.

また筆者がVHDLをメインに使っているためVHDLの特殊な記法に言及しているようなものだ.

コンポーネント宣言

悪名高いVHDLのコンポーネント宣言. ライブラリ宣言の問題でしかない.

カウンタ

Verilogではビット幅を指定せずに整数を宣言すると32ビットとして解釈される. 安全のために信号の幅はきちんと揃えておくべき. これがカウンタだといちいちビット幅を考える必要があるので面倒.

Verilog

reg [3:0] cnt; // Counter
~
always @(negedge nRST, posedge CLK) begin
if (~ nRST)
cnt <= 4'd0;
else if (CLK) begin
if (cnt == CntMax)
cnt <= 4'd0;
else
cnt <= cnt + 4'd1;
end
end
view raw cnt.v hosted with ❤ by GitHub

VHDLでは算術演算子がオーバーロードファンクションとして定義されているため, std_logic_vectorだろうがintegerだろうが関係なく扱える.

VHDL

cnt : integer range 0 to CntMax -- Counter
~
process (CLK, nRST) begin
if (nRST = '0') then
cnt <= 0;
elsif (CLK'event and CLK = '1') then
if (cnt = CntMax) then
cnt <= 0;
else
cnt <= cnt + 1;
end if;
end if;
end process;
view raw cnt.vhd hosted with ❤ by GitHub

集合体(Aggregate)

VHDLはベクタに集合体を代入することができる. a <= (others => '0')も集合体の代入. これを使えばエンコーダがすっきりする.

a : std_logic_vector(7 downto 0);
b : std_logic_vector(3 downto 0);
~
process (CLK, nRST) begin
if (nRST = '0') then
a <= (others => '0');
elsif (CLK'event and CLK = '1') then
case (b) is
when X"0" => a <= (0 => '1', others => '0');
when X"1" => a <= (1 => '1', others => '0');
when X"2" => a <= (2 => '1', others => '0');
when X"3" => a <= (3 => '1', others => '0');
when X"4" => a <= (4 => '1', others => '0');
when X"5" => a <= (5 => '1', others => '0');
when X"6" => a <= (6 => '1', others => '0');
when X"7" => a <= (7 => '1', others => '0');
when others => a <= (others => '0');
end case
end if;
end process;

列挙型(Enumeration)

VHDLでtype宣言と呼ばれるやつ. Verilogでは列挙型をサポートしない. ステートマシンの宣言が異なる.

VHDL

-- State machine --
type main_state is (
WakeUp, -- Device wake up
Init, -- Initialization
Idle, -- Idle
StateA, -- State A
StateB, -- State B
TurnAround -- Turn around idle
);
signal main_st : main_state;
view raw enum_state.vhd hosted with ❤ by GitHub

Verilog

// State machine //
parameter WakeUp = 6'd000001; // Device wake up
parameter Init = 6'd000010; // Initialization
parameter Idle = 6'd000100; // Idle
parameter StateA = 6'd001000; // State A
parameter StateB = 6'd010000; // State B
parameter TurnAround = 6'd100000; // Turn around idle
reg [2:0] main_st; // State machine
view raw enum_state.v hosted with ❤ by GitHub

System Verilogで列挙型がサポートされた.

System Verilog

typedef enum logic [2:0] {
WakeUp, // Device wake up
Init, // Initialization
Idle, // Idle
StateA, // State A
StateB, // State B
TurnAround // Turn around idle
} main_st;
view raw enum_state.sv hosted with ❤ by GitHub

アトリビュート

VHDLではアトリビュートによってビット数を意識せずにビット位置の指定ができる.

ex. シフトレジスタ

シフトレジスタではビット幅を全く意識せずに記述することができる.

process (CLK, nRST) begin
if (nRST = '0') then
a <= (others => '0');
elsif (CLK'event and CLK = '1') then
a <= a(a'left - 1 downto 0) & in_a;
end if;
end process;

ex. 乗算器

算術演算では頻繁にビット幅が変わるが, いちいち計算しなくてもよい.

a : std_logic_vector(3 downto 0);
b : std_logic_vector(3 downto 0);
product : std_logic_vector(a'length + b'length - 1 downto 0);
~
product <= a * b;
view raw multiplier.vhd hosted with ❤ by GitHub

リダクション演算子

Verilogではリダクション演算子をサポートする.

Verilog

parameter a = 4'b1010;
assign b = or a; // b:1'b1
assign c = and a; // c:1'b0
view raw reduction.v hosted with ❤ by GitHub

VHDLではstd_logic_1164でサポートしないが, std_logic_miscで使うことができる.

VHDL

constant : std_logic_vector(3 downto 0) := "1010";
b <= or_reduce(a);
c <= and_reduce(a);
view raw reduction.vhd hosted with ❤ by GitHub

またVHDL-2008でVerilogのようなリダクション演算子がサポートされたようだ. なおQuartusはLite, Standard editionではVHDL-2008未対応.

多次元配列

Verilogでは行列のような3次元以上の多次元配列を扱えない. VHDLでは2次元配列と同様に扱える. 簡単な2×2行列くらいなら2次元化しても問題ないが, テンソルを扱ったりする場合は有用(テンソル使うか?).

type MatrixTyp is array (0 to 2, 0 to 2) of std_logic_vector(7 downto 0);
signal matrix_cell : MatrixTyp; -- Matrix cells
~
matrix_cell(0, 0) <= a00;
matrix_cell(0, 1) <= a01;
matrix_cell(0, 2) <= a02;
matrix_cell(1, 0) <= a10;
matrix_cell(1, 1) <= a11;
matrix_cell(1, 2) <= a12;
matrix_cell(2, 0) <= a20;
matrix_cell(2, 1) <= a21;
matrix_cell(2, 2) <= a22;
view raw matrix.vhd hosted with ❤ by GitHub

0 件のコメント:

コメントを投稿