Adım 1: Klasör Yapısını Oluşturma #
-
riscv
Klasörünü Oluşturun:mkdir ~/riscv cd ~/riscv
-
Alt Klasörleri Oluşturun: Toolchain, Spike, pk ve test süitleri için ayrı klasörler oluşturalım:
mkdir toolchain spike pk tests
Adım 2: RISC-V Toolchain Kurulumu #
2.1. Toolchain’i Kaynaktan Derleme #
-
Kaynak Kodunu İndirin:
cd ~/riscv/toolchain git clone https://github.com/riscv/riscv-gnu-toolchain cd riscv-gnu-toolchain
-
Gerekli Bağımlılıkları Kurun:
sudo apt install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
-
Toolchain’i Derleyin:
-
RISC-V 32-bit
IMC
mimarisi için:./configure --prefix=$HOME/riscv/toolchain/install --with-arch=rv32imc --with-abi=ilp32 make
CSR desteği için
./configure --prefix=$HOME/riscv/toolchain/install --with-arch=rv32imc_zicsr --with-abi=ilp32 make
-
-
Toolchain’i PATH’e Ekleyin:
export PATH=$HOME/riscv/toolchain/install/bin:$PATH echo 'export PATH=$HOME/riscv/toolchain/install/bin:$PATH' >> ~/.bashrc source ~/.bashrc
-
Toolchain’i Test Edin:
riscv32-unknown-elf-gcc --version
Adım 3: Spike Simülatörü Kurulumu #
3.1. Spike’ı Kurma #
-
Kaynak Kodunu İndirin:
cd ~/riscv/spike git clone https://github.com/riscv-software-src/riscv-isa-sim cd riscv-isa-sim
-
Derleme ve Kurulum:
mkdir build cd build ../configure --prefix=$HOME/riscv/spike/install make make install
-
Spike’ı PATH’e Ekleyin:
export PATH=$HOME/riscv/spike/install/bin:$PATH echo 'export PATH=$HOME/riscv/spike/install/bin:$PATH' >> ~/.bashrc source ~/.bashrc
-
Spike’ı Test Edin:
spike --version
Adım 4: Proxy Kernel (pk) Kurulumu #
4.1. pk’yı Kurma #
-
Kaynak Kodunu İndirin:
cd ~/riscv/pk git clone https://github.com/riscv/riscv-pk cd riscv-pk
-
Derleme ve Kurulum:
mkdir build cd build ../configure --prefix=$HOME/riscv/pk/install --host=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 make make install
-
pk’yı Test Edin:
ls $HOME/riscv/pk/install/riscv32-unknown-elf/bin/pk
Adım 5: Test Programları ve Doğrulama #
5.1. Basit Bir Test Programı Yazma #
-
Örnek C Programı:
~/riscv/tests
klasörüne gidin vetest.c
adında bir dosya oluşturun:cd ~/riscv/tests nano test.c
İçeriği:
int main() { int a = 5; int b = 10; int c = a + b; return c; }
-
Programı Derleyin:
riscv32-unknown-elf-gcc -o test test.c
-
Spike ile Çalıştırın:
spike $HOME/riscv/pk/install/riscv32-unknown-elf/bin/pk test
5.2. RISC-V Test Süitlerini Kullanma #
-
Test Süitlerini İndirin:
cd ~/riscv/tests git clone --recurse-submodules https://github.com/riscv/riscv-tests cd riscv-tests
-
Testleri Derleyin:
autoconf ./configure --prefix=$HOME/riscv-tests/target --with-xlen=32 CC=riscv32-unknown-elf-gcc CFLAGS="-mabi=ilp32 -march=rv32imc_zicsr -mcmodel=medany -static -fno-common -nostdlib -nostartfiles -fno-builtin -ffunction-sections -lm -lgcc" make
Bu kısımda biz kendi işlemcimiz için sadece fiziksel testleri ve rv32imc mimarisini koşacağımızdan isa içerisindeki makefile’ı şöyle güncelledik :
#=======================================================================
# Makefile for riscv-tests/isa
#-----------------------------------------------------------------------
XLEN ?= 32
src_dir := .
# Yalnızca 32-bit testleri için gerekli Makefrag dosyalarını ekliyoruz.
include $(src_dir)/rv32ui/Makefrag
include $(src_dir)/rv32uc/Makefrag
include $(src_dir)/rv32um/Makefrag
default: all
#--------------------------------------------------------------------
# Build rules
#--------------------------------------------------------------------
RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf-
RISCV_GCC ?= $(RISCV_PREFIX)gcc
RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data
RISCV_SIM ?= spike
vpath %.S $(src_dir)
#------------------------------------------------------------
# Build assembly tests
%.dump: %
$(RISCV_OBJDUMP) $< > $@
# Yalnızca 32-bit testler için çıktı dosyası oluşturma kuralı.
%.out32: %
$(RISCV_SIM) --isa=rv32imc_zicsr_zifencei --misaligned $< 2> $@
# compile_template fonksiyonu, yalnızca p testleri için kullanılacak şekilde düzenlendi.
define compile_template
# p testlerini derleme kuralı.
$$($(1)_p_tests): $(1)-p-%: $(1)/%.S
$$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) -I$(src_dir)/../env/p -I$(src_dir)/macros/scalar -T$(src_dir)/../env/p/link.ld $$< -o $$@
$(1)_tests += $$($(1)_p_tests)
# Testlerin dump dosyalarını oluşturma kuralı.
$(1)_tests_dump = $$(addsuffix .dump, $$($(1)_tests))
$(1): $$($(1)_tests_dump)
.PHONY: $(1)
# Derleyicinin belirtilen mimariyi destekleyip desteklemediğini kontrol etme.
COMPILER_SUPPORTS_$(1) := $$(shell $$(RISCV_GCC) $(2) -c -x c /dev/null -o /dev/null 2> /dev/null; echo $$$$?)
# Eğer destekliyorsa, testleri ekle.
ifeq ($$(COMPILER_SUPPORTS_$(1)),0)
tests += $$($(1)_tests)
endif
endef
# Yalnızca rv32ui, rv32uc ve rv32um testleri için compile_template çağrılıyor.
$(eval $(call compile_template,rv32ui,-march=rv32imc_zicsr_zifencei -mabi=ilp32))
$(eval $(call compile_template,rv32uc,-march=rv32imc_zicsr_zifencei -mabi=ilp32))
$(eval $(call compile_template,rv32um,-march=rv32imc_zicsr_zifencei -mabi=ilp32))
# Testlerin dump ve çıktı dosyalarını oluşturma kuralları.
tests_dump = $(addsuffix .dump, $(tests))
tests32_out = $(addsuffix .out32, $(filter rv32%,$(tests)))
# run hedefi, yalnızca 32-bit testleri çalıştırır.
run: $(tests32_out)
# Temizleme işlemi için junk değişkeni.
junk += $(tests) $(tests_dump) $(tests32_out)
# Script'i çalıştıracak hedef
convert_dump:
chmod +x convert_dump.sh # Script'e çalıştırma izni ver (gerekirse)
./convert_dump.sh $(src_dir) # Script'i belirtilen dizinde çalıştır
# all hedefine convert_dump ekleyerek otomatik olarak çalıştırılmasını sağlayabilirsiniz.
all: $(tests_dump) convert_dump
# clean hedefine .elf ve .hex dosyalarını da ekleyerek temizleme işlemini genişletebilirsiniz.
clean:
rm -rf $(junk) $(wildcard *.elf) $(wildcard *.hex)
spike .elf dosyası alıyor ve kendi işlemcimize de .hex verebilmek için şu scripti kullandık. Bu oluşan object dosyalarını istenen formatlara dönüştürüyor.
#!/bin/bash
# Kullanım: ./convert_dump.sh /path/to/directory
# Varsayılan olarak geçerli dizini kullan
TARGET_DIR=${1:-$(pwd)}
# Eğer dizin yoksa hata ver
if [ ! -d "$TARGET_DIR" ]; then
echo "Hata: '$TARGET_DIR' geçerli bir dizin değil!"
exit 1
fi
# RISC-V Toolchain için gerekli komutlar
OBJCOPY=riscv32-unknown-elf-objcopy
# Dosyaları işle
for dump_file in "$TARGET_DIR"/*.dump; do
# Eğer hiç dump dosyası yoksa atla
[ -e "$dump_file" ] || continue
# Dosya adı uzantısız
base_name="${dump_file%.dump}"
# ELF formatına dönüştür
elf_file="${base_name}.elf"
$OBJCOPY -I binary -O elf32-littleriscv "$dump_file" "$elf_file"
echo "✔ ELF oluşturuldu: $elf_file"
# HEX formatına dönüştür
hex_file="${base_name}.hex"
$OBJCOPY -I binary -O ihex "$dump_file" "$hex_file"
# HEX dosyasının başındaki ':' işaretlerini kaldır
sed -i 's/^://g' "$hex_file"
echo "✔ HEX oluşturuldu (başındaki ':' kaldırıldı): $hex_file"
done
echo "✅ Tüm .dump dosyaları ELF ve HEX'e dönüştürüldü!"
Ek olarak Benchmark için aşağıdaki ayarlamalar yapıldı ve bazı testler kapatıldı.
Bu Makefile, RISC-V benchmark’larını (bmarks
) derlemek ve çalıştırmak için kullanılıyor. Eğer bu Makefile’ı özelleştirmek veya düzenlemek istiyorsanız, aşağıdaki adımları takip edebilirsiniz. Özellikle, 32-bit (rv32imc
) mimarisi için düzenleme yapmak istiyorsanız, XLEN
değişkenini 32
olarak ayarlamanız ve diğer ilgili flag’leri güncellemeniz gerekecek.
1. XLEN
Değişkenini 32-bit Olarak Ayarlama
#
Makefile’ın başında XLEN
değişkeni 64
olarak ayarlanmış. Eğer 32-bit mimarisi için derleme yapmak istiyorsanız, bu değişkeni 32
olarak güncelleyin:
XLEN ?= 32
2. ABI
(Application Binary Interface) Ayarları
#
XLEN
değişkenine bağlı olarak ABI
(Application Binary Interface) otomatik olarak ayarlanıyor. 32-bit için ilp32
, 64-bit için lp64d
kullanılıyor. Bu kısım zaten doğru şekilde ayarlanmış, ancak kontrol edebilirsiniz:
ifeq ($(XLEN),32)
ABI ?= ilp32
endif
ifeq ($(XLEN),64)
ABI ?= lp64d
endif
3. Derleyici Flag’lerini Güncelleme #
RISCV_GCC_OPTS
değişkeni, derleyici flag’lerini içerir. 32-bit mimarisi için -march=rv32imc_zicsr
ve -mabi=ilp32
kullanılmalıdır. Bu kısım zaten ayarlanmış, ancak kontrol edebilirsiniz:
RISCV_GCC_OPTS ?= -DPREALLOCATE=1 -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf -fno-tree-loop-distribute-patterns -Wno-implicit-int -Wno-implicit-function-declaration -march=rv$(XLEN)imc_zicsr -mabi=$(ABI)
-march=rv32imc_zicsr
: 32-bit RISC-V mimarisi için temel komut setlerini belirtir (I
,M
,C
,Zicsr
).-mabi=ilp32
: 32-bit ABI’yi belirtir.
4. Simülatör Flag’lerini Güncelleme #
RISCV_SIM
değişkeni, Spike simülatörünü çalıştırmak için kullanılan flag’leri içerir. 32-bit mimarisi için --isa=rv32gcv
kullanılmalıdır:
RISCV_SIM ?= spike --isa=rv$(XLEN)gcv
rv32gcv
: 32-bit RISC-V mimarisi için temel komut setlerini belirtir (G
=IMAFD
,C
= Compressed,V
= Vector).
5. Benchmark Listesini Özelleştirme #
bmarks
değişkeni, derlenecek benchmark’ları içerir. İhtiyacınıza göre bu listeyi özelleştirebilirsiniz:
bmarks = \
median \
qsort \
rsort \
towers \
vvadd \
memcpy \
multiply \
mm \
dhrystone \
spmv \
mt-vvadd \
mt-matmul \
mt-memcpy \
pmp \
vec-memcpy \
vec-daxpy \
vec-sgemm \
vec-strcmp \
Eğer belirli benchmark’ları derlemek istemiyorsanız, bu listeden çıkarabilirsiniz.
6. Derleme ve Çalıştırma Hedefleri #
Makefile’da riscv
ve run
hedefleri, benchmark’ları derlemek ve çalıştırmak için kullanılır. Bu hedefler zaten doğru şekilde ayarlanmış:
riscv: $(bmarks_riscv_dump)
run: $(bmarks_riscv_out)
riscv
: Benchmark’ları derler ve disassembly (dump
) dosyalarını oluşturur.run
: Benchmark’ları Spike simülatöründe çalıştırır ve çıktıları kaydeder.
7. Temizleme Hedefi #
clean
hedefi, derlenmiş dosyaları temizler. Bu hedef zaten doğru şekilde ayarlanmış:
clean:
rm -rf $(objs) $(junk)
8. Kurulum Hedefleri #
install
ve install-link
hedefleri, derlenmiş benchmark’ları belirli bir dizine kopyalar. Bu hedefler de doğru şekilde ayarlanmış:
install:
mkdir $(install_dir)
cp -r $(bmarks_riscv_bin) $(bmarks_riscv_dump) $(install_dir)
install-link:
rm -rf $(instbasedir)/$(instname)
ln -s $(latest_install) $(instbasedir)/$(instname)
Düzenlenmiş Makefile (32-bit için) #
Aşağıda, 32-bit mimarisi için düzenlenmiş Makefile bulunmaktadır:
#=======================================================================
# UCB VLSI FLOW: Makefile for riscv-bmarks
#-----------------------------------------------------------------------
# Yunsup Lee (yunsup@cs.berkeley.edu)
#
XLEN ?= 32
ifeq ($(XLEN),32)
ABI ?= ilp32
endif
ifeq ($(XLEN),64)
ABI ?= lp64d
endif
default: all
src_dir = .
instname = riscv-bmarks
instbasedir = $(UCB_VLSI_HOME)/install
#--------------------------------------------------------------------
# Sources
#--------------------------------------------------------------------
bmarks = \
median \
qsort \
rsort \
towers \
vvadd \
memcpy \
multiply \
mm \
dhrystone \
spmv \
mt-vvadd \
mt-matmul \
mt-memcpy \
pmp \
vec-memcpy \
vec-daxpy \
vec-sgemm \
vec-strcmp \
#--------------------------------------------------------------------
# Build rules
#--------------------------------------------------------------------
RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf-
RISCV_GCC ?= $(RISCV_PREFIX)gcc
RISCV_GCC_OPTS ?= -DPREALLOCATE=1 -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf -fno-tree-loop-distribute-patterns -Wno-implicit-int -Wno-implicit-function-declaration -march=rv$(XLEN)imc_zicsr -mabi=$(ABI)
RISCV_LINK ?= $(RISCV_GCC) -T $(src_dir)/common/test.ld $(incs)
RISCV_LINK_OPTS ?= -static -nostdlib -nostartfiles -lm -lgcc -T $(src_dir)/common/test.ld
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data
RISCV_SIM ?= spike --isa=rv$(XLEN)gcv
incs += -I$(src_dir)/../env -I$(src_dir)/common $(addprefix -I$(src_dir)/, $(bmarks))
objs :=
define compile_template
$(1).riscv: $(wildcard $(src_dir)/$(1)/*) $(wildcard $(src_dir)/common/*)
$$(RISCV_GCC) $$(incs) $$(RISCV_GCC_OPTS) -o $$@ $(wildcard $(src_dir)/$(1)/*.c) $(wildcard $(src_dir)/$(1)/*.S) $(wildcard $(src_dir)/common/*.c) $(wildcard $(src_dir)/common/*.S) $$(RISCV_LINK_OPTS)
endef
$(foreach bmark,$(bmarks),$(eval $(call compile_template,$(bmark))))
#------------------------------------------------------------
# Build and run benchmarks on riscv simulator
bmarks_riscv_bin = $(addsuffix .riscv, $(bmarks))
bmarks_riscv_dump = $(addsuffix .riscv.dump, $(bmarks))
bmarks_riscv_out = $(addsuffix .riscv.out, $(bmarks))
$(bmarks_riscv_dump): %.riscv.dump: %.riscv
$(RISCV_OBJDUMP) $< > $@
$(bmarks_riscv_out): %.riscv.out: %.riscv
$(RISCV_SIM) $< > $@
riscv: $(bmarks_riscv_dump)
run: $(bmarks_riscv_out)
junk += $(bmarks_riscv_bin) $(bmarks_riscv_dump) $(bmarks_riscv_hex) $(bmarks_riscv_out)
#------------------------------------------------------------
# Default
all: riscv
#------------------------------------------------------------
# Install
date_suffix = $(shell date +%Y-%m-%d_%H-%M)
install_dir = $(instbasedir)/$(instname)-$(date_suffix)
latest_install = $(shell ls -1 -d $(instbasedir)/$(instname)* | tail -n 1)
install:
mkdir $(install_dir)
cp -r $(bmarks_riscv_bin) $(bmarks_riscv_dump) $(install_dir)
install-link:
rm -rf $(instbasedir)/$(instname)
ln -s $(latest_install) $(instbasedir)/$(instname)
#------------------------------------------------------------
# Clean up
clean:
rm -rf $(objs) $(junk)
Nasıl Kullanılır? #
- Derleme:
make riscv
- Çalıştırma:
make run
- Temizleme:
make clean
Bu düzenlemelerle, 32-bit RISC-V mimarisi için benchmark’ları derleyebilir ve çalıştırabilirsiniz. 😊
- Testleri Spike ile Çalıştırın:
spike $HOME/riscv/pk/install/riscv32-unknown-elf/bin/pk <test_program> spike --isa=RV32IMC /home/kerim/riscv/pk/install/riscv32-unknown-elf/bin/pk isa/rv32ui-p-add.elf > spike_output.txt
Adım 6: Kendi İşlemcinizi Doğrulama #
-
İşlemcinizi Simüle Edin:
- İşlemcinizi Verilator veya benzeri bir araçla simüle edin.
- Simülatörünüzün çıktılarını Spike ile karşılaştırın.
-
Test Programlarını İşlemcinizde Çalıştırın:
- Derlenen test programlarını işlemcinizde çalıştırın ve sonuçları doğrulayın.
Adım 7: Ek Araçlar (Opsiyonel) #
- QEMU: RISC-V emülasyonu için kullanılır.
sudo apt install qemu-system-riscv32
- Verilator: İşlemcinizi simüle etmek için kullanılır.
sudo apt install verilator
Bu adımları takip ederek, ~/riscv
klasörü altında RISC-V 32-bit IMC
işlemciniz için tam bir doğrulama ortamı kurabilirsiniz. Herhangi bir sorunuz veya ek bilgiye ihtiyacınız varsa, bana her zaman ulaşabilirsiniz! 🚀
Bu hata, Spike simülatörünün 64-bit (RV64
) modunda çalıştığını, ancak sizin 32-bit (RV32
) bir programı çalıştırmaya çalıştığınızı gösteriyor. Spike, varsayılan olarak 64-bit modunda çalışır ve 32-bit programları çalıştırmak için özel olarak yapılandırılması gerekir.
Bu sorunu çözmek için aşağıdaki adımları izleyebilirsiniz:
Çözüm 1: Spike’ı 32-bit Modunda Çalıştırma #
Spike’ı 32-bit modunda çalıştırmak için --isa
parametresini kullanabilirsiniz. Bu parametre, Spike’a 32-bit mimarisini (RV32
) kullanmasını söyler.
Adımlar: #
-
Spike’ı 32-bit Modunda Çalıştırın:
spike --isa=RV32IMC $HOME/riscv/pk/install/riscv32-unknown-elf/bin/pk test
Bu komut, Spike’ı
RV32IMC
mimarisiyle çalıştıracak ve 32-bit programınızı başarıyla çalıştıracaktır.
Çözüm 2: pk (Proxy Kernel) ve Toolchain Uyumluluğunu Kontrol Etme #
Eğer yukarıdaki çözüm işe yaramazsa, pk
ve toolchain’inizin 32-bit modunda doğru şekilde yapılandırıldığından emin olun.
Adımlar: #
-
Toolchain’in 32-bit Modunda Olduğunu Kontrol Edin:
- Toolchain’i kurarken
--with-arch=rv32imc
ve--with-abi=ilp32
seçeneklerini kullandığınızdan emin olun. - Toolchain’inizi test edin:
riscv32-unknown-elf-gcc --version
- Toolchain’i kurarken
-
pk’nın 32-bit Modunda Olduğunu Kontrol Edin:
pk
‘yı kurarken--host=riscv32-unknown-elf
seçeneğini kullandığınızdan emin olun.pk
‘yı test edin:ls $HOME/riscv/pk/install/riscv32-unknown-elf/bin/pk
Çözüm 3: Spike’ı Yeniden Yapılandırma ve Derleme #
Eğer Spike hala 64-bit modunda çalışıyorsa, Spike’ı 32-bit modunda yeniden yapılandırıp derleyebilirsiniz.
Adımlar: #
-
Spike Kaynak Koduna Gidin:
cd ~/riscv/spike/riscv-isa-sim
-
Build Klasörünü Temizleyin:
rm -rf build mkdir build cd build
-
Spike’ı 32-bit Modunda Yapılandırın:
../configure --prefix=$HOME/riscv/spike/install --with-isa=RV32IMC
-
Spike’ı Derleyin ve Kurun:
make make install
-
Spike’ı Test Edin:
spike --version spike --isa=RV32IMC $HOME/riscv/pk/install/riscv32-unknown-elf/bin/pk test
Çözüm 4: QEMU ile 32-bit Programları Çalıştırma (Opsiyonel) #
Eğer Spike ile sorun yaşamaya devam ederseniz, QEMU‘yu kullanarak 32-bit RISC-V programlarınızı çalıştırabilirsiniz.
Adımlar: #
-
QEMU’yu Kurun:
sudo apt install qemu-system-riscv32
-
Programınızı QEMU ile Çalıştırın:
qemu-riscv32 $HOME/riscv/pk/install/riscv32-unknown-elf/bin/pk test
Özet #
- Spike’ı 32-bit modunda çalıştırmak için:
spike --isa=RV32IMC $HOME/riscv/pk/install/riscv32-unknown-elf/bin/pk test
- Eğer sorun devam ederse, Spike’ı 32-bit modunda yeniden yapılandırıp derleyin.
- Alternatif olarak, QEMU’yu kullanabilirsiniz.