LoginSignup
3
3

More than 5 years have passed since last update.

GHDL を cygwin で使う

Last updated at Posted at 2015-12-06

VHDL のコンパイラである GHDL を cygwin で使ってみました。

まずは cygwin(64bit) 上でのコンパイル

GHDL のコンパイルには Ada の環境が必要です。cygwin の setup から gcc-ada:GNU Compiler Collection(Ada) をインストールします。バージョンは 4.9.3-1 です。
Ada がちゃんとインストールされていれば gnatmake というコマンドがインストールされているはずです。Ada のプログラムを書きコンパイル・実行できるか確認してみます。
次のプログラムを example.adb としてセーブします。

procedure Example is
begin
   null;
end Example;

その後、gnatmake example とうちコンパイル可能であることを確認します。

hanzer/gVHDL を入手しコンパイル

オリジナルの GHDL は 32bit 環境しか対応していないらしくうまくいきませんでした。そこで、github にある hanzer さんの gVHDL を入手します。
hanzer/gVHDL
また、ghdl のコンパイルに必要な gcc の環境 gcc-4.9.3 のソースも展開しておきます。その後 gVHDL で configure および make copy-sources を実行します。

> $ ./configure --with-gcc=/path/to/gcc/source/dir
> $ make copy-sources

with-gcc にはgcc-4.9.3 のソースディレクトリを指定します。すると gcc-4.9.3 に ghdl のソースがコピーされます。あとは gcc のコンパイルと同じ要領で enable-languages に vhdl を指定してコンパイル、そしてインストールを実行します。

> $ .configure --enable-languages=vhdl --disable-bootstrap
> $ make
> $ make install

GHDL で Hello World

