|
|
# Verilatorを用いた高速シミュレーション
|
|
|
|
|
|
## Verilatorとは
|
|
|
|
|
|
VerilatorはオープンソースのVerilog HDLシミュレータです。
|
|
|
|
|
|
Verilog HDLの記述をC++に変換し、コンパイル後にシミュレーションするため非常に高速という特徴があります。
|
|
|
一方、高速化のためにVerilog HDLの一部の機能が使えないという制約があります。
|
|
|
|
|
|
また、テストベンチをC/C++で書く必要があります。
|
|
|
|
|
|
## Verilatorのインストール
|
|
|
|
|
|
```
|
|
|
$ sudo apt-get install verilator
|
|
|
```
|
|
|
|
|
|
高速化のため、以下の設定をおすすめします。
|
|
|
|
|
|
* `/usr/share/verilator/include/verilated.mk`の89行目`#OPT_FAST = -O2 -fstrict-aliasing`の`#`を消すことで最適化を有効にする
|
|
|
|
|
|
## Verilatorを用いてCoreMark_for_Synthesisのシミュレーションを行う
|
|
|
|
|
|
適当な作業ディレクトリを用意し、そこにVerilog HDLのソースファイルを置いたとします。
|
|
|
|
|
|
そのディレクトリに、C/C++で書かれたテストベンチファイルを作成します。例を一番下に書きました。
|
|
|
|
|
|
`$ verilator --cc top.v -exe test_bench.cpp`とコマンドを実行することで、`obj_dir`というディレクトリが作成されます(Vivadoでは出ないLintエラーの警告が出るかもしれません)。このディレクトリの中には、C++に変換された`top.v`である`Vtop.cpp`などが含まれています。
|
|
|
|
|
|
`$ make -C obj_dir -f Vtop.mk`とコマンドを実行することで、`obj_dir`の中に`Vtop`という実行ファイルが作成されます。
|
|
|
これを実行する(`$ obj_dir/Vtop`)ことで、シミュレーションが行われます。
|
|
|
|
|
|
```
|
|
|
#include <iostream>
|
|
|
#include <verilated.h>
|
|
|
#include "Vtop.h"
|
|
|
|
|
|
// Set the clock speed of your processor.
|
|
|
static constexpr size_t clock_Hz = 55000000;
|
|
|
// UART baudrate
|
|
|
static constexpr size_t uart_Hz = 115200;
|
|
|
// The number of CoreMark iterations is depend on clock speed.
|
|
|
// Max: 20 seconds
|
|
|
static constexpr size_t max_cycle = 20 * clock_Hz;
|
|
|
|
|
|
size_t timer_ps = 0;
|
|
|
|
|
|
void uart_rx(unsigned int u) {
|
|
|
static size_t s = 0;
|
|
|
static size_t b = 0;
|
|
|
static char c = 0;
|
|
|
if( s == 0 && u == 0 ) {
|
|
|
s = timer_ps;
|
|
|
b = 0;
|
|
|
c = 0;
|
|
|
} else if( s != 0 && s + 1000000000000 / uart_Hz / 2 * (2*b+3) < timer_ps ) {
|
|
|
c |= u << b;
|
|
|
if( ++b == 8 ) {
|
|
|
putchar(c);
|
|
|
s = 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
Vtop top;
|
|
|
|
|
|
top.cpu_resetn = 0;
|
|
|
top.sysclk = 0;
|
|
|
top.eval();
|
|
|
top.sysclk = 1;
|
|
|
top.eval();
|
|
|
top.sysclk = 0;
|
|
|
top.eval();
|
|
|
top.cpu_resetn = 1;
|
|
|
|
|
|
for( size_t cycle = 0; cycle < max_cycle; ++cycle ) {
|
|
|
top.sysclk = 0;
|
|
|
top.eval();
|
|
|
top.sysclk = 1;
|
|
|
top.eval();
|
|
|
uart_rx(top.uart_rx_out);
|
|
|
timer_ps += 1000000000000 / clock_Hz;
|
|
|
}
|
|
|
}
|
|
|
``` |
|
|
\ No newline at end of file |