Building the example
최상위 레벨에 Makefile을 가지고 있습니다. 이것을 이용해서 빌드합니다.
빌드 타겟은 아래와 같습니다.
make simulate
요건 ICARUS를 위해서 준비된 것입니다.
make verilate
이것이 Verilator를 위해서 준비한 것입니다.
make clean
Command files
cf-baseline.scr을 이용해서 빌드합니다.
다음과 같이 커맨드라인에서 넣어서 진행합니다.
make simulate COMMAND_FILE=cf-baseline-5.scr
일단 위의 것을 실행하기 전에
먼저 해야 할 것이 몇개의 환경 변수를 정의하는 것입니다.
$BENCH_DIR
~/orp_soc/bench/verilog
.
을 가리키도록 정의되어야 합니다.
$RTL_DIR
~/orp_soc/rtl/verilog
을 가리키도록 정의되어야 합니다.
$BENCH_LOCAL
~/orp_soc/local/bench/verilog
를 가리키도록 정의합니다.
$RTL_LOCAL
~/opr_soc/local/rtl/verilog
를 가리키도록 정의합니다.
set_env.sh 파일로 아래와 같이 정의하여 둡니다.
GUNDAM-NT:embecosm-esp5-or1k-verilator-1.0 kevinim$ source set_env.sh
export BENCH_DIR=orp_soc/bench/verilog
export RTL_DIR=orp_soc/rtl/verilog
export RTL_LOCAL=local/rtl/verilog
export BENCH_LOCAL=local/bench/verilog
(주) 폴더의 위치는 사용자마다 틀리므로 참고해서 재구성하시기 바랍니다.
(주) 절대 위치가 아니라 상대 위치로 해야 하며 앞뒤에 /가 빠져야 잘 구성됩니다.
사용은
source set_env.sh
로 합니다.
Additional Flags
VFLAGS라는 변수를 통해서 verilator에 필요한 정보를 전달할 수 있습니다.
용법은 다음과 같습니다.
make verilate VFLAGS=-trace
타겟 어플인 Dhrystone은 반복해서 몇번 돌아서 그 값을 추출하는 프로그램입니다.
반복의 회수를 미리 정의할 수 있다면 편리합니다. 다음과 같은 방법으로 정의합니다.
make verilate NUM_RUNS=100
Building Base Line Simulation
Command File
Baseline simulation을 위한 커맨드 라인은 아래 위치에 있습니다.
sim/cf-baseline.scr
이 파일은 주로 인자와 사용할 파일의 목록이 포함되어 있습니다.
우선 첫 부분에 있는 것은 헤더 디렉토리들의 목록입니다. 다음과 같이 선언되어 있습니다.
+incdir+$BENCH_LOCAL
+incdir+$BENCH_DIR
+incdir+$RTL_LOCAL
+incdir+$RTL_LOCAL/or1200
+incdir+$RTL_DIR/or1200
+incdir+$RTL_DIR/dbg_interface
+incdir+$RTL_DIR/audio
+incdir+$RTL_DIR/ethernet
+incdir+$RTL_DIR/ps2
+incdir+$RTL_DIR/uart16550
+incdir+$RTL_DIR/ssvga
timescale.v에 필요한 시뮬레이션 타임을 설정하는 정보가 있는데 문제는 이 파일이 여러군데에 존재할 수 있다는 점입니다. 그래서 $BENCH_DIR
에 있는 파일을 한번 참조하면 그 이후에는 해당 파일을 찾지 않습니다.
3개의 테스트 벤치 파일이 있습니다.
그중에 중요한 것은 ORPSoC Testbench와 l.nop를 지원하기 위한 모니터 모듈입니다.
위의 것은 아래에서 찾아 볼 수 있습니다.
$BENCH_LOCAL/orpsoc_bench.v
$BENCH_LOCAL/or1200_monitor.v
최상위 DUT 모델은 orpsoc_fpga_top 입니다. 버스에 대한 것도 인스턴스를 만들어 진행하므로
이에 대한 정보는 다음과 같은 파일들에서 찾아 볼 수 있습니다.
$RTL_LOCAL/orpsoc_fpga_top.v
$RTL_DIR/tc_top.v
Running the baseline simulation
이제 길고도 길었던 설명이 정리되고 진짜 시뮬레이션을 해보는 시간이 왔다.
시뮬레이션은 다음과 같이 커맨드를 넣어서 진행합니다.
make simulate COMMAND_FILE=cf-baseline.scr NUM_RUNS=1000
이제 위의 코드대로 넣으면 시뮬레이션을 할 수 있습니다.
GUNDAM-NT:embecosm-esp5-or1k-verilator-1.0 kevinim$ make simulate COMMAND_FILE=cf-baseline.scr NUM_RUNS=1000
cd local/sw && make
cd utils && make
gcc -o bin2c -O2 -Wall bin2c.c
gcc -o bin2srec -O2 -Wall bin2srec.c
gcc -o bin2flimg -O2 -Wall bin2flimg.c
gcc -o bin2hex -O2 -Wall bin2hex.c
cd support && make
or32-uclinux-gcc -mhard-div -O2 -c -o support.o support.c
make[2]: or32-uclinux-gcc: No such file or directory
make[2]: *** [support.o] Error 1
make[1]: *** [all] Error 2
make: *** [software] Error 2
흐.. 그러고 보니 OpenRISC용 컴파일러를 설치하지 않았습니다. 이것을 설치하고 다시 합니다.
위의 링크를 참조하여 설치한 뒤에 다시 시작합니다.
앞의 명령어를 넣으면 진행이 잘 될것 같은데 뜻밖의 오류가 발생합니다.
GUNDAM-NT:embecosm-esp5-or1k-verilator-1.0 kevinim$ make simulate COMMAND_FILE=cf-baseline.scr NUM_RUNS=1000
cd local/sw && make
cd utils && make
make[2]: Nothing to be done for `all'.
cd support && make
or32-elf-gcc -I/opt/or32-elf/or32-elf/newlib-include -mhard-div -O2 -c -o support.o support.c
In file included from support.c:8:0:
support.h:45:20: error: macro "putc" requires 2 arguments, but only 1 given
support.h:45:6: error: 'putc' redeclared as different kind of symbol
make[2]: *** [support.o] Error 1
make[1]: *** [all] Error 2
make: *** [software] Error 2
putc가 따로 정의된 것이 있는데, 여기서는 시뮬레이션용으로 새롭게 만드는 것이라 인자가 틀리다는 내용입니다. 일단 해당 폴더로 이동해서
코드를 보면, 옵션에서 #ifdef등으로 처리되고 있는 것을 확인할 수 있습니다.
결과적으로 GCC를 빌드할 때 OR1K 옵션이 정의가 안되어 있어서
여기서 오류가 난것입니다. 뭐, 이제와서 돌아갈 수 는 없는일 강제로 여기서 고치도록 하겠습니다.
Makefile의 수정을 아래와 같이 합니다.
INC_PATH = /opt/or32-elf/or32-elf/newlib-include
LOCAL_OPTION = ${INC_PATH} -DOR1K
이후 빌드 옵션에 아래와 같이 넣어줍니다.
...
support.o: support.c
or32-elf-gcc ${LOCAL_OPTION} -mhard-div -O2 -c -o $@ $?
....
그리고 빌드하면 잘 됩니다.
dhry 빌드
dhry를 빌드하게 되는데 여기서 또 오류가 발생합니다.
GUNDAM-NT:dhry kevinim$ make
or32-elf-ld -T ../support/orp.ld dhry-O0.o ../support/reset-nocache.o ../support/libsupport.a -o dhry-nocache-O0.or32
../support/libsupport.a(except.o): In function `_reset':
(.text+0x104): undefined reference to `_reset_except'
make: *** [dhry-nocache-O0] Error 1
...
통밥으로 보면 Reset_except는 reset을 받았을때 점프해가는 위치 즉 리셋 벡터를 의미합니다.
../support/reset.S 파일에서 reset exception 관련 루틴을 가지고 있으므로,
확인합니다.
....
.section .stack
.space 0x10000
_stack:
.section .reset, "ax"
.org 0x100
_reset_vector:
l.nop
l.nop
l.addi r2,r0,0x0
l.addi r3,r0,0x0
l.addi r4,r0,0x0
....
위의 코드를 보면 reset_vector에 연결되는데 여기에 넣어야 할 것 같습니다.
그래서 아래와 같이 수정합니다.
.section .stack
.space 0x10000
_stack:
.section .reset, "ax"
.org 0x100
.global _reset_except
_reset_except:
_reset_vector:
l.nop
l.nop
l.addi r2,r0,0x0
l.addi r3,r0,0x0
l.addi r4,r0,0x0
.....
이후에 컴파일 하면 잘 됩니다.
최상위 폴더에서 다시 빌드하면 잘 되고 끝납니다.
GUNDAM-NT:embecosm-esp5-or1k-verilator-1.0 kevinim$ make simulate COMMAND_FILE=cf-baseline.scr NUM_RUNS=1000
cd local/sw && make
cd utils && make
make[2]: Nothing to be done for `all'.
cd support && make
make[2]: Nothing to be done for `all'.
cd dhry && make
or32-elf-ld -T ../support/orp.ld dhry-O0.o ../support/reset-nocache.o ../support/libsupport.a -o dhry-nocache-O0.or32
or32-elf-objcopy -O binary dhry-nocache-O0.or32 dhry-nocache-O0.bin
../utils/bin2hex dhry-nocache-O0.bin > dhry-nocache-O0.hex
or32-elf-ld -T ../support/orp.ld dhry-O2.o ../support/reset-nocache.o ../support/libsupport.a -o dhry-nocache-O2.or32
or32-elf-objcopy -O binary dhry-nocache-O2.or32 dhry-nocache-O2.bin
../utils/bin2hex dhry-nocache-O2.bin > dhry-nocache-O2.hex
or32-elf-ld -T ../support/orp.ld dhry-O2.o ../support/reset-icdc.o ../support/libsupport.a -o dhry-icdc-O2.or32
or32-elf-objcopy -O binary dhry-icdc-O2.or32 dhry-icdc-O2.bin
../utils/bin2hex dhry-icdc-O2.bin > dhry-icdc-O2.hex
cd sim/src && rm -f flash.in
cd sim/src && ln -s ../../local/sw/dhry/dhry-icdc-O2.hex flash.in
cd sim/run && time -p iverilog -c iv-processed.scr
/bin/sh: iverilog: command not found
real 0.09
user 0.00
sys 0.00
make: *** [simulate] Error 127
GUNDAM-NT:embecosm-esp5-or1k-verilator-1.0 kevinim$
제일 밑에 보면 iverilog등을 찾고 있는 것을 알수 있습니다.
http://www.embecosm.com/appnotes/ean6/html/ch03s08.html
을 보면
icarus로 한다면 simulate로 하고,
verilator로 한다면,
make verilate COMMAND_FILE=cf-baseline.scr NUM_RUNS=1000
커맨드로 해야 합니다.
위의 커맨드로 하면 다음과 같은 오류를 내고 멈춥니다.
GUNDAM-NT:embecosm-esp5-or1k-verilator-1.0 kevinim$ make verilate COMMAND_FILE=cf-baseline.scr NUM_RUNS=1000
cd local/sw && make
cd utils && make
make[2]: Nothing to be done for `all'.
cd support && make
make[2]: Nothing to be done for `all'.
cd dhry && make
or32-elf-ld -T ../support/orp.ld dhry-O0.o ../support/reset-nocache.o ../support/libsupport.a -o dhry-nocache-O0.or32
or32-elf-objcopy -O binary dhry-nocache-O0.or32 dhry-nocache-O0.bin
../utils/bin2hex dhry-nocache-O0.bin > dhry-nocache-O0.hex
or32-elf-ld -T ../support/orp.ld dhry-O2.o ../support/reset-nocache.o ../support/libsupport.a -o dhry-nocache-O2.or32
........
cd verilator-model && time -p make
......
verilator -Mdir . -sc -f v-processed.scr
%Error: Need $SYSTEMC in environment
Probably System-C isn't installed, see http://www.systemc.org
%Error: Command Failed verilator_bin -Mdir . -sc -f v-processed.scr
make[1]: *** [Vorpsoc_fpga_top.mk] Error 10
real 3.43
user 0.07
sys 0.05
make: *** [model] Error 2
...
위의 오류는 systemc환경 변수를 설정 하지 않아서 생긴 문제입니다.
필요로 하는 systemc환경 변수는 아래와 같습니다.
export SYSTEMC=/Library/SystemC/systemc-2.2.0/
로 하고 실행하면 다음과 같은 오류가 또 발생합니다.
..
GUNDAM-NT:embecosm-esp5-or1k-verilator-1.0 kevinim$ make verilate COMMAND_FILE=cf-baseline.scr NUM_RUNS=1000
........
cd sim/src && ln -s ../../local/sw/dhry/dhry-icdc-O2.hex flash.in
cd verilator-model && time -p make
Makefile:121: OrpsocAccess.d: No such file or directory
Makefile:121: TraceSC.d: No such file or directory
Makefile:122: Vorpsoc_fpga_top__ALLcls.d: No such file or directory
Makefile:122: Vorpsoc_fpga_top__ALLsup.d: No such file or directory
Makefile:122: Vorpsoc_fpga_top__ver.d: No such file or directory
...
일단 오류의 원인을 확인해 보도록 하지요 TT_TT
디버깅 할 때 제일 먼저 고쳐야 할 것은
(1) 제일 먼저 나타나는 오류부터 수정합니다. 그것 때문에 그 오류 밑에서 나타나는 오류는 연쇄적인 오류가 많기 때문입니다.
(2) 알려진 오류 부터 수정합니다.
잘 알고 있는 그리고 잘 알려진 오류가 대부분 또 발생합니다. 그래서 그것 부터 수정해나가면 빠릅니다.
이 경우 잘 알려진 (홈피에 있는) 오류부터 수정해 보도록 하겠습니다.
...
verilator -Mdir . -sc -f v-processed.scr
%Error: ../orp_soc/rtl/verilog/mem_if/flash_top.v:210: syntax error, unexpected ')'
%Error: ../orp_soc/rtl/verilog/mem_if/sram_top.v:236: syntax error, unexpected ')'
...
verilog 파일 내에서 지원하지 않는 문법으로 발생된 오류입니다.
해당 위치에 가면 아래와 같은 코드를 볼 수 있습니다.
...
// synopsys translate_off
integer fflash;
initial fflash = $fopen("flash.log");
...
두가지 해결책이 있는데 하나는 아래와 같이 코드를 고치는 것입니다.
initial fflash = $fopen("flash.log", "w");
또하나는 이것보다 단순한 Flash Model로 바꾸는 것입니다.
해당 모델은
$RTL_LOCAL/mem_if/flash_top.v
에 있습니다. 이것을 컴파일 하도록 cf-baseline.scr을 수정하는 것입니다.
여기서는 후자로 가보도록 하겠습니다.
...// RTL files (mem_if)
//$RTL_DIR/mem_if/flash_top.v
$RTL_LOCAL/mem_if/flash_top.v
...
위와 같이 cf-baseline.scr을 수정한 후에 다시 컴파일 해 봅니다.
그러면 위의 오류는 없어지고 다음 오류를 볼 수 있습니다.
..
%Error: ../orp_soc/rtl/verilog/mem_if/sram_top.v:236: syntax error, unexpected ')'
..
같은 오류이니 같은 방법으로 수정합니다.
그 다음 오류는 아래와 같습니다.
...
%Error: ../orp_soc/rtl/verilog/ethernet/eth_wishbone.v:564: Unexpected "do": "do" is a SystemVerilog keyword misused as an identifier
...
키워드를 변수로 썻기 때문에 발생한 오류입니다.
쉬운 해결법은 변수 이름을 바꾸거나
아니면 verilog 버전 지원 옵션을 사용하는 것입니다.
후자의 방법으로 한다면 다음과 같이 옵션을 바꿉니다.
make verilate COMMAND_FILE=cf-baseline.scr VFLAGS="-Wno-lint -language 1364-2001"
language 옵션이 그에 해당하는 옵션입니다. 이제 컴 파일 해보면 ...
warning이 많이 발생하면서 진행하고 끝납니다.
...
%Warning-COMBDLY: ../orp_soc/rtl/verilog/ps2/ps2_keyboard.v:353: Delayed assignments (<=) in non-clocked (non flop or latch) blocks should be non-delayed assignments (=).
%Warning-COMBDLY: ../orp_soc/rtl/verilog/ps2/ps2_keyboard.v:355: Delayed assignments (<=) in non-clocked (non flop or latch) blocks should be non-delayed assignments (=).
%Warning-COMBDLY: ../orp_soc/rtl/verilog/ps2/ps2_keyboard.v:360: Delayed assignments (<=) in non-clocked (non flop or latch) blocks should be non-delayed assignments (=).
...
대부분의 경고가 위와 같은 구문인데 확인을 해보변
...
ps2_data_hi_z <= #1 0;
...
즉 타임 딜레이를 먹이고 있는데 이를 처리할 수 없다는 오류입니다.
CBS의 숙명이죠.. 그냥 패스
이 경고 메시지가 싫다면 다음과 같이 옵션을 추가합니다.
그러면 다음과 같이 되는데 결과적으로 해당 오류 메시지를 덤프하지 않습니다.
make verilate COMMAND_FILE=cf-baseline.scr VFLAGS="-Wno-lint -language 1364-2001 -Wno-COMBDLY "
같은 방식으로 나타나는 오류인
...
%Warning-UNOPTFLAT: Use "/* verilator lint_off UNOPTFLAT */" and lint_on around source to disable this message.
%Warning-UNOPTFLAT: Example path: ../orp_soc/rtl/verilog/ps2/ps2_top.v:145: TOP->v.ps2_top.rx_kbd_data_ready
%Warning-UNOPTFLAT: Example path: ../orp_soc/rtl/verilog/ps2/ps2_translation_table.v:289: ASSIGNW
%
...
위의 경고 메시지도 다음과 같은 옵션을 넣어서 없앨 수 있습니다.
그러면 최종적으로 다음과 같이 나옵니다.
make verilate COMMAND_FILE=cf-baseline.scr VFLAGS="-Wno-lint -language 1364-2001 -Wno-COMBDLY -Wno-UNOPTFLAT "
위의 커맨드를 다시 실행하면
아래와 같은 오류 메시지가 나옵니다.
...
Vorpsoc_fpga_top.h:12:26: error: verilated_sc.h: No such file or directory
Vorpsoc_fpga_top.h:13:23: error: verilated.h: No such file or directory
...
Header File을 찾을 수 없다는 것입니다.
compile option에서 추가되지 않아서 그런것으로 보입니다.
이것은 환경 변수인 VERILATOR_ROOT을 설정해서 맞추어야 합니다.
.bashrc 파일에 다음 변수를 추가합니다.
export VERILATOR_ROOT=/Users/kevinim/Documents/Verilator/verilator-3.804
이후에 source 하고 다시 컴파일하면 아래와 같은 오류 메시지가 나타납니다.
....
OrpsocAccess.cpp:32:41: error: Vorpsoc_fpga_top_or1200_cpu.h: No such file or directory
OrpsocAccess.cpp:33:42: error: Vorpsoc_fpga_top_or1200_ctrl.h: No such file or directory
OrpsocAccess.cpp:34:40: error: Vorpsoc_fpga_top_or1200_rf.h: No such file or directory
OrpsocAccess.cpp:35:51: error: Vorpsoc_fpga_top_or1200_rfram_generic.h: No such file or directory
OrpsocAccess.cpp:36:41: error: Vorpsoc_fpga_top_or1200_top.h: No such file or directory
OrpsocAccess.cpp:37:46: error: Vorpsoc_fpga_top_orpsoc_fpga_top.h: No such file or directory
...
거의다 온 느낌이지만, 하여튼 오류는 죽어라나 나오는 군요