インストールした ghdl がちゃんと動くか Hello World プログラムで確認します。

     --  Hello world program.
     use std.textio.all; --  Imports the standard textio package.

     --  Defines a design entity, without any ports.
     entity hello_world is
     end hello_world;

     architecture behaviour of hello_world is
     begin
        process
           variable l : line;
        begin
           write (l, String'("Hello world!"));
           writeline (output, l);
           wait;
        end process;
     end behaviour;

ghdl では -a でアナライズ、-e でエラボレートすることができます。アナライズでは vhdl のプログラムを解析して cf というファイルにモジュールの情報を生成するようです。-e で実際の実行可能なオブジェクトを生成します。

>$ ghdl -a hello.vhdl
>$ ghdl -e hello.vhdl
>ghdl: bad unit name 'hello.vhdl'
>ghdl: (a unit name is required instead of a filename)
>$ ghdl -e hello_world
>$ ls
e~hello_world.o  hello.o  hello.vhdl  hello_world.exe*  work-obj93.cf
>$ ./hello_world.exe
Hello world!

簡単なテストベンチを動かしてみる

次の簡単なテストベンチを動かしてみます。

ibrary IEEE, std;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.numeric_std_unsigned.all;
use IEEE.std_logic_textio.all;
use std.textio.all;

entity text_io_example is
end text_io_example;

architecture beh of text_io_example is
    signal v : std_logic_vector(5 downto 0);
    signal i : integer;
begin
    process is
    variable line0 : line;
    variable c : std_logic;
    begin
        c := '0';
        write(line0, c);
        writeline(output, line0);
        v <= v - 1;
        i <= i - 1;
        wait;
    end process;
end beh;

ghdl では makefile をつくるオプションがあります。単純に --gen-makefile を
実行しただけだとエラーになるので、その前に -a で vhdl ファイルを解析しておきます。

> $ghdl --gen-makefile --std=08 text_io_example
> ghdl: cannot find entity or configuration text_io_example
> $ghdl -a --std=08 test_tb.vhdl
> $ls
> test_tb.o  test_tb.vhdl  text_io_example.exe*  work-obj08.cf
> $ghdl --gen-makefile --std=08 text_io_example > makefile
> $ls
> makefile  test_tb.o  test_tb.vhdl  text_io_example.exe*  work-obj08.cf
> $make
> ghdl -e --std=08 text_io_example 

ここでは --std=08 オプションをつけています。ghdl は表示に厳密に IEEE のライブラリを定義していて numeric_std は v87(指定なしの時のバージョン) にはありますが、numeric_std_unsigned がありません。各ベンダーは IEEE の正式なライブラリを無視しているようです。std_logic_vecotr への足し算引き算ができるようになるために numeric_std_unsigned が本当は必要なようです。

Xilinx の FIFO を使用してみる

手元の PC では Vivado の 2015.3 をインストールしてあったので FIFO を使ってみることにします。FIFO を使うには unisims と unimacro を -i でインポートする必要があります。ここでは先の厳密な IEEE の問題を回避するために --ieee=synopsys というオプションを使っています。

> $ghdl -i --ieee=synopsys --work=unisim <パス>/unisims/*.vhd
> $$ghdl -i --ieee=synopsys --work=unisim <パス>/unisims/primitive/*.vhd
> $ghdl -i --ieee=synopsys --work=unimacro <パス>/unimacro/*.vhd
> $ls -1 *.cf
unimacro-obj93.cf
unisim-obj93.cf

これで unisim と unimacor の cf というファイルができました。さらに自分で作った fifo_test.vhdl(FIFO_DUALCLOCK_MACRO を使用したプログラム) と fifo_tb.vhdl(テストベンチ) をアナライズします。

> $ghdl -a --ieee=synopsys fifo_test.vhdl
> $ghdl -a --ieee=synopsys fifo_tb.vhdl

依存関係をチェックしなくて済むように -m というオプションで一気にコンパイルが可能です。

> $ ghdl -m --ieee=synopsys fifo_test
> <ワーニング中略>
> unimacro/FIFO_DUALCLOCK_MACRO.vhd:631:20: no declaration ?for "fifo18"
> unimacro/FIFO_DUALCLOCK_MACRO.vhd:631:20: component name expected
> unimacro/FIFO_DUALCLOCK_MACRO.vhd:664:23: no declaration for "fifo18_36"
> unimacro/FIFO_DUALCLOCK_MACRO.vhd:664:23: component name expected
> unimacro/FIFO_DUALCLOCK_MACRO.vhd:696:20: no declaration for "fifo36"
> unimacro/FIFO_DUALCLOCK_MACRO.vhd:696:20: component name expected
> unimacro/FIFO_DUALCLOCK_MACRO.vhd:729:23: no declaration for "fifo36_72"
> unimacro/FIFO_DUALCLOCK_MACRO.vhd:729:23: component name expected

残念、エラーです。FIFO_DUALCLOCK_MACRO に Virtex5 用の記述があって primitive にはそれがないようです。unimacro/FIFO_DUALCLOCK_MACRO.vhd の 627 行目からの 137 行を何とかすると何とかなりそうです。

> $ghdl -m --ieee=synopsys fifo_test
> <ワーニング中略>
> analyze unisims/unisim_VCOMP.vhd
> analyze unimacro/unimacro_VCOMP.vhd
> analyze fifo_test.vhdl
> analyze unimacro/FIFO_DUALCLOCK_MACRO.vhd
> analyze unisims/unisim_VPKG.vhd
> analyze unisims/primitive/FIFO18E1.vhd
> analyze unisims/primitive/FIFO36E1.vhd
> elaborate fifo_test

V5 の記述をうまく回避するとコンパイルが通りました。当然実行することが出来ます。--stop-time でシミュレーションの時間 --vcd で vcd ファイルの指定ができます。

> $ ./fifo_test.exe --stop-time=10us --vcd=fifo_test.vcd
> $ ls *.vcd
fifo_test.vcd

これで cygwin + ghdl + vi (あるいは emacs ) というシミュレーション環境を構築することができました。vi を使っている人は開発効率があがるでしょう。

3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3