simulation framework refactoring
This commit is contained in:
5
Makefile
5
Makefile
@@ -1,14 +1,13 @@
|
|||||||
|
|
||||||
all:
|
all:
|
||||||
$(MAKE) -C hw
|
$(MAKE) -C hw
|
||||||
|
$(MAKE) -C sim
|
||||||
$(MAKE) -C driver
|
$(MAKE) -C driver
|
||||||
$(MAKE) -C runtime
|
$(MAKE) -C runtime
|
||||||
$(MAKE) -C simX
|
|
||||||
$(MAKE) -C tests
|
$(MAKE) -C tests
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C hw clean
|
$(MAKE) -C hw clean
|
||||||
|
$(MAKE) -C sim clean
|
||||||
$(MAKE) -C driver clean
|
$(MAKE) -C driver clean
|
||||||
$(MAKE) -C simX clean
|
|
||||||
$(MAKE) -C runtime clean
|
$(MAKE) -C runtime clean
|
||||||
$(MAKE) -C tests clean
|
$(MAKE) -C tests clean
|
||||||
@@ -24,11 +24,11 @@ Vortex is a full-system RISCV-based GPGPU processor.
|
|||||||
|
|
||||||
- `hw`: Hardware sources.
|
- `hw`: Hardware sources.
|
||||||
|
|
||||||
- `driver`: Host driver software.
|
- `driver`: Host drivers repository.
|
||||||
|
|
||||||
- `runtime`: Kernel Runtime software.
|
- `runtime`: Kernel Runtime software.
|
||||||
|
|
||||||
- `simX`: Cycle-approximate simulator.
|
- `sim`: Simulators repository.
|
||||||
|
|
||||||
- `tests`: Tests repository.
|
- `tests`: Tests repository.
|
||||||
|
|
||||||
|
|||||||
@@ -88,28 +88,18 @@ done
|
|||||||
case $DRIVER in
|
case $DRIVER in
|
||||||
rtlsim)
|
rtlsim)
|
||||||
DRIVER_PATH=$VORTEX_HOME/driver/rtlsim
|
DRIVER_PATH=$VORTEX_HOME/driver/rtlsim
|
||||||
DRIVER_EXTRA=
|
|
||||||
CLEAN_TOKEN=clean
|
|
||||||
;;
|
;;
|
||||||
vlsim)
|
vlsim)
|
||||||
DRIVER_PATH=$VORTEX_HOME/driver/opae
|
DRIVER_PATH=$VORTEX_HOME/driver/vlsim
|
||||||
DRIVER_EXTRA=vlsim
|
|
||||||
CLEAN_TOKEN=clean-vlsim
|
|
||||||
;;
|
;;
|
||||||
asesim)
|
asesim)
|
||||||
DRIVER_PATH=$VORTEX_HOME/driver/opae
|
DRIVER_PATH=$VORTEX_HOME/driver/asesim
|
||||||
DRIVER_EXTRA=asesim
|
|
||||||
CLEAN_TOKEN=clean-asesim
|
|
||||||
;;
|
;;
|
||||||
fpga)
|
fpga)
|
||||||
DRIVER_PATH=$VORTEX_HOME/driver/opae
|
DRIVER_PATH=$VORTEX_HOME/driver/fpga
|
||||||
DRIVER_EXTRA=fpga
|
|
||||||
CLEAN_TOKEN=clean-fpga
|
|
||||||
;;
|
;;
|
||||||
simx)
|
simx)
|
||||||
DRIVER_PATH=$VORTEX_HOME/driver/simx
|
DRIVER_PATH=$VORTEX_HOME/driver/simx
|
||||||
DRIVER_EXTRA=
|
|
||||||
CLEAN_TOKEN=clean
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "invalid driver: $DRIVER"
|
echo "invalid driver: $DRIVER"
|
||||||
@@ -132,7 +122,7 @@ CONFIGS="-DNUM_CLUSTERS=$CLUSTERS -DNUM_CORES=$CORES -DNUM_WARPS=$WARPS -DNUM_TH
|
|||||||
|
|
||||||
echo "CONFIGS=$CONFIGS"
|
echo "CONFIGS=$CONFIGS"
|
||||||
|
|
||||||
make -C $DRIVER_PATH $CLEAN_TOKEN
|
make -C $DRIVER_PATH clean
|
||||||
|
|
||||||
status=0
|
status=0
|
||||||
|
|
||||||
@@ -140,9 +130,9 @@ if [ $DEBUG -eq 1 ]
|
|||||||
then
|
then
|
||||||
if [ $SCOPE -eq 1 ]
|
if [ $SCOPE -eq 1 ]
|
||||||
then
|
then
|
||||||
DEBUG=1 SCOPE=1 CONFIGS="$CONFIGS" make -s -C $DRIVER_PATH $DRIVER_EXTRA
|
DEBUG=1 SCOPE=1 CONFIGS="$CONFIGS" make -s -C $DRIVER_PATH
|
||||||
else
|
else
|
||||||
DEBUG=1 CONFIGS="$CONFIGS" make -s -C $DRIVER_PATH $DRIVER_EXTRA
|
DEBUG=1 CONFIGS="$CONFIGS" make -s -C $DRIVER_PATH
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $HAS_ARGS -eq 1 ]
|
if [ $HAS_ARGS -eq 1 ]
|
||||||
@@ -161,9 +151,9 @@ then
|
|||||||
else
|
else
|
||||||
if [ $SCOPE -eq 1 ]
|
if [ $SCOPE -eq 1 ]
|
||||||
then
|
then
|
||||||
SCOPE=1 CONFIGS="$CONFIGS" make -s -C $DRIVER_PATH $DRIVER_EXTRA
|
SCOPE=1 CONFIGS="$CONFIGS" make -s -C $DRIVER_PATH
|
||||||
else
|
else
|
||||||
CONFIGS="$CONFIGS" make -s -C $DRIVER_PATH $DRIVER_EXTRA
|
CONFIGS="$CONFIGS" make -s -C $DRIVER_PATH
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $HAS_ARGS -eq 1 ]
|
if [ $HAS_ARGS -eq 1 ]
|
||||||
|
|||||||
@@ -7,24 +7,29 @@ The directory/file layout of the Vortex codebase is as followed:
|
|||||||
- `cache`: cache subsystem code
|
- `cache`: cache subsystem code
|
||||||
- `fp_cores`: floating point unit code
|
- `fp_cores`: floating point unit code
|
||||||
- `interfaces`: interfaces for inter-module communication
|
- `interfaces`: interfaces for inter-module communication
|
||||||
- `libs`: general-purpose modules (i.e., encoder, arbiter, ...)
|
- `libs`: general-purpose RTL modules
|
||||||
- `syn`: synthesis directory
|
- `syn`: synthesis directory
|
||||||
- `opae`: OPAE synthesis scripts
|
- `opae`: OPAE synthesis scripts
|
||||||
- `quartus`: Quartus synthesis scripts
|
- `quartus`: Quartus synthesis scripts
|
||||||
- `synopsys`: Synopsys synthesis scripts
|
- `synopsys`: Synopsys synthesis scripts
|
||||||
|
- `modelsim`: Modelsim synthesis scripts
|
||||||
- `yosys`: Yosys synthesis scripts
|
- `yosys`: Yosys synthesis scripts
|
||||||
- `simulate`: baseline RTL simulator (used by RTLSIM)
|
|
||||||
- `unit_tests`: unit tests for some hardware components
|
- `unit_tests`: unit tests for some hardware components
|
||||||
- `driver`: Host driver software
|
- `driver`: host drivers repository
|
||||||
- `include`: Vortex driver public headers
|
- `include`: Vortex driver public headers
|
||||||
- `opae`: software driver that uses Intel OPAE
|
- `stub`: Vortex stub driver library
|
||||||
- `vlsim`: software driver that simulates Full RTL (include AFU)
|
- `fpga`: software driver that uses Intel OPAE FPGA
|
||||||
- `rtlsim`: software driver that simulates processor RTL
|
- `asesim`: software driver that uses Intel ASE simulator
|
||||||
|
- `vlsim`: software driver that uses vlsim simulator
|
||||||
|
- `rtlsim`: software driver that uses rtlsim simulator
|
||||||
- `simx`: software driver that uses simX simulator
|
- `simx`: software driver that uses simX simulator
|
||||||
- `runtime`: Kernel runtime software
|
- `runtime`: kernel runtime software
|
||||||
- `include`: Vortex runtime public headers
|
- `include`: Vortex runtime public headers
|
||||||
- `linker`: linker file for compiling kernels
|
- `linker`: linker file for compiling kernels
|
||||||
- `src`: runtime implementation
|
- `src`: runtime implementation
|
||||||
|
- `sim`:
|
||||||
|
- `vlsim`: AFU RTL simulator
|
||||||
|
- `rtlsim`: processor RTL simulator
|
||||||
- `simX`: cycle approximate simulator for vortex
|
- `simX`: cycle approximate simulator for vortex
|
||||||
- `tests`: tests repository.
|
- `tests`: tests repository.
|
||||||
- `runtime`: runtime tests
|
- `runtime`: runtime tests
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
all: stub rtlsim simx opae
|
all: stub rtlsim simx vlsim
|
||||||
|
|
||||||
stub:
|
stub:
|
||||||
$(MAKE) -C stub
|
$(MAKE) -C stub
|
||||||
|
|
||||||
opae:
|
fpga:
|
||||||
$(MAKE) -C opae
|
$(MAKE) -C fpga
|
||||||
|
|
||||||
|
asesim:
|
||||||
|
$(MAKE) -C asesim
|
||||||
|
|
||||||
|
vlsim:
|
||||||
|
$(MAKE) -C vlsim
|
||||||
|
|
||||||
rtlsim:
|
rtlsim:
|
||||||
$(MAKE) -C rtlsim
|
$(MAKE) -C rtlsim
|
||||||
@@ -14,8 +20,10 @@ simx:
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) clean -C stub
|
$(MAKE) clean -C stub
|
||||||
$(MAKE) clean -C opae
|
$(MAKE) clean -C fpga
|
||||||
|
$(MAKE) clean -C asesim
|
||||||
|
$(MAKE) clean -C vlsim
|
||||||
$(MAKE) clean -C rtlsim
|
$(MAKE) clean -C rtlsim
|
||||||
$(MAKE) clean -C simx
|
$(MAKE) clean -C simx
|
||||||
|
|
||||||
.PHONY: all stub opae rtlsim simx clean
|
.PHONY: all stub fpga asesim vlsim rtlsim simx clean
|
||||||
75
driver/asesim/Makefile
Normal file
75
driver/asesim/Makefile
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
OPAE_HOME ?= /tools/opae/1.4.0
|
||||||
|
|
||||||
|
CXXFLAGS += -std=c++11 -O2 -DNDEBUG -Wall -Wextra -pedantic -Wfatal-errors
|
||||||
|
#CXXFLAGS += -std=c++11 -O0 -g -Wall -Wextra -pedantic -Wfatal-errors
|
||||||
|
|
||||||
|
CXXFLAGS += -I../include -I../../hw -I$(OPAE_HOME)/include
|
||||||
|
|
||||||
|
LDFLAGS += -L$(OPAE_HOME)/lib -luuid -lopae-c-ase
|
||||||
|
|
||||||
|
# stack execution protection
|
||||||
|
LDFLAGS +=-z noexecstack
|
||||||
|
|
||||||
|
# data relocation and projection
|
||||||
|
LDFLAGS +=-z relro -z now
|
||||||
|
|
||||||
|
# stack buffer overrun detection
|
||||||
|
CXXFLAGS +=-fstack-protector
|
||||||
|
|
||||||
|
# Position independent code
|
||||||
|
CXXFLAGS += -fPIC
|
||||||
|
|
||||||
|
# Add external configuration
|
||||||
|
CXXFLAGS += $(CONFIGS)
|
||||||
|
|
||||||
|
# Dump perf stats
|
||||||
|
CXXFLAGS += -DDUMP_PERF_STATS
|
||||||
|
|
||||||
|
LDFLAGS += -shared
|
||||||
|
|
||||||
|
RTL_DIR=../../hw/rtl
|
||||||
|
|
||||||
|
SCRIPT_DIR=../../hw/scripts
|
||||||
|
|
||||||
|
PROJECT = libvortex.so
|
||||||
|
|
||||||
|
AFU_JSON_INFO = vortex_afu.h
|
||||||
|
|
||||||
|
SRCS = ../common/opae.cpp ../common/vx_utils.cpp
|
||||||
|
|
||||||
|
# Enable scope analyzer
|
||||||
|
ifdef SCOPE
|
||||||
|
CXXFLAGS += -DSCOPE
|
||||||
|
SRCS += ../common/vx_scope.cpp
|
||||||
|
SCOPE_H = scope-defs.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Enable perf counters
|
||||||
|
ifdef PERF
|
||||||
|
CXXFLAGS += -DPERF_ENABLE
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: $(PROJECT)
|
||||||
|
|
||||||
|
# AFU info from JSON file, including AFU UUID
|
||||||
|
json: ../../hw/opae/vortex_afu.json
|
||||||
|
afu_json_mgr json-info --afu-json=$^ --c-hdr=$@
|
||||||
|
|
||||||
|
scope-defs.h: $(SCRIPT_DIR)/scope.json
|
||||||
|
$(SCRIPT_DIR)/scope.py $(CONFIGS) -cc scope-defs.h -vl $(RTL_DIR)/scope-defs.vh $(SCRIPT_DIR)/scope.json
|
||||||
|
|
||||||
|
# generate scope data
|
||||||
|
scope: scope-defs.h
|
||||||
|
|
||||||
|
$(PROJECT): $(SRCS) $(SCOPE_H)
|
||||||
|
$(CXX) $(CXXFLAGS) -DUSE_ASE $(SRCS) $(LDFLAGS) -o $(PROJECT)
|
||||||
|
|
||||||
|
.depend: $(SRCS)
|
||||||
|
$(CXX) $(CXXFLAGS) -MM $(SRCS) > .depend;
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROJECT) *.o .depend
|
||||||
|
|
||||||
|
ifneq ($(MAKECMDGOALS),clean)
|
||||||
|
-include .depend
|
||||||
|
endif
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
#include <opae/fpga.h>
|
#include <opae/fpga.h>
|
||||||
#include <uuid/uuid.h>
|
#include <uuid/uuid.h>
|
||||||
#elif defined(USE_VLSIM)
|
#elif defined(USE_VLSIM)
|
||||||
#include "vlsim/fpga.h"
|
#include <fpga.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <vortex.h>
|
#include <vortex.h>
|
||||||
@@ -5,7 +5,7 @@ CXXFLAGS += -std=c++11 -O2 -DNDEBUG -Wall -Wextra -pedantic -Wfatal-errors
|
|||||||
|
|
||||||
CXXFLAGS += -I../include -I$(OPAE_HOME)/include -I../../hw
|
CXXFLAGS += -I../include -I$(OPAE_HOME)/include -I../../hw
|
||||||
|
|
||||||
LDFLAGS += -L$(OPAE_HOME)/lib
|
LDFLAGS += -L$(OPAE_HOME)/lib -luuid -lopae-c
|
||||||
|
|
||||||
#SCOPE=1
|
#SCOPE=1
|
||||||
|
|
||||||
@@ -29,45 +29,29 @@ CXXFLAGS += -DDUMP_PERF_STATS
|
|||||||
|
|
||||||
LDFLAGS += -shared
|
LDFLAGS += -shared
|
||||||
|
|
||||||
FPGA_LIBS += -luuid -lopae-c
|
|
||||||
|
|
||||||
ASE_LIBS += -luuid -lopae-c-ase
|
|
||||||
|
|
||||||
VLSIM_LIBS += -lopae-c-vlsim
|
|
||||||
|
|
||||||
ASE_DIR = ase
|
|
||||||
|
|
||||||
VLSIM_DIR = vlsim
|
|
||||||
|
|
||||||
RTL_DIR=../../hw/rtl
|
RTL_DIR=../../hw/rtl
|
||||||
|
|
||||||
SCRIPT_DIR=../../hw/scripts
|
SCRIPT_DIR=../../hw/scripts
|
||||||
|
|
||||||
PROJECT = libvortex.so
|
PROJECT = libvortex.so
|
||||||
|
|
||||||
PROJECT_ASE = $(ASE_DIR)/libvortex.so
|
|
||||||
|
|
||||||
PROJECT_VLSIM = $(VLSIM_DIR)/libvortex.so
|
|
||||||
|
|
||||||
AFU_JSON_INFO = vortex_afu.h
|
AFU_JSON_INFO = vortex_afu.h
|
||||||
|
|
||||||
SRCS = vortex.cpp ../common/vx_utils.cpp
|
SRCS = ../common/opae.cpp ../common/vx_utils.cpp
|
||||||
|
|
||||||
# Enable scope analyzer
|
# Enable scope analyzer
|
||||||
ifdef SCOPE
|
ifdef SCOPE
|
||||||
CXXFLAGS += -DSCOPE
|
CXXFLAGS += -DSCOPE
|
||||||
SRCS += vx_scope.cpp
|
SRCS += ../common/vx_scope.cpp
|
||||||
SCOPE_ENABLE = SCOPE=1
|
|
||||||
SCOPE_H = scope-defs.h
|
SCOPE_H = scope-defs.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Enable perf counters
|
# Enable perf counters
|
||||||
ifdef PERF
|
ifdef PERF
|
||||||
CXXFLAGS += -DPERF_ENABLE
|
CXXFLAGS += -DPERF_ENABLE
|
||||||
PERF_ENABLE = PERF=1
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: vlsim
|
all: $(PROJECT)
|
||||||
|
|
||||||
# AFU info from JSON file, including AFU UUID
|
# AFU info from JSON file, including AFU UUID
|
||||||
json: ../../hw/opae/vortex_afu.json
|
json: ../../hw/opae/vortex_afu.json
|
||||||
@@ -79,38 +63,15 @@ scope-defs.h: $(SCRIPT_DIR)/scope.json
|
|||||||
# generate scope data
|
# generate scope data
|
||||||
scope: scope-defs.h
|
scope: scope-defs.h
|
||||||
|
|
||||||
vlsim-hw: $(SCOPE_H)
|
$(PROJECT): $(SRCS) $(SCOPE_H)
|
||||||
$(SCOPE_ENABLE) $(PERF_ENABLE) $(MAKE) -C vlsim
|
$(CXX) $(CXXFLAGS) -DUSE_FPGA $^ $(LDFLAGS) -o $(PROJECT)
|
||||||
|
|
||||||
fpga: $(SRCS) $(SCOPE_H)
|
|
||||||
$(CXX) $(CXXFLAGS) -DUSE_FPGA $^ $(LDFLAGS) $(FPGA_LIBS) -o $(PROJECT)
|
|
||||||
|
|
||||||
asesim: $(SRCS) $(ASE_DIR) $(SCOPE_H)
|
|
||||||
$(CXX) $(CXXFLAGS) -DUSE_ASE $(SRCS) $(LDFLAGS) $(ASE_LIBS) -o $(PROJECT_ASE)
|
|
||||||
|
|
||||||
vlsim: $(SRCS) vlsim-hw
|
|
||||||
$(CXX) $(CXXFLAGS) -DUSE_VLSIM $(SRCS) $(LDFLAGS) -L./vlsim $(VLSIM_LIBS) -o $(PROJECT_VLSIM)
|
|
||||||
|
|
||||||
vortex.o: vortex.cpp
|
|
||||||
$(CXX) $(CXXFLAGS) -c vortex.cpp -o $@
|
|
||||||
|
|
||||||
$(ASE_DIR):
|
|
||||||
mkdir -p ase
|
|
||||||
|
|
||||||
.depend: $(SRCS)
|
.depend: $(SRCS)
|
||||||
$(CXX) $(CXXFLAGS) -MM $(SRCS) > .depend;
|
$(CXX) $(CXXFLAGS) -MM $(SRCS) > .depend;
|
||||||
|
|
||||||
clean-fpga:
|
clean:
|
||||||
rm -rf $(PROJECT) *.o .depend
|
rm -rf $(PROJECT) *.o .depend
|
||||||
|
|
||||||
clean-asesim:
|
|
||||||
rm -rf $(PROJECT_ASE) *.o .depend
|
|
||||||
|
|
||||||
clean-vlsim:
|
|
||||||
$(MAKE) -C vlsim clean
|
|
||||||
|
|
||||||
clean: clean-fpga clean-asesim clean-vlsim
|
|
||||||
|
|
||||||
ifneq ($(MAKECMDGOALS),clean)
|
ifneq ($(MAKECMDGOALS),clean)
|
||||||
-include .depend
|
-include .depend
|
||||||
endif
|
endif
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
class RAM {
|
|
||||||
private:
|
|
||||||
|
|
||||||
mutable uint8_t *mem_[(1 << 12)];
|
|
||||||
|
|
||||||
uint8_t *get(uint32_t address) const {
|
|
||||||
uint32_t block_addr = address >> 20;
|
|
||||||
uint32_t block_offset = address & 0x000FFFFF;
|
|
||||||
if (mem_[block_addr] == NULL) {
|
|
||||||
mem_[block_addr] = new uint8_t[(1 << 20)];
|
|
||||||
}
|
|
||||||
return mem_[block_addr] + block_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
RAM() {
|
|
||||||
for (uint32_t i = 0; i < (1 << 12); i++) {
|
|
||||||
mem_[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~RAM() {
|
|
||||||
this->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const {
|
|
||||||
return (1ull << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
for (uint32_t i = 0; i < (1 << 12); i++) {
|
|
||||||
if (mem_[i]) {
|
|
||||||
delete [] mem_[i];
|
|
||||||
mem_[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void read(uint32_t address, uint32_t length, uint8_t *data) const {
|
|
||||||
for (unsigned i = 0; i < length; i++) {
|
|
||||||
data[i] = *this->get(address + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(uint32_t address, uint32_t length, const uint8_t *data) {
|
|
||||||
for (unsigned i = 0; i < length; i++) {
|
|
||||||
*this->get(address + i) = data[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t& operator[](uint32_t address) {
|
|
||||||
return *get(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t& operator[](uint32_t address) const {
|
|
||||||
return *get(address);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
//
|
|
||||||
// Generated by afu_json_mgr from ../../hw/opae/vortex_afu.json
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __AFU_JSON_INFO__
|
|
||||||
#define __AFU_JSON_INFO__
|
|
||||||
|
|
||||||
#define AFU_ACCEL_NAME "vortex_afu"
|
|
||||||
#define AFU_ACCEL_UUID "35F9452B-25C2-434C-93D5-6F8C60DB361C"
|
|
||||||
#define AFU_IMAGE_CMD_MEM_READ 1
|
|
||||||
#define AFU_IMAGE_CMD_MEM_WRITE 2
|
|
||||||
#define AFU_IMAGE_CMD_RUN 3
|
|
||||||
#define AFU_IMAGE_MMIO_CMD_TYPE 10
|
|
||||||
#define AFU_IMAGE_MMIO_DATA_SIZE 16
|
|
||||||
#define AFU_IMAGE_MMIO_IO_ADDR 12
|
|
||||||
#define AFU_IMAGE_MMIO_MEM_ADDR 14
|
|
||||||
#define AFU_IMAGE_MMIO_SCOPE_READ 20
|
|
||||||
#define AFU_IMAGE_MMIO_SCOPE_WRITE 22
|
|
||||||
#define AFU_IMAGE_MMIO_DEV_CAPS 24
|
|
||||||
#define AFU_IMAGE_MMIO_STATUS 18
|
|
||||||
#define AFU_IMAGE_POWER 0
|
|
||||||
#define AFU_TOP_IFC "ccip_std_afu_avalon_mm"
|
|
||||||
|
|
||||||
#endif // __AFU_JSON_INFO__
|
|
||||||
@@ -1,90 +1,38 @@
|
|||||||
CFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
RTLSIM_DIR = ../../sim/rtlsim
|
||||||
#CFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors
|
|
||||||
|
|
||||||
CFLAGS += -DUSE_RTLSIM -fPIC -Wno-maybe-uninitialized
|
CXXFLAGS += -std=c++11 -O2 -DNDEBUG -Wall -Wextra -pedantic -Wfatal-errors
|
||||||
CFLAGS += -I../../include -I../../../hw/simulate -I../../../hw
|
#CXXFLAGS += -std=c++11 -O0 -g -Wall -Wextra -pedantic -Wfatal-errors
|
||||||
|
|
||||||
# control RTL debug print states
|
CXXFLAGS += -I../include -I../../hw -I$(RTLSIM_DIR) -I$(RTLSIM_DIR)/../common
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_PIPELINE
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CORE_ICACHE
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CORE_DCACHE
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_BANK
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_MSHR
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_TAG
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_DATA
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_MEM
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_OPAE
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_AVS
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_SCOPE
|
|
||||||
|
|
||||||
DBG_FLAGS += $(DBG_PRINT_FLAGS)
|
LDFLAGS += $(RTLSIM_DIR)/librtlsim.a
|
||||||
DBG_FLAGS += -DDBG_CACHE_REQ_INFO
|
|
||||||
|
|
||||||
CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=1
|
# Position independent code
|
||||||
|
CXXFLAGS += -fPIC
|
||||||
|
|
||||||
CFLAGS += $(CONFIGS)
|
# Add external configuration
|
||||||
CFLAGS += -DDUMP_PERF_STATS
|
CXXFLAGS += $(CONFIGS)
|
||||||
|
|
||||||
LDFLAGS += -shared -pthread
|
# Dump perf stats
|
||||||
#LDFLAGS += -dynamiclib -pthread
|
CXXFLAGS += -DDUMP_PERF_STATS
|
||||||
|
|
||||||
ifdef AXI_BUS
|
LDFLAGS += -shared
|
||||||
TOP = Vortex_axi
|
|
||||||
CFLAGS += -DAXI_BUS
|
|
||||||
else
|
|
||||||
TOP = Vortex
|
|
||||||
endif
|
|
||||||
|
|
||||||
RTL_DIR = ../../hw/rtl
|
SRCS = vortex.cpp ../common/vx_utils.cpp
|
||||||
DPI_DIR = ../../hw/dpi
|
|
||||||
|
|
||||||
SRCS = vortex.cpp ../common/vx_utils.cpp ../../hw/simulate/simulator.cpp
|
|
||||||
SRCS += $(DPI_DIR)/util_dpi.cpp $(DPI_DIR)/float_dpi.cpp
|
|
||||||
|
|
||||||
FPU_INCLUDE = -I$(RTL_DIR)/fp_cores -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src -I$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(RTL_DIR)/fp_cores/fpnew/src
|
|
||||||
RTL_INCLUDE = -I$(RTL_DIR) -I$(DPI_DIR) -I$(RTL_DIR)/libs -I$(RTL_DIR)/interfaces -I$(RTL_DIR)/cache $(FPU_INCLUDE)
|
|
||||||
|
|
||||||
VL_FLAGS += -O2 --language 1800-2009 --assert -Wall -Wpedantic
|
|
||||||
VL_FLAGS += -Wno-DECLFILENAME -Wno-REDEFMACRO
|
|
||||||
VL_FLAGS += --x-initial unique --x-assign unique
|
|
||||||
VL_FLAGS += verilator.vlt
|
|
||||||
VL_FLAGS += $(CONFIGS)
|
|
||||||
|
|
||||||
# Enable Verilator multithreaded simulation
|
|
||||||
#THREADS ?= $(shell python3 -c 'import multiprocessing as mp; print(max(1, mp.cpu_count() // 2))')
|
|
||||||
#VL_FLAGS += --threads $(THREADS)
|
|
||||||
|
|
||||||
# Debugigng
|
|
||||||
ifdef DEBUG
|
|
||||||
VL_FLAGS += -DVCD_OUTPUT --trace --trace-structs $(DBG_FLAGS)
|
|
||||||
CFLAGS += -DVCD_OUTPUT $(DBG_FLAGS)
|
|
||||||
else
|
|
||||||
VL_FLAGS += -DNDEBUG
|
|
||||||
CFLAGS += -DNDEBUG
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Enable perf counters
|
# Enable perf counters
|
||||||
ifdef PERF
|
ifdef PERF
|
||||||
VL_FLAGS += -DPERF_ENABLE
|
CXXFLAGS += -DPERF_ENABLE
|
||||||
CFLAGS += -DPERF_ENABLE
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# ALU backend
|
|
||||||
VL_FLAGS += -DIMUL_DPI
|
|
||||||
VL_FLAGS += -DIDIV_DPI
|
|
||||||
|
|
||||||
# FPU backend
|
|
||||||
FPU_CORE ?= FPU_DPI
|
|
||||||
VL_FLAGS += -D$(FPU_CORE)
|
|
||||||
|
|
||||||
PROJECT = libvortex.so
|
PROJECT = libvortex.so
|
||||||
# PROJECT = libvortex.dylib
|
|
||||||
|
|
||||||
all: $(PROJECT)
|
all: $(PROJECT)
|
||||||
|
|
||||||
$(PROJECT): $(SRCS)
|
$(PROJECT): $(SRCS)
|
||||||
verilator --exe --cc $(TOP) --top-module $(TOP) $(RTL_INCLUDE) $(VL_FLAGS) $(SRCS) -CFLAGS '$(CFLAGS)' -LDFLAGS '$(LDFLAGS)' -o ../$(PROJECT)
|
$(MAKE) -C $(RTLSIM_DIR) static
|
||||||
make -j -C obj_dir -f V$(TOP).mk
|
$(CXX) $(CXXFLAGS) $(SRCS) $(LDFLAGS) -o $(PROJECT)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(PROJECT) obj_dir
|
$(MAKE) -C $(RTLSIM_DIR) clean-objdir
|
||||||
|
rm -rf $(PROJECT) *.o .depend
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
class RAM {
|
|
||||||
private:
|
|
||||||
|
|
||||||
mutable uint8_t *mem_[(1 << 12)];
|
|
||||||
|
|
||||||
uint8_t *get(uint32_t address) const {
|
|
||||||
uint32_t block_addr = address >> 20;
|
|
||||||
uint32_t block_offset = address & 0x000FFFFF;
|
|
||||||
if (mem_[block_addr] == NULL) {
|
|
||||||
mem_[block_addr] = new uint8_t[(1 << 20)];
|
|
||||||
}
|
|
||||||
return mem_[block_addr] + block_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
RAM() {
|
|
||||||
for (uint32_t i = 0; i < (1 << 12); i++) {
|
|
||||||
mem_[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~RAM() {
|
|
||||||
this->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const {
|
|
||||||
return (1ull << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
for (uint32_t i = 0; i < (1 << 12); i++) {
|
|
||||||
if (mem_[i]) {
|
|
||||||
delete [] mem_[i];
|
|
||||||
mem_[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void read(uint32_t address, uint32_t length, uint8_t *data) const {
|
|
||||||
for (unsigned i = 0; i < length; i++) {
|
|
||||||
data[i] = *this->get(address + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(uint32_t address, uint32_t length, const uint8_t *data) {
|
|
||||||
for (unsigned i = 0; i < length; i++) {
|
|
||||||
*this->get(address + i) = data[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t& operator[](uint32_t address) {
|
|
||||||
return *get(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t& operator[](uint32_t address) const {
|
|
||||||
return *get(address);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -8,15 +8,11 @@
|
|||||||
|
|
||||||
#include <vortex.h>
|
#include <vortex.h>
|
||||||
#include <VX_config.h>
|
#include <VX_config.h>
|
||||||
#include <ram.h>
|
#include <mem.h>
|
||||||
|
#include <util.h>
|
||||||
#include <simulator.h>
|
#include <simulator.h>
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
using namespace vortex;
|
||||||
|
|
||||||
inline size_t align_size(size_t size, size_t alignment) {
|
|
||||||
assert(0 == (alignment & (alignment - 1)));
|
|
||||||
return (size + alignment - 1) & ~(alignment - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -58,7 +54,7 @@ private:
|
|||||||
|
|
||||||
class vx_device {
|
class vx_device {
|
||||||
public:
|
public:
|
||||||
vx_device() {
|
vx_device() : ram_((1<<12), (1<<20)) {
|
||||||
mem_allocation_ = ALLOC_BASE_ADDR;
|
mem_allocation_ = ALLOC_BASE_ADDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +88,7 @@ public:
|
|||||||
}
|
}
|
||||||
printf("\n");*/
|
printf("\n");*/
|
||||||
|
|
||||||
ram_.write(dest_addr, asize, (const uint8_t*)src + src_offset);
|
ram_.write((const uint8_t*)src + src_offset, dest_addr, asize);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +97,7 @@ public:
|
|||||||
if (src_addr + asize > ram_.size())
|
if (src_addr + asize > ram_.size())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ram_.read(src_addr, asize, (uint8_t*)dest + dest_offset);
|
ram_.read((uint8_t*)dest + dest_offset, src_addr, asize);
|
||||||
|
|
||||||
/*printf("VXDRV: download %ld bytes to 0x%lx:", size, uintptr_t((uint8_t*)dest + dest_offset));
|
/*printf("VXDRV: download %ld bytes to 0x%lx:", size, uintptr_t((uint8_t*)dest + dest_offset));
|
||||||
for (int i = 0; i < (asize / CACHE_BLOCK_SIZE); ++i) {
|
for (int i = 0; i < (asize / CACHE_BLOCK_SIZE); ++i) {
|
||||||
|
|||||||
@@ -1,37 +1,29 @@
|
|||||||
PROJECT = libvortex.so
|
PROJECT = libvortex.so
|
||||||
#PROJECT = libvortex.dylib
|
|
||||||
|
|
||||||
SIMX_DIR = ../../simX
|
SIMX_DIR = ../../sim/simX
|
||||||
|
|
||||||
CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
||||||
#CXXFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors
|
#CXXFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors
|
||||||
|
|
||||||
CXXFLAGS += -DUSE_SIMX -fPIC -Wno-maybe-uninitialized
|
CXXFLAGS += -fPIC -Wno-maybe-uninitialized
|
||||||
CXXFLAGS += -I../include -I../../hw -I$(SIMX_DIR)
|
CXXFLAGS += -I../include -I../../hw -I$(SIMX_DIR) -I$(SIMX_DIR)/../common
|
||||||
|
|
||||||
CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=1
|
|
||||||
|
|
||||||
CXXFLAGS += $(CONFIGS)
|
CXXFLAGS += $(CONFIGS)
|
||||||
CXXFLAGS += -DDUMP_PERF_STATS
|
CXXFLAGS += -DDUMP_PERF_STATS
|
||||||
|
|
||||||
LDFLAGS += -shared -pthread
|
LDFLAGS += -shared -pthread
|
||||||
#LDFLAGS += -dynamiclib -pthread
|
LDFLAGS += $(SIMX_DIR)/libsimX.a
|
||||||
|
|
||||||
SRCS = vortex.cpp ../common/vx_utils.cpp
|
SRCS = vortex.cpp ../common/vx_utils.cpp
|
||||||
SRCS += $(SIMX_DIR)/util.cpp $(SIMX_DIR)/args.cpp $(SIMX_DIR)/mem.cpp $(SIMX_DIR)/pipeline.cpp $(SIMX_DIR)/warp.cpp $(SIMX_DIR)/core.cpp $(SIMX_DIR)/decode.cpp $(SIMX_DIR)/execute.cpp
|
|
||||||
|
|
||||||
# Debugigng
|
|
||||||
ifndef DEBUG
|
|
||||||
CXXFLAGS += -DNDEBUG
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROJECT)
|
all: $(PROJECT)
|
||||||
|
|
||||||
$(PROJECT): $(SRCS)
|
$(PROJECT): $(SRCS)
|
||||||
|
$(MAKE) -C $(SIMX_DIR) static
|
||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
.depend: $(SRCS)
|
.depend: $(SRCS)
|
||||||
$(CXX) $(CXXFLAGS) -MM $^ > .depend;
|
$(CXX) $(CXXFLAGS) -MM $^ > .depend;
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
$(MAKE) -C $(SIMX_DIR) clean-objdir
|
||||||
rm -rf $(PROJECT) *.o .depend
|
rm -rf $(PROJECT) *.o .depend
|
||||||
@@ -10,15 +10,11 @@
|
|||||||
#include <vortex.h>
|
#include <vortex.h>
|
||||||
#include <core.h>
|
#include <core.h>
|
||||||
#include <VX_config.h>
|
#include <VX_config.h>
|
||||||
|
#include <util.h>
|
||||||
|
|
||||||
#define PAGE_SIZE 4096
|
#define PAGE_SIZE 4096
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
using namespace vortex;
|
||||||
|
|
||||||
inline size_t align_size(size_t size, size_t alignment) {
|
|
||||||
assert(0 == (alignment & (alignment - 1)));
|
|
||||||
return (size + alignment - 1) & ~(alignment - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -74,7 +70,7 @@ public:
|
|||||||
mem_allocation_ = ALLOC_BASE_ADDR;
|
mem_allocation_ = ALLOC_BASE_ADDR;
|
||||||
mmu_.attach(ram_, 0, 0xffffffff);
|
mmu_.attach(ram_, 0, 0xffffffff);
|
||||||
for (int i = 0; i < arch_.num_cores(); ++i) {
|
for (int i = 0; i < arch_.num_cores(); ++i) {
|
||||||
cores_[i] = std::make_shared<vortex::Core>(arch_, decoder_, mmu_, i);
|
cores_[i] = std::make_shared<Core>(arch_, decoder_, mmu_, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +97,7 @@ public:
|
|||||||
if (dest_addr + asize > ram_.size())
|
if (dest_addr + asize > ram_.size())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ram_.write(dest_addr, (const uint8_t*)src + src_offset, asize);
|
ram_.write((const uint8_t*)src + src_offset, dest_addr, asize);
|
||||||
|
|
||||||
/*printf("VXDRV: upload %d bytes to 0x%x\n", size, dest_addr);
|
/*printf("VXDRV: upload %d bytes to 0x%x\n", size, dest_addr);
|
||||||
for (int i = 0; i < size; i += 4) {
|
for (int i = 0; i < size; i += 4) {
|
||||||
@@ -116,7 +112,7 @@ public:
|
|||||||
if (src_addr + asize > ram_.size())
|
if (src_addr + asize > ram_.size())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ram_.read(src_addr, (uint8_t*)dest + dest_offset, asize);
|
ram_.read((uint8_t*)dest + dest_offset, src_addr, asize);
|
||||||
|
|
||||||
/*printf("VXDRV: download %d bytes from 0x%x\n", size, src_addr);
|
/*printf("VXDRV: download %d bytes from 0x%x\n", size, src_addr);
|
||||||
for (int i = 0; i < size; i += 4) {
|
for (int i = 0; i < size; i += 4) {
|
||||||
@@ -209,15 +205,15 @@ private:
|
|||||||
device->thread_proc();
|
device->thread_proc();
|
||||||
}
|
}
|
||||||
|
|
||||||
vortex::ArchDef arch_;
|
ArchDef arch_;
|
||||||
vortex::Decoder decoder_;
|
Decoder decoder_;
|
||||||
vortex::MemoryUnit mmu_;
|
MemoryUnit mmu_;
|
||||||
std::vector<std::shared_ptr<vortex::Core>> cores_;
|
std::vector<std::shared_ptr<Core>> cores_;
|
||||||
bool is_done_;
|
bool is_done_;
|
||||||
bool is_running_;
|
bool is_running_;
|
||||||
size_t mem_allocation_;
|
size_t mem_allocation_;
|
||||||
std::thread thread_;
|
std::thread thread_;
|
||||||
vortex::RAM ram_;
|
RAM ram_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
64
driver/vlsim/Makefile
Normal file
64
driver/vlsim/Makefile
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
VLSIM_DIR = ../../sim/vlsim
|
||||||
|
|
||||||
|
CXXFLAGS += -std=c++11 -O2 -DNDEBUG -Wall -Wextra -pedantic -Wfatal-errors
|
||||||
|
#CXXFLAGS += -std=c++11 -O0 -g -Wall -Wextra -pedantic -Wfatal-errors
|
||||||
|
|
||||||
|
CXXFLAGS += -I../include -I../../hw -I$(VLSIM_DIR)
|
||||||
|
|
||||||
|
LDFLAGS += $(VLSIM_DIR)/libopae-c-vlsim.a
|
||||||
|
|
||||||
|
# Position independent code
|
||||||
|
CXXFLAGS += -fPIC
|
||||||
|
|
||||||
|
# Add external configuration
|
||||||
|
CXXFLAGS += $(CONFIGS)
|
||||||
|
|
||||||
|
# Dump perf stats
|
||||||
|
CXXFLAGS += -DDUMP_PERF_STATS
|
||||||
|
|
||||||
|
LDFLAGS += -shared
|
||||||
|
|
||||||
|
RTL_DIR=../../hw/rtl
|
||||||
|
|
||||||
|
SCRIPT_DIR=../../hw/scripts
|
||||||
|
|
||||||
|
AFU_JSON_INFO = vortex_afu.h
|
||||||
|
|
||||||
|
SRCS = ../common/opae.cpp ../common/vx_utils.cpp
|
||||||
|
|
||||||
|
# Enable scope analyzer
|
||||||
|
ifdef SCOPE
|
||||||
|
CXXFLAGS += -DSCOPE
|
||||||
|
SRCS += ../common/vx_scope.cpp
|
||||||
|
SCOPE_H = scope-defs.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Enable perf counters
|
||||||
|
ifdef PERF
|
||||||
|
CXXFLAGS += -DPERF_ENABLE
|
||||||
|
endif
|
||||||
|
|
||||||
|
PROJECT = libvortex.so
|
||||||
|
|
||||||
|
all: $(PROJECT)
|
||||||
|
|
||||||
|
scope-defs.h: $(SCRIPT_DIR)/scope.json
|
||||||
|
$(SCRIPT_DIR)/scope.py $(CONFIGS) -cc scope-defs.h -vl $(RTL_DIR)/scope-defs.vh $(SCRIPT_DIR)/scope.json
|
||||||
|
|
||||||
|
# generate scope data
|
||||||
|
scope: scope-defs.h
|
||||||
|
|
||||||
|
$(PROJECT): $(SRCS) $(SCOPE_H)
|
||||||
|
$(SCOPE_ENABLE) $(PERF_ENABLE) $(MAKE) -C $(VLSIM_DIR) static
|
||||||
|
$(CXX) $(CXXFLAGS) -DUSE_VLSIM $(SRCS) $(LDFLAGS) -o $(PROJECT)
|
||||||
|
|
||||||
|
.depend: $(SRCS)
|
||||||
|
$(CXX) $(CXXFLAGS) -MM $(SRCS) > .depend;
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C $(VLSIM_DIR) clean-objdir
|
||||||
|
rm -rf $(PROJECT) *.o .depend
|
||||||
|
|
||||||
|
ifneq ($(MAKECMDGOALS),clean)
|
||||||
|
-include .depend
|
||||||
|
endif
|
||||||
19
hw/Makefile
19
hw/Makefile
@@ -1,9 +1,16 @@
|
|||||||
.PHONY: build_config
|
RTL_DIR=./rtl
|
||||||
|
SCRIPT_DIR=./scripts
|
||||||
|
DESTDIR ?= .
|
||||||
|
|
||||||
build_config: ./rtl/VX_config.vh
|
all: VX_config.h vortex_afu.h
|
||||||
./scripts/gen_config.py -i ./rtl/VX_config.vh -o ./VX_config.h
|
|
||||||
$(MAKE) -C simulate
|
VX_config.h: $(RTL_DIR)/VX_config.vh
|
||||||
|
$(SCRIPT_DIR)/gen_config.py -i $(RTL_DIR)/VX_config.vh -o $(DESTDIR)/VX_config.h
|
||||||
|
|
||||||
|
vortex_afu.h : $(RTL_DIR)/afu/vortex_afu.vh
|
||||||
|
$(SCRIPT_DIR)/gen_config.py -i $(RTL_DIR)/afu/vortex_afu.vh -o $(DESTDIR)/vortex_afu.h
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f ./VX_config.h
|
rm -f $(DESTDIR)/VX_config.h $(DESTDIR)/vortex_afu.h
|
||||||
$(MAKE) -C simulate clean
|
|
||||||
|
.PHONY: VX_config.h vortex_afu.h
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
CFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
|
||||||
#CFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors
|
|
||||||
|
|
||||||
CFLAGS += -Wno-maybe-uninitialized
|
|
||||||
|
|
||||||
CFLAGS += -I../..
|
|
||||||
|
|
||||||
# control RTL debug print states
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_PIPELINE
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CORE_ICACHE
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CORE_DCACHE
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_BANK
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_MSHR
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_TAG
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_DATA
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_MEM
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_OPAE
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_AVS
|
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_SCOPE
|
|
||||||
|
|
||||||
DBG_FLAGS += $(DBG_PRINT_FLAGS)
|
|
||||||
DBG_FLAGS += -DDBG_CACHE_REQ_INFO
|
|
||||||
|
|
||||||
SINGLECORE = -DNUM_CLUSTERS=1 -DNUM_CORES=1 -DL2_ENABLE=0
|
|
||||||
|
|
||||||
#MULTICORE = -DNUM_CLUSTERS=2 -DNUM_CORES=4 -DL2_ENABLE=1
|
|
||||||
#MULTICORE = -DNUM_CLUSTERS=1 -DNUM_CORES=4 -DL2_ENABLE=1
|
|
||||||
MULTICORE = -DNUM_CLUSTERS=1 -DNUM_CORES=2 -DL2_ENABLE=0
|
|
||||||
|
|
||||||
SINGLECORE += $(CONFIGS)
|
|
||||||
MULTICORE += $(CONFIGS)
|
|
||||||
|
|
||||||
TOP = Vortex
|
|
||||||
|
|
||||||
RTL_DIR=../rtl
|
|
||||||
DPI_DIR=../dpi
|
|
||||||
|
|
||||||
FPU_INCLUDE = -I$(RTL_DIR)/fp_cores -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src -I$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(RTL_DIR)/fp_cores/fpnew/src
|
|
||||||
RTL_INCLUDE = -I$(RTL_DIR) -I$(DPI_DIR) -I$(RTL_DIR)/libs -I$(RTL_DIR)/interfaces -I$(RTL_DIR)/cache -I$(RTL_DIR)/simulate $(FPU_INCLUDE)
|
|
||||||
|
|
||||||
SRCS = simulator.cpp main.cpp
|
|
||||||
SRCS += $(DPI_DIR)/util_dpi.cpp $(DPI_DIR)/float_dpi.cpp
|
|
||||||
|
|
||||||
VL_FLAGS += -O2 --language 1800-2009 --assert -Wall -Wpedantic
|
|
||||||
VL_FLAGS += -Wno-DECLFILENAME -Wno-REDEFMACRO
|
|
||||||
VL_FLAGS += --x-initial unique --x-assign unique
|
|
||||||
VL_FLAGS += verilator.vlt
|
|
||||||
|
|
||||||
VL_FLAGS += --exe $(SRCS) $(RTL_INCLUDE)
|
|
||||||
VL_FLAGS += --cc $(TOP) --top-module $(TOP)
|
|
||||||
|
|
||||||
# FPU backend
|
|
||||||
FPU_CORE ?= FPU_FPNEW
|
|
||||||
VL_FLAGS += -D$(FPU_CORE)
|
|
||||||
|
|
||||||
DBG_FLAGS += -DVCD_OUTPUT
|
|
||||||
|
|
||||||
THREADS ?= $(shell python3 -c 'import multiprocessing as mp; print(max(1, mp.cpu_count() // 2))')
|
|
||||||
|
|
||||||
all: build-s
|
|
||||||
|
|
||||||
gen-s:
|
|
||||||
verilator $(VL_FLAGS) -DNDEBUG $(SINGLECORE) -CFLAGS '$(CFLAGS) -DNDEBUG $(SINGLECORE)'
|
|
||||||
|
|
||||||
gen-sd:
|
|
||||||
verilator $(VL_FLAGS) $(SINGLECORE) -CFLAGS '$(CFLAGS) $(DBG_FLAGS) $(SINGLECORE)' --trace --trace-structs $(DBG_FLAGS)
|
|
||||||
|
|
||||||
gen-st:
|
|
||||||
verilator $(VL_FLAGS) -DNDEBUG $(SINGLECORE) -CFLAGS '$(CFLAGS) -DNDEBUG $(SINGLECORE)' --threads $(THREADS)
|
|
||||||
|
|
||||||
gen-m:
|
|
||||||
verilator $(VL_FLAGS) -DNDEBUG $(MULTICORE) -CFLAGS '$(CFLAGS) -DNDEBUG $(MULTICORE)'
|
|
||||||
|
|
||||||
gen-md:
|
|
||||||
verilator $(VL_FLAGS) $(MULTICORE) -CFLAGS '$(CFLAGS) $(DBG_FLAGS) $(MULTICORE)' --trace --trace-structs $(DBG_FLAGS)
|
|
||||||
|
|
||||||
gen-mt:
|
|
||||||
verilator $(VL_FLAGS) -DNDEBUG $(MULTICORE) -CFLAGS '$(CFLAGS) -DNDEBUG $(MULTICORE)' --threads $(THREADS)
|
|
||||||
|
|
||||||
build-s: gen-s
|
|
||||||
make -j -C obj_dir -f VVortex.mk
|
|
||||||
|
|
||||||
build-sd: gen-sd
|
|
||||||
make -j -C obj_dir -f VVortex.mk
|
|
||||||
|
|
||||||
build-st: gen-st
|
|
||||||
make -j -C obj_dir -f VVortex.mk
|
|
||||||
|
|
||||||
build-m: gen-m
|
|
||||||
make -j -C obj_dir -f VVortex.mk
|
|
||||||
|
|
||||||
build-md: gen-md
|
|
||||||
make -j -C obj_dir -f VVortex.mk
|
|
||||||
|
|
||||||
build-mt: gen-mt
|
|
||||||
make -j -C obj_dir -f VVortex.mk
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf obj_dir
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
class RAM {
|
|
||||||
private:
|
|
||||||
|
|
||||||
mutable uint8_t *mem_[(1 << 12)];
|
|
||||||
|
|
||||||
uint8_t *get(uint32_t address) const {
|
|
||||||
uint32_t block_addr = address >> 20;
|
|
||||||
uint32_t block_offset = address & 0x000FFFFF;
|
|
||||||
if (mem_[block_addr] == NULL) {
|
|
||||||
mem_[block_addr] = new uint8_t[(1 << 20)];
|
|
||||||
}
|
|
||||||
return mem_[block_addr] + block_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
RAM() {
|
|
||||||
for (uint32_t i = 0; i < (1 << 12); i++) {
|
|
||||||
mem_[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~RAM() {
|
|
||||||
this->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const {
|
|
||||||
return (1ull << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
for (uint32_t i = 0; i < (1 << 12); i++) {
|
|
||||||
if (mem_[i]) {
|
|
||||||
delete [] mem_[i];
|
|
||||||
mem_[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void read(uint32_t address, uint32_t length, uint8_t *data) const {
|
|
||||||
for (unsigned i = 0; i < length; i++) {
|
|
||||||
data[i] = *this->get(address + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(uint32_t address, uint32_t length, const uint8_t *data) {
|
|
||||||
for (unsigned i = 0; i < length; i++) {
|
|
||||||
*this->get(address + i) = data[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t& operator[](uint32_t address) {
|
|
||||||
return *get(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t& operator[](uint32_t address) const {
|
|
||||||
return *get(address);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
`verilator_config
|
|
||||||
|
|
||||||
lint_off -rule BLKANDNBLK -file "../rtl/fp_cores/fpnew/*"
|
|
||||||
lint_off -rule UNOPTFLAT -file "../rtl/fp_cores/fpnew/*"
|
|
||||||
lint_off -rule WIDTH -file "../rtl/fp_cores/fpnew/*"
|
|
||||||
lint_off -rule UNUSED -file "../rtl/fp_cores/fpnew/*"
|
|
||||||
lint_off -rule LITENDIAN -file "../rtl/fp_cores/fpnew/*"
|
|
||||||
lint_off -rule IMPORTSTAR -file "../rtl/fp_cores/fpnew/*"
|
|
||||||
lint_off -rule PINCONNECTEMPTY -file "../rtl/fp_cores/fpnew/*"
|
|
||||||
lint_off -file "../rtl/fp_cores/fpnew/*"
|
|
||||||
@@ -35,5 +35,5 @@ done
|
|||||||
# run application
|
# run application
|
||||||
pushd $PROGRAM_DIR
|
pushd $PROGRAM_DIR
|
||||||
echo " [DBG] running ./$PROGRAM $*"
|
echo " [DBG] running ./$PROGRAM $*"
|
||||||
ASE_LOG=0 LD_LIBRARY_PATH=$POCL_RT_PATH/lib:$VORTEX_DRV_PATH/opae/ase:$LD_LIBRARY_PATH ./$PROGRAM $*
|
ASE_LOG=0 LD_LIBRARY_PATH=$POCL_RT_PATH/lib:$VORTEX_DRV_PATH/asesim:$LD_LIBRARY_PATH ./$PROGRAM $*
|
||||||
popd
|
popd
|
||||||
9
sim/Makefile
Normal file
9
sim/Makefile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
all:
|
||||||
|
$(MAKE) -C simX
|
||||||
|
$(MAKE) -C rtlsim
|
||||||
|
$(MAKE) -C vlsim
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C simX clean
|
||||||
|
$(MAKE) -C rtlsim clean
|
||||||
|
$(MAKE) -C vlsim clean
|
||||||
@@ -1,21 +1,13 @@
|
|||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "debug.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "core.h"
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
using namespace vortex;
|
using namespace vortex;
|
||||||
|
|
||||||
RamMemDevice::RamMemDevice(const char *filename, Size wordSize)
|
RamMemDevice::RamMemDevice(const char *filename, uint32_t wordSize)
|
||||||
: wordSize_(wordSize) {
|
: wordSize_(wordSize) {
|
||||||
std::ifstream input(filename);
|
std::ifstream input(filename);
|
||||||
|
|
||||||
@@ -32,12 +24,12 @@ RamMemDevice::RamMemDevice(const char *filename, Size wordSize)
|
|||||||
contents_.push_back(0x00);
|
contents_.push_back(0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
RamMemDevice::RamMemDevice(Size size, Size wordSize)
|
RamMemDevice::RamMemDevice(uint64_t size, uint32_t wordSize)
|
||||||
: contents_(size)
|
: contents_(size)
|
||||||
, wordSize_(wordSize)
|
, wordSize_(wordSize)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void RamMemDevice::read(Addr addr, void *data, Size size) {
|
void RamMemDevice::read(void *data, uint64_t addr, uint64_t size) {
|
||||||
auto addr_end = addr + size;
|
auto addr_end = addr + size;
|
||||||
if ((addr & (wordSize_-1))
|
if ((addr & (wordSize_-1))
|
||||||
|| (addr_end & (wordSize_-1))
|
|| (addr_end & (wordSize_-1))
|
||||||
@@ -46,13 +38,13 @@ void RamMemDevice::read(Addr addr, void *data, Size size) {
|
|||||||
throw BadAddress();
|
throw BadAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Byte *s = contents_.data() + addr;
|
const uint8_t *s = contents_.data() + addr;
|
||||||
for (Byte *d = (Byte*)data, *de = d + size; d != de;) {
|
for (uint8_t *d = (uint8_t*)data, *de = d + size; d != de;) {
|
||||||
*d++ = *s++;
|
*d++ = *s++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RamMemDevice::write(Addr addr, const void *data, Size size) {
|
void RamMemDevice::write(const void *data, uint64_t addr, uint64_t size) {
|
||||||
auto addr_end = addr + size;
|
auto addr_end = addr + size;
|
||||||
if ((addr & (wordSize_-1))
|
if ((addr & (wordSize_-1))
|
||||||
|| (addr_end & (wordSize_-1))
|
|| (addr_end & (wordSize_-1))
|
||||||
@@ -61,23 +53,23 @@ void RamMemDevice::write(Addr addr, const void *data, Size size) {
|
|||||||
throw BadAddress();
|
throw BadAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Byte *s = (const Byte*)data;
|
const uint8_t *s = (const uint8_t*)data;
|
||||||
for (Byte *d = contents_.data() + addr, *de = d + size; d != de;) {
|
for (uint8_t *d = contents_.data() + addr, *de = d + size; d != de;) {
|
||||||
*d++ = *s++;
|
*d++ = *s++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void RomMemDevice::write(Addr /*addr*/, const void* /*data*/, Size /*size*/) {
|
void RomMemDevice::write(const void* /*data*/, uint64_t /*addr*/, uint64_t /*size*/) {
|
||||||
std::cout << "attempt to write to ROM.\n";
|
std::cout << "attempt to write to ROM.\n";
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool MemoryUnit::ADecoder::lookup(Addr a, Size wordSize, mem_accessor_t* ma) {
|
bool MemoryUnit::ADecoder::lookup(uint64_t a, uint32_t wordSize, mem_accessor_t* ma) {
|
||||||
Addr e = a + (wordSize - 1);
|
uint64_t e = a + (wordSize - 1);
|
||||||
assert(e >= a);
|
assert(e >= a);
|
||||||
for (auto iter = entries_.rbegin(), iterE = entries_.rend(); iter != iterE; ++iter) {
|
for (auto iter = entries_.rbegin(), iterE = entries_.rend(); iter != iterE; ++iter) {
|
||||||
if (a >= iter->start && e <= iter->end) {
|
if (a >= iter->start && e <= iter->end) {
|
||||||
@@ -89,89 +81,87 @@ bool MemoryUnit::ADecoder::lookup(Addr a, Size wordSize, mem_accessor_t* ma) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryUnit::ADecoder::map(Addr a, Addr e, MemDevice &m) {
|
void MemoryUnit::ADecoder::map(uint64_t a, uint64_t e, MemDevice &m) {
|
||||||
assert(e >= a);
|
assert(e >= a);
|
||||||
entry_t entry{&m, a, e};
|
entry_t entry{&m, a, e};
|
||||||
entries_.emplace_back(entry);
|
entries_.emplace_back(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryUnit::ADecoder::read(Addr addr, void *data, Size size) {
|
void MemoryUnit::ADecoder::read(void *data, uint64_t addr, uint64_t size) {
|
||||||
mem_accessor_t ma;
|
mem_accessor_t ma;
|
||||||
if (!this->lookup(addr, size, &ma)) {
|
if (!this->lookup(addr, size, &ma)) {
|
||||||
std::cout << "lookup of 0x" << std::hex << addr << " failed.\n";
|
std::cout << "lookup of 0x" << std::hex << addr << " failed.\n";
|
||||||
throw BadAddress();
|
throw BadAddress();
|
||||||
}
|
}
|
||||||
ma.md->read(ma.addr, data, size);
|
ma.md->read(data, ma.addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryUnit::ADecoder::write(Addr addr, const void *data, Size size) {
|
void MemoryUnit::ADecoder::write(const void *data, uint64_t addr, uint64_t size) {
|
||||||
mem_accessor_t ma;
|
mem_accessor_t ma;
|
||||||
if (!this->lookup(addr, size, &ma)) {
|
if (!this->lookup(addr, size, &ma)) {
|
||||||
std::cout << "lookup of 0x" << std::hex << addr << " failed.\n";
|
std::cout << "lookup of 0x" << std::hex << addr << " failed.\n";
|
||||||
throw BadAddress();
|
throw BadAddress();
|
||||||
}
|
}
|
||||||
ma.md->write(ma.addr, data, size);
|
ma.md->write(data, ma.addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
MemoryUnit::MemoryUnit(Size pageSize, Size addrBytes, bool disableVm)
|
MemoryUnit::MemoryUnit(uint64_t pageSize, uint64_t addrBytes, bool disableVm)
|
||||||
: pageSize_(pageSize)
|
: pageSize_(pageSize)
|
||||||
, addrBytes_(addrBytes)
|
, addrBytes_(addrBytes)
|
||||||
, disableVm_(disableVm) {
|
, disableVM_(disableVm) {
|
||||||
if (!disableVm) {
|
if (!disableVm) {
|
||||||
tlb_[0] = TLBEntry(0, 077);
|
tlb_[0] = TLBEntry(0, 077);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryUnit::attach(MemDevice &m, Addr start, Addr end) {
|
void MemoryUnit::attach(MemDevice &m, uint64_t start, uint64_t end) {
|
||||||
decoder_.map(start, end, m);
|
decoder_.map(start, end, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryUnit::TLBEntry MemoryUnit::tlbLookup(Addr vAddr, Word flagMask) {
|
MemoryUnit::TLBEntry MemoryUnit::tlbLookup(uint64_t vAddr, uint32_t flagMask) {
|
||||||
auto iter = tlb_.find(vAddr / pageSize_);
|
auto iter = tlb_.find(vAddr / pageSize_);
|
||||||
if (iter != tlb_.end()) {
|
if (iter != tlb_.end()) {
|
||||||
if (iter->second.flags & flagMask)
|
if (iter->second.flags & flagMask)
|
||||||
return iter->second;
|
return iter->second;
|
||||||
else {
|
else {
|
||||||
D(3, "*** Page fault on addr 0x" << std::hex << vAddr << "(bad flags)");
|
|
||||||
throw PageFault(vAddr, false);
|
throw PageFault(vAddr, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
D(3, "*** Page fault on addr 0x" << std::hex << vAddr << "(not in TLB)");
|
|
||||||
throw PageFault(vAddr, true);
|
throw PageFault(vAddr, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryUnit::read(Addr addr, void *data, Size size, bool sup) {
|
void MemoryUnit::read(void *data, uint64_t addr, uint64_t size, bool sup) {
|
||||||
Addr pAddr;
|
uint64_t pAddr;
|
||||||
if (disableVm_) {
|
if (disableVM_) {
|
||||||
pAddr = addr;
|
pAddr = addr;
|
||||||
} else {
|
} else {
|
||||||
Word flagMask = sup ? 8 : 1;
|
uint32_t flagMask = sup ? 8 : 1;
|
||||||
TLBEntry t = this->tlbLookup(addr, flagMask);
|
TLBEntry t = this->tlbLookup(addr, flagMask);
|
||||||
pAddr = t.pfn * pageSize_ + addr % pageSize_;
|
pAddr = t.pfn * pageSize_ + addr % pageSize_;
|
||||||
}
|
}
|
||||||
return decoder_.read(pAddr, data, size);
|
return decoder_.read(data, pAddr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryUnit::write(Addr addr, const void *data, Size size, bool sup) {
|
void MemoryUnit::write(const void *data, uint64_t addr, uint64_t size, bool sup) {
|
||||||
Addr pAddr;
|
uint64_t pAddr;
|
||||||
if (disableVm_) {
|
if (disableVM_) {
|
||||||
pAddr = addr;
|
pAddr = addr;
|
||||||
} else {
|
} else {
|
||||||
Word flagMask = sup ? 16 : 2;
|
uint32_t flagMask = sup ? 16 : 2;
|
||||||
TLBEntry t = tlbLookup(addr, flagMask);
|
TLBEntry t = tlbLookup(addr, flagMask);
|
||||||
pAddr = t.pfn * pageSize_ + addr % pageSize_;
|
pAddr = t.pfn * pageSize_ + addr % pageSize_;
|
||||||
}
|
}
|
||||||
decoder_.write(pAddr, data, size);
|
decoder_.write(data, pAddr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryUnit::tlbAdd(Addr virt, Addr phys, Word flags) {
|
void MemoryUnit::tlbAdd(uint64_t virt, uint64_t phys, uint32_t flags) {
|
||||||
tlb_[virt / pageSize_] = TLBEntry(phys / pageSize_, flags);
|
tlb_[virt / pageSize_] = TLBEntry(phys / pageSize_, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryUnit::tlbRm(Addr va) {
|
void MemoryUnit::tlbRm(uint64_t va) {
|
||||||
if (tlb_.find(va / pageSize_) != tlb_.end())
|
if (tlb_.find(va / pageSize_) != tlb_.end())
|
||||||
tlb_.erase(tlb_.find(va / pageSize_));
|
tlb_.erase(tlb_.find(va / pageSize_));
|
||||||
}
|
}
|
||||||
@@ -182,8 +172,7 @@ RAM::RAM(uint32_t num_pages, uint32_t page_size)
|
|||||||
: page_bits_(log2ceil(page_size)) {
|
: page_bits_(log2ceil(page_size)) {
|
||||||
assert(ispow2(page_size));
|
assert(ispow2(page_size));
|
||||||
mem_.resize(num_pages, NULL);
|
mem_.resize(num_pages, NULL);
|
||||||
uint64_t sizel = uint64_t(mem_.size()) << page_bits_;
|
size_ = uint64_t(mem_.size()) << page_bits_;
|
||||||
size_ = (sizel <= 0xFFFFFFFF) ? sizel : 0xffffffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RAM::~RAM() {
|
RAM::~RAM() {
|
||||||
@@ -197,16 +186,16 @@ void RAM::clear() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Size RAM::size() const {
|
uint64_t RAM::size() const {
|
||||||
return size_;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *RAM::get(uint32_t address) {
|
uint8_t *RAM::get(uint32_t address) const {
|
||||||
uint32_t page_size = 1 << page_bits_;
|
uint32_t page_size = 1 << page_bits_;
|
||||||
uint32_t page_index = address >> page_bits_;
|
uint32_t page_index = address >> page_bits_;
|
||||||
uint32_t byte_offset = address & ((1 << page_bits_) - 1);
|
uint32_t byte_offset = address & ((1 << page_bits_) - 1);
|
||||||
|
|
||||||
uint8_t* &page = mem_.at(page_index);
|
auto &page = mem_.at(page_index);
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
uint8_t *ptr = new uint8_t[page_size];
|
uint8_t *ptr = new uint8_t[page_size];
|
||||||
// set uninitialized data to "baadf00d"
|
// set uninitialized data to "baadf00d"
|
||||||
@@ -218,37 +207,37 @@ uint8_t *RAM::get(uint32_t address) {
|
|||||||
return page + byte_offset;
|
return page + byte_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RAM::read(Addr addr, void *data, Size size) {
|
void RAM::read(void *data, uint64_t addr, uint64_t size) {
|
||||||
Byte* d = (Byte*)data;
|
uint8_t* d = (uint8_t*)data;
|
||||||
for (unsigned i = 0; i < size; i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
d[i] = *this->get(addr + i);
|
d[i] = *this->get(addr + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RAM::write(Addr addr, const void *data, Size size) {
|
void RAM::write(const void *data, uint64_t addr, uint64_t size) {
|
||||||
const Byte* s = (const Byte*)data;
|
const uint8_t* s = (const uint8_t*)data;
|
||||||
for (unsigned i = 0; i < size; i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
*this->get(addr + i) = s[i];
|
*this->get(addr + i) = s[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RAM::loadBinImage(const char* path) {
|
void RAM::loadBinImage(const char* filename, uint64_t destination) {
|
||||||
std::ifstream ifs(path);
|
std::ifstream ifs(filename);
|
||||||
if (!ifs) {
|
if (!ifs) {
|
||||||
std::cout << "error: " << path << " not found" << std::endl;
|
std::cout << "error: " << filename << " not found" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifs.seekg(0, ifs.end);
|
ifs.seekg(0, ifs.end);
|
||||||
auto size = ifs.tellg();
|
size_t size = ifs.tellg();
|
||||||
std::vector<uint8_t> content(size);
|
std::vector<uint8_t> content(size);
|
||||||
ifs.seekg(0, ifs.beg);
|
ifs.seekg(0, ifs.beg);
|
||||||
ifs.read((char*)content.data(), size);
|
ifs.read((char*)content.data(), size);
|
||||||
|
|
||||||
this->clear();
|
this->clear();
|
||||||
this->write(STARTUP_ADDR, content.data(), size);
|
this->write(content.data(), destination, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RAM::loadHexImage(const char* path) {
|
void RAM::loadHexImage(const char* filename) {
|
||||||
auto hti = [&](char c)->uint32_t {
|
auto hti = [&](char c)->uint32_t {
|
||||||
if (c >= 'A' && c <= 'F')
|
if (c >= 'A' && c <= 'F')
|
||||||
return c - 'A' + 10;
|
return c - 'A' + 10;
|
||||||
@@ -265,13 +254,13 @@ void RAM::loadHexImage(const char* path) {
|
|||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ifstream ifs(path);
|
std::ifstream ifs(filename);
|
||||||
if (!ifs) {
|
if (!ifs) {
|
||||||
std::cout << "error: " << path << " not found" << std::endl;
|
std::cout << "error: " << filename << " not found" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifs.seekg(0, ifs.end);
|
ifs.seekg(0, ifs.end);
|
||||||
uint32_t size = ifs.tellg();
|
size_t size = ifs.tellg();
|
||||||
std::vector<char> content(size);
|
std::vector<char> content(size);
|
||||||
ifs.seekg(0, ifs.beg);
|
ifs.seekg(0, ifs.beg);
|
||||||
ifs.read(content.data(), size);
|
ifs.read(content.data(), size);
|
||||||
163
sim/common/mem.h
Normal file
163
sim/common/mem.h
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace vortex {
|
||||||
|
struct BadAddress {};
|
||||||
|
|
||||||
|
class MemDevice {
|
||||||
|
public:
|
||||||
|
virtual ~MemDevice() {}
|
||||||
|
virtual uint64_t size() const = 0;
|
||||||
|
virtual void read(void *data, uint64_t addr, uint64_t size) = 0;
|
||||||
|
virtual void write(const void *data, uint64_t addr, uint64_t size) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class RamMemDevice : public MemDevice {
|
||||||
|
public:
|
||||||
|
RamMemDevice(uint64_t size, uint32_t wordSize);
|
||||||
|
RamMemDevice(const char *filename, uint32_t wordSize);
|
||||||
|
~RamMemDevice() {}
|
||||||
|
|
||||||
|
void read(void *data, uint64_t addr, uint64_t size) override;
|
||||||
|
void write(const void *data, uint64_t addr, uint64_t size) override;
|
||||||
|
|
||||||
|
virtual uint64_t size() const {
|
||||||
|
return contents_.size();
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<uint8_t> contents_;
|
||||||
|
uint32_t wordSize_;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class RomMemDevice : public RamMemDevice {
|
||||||
|
public:
|
||||||
|
RomMemDevice(const char *filename, uint32_t wordSize)
|
||||||
|
: RamMemDevice(filename, wordSize)
|
||||||
|
{}
|
||||||
|
|
||||||
|
RomMemDevice(uint64_t size, uint32_t wordSize)
|
||||||
|
: RamMemDevice(size, wordSize)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~RomMemDevice();
|
||||||
|
|
||||||
|
void write(const void *data, uint64_t addr, uint64_t size) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class MemoryUnit {
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct PageFault {
|
||||||
|
PageFault(uint64_t a, bool nf)
|
||||||
|
: faultAddr(a)
|
||||||
|
, notFound(nf)
|
||||||
|
{}
|
||||||
|
uint64_t faultAddr;
|
||||||
|
bool notFound;
|
||||||
|
};
|
||||||
|
|
||||||
|
MemoryUnit(uint64_t pageSize, uint64_t addrBytes, bool disableVm = false);
|
||||||
|
|
||||||
|
void attach(MemDevice &m, uint64_t start, uint64_t end);
|
||||||
|
|
||||||
|
void read(void *data, uint64_t addr, uint64_t size, bool sup);
|
||||||
|
void write(const void *data, uint64_t addr, uint64_t size, bool sup);
|
||||||
|
|
||||||
|
void tlbAdd(uint64_t virt, uint64_t phys, uint32_t flags);
|
||||||
|
void tlbRm(uint64_t va);
|
||||||
|
void tlbFlush() {
|
||||||
|
tlb_.clear();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
|
||||||
|
class ADecoder {
|
||||||
|
public:
|
||||||
|
ADecoder() {}
|
||||||
|
|
||||||
|
void read(void *data, uint64_t addr, uint64_t size);
|
||||||
|
void write(const void *data, uint64_t addr, uint64_t size);
|
||||||
|
|
||||||
|
void map(uint64_t start, uint64_t end, MemDevice &md);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct mem_accessor_t {
|
||||||
|
MemDevice* md;
|
||||||
|
uint64_t addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct entry_t {
|
||||||
|
MemDevice *md;
|
||||||
|
uint64_t start;
|
||||||
|
uint64_t end;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool lookup(uint64_t a, uint32_t wordSize, mem_accessor_t*);
|
||||||
|
|
||||||
|
std::vector<entry_t> entries_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TLBEntry {
|
||||||
|
TLBEntry() {}
|
||||||
|
TLBEntry(uint32_t pfn, uint32_t flags)
|
||||||
|
: pfn(pfn)
|
||||||
|
, flags(flags)
|
||||||
|
{}
|
||||||
|
uint32_t pfn;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
TLBEntry tlbLookup(uint64_t vAddr, uint32_t flagMask);
|
||||||
|
|
||||||
|
std::unordered_map<uint64_t, TLBEntry> tlb_;
|
||||||
|
uint64_t pageSize_;
|
||||||
|
uint64_t addrBytes_;
|
||||||
|
ADecoder decoder_;
|
||||||
|
bool disableVM_;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class RAM : public MemDevice {
|
||||||
|
public:
|
||||||
|
|
||||||
|
RAM(uint32_t num_pages, uint32_t page_size);
|
||||||
|
|
||||||
|
~RAM();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
uint64_t size() const override;
|
||||||
|
void read(void *data, uint64_t addr, uint64_t size) override;
|
||||||
|
void write(const void *data, uint64_t addr, uint64_t size) override;
|
||||||
|
|
||||||
|
void loadBinImage(const char* filename, uint64_t destination);
|
||||||
|
void loadHexImage(const char* filename);
|
||||||
|
|
||||||
|
uint8_t& operator[](uint64_t address) {
|
||||||
|
return *this->get(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t& operator[](uint64_t address) const {
|
||||||
|
return *this->get(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint8_t *get(uint32_t address) const;
|
||||||
|
|
||||||
|
mutable std::vector<uint8_t*> mem_;
|
||||||
|
uint32_t page_bits_;
|
||||||
|
uint64_t size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace vortex
|
||||||
92
sim/common/util.cpp
Normal file
92
sim/common/util.cpp
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#include "util.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <math.h>
|
||||||
|
#include <climits>
|
||||||
|
#include <string.h>
|
||||||
|
#include <bitset>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
using namespace vortex;
|
||||||
|
|
||||||
|
// Apply integer sign extension
|
||||||
|
uint32_t vortex::signExt(uint32_t w, uint32_t bit, uint32_t mask) {
|
||||||
|
if (w >> (bit - 1))
|
||||||
|
w |= ~mask;
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a floating point number to IEEE-754 32-bit representation,
|
||||||
|
// so that it could be stored in a 32-bit integer register file
|
||||||
|
// Reference: https://www.wikihow.com/Convert-a-Number-from-Decimal-to-IEEE-754-Floating-Point-Representation
|
||||||
|
// https://www.technical-recipes.com/2012/converting-between-binary-and-decimal-representations-of-ieee-754-floating-point-numbers-in-c/
|
||||||
|
uint32_t vortex::floatToBin(float in_value) {
|
||||||
|
union {
|
||||||
|
float input; // assumes sizeof(float) == sizeof(int)
|
||||||
|
int output;
|
||||||
|
} data;
|
||||||
|
|
||||||
|
data.input = in_value;
|
||||||
|
|
||||||
|
std::bitset<sizeof(float) * CHAR_BIT> bits(data.output);
|
||||||
|
std::string mystring = bits.to_string<char, std::char_traits<char>, std::allocator<char>>();
|
||||||
|
// Convert binary to uint32_t
|
||||||
|
uint32_t result = stoul(mystring, nullptr, 2);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/Single-precision_floating-point_format
|
||||||
|
// check floating-point number in binary format is NaN
|
||||||
|
uint8_t vortex::fpBinIsNan(uint32_t din) {
|
||||||
|
bool fsign = din & 0x80000000;
|
||||||
|
uint32_t expo = (din>>23) & 0x000000FF;
|
||||||
|
uint32_t fraction = din & 0x007FFFFF;
|
||||||
|
uint32_t bit_22 = din & 0x00400000;
|
||||||
|
|
||||||
|
if ((expo==0xFF) && (fraction!=0)) {
|
||||||
|
// if (!fsign && (fraction == 0x00400000))
|
||||||
|
if (!fsign && (bit_22))
|
||||||
|
return 1; // quiet NaN, return 1
|
||||||
|
else
|
||||||
|
return 2; // signaling NaN, return 2
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check floating-point number in binary format is zero
|
||||||
|
uint8_t vortex::fpBinIsZero(uint32_t din) {
|
||||||
|
bool fsign = din & 0x80000000;
|
||||||
|
uint32_t expo = (din>>23) & 0x000000FF;
|
||||||
|
uint32_t fraction = din & 0x007FFFFF;
|
||||||
|
|
||||||
|
if ((expo==0) && (fraction==0)) {
|
||||||
|
if (fsign)
|
||||||
|
return 1; // negative 0
|
||||||
|
else
|
||||||
|
return 2; // positive 0
|
||||||
|
}
|
||||||
|
return 0; // not zero
|
||||||
|
}
|
||||||
|
|
||||||
|
// check floating-point number in binary format is infinity
|
||||||
|
uint8_t vortex::fpBinIsInf(uint32_t din) {
|
||||||
|
bool fsign = din & 0x80000000;
|
||||||
|
uint32_t expo = (din>>23) & 0x000000FF;
|
||||||
|
uint32_t fraction = din & 0x007FFFFF;
|
||||||
|
|
||||||
|
if ((expo==0xFF) && (fraction==0)) {
|
||||||
|
if (fsign)
|
||||||
|
return 1; // negative infinity
|
||||||
|
else
|
||||||
|
return 2; // positive infinity
|
||||||
|
}
|
||||||
|
return 0; // not infinity
|
||||||
|
}
|
||||||
|
|
||||||
|
// return file extension
|
||||||
|
const char* vortex::fileExtension(const char* filepath) {
|
||||||
|
const char *ext = strrchr(filepath, '.');
|
||||||
|
if (ext == NULL || ext == filepath)
|
||||||
|
return "";
|
||||||
|
return ext + 1;
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <cstdint>
|
||||||
#include "types.h"
|
#include <assert.h>
|
||||||
|
|
||||||
namespace vortex {
|
namespace vortex {
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ void unused(Args&&...) {}
|
|||||||
|
|
||||||
#define __unused(...) unused(__VA_ARGS__)
|
#define __unused(...) unused(__VA_ARGS__)
|
||||||
|
|
||||||
constexpr bool ispow2(uint32_t value) {
|
constexpr bool ispow2(uint64_t value) {
|
||||||
return value && !(value & (value - 1));
|
return value && !(value & (value - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,20 +18,13 @@ constexpr unsigned log2ceil(uint32_t value) {
|
|||||||
return 32 - __builtin_clz(value - 1);
|
return 32 - __builtin_clz(value - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Word signExt(Word w, Size bit, Word mask);
|
inline uint64_t align_size(uint64_t size, uint64_t alignment) {
|
||||||
|
assert(0 == (alignment & (alignment - 1)));
|
||||||
|
return (size + alignment - 1) & ~(alignment - 1);
|
||||||
|
}
|
||||||
|
|
||||||
Word bytesToWord(const Byte *b, Size wordSize);
|
// Apply integer sign extension
|
||||||
void wordToBytes(Byte *b, Word w, Size wordSize);
|
uint32_t signExt(uint32_t w, uint32_t bit, uint32_t mask);
|
||||||
Word flagsToWord(bool r, bool w, bool x);
|
|
||||||
void wordToFlags(bool &r, bool &w, bool &x, Word f);
|
|
||||||
|
|
||||||
Byte readByte(const std::vector<Byte> &b, Size &n);
|
|
||||||
Word readWord(const std::vector<Byte> &b, Size &n, Size wordSize);
|
|
||||||
void writeByte(std::vector<Byte> &p, Size &n, Byte b);
|
|
||||||
void writeWord(std::vector<Byte> &p, Size &n, Size wordSize, Word w);
|
|
||||||
|
|
||||||
// Convert 32-bit integer register file to IEEE-754 floating point number.
|
|
||||||
float intregToFloat(uint32_t input);
|
|
||||||
|
|
||||||
// Convert a floating point number to IEEE-754 32-bit representation
|
// Convert a floating point number to IEEE-754 32-bit representation
|
||||||
uint32_t floatToBin(float in_value);
|
uint32_t floatToBin(float in_value);
|
||||||
123
sim/rtlsim/Makefile
Normal file
123
sim/rtlsim/Makefile
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
||||||
|
#CXXFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors
|
||||||
|
|
||||||
|
CXXFLAGS += -fPIC -Wno-maybe-uninitialized
|
||||||
|
CXXFLAGS += -I. -I../../../hw -I../../common
|
||||||
|
CXXFLAGS += -I$(VERILATOR_ROOT)/include -I$(VERILATOR_ROOT)/include/vltstd
|
||||||
|
|
||||||
|
# control RTL debug print states
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_PIPELINE
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_CORE_ICACHE
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_CORE_DCACHE
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_BANK
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_MSHR
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_TAG
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_CACHE_DATA
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_MEM
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_OPAE
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_AVS
|
||||||
|
DBG_PRINT_FLAGS += -DDBG_PRINT_SCOPE
|
||||||
|
|
||||||
|
DBG_FLAGS += $(DBG_PRINT_FLAGS)
|
||||||
|
DBG_FLAGS += -DDBG_CACHE_REQ_INFO
|
||||||
|
DBG_FLAGS += -DVCD_OUTPUT
|
||||||
|
|
||||||
|
SINGLECORE = -DNUM_CLUSTERS=1 -DNUM_CORES=1 -DL2_ENABLE=0
|
||||||
|
MULTICORE = -DNUM_CLUSTERS=1 -DNUM_CORES=2 -DL2_ENABLE=0
|
||||||
|
|
||||||
|
RTL_DIR=../../hw/rtl
|
||||||
|
DPI_DIR=../../hw/dpi
|
||||||
|
|
||||||
|
FPU_INCLUDE = -I$(RTL_DIR)/fp_cores -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src -I$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(RTL_DIR)/fp_cores/fpnew/src
|
||||||
|
RTL_INCLUDE = -I$(RTL_DIR) -I$(DPI_DIR) -I$(RTL_DIR)/libs -I$(RTL_DIR)/interfaces -I$(RTL_DIR)/cache -I$(RTL_DIR)/simulate $(FPU_INCLUDE)
|
||||||
|
|
||||||
|
SRCS = ../common/util.cpp ../common/mem.cpp
|
||||||
|
SRCS += $(DPI_DIR)/util_dpi.cpp $(DPI_DIR)/float_dpi.cpp
|
||||||
|
SRCS += simulator.cpp
|
||||||
|
|
||||||
|
ifdef AXI_BUS
|
||||||
|
TOP = Vortex_axi
|
||||||
|
CFLAGS += -DAXI_BUS
|
||||||
|
else
|
||||||
|
TOP = Vortex
|
||||||
|
endif
|
||||||
|
|
||||||
|
VL_FLAGS = --cc $(TOP) --top-module $(TOP)
|
||||||
|
VL_FLAGS += -O2 --language 1800-2009 --assert -Wall -Wpedantic
|
||||||
|
VL_FLAGS += -Wno-DECLFILENAME -Wno-REDEFMACRO
|
||||||
|
VL_FLAGS += --x-initial unique --x-assign unique
|
||||||
|
VL_FLAGS += verilator.vlt
|
||||||
|
VL_FLAGS += $(CONFIGS)
|
||||||
|
VL_FLAGS += $(RTL_INCLUDE)
|
||||||
|
|
||||||
|
# Debugigng
|
||||||
|
ifdef DEBUG
|
||||||
|
VL_FLAGS += -DVCD_OUTPUT --trace --trace-structs $(DBG_FLAGS)
|
||||||
|
CXXFLAGS += -DVCD_OUTPUT $(DBG_FLAGS)
|
||||||
|
else
|
||||||
|
VL_FLAGS += -DNDEBUG
|
||||||
|
CXXFLAGS += -DNDEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Enable perf counters
|
||||||
|
ifdef PERF
|
||||||
|
VL_FLAGS += -DPERF_ENABLE
|
||||||
|
CXXFLAGS += -DPERF_ENABLE
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ALU backend
|
||||||
|
VL_FLAGS += -DIMUL_DPI
|
||||||
|
VL_FLAGS += -DIDIV_DPI
|
||||||
|
|
||||||
|
# FPU backend
|
||||||
|
FPU_CORE ?= FPU_FPNEW
|
||||||
|
VL_FLAGS += -D$(FPU_CORE)
|
||||||
|
|
||||||
|
THREADS ?= $(shell python3 -c 'import multiprocessing as mp; print(max(1, mp.cpu_count() // 2))')
|
||||||
|
|
||||||
|
OBJS := $(patsubst %.cpp, obj_dir/%.o, $(notdir $(SRCS)))
|
||||||
|
VPATH := $(sort $(dir $(SRCS)))
|
||||||
|
|
||||||
|
#$(info OBJS is $(OBJS))
|
||||||
|
#$(info VPATH is $(VPATH))
|
||||||
|
|
||||||
|
PROJECT = rtlsim
|
||||||
|
|
||||||
|
all: build-s
|
||||||
|
|
||||||
|
build-s:
|
||||||
|
verilator --build --exe main.cpp $(SRCS) $(VL_FLAGS) -DNDEBUG $(SINGLECORE) -CFLAGS '$(CXXFLAGS) -DNDEBUG $(SINGLECORE)' -o ../$(PROJECT)
|
||||||
|
|
||||||
|
build-sd:
|
||||||
|
verilator --build --exe main.cpp $(SRCS) $(VL_FLAGS) $(SINGLECORE) -CFLAGS '$(CXXFLAGS) $(DBG_FLAGS) $(SINGLECORE)' --trace --trace-structs $(DBG_FLAGS) -o ../$(PROJECT)
|
||||||
|
|
||||||
|
build-st:
|
||||||
|
verilator --build --exe main.cpp $(SRCS) $(VL_FLAGS) -DNDEBUG $(SINGLECORE) -CFLAGS '$(CXXFLAGS) -DNDEBUG $(SINGLECORE)' --threads $(THREADS) -o ../$(PROJECT)
|
||||||
|
|
||||||
|
build-m:
|
||||||
|
verilator --build --exe main.cpp $(SRCS) $(VL_FLAGS) -DNDEBUG $(MULTICORE) -CFLAGS '$(CXXFLAGS) -DNDEBUG $(MULTICORE)' -o ../$(PROJECT)
|
||||||
|
|
||||||
|
build-md:
|
||||||
|
verilator --build --exe main.cpp $(SRCS) $(VL_FLAGS) $(MULTICORE) -CFLAGS '$(CXXFLAGS) $(DBG_FLAGS) $(MULTICORE)' --trace --trace-structs $(DBG_FLAGS) -o ../$(PROJECT)
|
||||||
|
|
||||||
|
build-mt:
|
||||||
|
verilator --build --exe main.cpp $(SRCS) $(VL_FLAGS) -DNDEBUG $(MULTICORE) -CFLAGS '$(CXXFLAGS) -DNDEBUG $(MULTICORE)' --threads $(THREADS) -o ../$(PROJECT)
|
||||||
|
|
||||||
|
obj_dir/V$(TOP)__ALL.a:
|
||||||
|
verilator --build $(VL_FLAGS) -CFLAGS '$(CXXFLAGS)'
|
||||||
|
|
||||||
|
obj_dir/%.o: %.cpp
|
||||||
|
cd obj_dir && $(CXX) $(CXXFLAGS) -c ../$< -o $(notdir $@)
|
||||||
|
|
||||||
|
obj_dir/verilated.o: $(VERILATOR_ROOT)/include/verilated.cpp
|
||||||
|
cd obj_dir && $(CXX) $(CXXFLAGS) -c $< -o verilated.o
|
||||||
|
|
||||||
|
static: obj_dir/V$(TOP)__ALL.a $(OBJS) obj_dir/verilated.o
|
||||||
|
cp obj_dir/V$(TOP)__ALL.a lib$(PROJECT).a
|
||||||
|
$(AR) rs lib$(PROJECT).a $(OBJS) obj_dir/verilated.o
|
||||||
|
|
||||||
|
clean-objdir:
|
||||||
|
rm -rf obj_dir
|
||||||
|
|
||||||
|
clean: clean-objdir
|
||||||
|
rm -rf $(PROJECT) lib$(PROJECT).a
|
||||||
@@ -1,7 +1,13 @@
|
|||||||
#include "simulator.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <util.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include "simulator.h"
|
||||||
|
|
||||||
|
using namespace vortex;
|
||||||
|
|
||||||
static void show_usage() {
|
static void show_usage() {
|
||||||
std::cout << "Usage: [-r] [-h: help] programs.." << std::endl;
|
std::cout << "Usage: [-r] [-h: help] programs.." << std::endl;
|
||||||
@@ -33,13 +39,6 @@ static void parse_args(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char* fileExtension(const char* filepath) {
|
|
||||||
const char *ext = strrchr(filepath, '.');
|
|
||||||
if (ext == NULL || ext == filepath)
|
|
||||||
return "";
|
|
||||||
return ext + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
int exitcode = 0;
|
int exitcode = 0;
|
||||||
@@ -50,15 +49,15 @@ int main(int argc, char **argv) {
|
|||||||
for (auto program : programs) {
|
for (auto program : programs) {
|
||||||
std::cout << "Running " << program << "..." << std::endl;
|
std::cout << "Running " << program << "..." << std::endl;
|
||||||
|
|
||||||
RAM ram;
|
vortex::RAM ram((1<<12), (1<<20));
|
||||||
Simulator simulator;
|
vortex::Simulator simulator;
|
||||||
simulator.attach_ram(&ram);
|
simulator.attach_ram(&ram);
|
||||||
|
|
||||||
std::string program_ext(fileExtension(program));
|
std::string program_ext(fileExtension(program));
|
||||||
if (program_ext == "bin") {
|
if (program_ext == "bin") {
|
||||||
simulator.load_bin(program);
|
ram.loadBinImage(program, STARTUP_ADDR);
|
||||||
} else if (program_ext == "hex") {
|
} else if (program_ext == "hex") {
|
||||||
simulator.load_ihex(program);
|
ram.loadHexImage(program);
|
||||||
} else {
|
} else {
|
||||||
std::cout << "*** error: only *.bin or *.hex images supported." << std::endl;
|
std::cout << "*** error: only *.bin or *.hex images supported." << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1,7 +1,23 @@
|
|||||||
#include "simulator.h"
|
#include "simulator.h"
|
||||||
|
|
||||||
|
#include <verilated.h>
|
||||||
|
|
||||||
|
#ifdef AXI_BUS
|
||||||
|
#include "VVortex_axi.h"
|
||||||
|
#include "VVortex_axi__Syms.h"
|
||||||
|
#else
|
||||||
|
#include "VVortex.h"
|
||||||
|
#include "VVortex__Syms.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VCD_OUTPUT
|
||||||
|
#include <verilated_vcd_c.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <mem.h>
|
||||||
|
|
||||||
#define ENABLE_MEM_STALLS
|
#define ENABLE_MEM_STALLS
|
||||||
|
|
||||||
@@ -32,6 +48,8 @@
|
|||||||
#define VL_WDATA_GETW(lwp, i, n, w) \
|
#define VL_WDATA_GETW(lwp, i, n, w) \
|
||||||
VL_SEL_IWII(0, n * w, 0, 0, lwp, i * w, w)
|
VL_SEL_IWII(0, n * w, 0, 0, lwp, i * w, w)
|
||||||
|
|
||||||
|
using namespace vortex;
|
||||||
|
|
||||||
static uint64_t timestamp = 0;
|
static uint64_t timestamp = 0;
|
||||||
|
|
||||||
double sc_time_stamp() {
|
double sc_time_stamp() {
|
||||||
@@ -57,7 +75,19 @@ void sim_trace_enable(bool enable) {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Simulator::Simulator() {
|
namespace vortex {
|
||||||
|
class VL_OBJ {
|
||||||
|
public:
|
||||||
|
#ifdef AXI_BUS
|
||||||
|
VVortex_axi *device;
|
||||||
|
#else
|
||||||
|
VVortex *device;
|
||||||
|
#endif
|
||||||
|
#ifdef VCD_OUTPUT
|
||||||
|
VerilatedVcdC *trace;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VL_OBJ() {
|
||||||
// force random values for unitialized signals
|
// force random values for unitialized signals
|
||||||
Verilated::randReset(VERILATOR_RESET_VALUE);
|
Verilated::randReset(VERILATOR_RESET_VALUE);
|
||||||
Verilated::randSeed(50);
|
Verilated::randSeed(50);
|
||||||
@@ -65,21 +95,35 @@ Simulator::Simulator() {
|
|||||||
// Turn off assertion before reset
|
// Turn off assertion before reset
|
||||||
Verilated::assertOn(false);
|
Verilated::assertOn(false);
|
||||||
|
|
||||||
ram_ = nullptr;
|
|
||||||
|
|
||||||
#ifdef AXI_BUS
|
#ifdef AXI_BUS
|
||||||
vortex_ = new VVortex_axi();
|
this->device = new VVortex_axi();
|
||||||
#else
|
#else
|
||||||
vortex_ = new VVortex();
|
this->device = new VVortex();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VCD_OUTPUT
|
#ifdef VCD_OUTPUT
|
||||||
Verilated::traceEverOn(true);
|
Verilated::traceEverOn(true);
|
||||||
trace_ = new VerilatedVcdC();
|
this->trace = new VerilatedVcdC();
|
||||||
vortex_->trace(trace_, 99);
|
this->device->trace(this->trace, 99);
|
||||||
trace_->open("trace.vcd");
|
this->trace->open("trace.vcd");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
~VL_OBJ() {
|
||||||
|
#ifdef VCD_OUTPUT
|
||||||
|
this->trace->close();
|
||||||
|
delete this->trace;
|
||||||
|
#endif
|
||||||
|
delete this->device;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Simulator::Simulator() {
|
||||||
|
vl_obj_ = new VL_OBJ();
|
||||||
|
ram_ = nullptr;
|
||||||
// reset the device
|
// reset the device
|
||||||
this->reset();
|
this->reset();
|
||||||
}
|
}
|
||||||
@@ -91,11 +135,7 @@ Simulator::~Simulator() {
|
|||||||
std::cout << "#" << buf.first << ": " << str << std::endl;
|
std::cout << "#" << buf.first << ": " << str << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef VCD_OUTPUT
|
delete vl_obj_;
|
||||||
trace_->close();
|
|
||||||
delete trace_;
|
|
||||||
#endif
|
|
||||||
delete vortex_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulator::attach_ram(RAM* ram) {
|
void Simulator::attach_ram(RAM* ram) {
|
||||||
@@ -122,16 +162,16 @@ void Simulator::reset() {
|
|||||||
this->reset_mem_bus();
|
this->reset_mem_bus();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vortex_->reset = 1;
|
vl_obj_->device->reset = 1;
|
||||||
|
|
||||||
for (int i = 0; i < RESET_DELAY; ++i) {
|
for (int i = 0; i < RESET_DELAY; ++i) {
|
||||||
vortex_->clk = 0;
|
vl_obj_->device->clk = 0;
|
||||||
this->eval();
|
this->eval();
|
||||||
vortex_->clk = 1;
|
vl_obj_->device->clk = 1;
|
||||||
this->eval();
|
this->eval();
|
||||||
}
|
}
|
||||||
|
|
||||||
vortex_->reset = 0;
|
vl_obj_->device->reset = 0;
|
||||||
|
|
||||||
// Turn on assertion after reset
|
// Turn on assertion after reset
|
||||||
Verilated::assertOn(true);
|
Verilated::assertOn(true);
|
||||||
@@ -139,7 +179,7 @@ void Simulator::reset() {
|
|||||||
|
|
||||||
void Simulator::step() {
|
void Simulator::step() {
|
||||||
|
|
||||||
vortex_->clk = 0;
|
vl_obj_->device->clk = 0;
|
||||||
this->eval();
|
this->eval();
|
||||||
|
|
||||||
#ifdef AXI_BUS
|
#ifdef AXI_BUS
|
||||||
@@ -148,7 +188,7 @@ void Simulator::step() {
|
|||||||
this->eval_mem_bus(0);
|
this->eval_mem_bus(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vortex_->clk = 1;
|
vl_obj_->device->clk = 1;
|
||||||
this->eval();
|
this->eval();
|
||||||
|
|
||||||
#ifdef AXI_BUS
|
#ifdef AXI_BUS
|
||||||
@@ -163,10 +203,10 @@ void Simulator::step() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Simulator::eval() {
|
void Simulator::eval() {
|
||||||
vortex_->eval();
|
vl_obj_->device->eval();
|
||||||
#ifdef VCD_OUTPUT
|
#ifdef VCD_OUTPUT
|
||||||
if (sim_trace_enabled()) {
|
if (sim_trace_enabled()) {
|
||||||
trace_->dump(timestamp);
|
vl_obj_->trace->dump(timestamp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
++timestamp;
|
++timestamp;
|
||||||
@@ -175,23 +215,23 @@ void Simulator::eval() {
|
|||||||
#ifdef AXI_BUS
|
#ifdef AXI_BUS
|
||||||
|
|
||||||
void Simulator::reset_axi_bus() {
|
void Simulator::reset_axi_bus() {
|
||||||
vortex_->m_axi_wready = 0;
|
vl_obj_->device->m_axi_wready = 0;
|
||||||
vortex_->m_axi_awready = 0;
|
vl_obj_->device->m_axi_awready = 0;
|
||||||
vortex_->m_axi_arready = 0;
|
vl_obj_->device->m_axi_arready = 0;
|
||||||
vortex_->m_axi_rvalid = 0;
|
vl_obj_->device->m_axi_rvalid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulator::eval_axi_bus(bool clk) {
|
void Simulator::eval_axi_bus(bool clk) {
|
||||||
if (!clk) {
|
if (!clk) {
|
||||||
mem_rd_rsp_ready_ = vortex_->m_axi_rready;
|
mem_rd_rsp_ready_ = vl_obj_->device->m_axi_rready;
|
||||||
mem_wr_rsp_ready_ = vortex_->m_axi_bready;
|
mem_wr_rsp_ready_ = vl_obj_->device->m_axi_bready;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ram_ == nullptr) {
|
if (ram_ == nullptr) {
|
||||||
vortex_->m_axi_wready = 0;
|
vl_obj_->device->m_axi_wready = 0;
|
||||||
vortex_->m_axi_awready = 0;
|
vl_obj_->device->m_axi_awready = 0;
|
||||||
vortex_->m_axi_arready = 0;
|
vl_obj_->device->m_axi_arready = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +262,7 @@ void Simulator::eval_axi_bus(bool clk) {
|
|||||||
|
|
||||||
// send memory read response
|
// send memory read response
|
||||||
if (mem_rd_rsp_active_
|
if (mem_rd_rsp_active_
|
||||||
&& vortex_->m_axi_rvalid && mem_rd_rsp_ready_) {
|
&& vl_obj_->device->m_axi_rvalid && mem_rd_rsp_ready_) {
|
||||||
mem_rd_rsp_active_ = false;
|
mem_rd_rsp_active_ = false;
|
||||||
}
|
}
|
||||||
if (!mem_rd_rsp_active_) {
|
if (!mem_rd_rsp_active_) {
|
||||||
@@ -235,21 +275,21 @@ void Simulator::eval_axi_bus(bool clk) {
|
|||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
*/
|
*/
|
||||||
vortex_->m_axi_rvalid = 1;
|
vl_obj_->device->m_axi_rvalid = 1;
|
||||||
vortex_->m_axi_rid = mem_rsp_it->tag;
|
vl_obj_->device->m_axi_rid = mem_rsp_it->tag;
|
||||||
vortex_->m_axi_rresp = 0;
|
vl_obj_->device->m_axi_rresp = 0;
|
||||||
vortex_->m_axi_rlast = 1;
|
vl_obj_->device->m_axi_rlast = 1;
|
||||||
memcpy((uint8_t*)vortex_->m_axi_rdata, mem_rsp_it->block.data(), MEM_BLOCK_SIZE);
|
memcpy((uint8_t*)vl_obj_->device->m_axi_rdata, mem_rsp_it->block.data(), MEM_BLOCK_SIZE);
|
||||||
mem_rsp_vec_[last_mem_rsp_bank_].erase(mem_rsp_it);
|
mem_rsp_vec_[last_mem_rsp_bank_].erase(mem_rsp_it);
|
||||||
mem_rd_rsp_active_ = true;
|
mem_rd_rsp_active_ = true;
|
||||||
} else {
|
} else {
|
||||||
vortex_->m_axi_rvalid = 0;
|
vl_obj_->device->m_axi_rvalid = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// send memory write response
|
// send memory write response
|
||||||
if (mem_wr_rsp_active_
|
if (mem_wr_rsp_active_
|
||||||
&& vortex_->m_axi_bvalid && mem_wr_rsp_ready_) {
|
&& vl_obj_->device->m_axi_bvalid && mem_wr_rsp_ready_) {
|
||||||
mem_wr_rsp_active_ = false;
|
mem_wr_rsp_active_ = false;
|
||||||
}
|
}
|
||||||
if (!mem_wr_rsp_active_) {
|
if (!mem_wr_rsp_active_) {
|
||||||
@@ -258,18 +298,18 @@ void Simulator::eval_axi_bus(bool clk) {
|
|||||||
/*
|
/*
|
||||||
printf("%0ld: [sim] MEM Wr Rsp: bank=%d, addr=%0lx\n", timestamp, last_mem_rsp_bank_, mem_rsp_it->addr);
|
printf("%0ld: [sim] MEM Wr Rsp: bank=%d, addr=%0lx\n", timestamp, last_mem_rsp_bank_, mem_rsp_it->addr);
|
||||||
*/
|
*/
|
||||||
vortex_->m_axi_bvalid = 1;
|
vl_obj_->device->m_axi_bvalid = 1;
|
||||||
vortex_->m_axi_bid = mem_rsp_it->tag;
|
vl_obj_->device->m_axi_bid = mem_rsp_it->tag;
|
||||||
vortex_->m_axi_bresp = 0;
|
vl_obj_->device->m_axi_bresp = 0;
|
||||||
mem_rsp_vec_[last_mem_rsp_bank_].erase(mem_rsp_it);
|
mem_rsp_vec_[last_mem_rsp_bank_].erase(mem_rsp_it);
|
||||||
mem_wr_rsp_active_ = true;
|
mem_wr_rsp_active_ = true;
|
||||||
} else {
|
} else {
|
||||||
vortex_->m_axi_bvalid = 0;
|
vl_obj_->device->m_axi_bvalid = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// select the memory bank
|
// select the memory bank
|
||||||
uint32_t req_addr = vortex_->m_axi_wvalid ? vortex_->m_axi_awaddr : vortex_->m_axi_araddr;
|
uint32_t req_addr = vl_obj_->device->m_axi_wvalid ? vl_obj_->device->m_axi_awaddr : vl_obj_->device->m_axi_araddr;
|
||||||
uint32_t req_bank = (MEMORY_BANKS >= 2) ? ((req_addr / MEM_BLOCK_SIZE) % MEMORY_BANKS) : 0;
|
uint32_t req_bank = (MEMORY_BANKS >= 2) ? ((req_addr / MEM_BLOCK_SIZE) % MEMORY_BANKS) : 0;
|
||||||
|
|
||||||
// handle memory stalls
|
// handle memory stalls
|
||||||
@@ -285,11 +325,11 @@ void Simulator::eval_axi_bus(bool clk) {
|
|||||||
|
|
||||||
// process memory requests
|
// process memory requests
|
||||||
if (!mem_stalled) {
|
if (!mem_stalled) {
|
||||||
if (vortex_->m_axi_wvalid || vortex_->m_axi_arvalid) {
|
if (vl_obj_->device->m_axi_wvalid || vl_obj_->device->m_axi_arvalid) {
|
||||||
if (vortex_->m_axi_wvalid) {
|
if (vl_obj_->device->m_axi_wvalid) {
|
||||||
uint64_t byteen = vortex_->m_axi_wstrb;
|
uint64_t byteen = vl_obj_->device->m_axi_wstrb;
|
||||||
unsigned base_addr = vortex_->m_axi_awaddr;
|
unsigned base_addr = vl_obj_->device->m_axi_awaddr;
|
||||||
uint8_t* data = (uint8_t*)(vortex_->m_axi_wdata);
|
uint8_t* data = (uint8_t*)(vl_obj_->device->m_axi_wdata);
|
||||||
|
|
||||||
// detect stdout write
|
// detect stdout write
|
||||||
if (base_addr >= IO_COUT_ADDR
|
if (base_addr >= IO_COUT_ADDR
|
||||||
@@ -319,17 +359,17 @@ void Simulator::eval_axi_bus(bool clk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mem_req_t mem_req;
|
mem_req_t mem_req;
|
||||||
mem_req.tag = vortex_->m_axi_arid;
|
mem_req.tag = vl_obj_->device->m_axi_arid;
|
||||||
mem_req.addr = vortex_->m_axi_araddr;
|
mem_req.addr = vl_obj_->device->m_axi_araddr;
|
||||||
mem_req.cycles_left = 0;
|
mem_req.cycles_left = 0;
|
||||||
mem_req.write = 1;
|
mem_req.write = 1;
|
||||||
mem_rsp_vec_[req_bank].emplace_back(mem_req);
|
mem_rsp_vec_[req_bank].emplace_back(mem_req);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mem_req_t mem_req;
|
mem_req_t mem_req;
|
||||||
mem_req.tag = vortex_->m_axi_arid;
|
mem_req.tag = vl_obj_->device->m_axi_arid;
|
||||||
mem_req.addr = vortex_->m_axi_araddr;
|
mem_req.addr = vl_obj_->device->m_axi_araddr;
|
||||||
ram_->read(vortex_->m_axi_araddr, MEM_BLOCK_SIZE, mem_req.block.data());
|
ram_->read(vl_obj_->device->m_axi_araddr, MEM_BLOCK_SIZE, mem_req.block.data());
|
||||||
mem_req.cycles_left = MEM_LATENCY;
|
mem_req.cycles_left = MEM_LATENCY;
|
||||||
mem_req.write = 0;
|
mem_req.write = 0;
|
||||||
for (auto& rsp : mem_rsp_vec_[req_bank]) {
|
for (auto& rsp : mem_rsp_vec_[req_bank]) {
|
||||||
@@ -344,26 +384,26 @@ void Simulator::eval_axi_bus(bool clk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vortex_->m_axi_wready = !mem_stalled;
|
vl_obj_->device->m_axi_wready = !mem_stalled;
|
||||||
vortex_->m_axi_awready = !mem_stalled;
|
vl_obj_->device->m_axi_awready = !mem_stalled;
|
||||||
vortex_->m_axi_arready = !mem_stalled;
|
vl_obj_->device->m_axi_arready = !mem_stalled;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void Simulator::reset_mem_bus() {
|
void Simulator::reset_mem_bus() {
|
||||||
vortex_->mem_req_ready = 0;
|
vl_obj_->device->mem_req_ready = 0;
|
||||||
vortex_->mem_rsp_valid = 0;
|
vl_obj_->device->mem_rsp_valid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulator::eval_mem_bus(bool clk) {
|
void Simulator::eval_mem_bus(bool clk) {
|
||||||
if (!clk) {
|
if (!clk) {
|
||||||
mem_rd_rsp_ready_ = vortex_->mem_rsp_ready;
|
mem_rd_rsp_ready_ = vl_obj_->device->mem_rsp_ready;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ram_ == nullptr) {
|
if (ram_ == nullptr) {
|
||||||
vortex_->mem_req_ready = 0;
|
vl_obj_->device->mem_req_ready = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,12 +430,12 @@ void Simulator::eval_mem_bus(bool clk) {
|
|||||||
|
|
||||||
// send memory response
|
// send memory response
|
||||||
if (mem_rd_rsp_active_
|
if (mem_rd_rsp_active_
|
||||||
&& vortex_->mem_rsp_valid && mem_rd_rsp_ready_) {
|
&& vl_obj_->device->mem_rsp_valid && mem_rd_rsp_ready_) {
|
||||||
mem_rd_rsp_active_ = false;
|
mem_rd_rsp_active_ = false;
|
||||||
}
|
}
|
||||||
if (!mem_rd_rsp_active_) {
|
if (!mem_rd_rsp_active_) {
|
||||||
if (has_response) {
|
if (has_response) {
|
||||||
vortex_->mem_rsp_valid = 1;
|
vl_obj_->device->mem_rsp_valid = 1;
|
||||||
auto mem_rsp_it = mem_rsp_vec_[last_mem_rsp_bank_].begin();
|
auto mem_rsp_it = mem_rsp_vec_[last_mem_rsp_bank_].begin();
|
||||||
/*
|
/*
|
||||||
printf("%0ld: [sim] MEM Rd: bank=%d, addr=%0lx, data=", timestamp, last_mem_rsp_bank_, mem_rsp_it->addr);
|
printf("%0ld: [sim] MEM Rd: bank=%d, addr=%0lx, data=", timestamp, last_mem_rsp_bank_, mem_rsp_it->addr);
|
||||||
@@ -404,17 +444,17 @@ void Simulator::eval_mem_bus(bool clk) {
|
|||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
*/
|
*/
|
||||||
memcpy((uint8_t*)vortex_->mem_rsp_data, mem_rsp_it->block.data(), MEM_BLOCK_SIZE);
|
memcpy((uint8_t*)vl_obj_->device->mem_rsp_data, mem_rsp_it->block.data(), MEM_BLOCK_SIZE);
|
||||||
vortex_->mem_rsp_tag = mem_rsp_it->tag;
|
vl_obj_->device->mem_rsp_tag = mem_rsp_it->tag;
|
||||||
mem_rsp_vec_[last_mem_rsp_bank_].erase(mem_rsp_it);
|
mem_rsp_vec_[last_mem_rsp_bank_].erase(mem_rsp_it);
|
||||||
mem_rd_rsp_active_ = true;
|
mem_rd_rsp_active_ = true;
|
||||||
} else {
|
} else {
|
||||||
vortex_->mem_rsp_valid = 0;
|
vl_obj_->device->mem_rsp_valid = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// select the memory bank
|
// select the memory bank
|
||||||
uint32_t req_bank = (MEMORY_BANKS >= 2) ? (vortex_->mem_req_addr % MEMORY_BANKS) : 0;
|
uint32_t req_bank = (MEMORY_BANKS >= 2) ? (vl_obj_->device->mem_req_addr % MEMORY_BANKS) : 0;
|
||||||
|
|
||||||
// handle memory stalls
|
// handle memory stalls
|
||||||
bool mem_stalled = false;
|
bool mem_stalled = false;
|
||||||
@@ -429,11 +469,11 @@ void Simulator::eval_mem_bus(bool clk) {
|
|||||||
|
|
||||||
// process memory requests
|
// process memory requests
|
||||||
if (!mem_stalled) {
|
if (!mem_stalled) {
|
||||||
if (vortex_->mem_req_valid) {
|
if (vl_obj_->device->mem_req_valid) {
|
||||||
if (vortex_->mem_req_rw) {
|
if (vl_obj_->device->mem_req_rw) {
|
||||||
uint64_t byteen = vortex_->mem_req_byteen;
|
uint64_t byteen = vl_obj_->device->mem_req_byteen;
|
||||||
unsigned base_addr = (vortex_->mem_req_addr * MEM_BLOCK_SIZE);
|
unsigned base_addr = (vl_obj_->device->mem_req_addr * MEM_BLOCK_SIZE);
|
||||||
uint8_t* data = (uint8_t*)(vortex_->mem_req_data);
|
uint8_t* data = (uint8_t*)(vl_obj_->device->mem_req_data);
|
||||||
if (base_addr >= IO_COUT_ADDR
|
if (base_addr >= IO_COUT_ADDR
|
||||||
&& base_addr <= (IO_COUT_ADDR + IO_COUT_SIZE - 1)) {
|
&& base_addr <= (IO_COUT_ADDR + IO_COUT_SIZE - 1)) {
|
||||||
for (int i = 0; i < MEM_BLOCK_SIZE; i++) {
|
for (int i = 0; i < MEM_BLOCK_SIZE; i++) {
|
||||||
@@ -463,9 +503,9 @@ void Simulator::eval_mem_bus(bool clk) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mem_req_t mem_req;
|
mem_req_t mem_req;
|
||||||
mem_req.tag = vortex_->mem_req_tag;
|
mem_req.tag = vl_obj_->device->mem_req_tag;
|
||||||
mem_req.addr = (vortex_->mem_req_addr * MEM_BLOCK_SIZE);
|
mem_req.addr = (vl_obj_->device->mem_req_addr * MEM_BLOCK_SIZE);
|
||||||
ram_->read(vortex_->mem_req_addr * MEM_BLOCK_SIZE, MEM_BLOCK_SIZE, mem_req.block.data());
|
ram_->read(mem_req.block.data(), vl_obj_->device->mem_req_addr * MEM_BLOCK_SIZE, MEM_BLOCK_SIZE);
|
||||||
mem_req.cycles_left = MEM_LATENCY;
|
mem_req.cycles_left = MEM_LATENCY;
|
||||||
for (auto& rsp : mem_rsp_vec_[req_bank]) {
|
for (auto& rsp : mem_rsp_vec_[req_bank]) {
|
||||||
if (mem_req.addr == rsp.addr) {
|
if (mem_req.addr == rsp.addr) {
|
||||||
@@ -479,7 +519,7 @@ void Simulator::eval_mem_bus(bool clk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vortex_->mem_req_ready = !mem_stalled;
|
vl_obj_->device->mem_req_ready = !mem_stalled;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -491,7 +531,7 @@ void Simulator::wait(uint32_t cycles) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Simulator::is_busy() const {
|
bool Simulator::is_busy() const {
|
||||||
return vortex_->busy;
|
return vl_obj_->device->busy;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Simulator::run() {
|
int Simulator::run() {
|
||||||
@@ -502,7 +542,7 @@ int Simulator::run() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// execute program
|
// execute program
|
||||||
while (vortex_->busy) {
|
while (vl_obj_->device->busy) {
|
||||||
if (get_ebreak()) {
|
if (get_ebreak()) {
|
||||||
exitcode = get_last_wb_value(3);
|
exitcode = get_last_wb_value(3);
|
||||||
break;
|
break;
|
||||||
@@ -518,104 +558,20 @@ int Simulator::run() {
|
|||||||
|
|
||||||
bool Simulator::get_ebreak() const {
|
bool Simulator::get_ebreak() const {
|
||||||
#ifdef AXI_BUS
|
#ifdef AXI_BUS
|
||||||
return (int)vortex_->Vortex_axi->vortex->genblk2__BRA__0__KET____DOT__cluster->genblk2__BRA__0__KET____DOT__core->pipeline->execute->ebreak;
|
return (int)vl_obj_->device->Vortex_axi->vortex->genblk2__BRA__0__KET____DOT__cluster->genblk2__BRA__0__KET____DOT__core->pipeline->execute->ebreak;
|
||||||
#else
|
#else
|
||||||
return (int)vortex_->Vortex->genblk2__BRA__0__KET____DOT__cluster->genblk2__BRA__0__KET____DOT__core->pipeline->execute->ebreak;
|
return (int)vl_obj_->device->Vortex->genblk2__BRA__0__KET____DOT__cluster->genblk2__BRA__0__KET____DOT__core->pipeline->execute->ebreak;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int Simulator::get_last_wb_value(int reg) const {
|
int Simulator::get_last_wb_value(int reg) const {
|
||||||
#ifdef AXI_BUS
|
#ifdef AXI_BUS
|
||||||
return (int)vortex_->Vortex_axi->vortex->genblk2__BRA__0__KET____DOT__cluster->genblk2__BRA__0__KET____DOT__core->pipeline->commit->writeback->last_wb_value[reg];
|
return (int)vl_obj_->device->Vortex_axi->vortex->genblk2__BRA__0__KET____DOT__cluster->genblk2__BRA__0__KET____DOT__core->pipeline->commit->writeback->last_wb_value[reg];
|
||||||
#else
|
#else
|
||||||
return (int)vortex_->Vortex->genblk2__BRA__0__KET____DOT__cluster->genblk2__BRA__0__KET____DOT__core->pipeline->commit->writeback->last_wb_value[reg];
|
return (int)vl_obj_->device->Vortex->genblk2__BRA__0__KET____DOT__cluster->genblk2__BRA__0__KET____DOT__core->pipeline->commit->writeback->last_wb_value[reg];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulator::load_bin(const char* program_file) {
|
|
||||||
if (ram_ == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::ifstream ifs(program_file);
|
|
||||||
if (!ifs) {
|
|
||||||
std::cout << "error: " << program_file << " not found" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
ifs.seekg(0, ifs.end);
|
|
||||||
auto size = ifs.tellg();
|
|
||||||
std::vector<uint8_t> content(size);
|
|
||||||
ifs.seekg(0, ifs.beg);
|
|
||||||
ifs.read((char*)content.data(), size);
|
|
||||||
|
|
||||||
ram_->write(STARTUP_ADDR, size, content.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Simulator::load_ihex(const char* program_file) {
|
|
||||||
if (ram_ == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto hti = [&](char c)->uint32_t {
|
|
||||||
if (c >= 'A' && c <= 'F')
|
|
||||||
return c - 'A' + 10;
|
|
||||||
if (c >= 'a' && c <= 'f')
|
|
||||||
return c - 'a' + 10;
|
|
||||||
return c - '0';
|
|
||||||
};
|
|
||||||
|
|
||||||
auto hToI = [&](const char *c, uint32_t size)->uint32_t {
|
|
||||||
uint32_t value = 0;
|
|
||||||
for (uint32_t i = 0; i < size; i++) {
|
|
||||||
value += hti(c[i]) << ((size - i - 1) * 4);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ifstream ifs(program_file);
|
|
||||||
if (!ifs) {
|
|
||||||
std::cout << "error: " << program_file << " not found" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
ifs.seekg(0, ifs.end);
|
|
||||||
uint32_t size = ifs.tellg();
|
|
||||||
std::vector<char> content(size);
|
|
||||||
ifs.seekg(0, ifs.beg);
|
|
||||||
ifs.read(content.data(), size);
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
char *line = content.data();
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (line[0] == ':') {
|
|
||||||
uint32_t byteCount = hToI(line + 1, 2);
|
|
||||||
uint32_t nextAddr = hToI(line + 3, 4) + offset;
|
|
||||||
uint32_t key = hToI(line + 7, 2);
|
|
||||||
switch (key) {
|
|
||||||
case 0:
|
|
||||||
for (uint32_t i = 0; i < byteCount; i++) {
|
|
||||||
(*ram_)[nextAddr + i] = hToI(line + 9 + i * 2, 2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
offset = hToI(line + 9, 4) << 4;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
offset = hToI(line + 9, 4) << 16;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (*line != '\n' && size != 0) {
|
|
||||||
++line;
|
|
||||||
--size;
|
|
||||||
}
|
|
||||||
if (size <= 1)
|
|
||||||
break;
|
|
||||||
++line;
|
|
||||||
--size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Simulator::print_stats(std::ostream& out) {
|
void Simulator::print_stats(std::ostream& out) {
|
||||||
out << std::left;
|
out << std::left;
|
||||||
out << std::setw(24) << "# of total cycles:" << std::dec << timestamp/2 << std::endl;
|
out << std::setw(24) << "# of total cycles:" << std::dec << timestamp/2 << std::endl;
|
||||||
@@ -1,22 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <verilated.h>
|
|
||||||
|
|
||||||
#ifdef AXI_BUS
|
|
||||||
#include "VVortex_axi.h"
|
|
||||||
#include "VVortex_axi__Syms.h"
|
|
||||||
#else
|
|
||||||
#include "VVortex.h"
|
|
||||||
#include "VVortex__Syms.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VCD_OUTPUT
|
|
||||||
#include <verilated_vcd_c.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <VX_config.h>
|
#include <VX_config.h>
|
||||||
#include "ram.h"
|
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -31,6 +15,11 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace vortex {
|
||||||
|
|
||||||
|
class VL_OBJ;
|
||||||
|
class RAM;
|
||||||
|
|
||||||
class Simulator {
|
class Simulator {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -39,9 +28,6 @@ public:
|
|||||||
|
|
||||||
void attach_ram(RAM* ram);
|
void attach_ram(RAM* ram);
|
||||||
|
|
||||||
void load_bin(const char* program_file);
|
|
||||||
void load_ihex(const char* program_file);
|
|
||||||
|
|
||||||
bool is_busy() const;
|
bool is_busy() const;
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
@@ -89,13 +75,7 @@ private:
|
|||||||
|
|
||||||
RAM *ram_;
|
RAM *ram_;
|
||||||
|
|
||||||
#ifdef AXI_BUS
|
VL_OBJ* vl_obj_;
|
||||||
VVortex_axi *vortex_;
|
|
||||||
#else
|
|
||||||
VVortex *vortex_;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VCD_OUTPUT
|
|
||||||
VerilatedVcdC *trace_;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,4 +7,4 @@ lint_off -rule UNUSED -file "../../hw/rtl/fp_cores/fpnew/*"
|
|||||||
lint_off -rule LITENDIAN -file "../../hw/rtl/fp_cores/fpnew/*"
|
lint_off -rule LITENDIAN -file "../../hw/rtl/fp_cores/fpnew/*"
|
||||||
lint_off -rule IMPORTSTAR -file "../../hw/rtl/fp_cores/fpnew/*"
|
lint_off -rule IMPORTSTAR -file "../../hw/rtl/fp_cores/fpnew/*"
|
||||||
lint_off -rule PINCONNECTEMPTY -file "../../hw/rtl/fp_cores/fpnew/*"
|
lint_off -rule PINCONNECTEMPTY -file "../../hw/rtl/fp_cores/fpnew/*"
|
||||||
lint_off -file "../rtl/fp_cores/fpnew/*"
|
lint_off -file "../../hw/rtl/fp_cores/fpnew/*"
|
||||||
49
sim/simX/Makefile
Normal file
49
sim/simX/Makefile
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
||||||
|
CXXFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors
|
||||||
|
|
||||||
|
CXXFLAGS += -fPIC -Wno-maybe-uninitialized
|
||||||
|
CXXFLAGS += -I. -I../common -I../../hw
|
||||||
|
CXXFLAGS += -DDUMP_PERF_STATS
|
||||||
|
|
||||||
|
TOP = vx_cache_sim
|
||||||
|
|
||||||
|
RTL_DIR = ../hw/rtl
|
||||||
|
|
||||||
|
PROJECT = simX
|
||||||
|
|
||||||
|
SRCS = ../common/util.cpp ../common/mem.cpp
|
||||||
|
SRCS += args.cpp pipeline.cpp warp.cpp core.cpp decode.cpp execute.cpp main.cpp
|
||||||
|
|
||||||
|
OBJS := $(patsubst %.cpp, obj_dir/%.o, $(notdir $(SRCS)))
|
||||||
|
VPATH := $(sort $(dir $(SRCS)))
|
||||||
|
|
||||||
|
#$(info OBJS is $(OBJS))
|
||||||
|
#$(info VPATH is $(VPATH))
|
||||||
|
|
||||||
|
# Debugigng
|
||||||
|
ifdef DEBUG
|
||||||
|
CXXFLAGS += -DDEBUG_LEVEL=$(DEBUG)
|
||||||
|
else
|
||||||
|
CXXFLAGS += -DNDEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: $(PROJECT)
|
||||||
|
|
||||||
|
$(PROJECT): $(SRCS)
|
||||||
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
obj_dir/%.o: %.cpp
|
||||||
|
mkdir -p obj_dir
|
||||||
|
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
static: $(OBJS)
|
||||||
|
$(AR) rs lib$(PROJECT).a $(OBJS)
|
||||||
|
|
||||||
|
.depend: $(SRCS)
|
||||||
|
$(CXX) $(CXXFLAGS) -MM $^ > .depend;
|
||||||
|
|
||||||
|
clean-objdir:
|
||||||
|
rm -rf obj_dir .depend
|
||||||
|
|
||||||
|
clean: clean-objdir
|
||||||
|
rm -rf $(PROJECT) lib$(PROJECT).a
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "util.h"
|
#include <util.h>
|
||||||
|
|
||||||
namespace vortex {
|
namespace vortex {
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <util.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "util.h"
|
|
||||||
#include "archdef.h"
|
#include "archdef.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
@@ -323,7 +323,7 @@ void Core::barrier(int bar_id, int count, int warp_id) {
|
|||||||
|
|
||||||
Word Core::icache_fetch(Addr addr) {
|
Word Core::icache_fetch(Addr addr) {
|
||||||
Word data;
|
Word data;
|
||||||
mem_.read(addr, &data, sizeof(Word), 0);
|
mem_.read(&data, addr, sizeof(Word), 0);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,11 +333,11 @@ Word Core::dcache_read(Addr addr, Size size) {
|
|||||||
#ifdef SM_ENABLE
|
#ifdef SM_ENABLE
|
||||||
if ((addr >= (SMEM_BASE_ADDR - SMEM_SIZE))
|
if ((addr >= (SMEM_BASE_ADDR - SMEM_SIZE))
|
||||||
&& ((addr + 3) < SMEM_BASE_ADDR)) {
|
&& ((addr + 3) < SMEM_BASE_ADDR)) {
|
||||||
shared_mem_.read(addr & (SMEM_SIZE-1), &data, size);
|
shared_mem_.read(&data, addr & (SMEM_SIZE-1), size);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
mem_.read(addr, &data, size, 0);
|
mem_.read(&data, addr, size, 0);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ void Core::dcache_write(Addr addr, Word data, Size size) {
|
|||||||
#ifdef SM_ENABLE
|
#ifdef SM_ENABLE
|
||||||
if ((addr >= (SMEM_BASE_ADDR - SMEM_SIZE))
|
if ((addr >= (SMEM_BASE_ADDR - SMEM_SIZE))
|
||||||
&& ((addr + 3) < SMEM_BASE_ADDR)) {
|
&& ((addr + 3) < SMEM_BASE_ADDR)) {
|
||||||
shared_mem_.write(addr & (SMEM_SIZE-1), &data, size);
|
shared_mem_.write(&data, addr & (SMEM_SIZE-1), size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -355,7 +355,7 @@ void Core::dcache_write(Addr addr, Word data, Size size) {
|
|||||||
this->writeToStdOut(addr, data);
|
this->writeToStdOut(addr, data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mem_.write(addr, &data, size, 0);
|
mem_.write(&data, addr, size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Core::running() const {
|
bool Core::running() const {
|
||||||
@@ -5,9 +5,9 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <util.h>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "util.h"
|
|
||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
#include "archdef.h"
|
#include "archdef.h"
|
||||||
#include "instr.h"
|
#include "instr.h"
|
||||||
@@ -280,7 +280,7 @@ Decoder::Decoder(const ArchDef &arch) {
|
|||||||
v_imm_mask_ = 0x7ff;
|
v_imm_mask_ = 0x7ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Instr> Decoder::decode(Word code) {
|
std::shared_ptr<Instr> Decoder::decode(Word code, Word PC) {
|
||||||
auto instr = std::make_shared<Instr>();
|
auto instr = std::make_shared<Instr>();
|
||||||
Opcode op = (Opcode)((code >> shift_opcode_) & opcode_mask_);
|
Opcode op = (Opcode)((code >> shift_opcode_) & opcode_mask_);
|
||||||
instr->setOpcode(op);
|
instr->setOpcode(op);
|
||||||
@@ -296,7 +296,7 @@ std::shared_ptr<Instr> Decoder::decode(Word code) {
|
|||||||
|
|
||||||
auto op_it = sc_instTable.find(op);
|
auto op_it = sc_instTable.find(op);
|
||||||
if (op_it == sc_instTable.end()) {
|
if (op_it == sc_instTable.end()) {
|
||||||
std::cout << std::hex << "invalid opcode: 0x" << op << ", instruction=0x" << code << std::endl;
|
std::cout << std::hex << "invalid opcode: 0x" << op << ", instruction=0x" << code << ", PC=" << PC << std::endl;
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ class Decoder {
|
|||||||
public:
|
public:
|
||||||
Decoder(const ArchDef &);
|
Decoder(const ArchDef &);
|
||||||
|
|
||||||
std::shared_ptr<Instr> decode(Word code);
|
std::shared_ptr<Instr> decode(Word code, Word PC);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <cfenv>
|
#include <cfenv>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "util.h"
|
#include <util.h>
|
||||||
#include "warp.h"
|
#include "warp.h"
|
||||||
#include "instr.h"
|
#include "instr.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
@@ -535,8 +535,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
else
|
else
|
||||||
rddata = rsdata[0];
|
rddata = rsdata[0];
|
||||||
} else {
|
} else {
|
||||||
float fpsrc_0 = intregToFloat(rsdata[0]);
|
float fpsrc_0 = *(float*)&rsdata[0];
|
||||||
float fpsrc_1 = intregToFloat(rsdata[1]);
|
float fpsrc_1 = *(float*)&rsdata[1];
|
||||||
float fpDest;
|
float fpDest;
|
||||||
|
|
||||||
feclearexcept(FE_ALL_EXCEPT);
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
@@ -618,8 +618,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
rddata = (sr1IsZero==2) ? rsdata[0] : rsdata[1];
|
rddata = (sr1IsZero==2) ? rsdata[0] : rsdata[1];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
float rs1 = intregToFloat(rsdata[0]);
|
float rs1 = *(float*)&rsdata[0];
|
||||||
float rs2 = intregToFloat(rsdata[1]);
|
float rs2 = *(float*)&rsdata[1];
|
||||||
if (func3) {
|
if (func3) {
|
||||||
// FMAX.S
|
// FMAX.S
|
||||||
float fmax = std::max(rs1, rs2);
|
float fmax = std::max(rs1, rs2);
|
||||||
@@ -635,7 +635,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
|
|
||||||
// FCVT.W.S FCVT.WU.S
|
// FCVT.W.S FCVT.WU.S
|
||||||
case 0x60: {
|
case 0x60: {
|
||||||
float fpSrc = intregToFloat(rsdata[0]);
|
float fpSrc = *(float*)&rsdata[0];
|
||||||
Word result;
|
Word result;
|
||||||
bool outOfRange = false;
|
bool outOfRange = false;
|
||||||
if (rsrc1 == 0) {
|
if (rsrc1 == 0) {
|
||||||
@@ -741,15 +741,15 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
switch(func3) {
|
switch(func3) {
|
||||||
case 0: {
|
case 0: {
|
||||||
// FLE.S
|
// FLE.S
|
||||||
rddata = (intregToFloat(rsdata[0]) <= intregToFloat(rsdata[1]));
|
rddata = (*(float*)&rsdata[0] <= *(float*)&rsdata[1]);
|
||||||
} break;
|
} break;
|
||||||
case 1: {
|
case 1: {
|
||||||
// FLT.S
|
// FLT.S
|
||||||
rddata = (intregToFloat(rsdata[0]) < intregToFloat(rsdata[1]));
|
rddata = (*(float*)&rsdata[0] < *(float*)&rsdata[1]);
|
||||||
} break;
|
} break;
|
||||||
case 2: {
|
case 2: {
|
||||||
// FEQ.S
|
// FEQ.S
|
||||||
rddata = (intregToFloat(rsdata[0]) == intregToFloat(rsdata[1]));
|
rddata = (*(float*)&rsdata[0] == *(float*)&rsdata[1]);
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
@@ -800,9 +800,9 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
}
|
}
|
||||||
rddata = 0x7fc00000; // canonical(quiet) NaN
|
rddata = 0x7fc00000; // canonical(quiet) NaN
|
||||||
} else {
|
} else {
|
||||||
float rs1 = intregToFloat(rsdata[0]);
|
float rs1 = *(float*)&rsdata[0];
|
||||||
float rs2 = intregToFloat(rsdata[1]);
|
float rs2 = *(float*)&rsdata[1];
|
||||||
float rs3 = intregToFloat(rsdata[2]);
|
float rs3 = *(float*)&rsdata[2];
|
||||||
float fpDest(0.0);
|
float fpDest(0.0);
|
||||||
feclearexcept(FE_ALL_EXCEPT);
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
@@ -57,7 +57,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
std::string program_ext(fileExtension(imgFileName.c_str()));
|
std::string program_ext(fileExtension(imgFileName.c_str()));
|
||||||
if (program_ext == "bin") {
|
if (program_ext == "bin") {
|
||||||
ram.loadBinImage(imgFileName.c_str());
|
ram.loadBinImage(imgFileName.c_str(), STARTUP_ADDR);
|
||||||
} else if (program_ext == "hex") {
|
} else if (program_ext == "hex") {
|
||||||
ram.loadHexImage(imgFileName.c_str());
|
ram.loadHexImage(imgFileName.c_str());
|
||||||
} else {
|
} else {
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <util.h>
|
||||||
|
#include "types.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
namespace vortex {
|
namespace vortex {
|
||||||
|
|
||||||
@@ -19,13 +19,4 @@ typedef std::bitset<32> ThreadMask;
|
|||||||
|
|
||||||
typedef std::bitset<32> WarpMask;
|
typedef std::bitset<32> WarpMask;
|
||||||
|
|
||||||
enum MemFlags {
|
|
||||||
RD_USR = 1,
|
|
||||||
WR_USR = 2,
|
|
||||||
EX_USR = 4,
|
|
||||||
RD_SUP = 8,
|
|
||||||
WR_SUP = 16,
|
|
||||||
EX_SUP = 32
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <util.h>
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
#include "instr.h"
|
#include "instr.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
CFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
||||||
#CFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors
|
#CXXFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors
|
||||||
|
|
||||||
CFLAGS += -DUSE_VLSIM -fPIC -Wno-maybe-uninitialized
|
CXXFLAGS += -fPIC -Wno-maybe-uninitialized
|
||||||
CFLAGS += -I../../../../hw
|
CXXFLAGS += -I. -I../../../hw -I../../common
|
||||||
|
CXXFLAGS += -I$(VERILATOR_ROOT)/include -I$(VERILATOR_ROOT)/include/vltstd
|
||||||
|
|
||||||
# control RTL debug print states
|
# control RTL debug print states
|
||||||
DBG_PRINT_FLAGS += -DDBG_PRINT_PIPELINE
|
DBG_PRINT_FLAGS += -DDBG_PRINT_PIPELINE
|
||||||
@@ -22,29 +23,31 @@ DBG_FLAGS += -DDBG_CACHE_REQ_INFO
|
|||||||
|
|
||||||
CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=1
|
CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=1
|
||||||
|
|
||||||
CFLAGS += $(CONFIGS)
|
CXXFLAGS += $(CONFIGS)
|
||||||
CFLAGS += -DDUMP_PERF_STATS
|
CXXFLAGS += -DDUMP_PERF_STATS
|
||||||
|
|
||||||
LDFLAGS += -shared -pthread
|
LDFLAGS += -shared
|
||||||
# LDFLAGS += -dynamiclib -pthread
|
|
||||||
|
|
||||||
TOP = vortex_afu_shim
|
RTL_DIR = ../../hw/rtl
|
||||||
|
DPI_DIR = ../../hw/dpi
|
||||||
|
|
||||||
RTL_DIR=../../../hw/rtl
|
SRCS = ../common/util.cpp ../common/mem.cpp
|
||||||
DPI_DIR=../../../hw/dpi
|
|
||||||
|
|
||||||
SRCS = fpga.cpp opae_sim.cpp
|
|
||||||
SRCS += $(DPI_DIR)/util_dpi.cpp $(DPI_DIR)/float_dpi.cpp
|
SRCS += $(DPI_DIR)/util_dpi.cpp $(DPI_DIR)/float_dpi.cpp
|
||||||
|
SRCS += fpga.cpp opae_sim.cpp
|
||||||
|
|
||||||
FPU_INCLUDE = -I$(RTL_DIR)/fp_cores -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src -I$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(RTL_DIR)/fp_cores/fpnew/src
|
FPU_INCLUDE = -I$(RTL_DIR)/fp_cores -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/include -I$(RTL_DIR)/fp_cores/fpnew/src/common_cells/src -I$(RTL_DIR)/fp_cores/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(RTL_DIR)/fp_cores/fpnew/src
|
||||||
RTL_INCLUDE = -I$(RTL_DIR) -I$(DPI_DIR) -I$(RTL_DIR)/libs -I$(RTL_DIR)/interfaces -I$(RTL_DIR)/cache $(FPU_INCLUDE)
|
RTL_INCLUDE = -I$(RTL_DIR) -I$(DPI_DIR) -I$(RTL_DIR)/libs -I$(RTL_DIR)/interfaces -I$(RTL_DIR)/cache $(FPU_INCLUDE)
|
||||||
RTL_INCLUDE += -I$(RTL_DIR)/afu -I$(RTL_DIR)/afu/ccip
|
RTL_INCLUDE += -I$(RTL_DIR)/afu -I$(RTL_DIR)/afu/ccip
|
||||||
|
|
||||||
|
TOP = vortex_afu_shim
|
||||||
|
|
||||||
|
VL_FLAGS = --cc $(TOP) --top-module $(TOP)
|
||||||
VL_FLAGS += -O2 --language 1800-2009 --assert -Wall -Wpedantic
|
VL_FLAGS += -O2 --language 1800-2009 --assert -Wall -Wpedantic
|
||||||
VL_FLAGS += -Wno-DECLFILENAME -Wno-REDEFMACRO
|
VL_FLAGS += -Wno-DECLFILENAME -Wno-REDEFMACRO
|
||||||
VL_FLAGS += --x-initial unique --x-assign unique
|
VL_FLAGS += --x-initial unique --x-assign unique
|
||||||
VL_FLAGS += verilator.vlt
|
VL_FLAGS += verilator.vlt
|
||||||
VL_FLAGS += $(CONFIGS)
|
VL_FLAGS += $(CONFIGS)
|
||||||
|
VL_FLAGS += $(RTL_INCLUDE)
|
||||||
|
|
||||||
# Enable Verilator multithreaded simulation
|
# Enable Verilator multithreaded simulation
|
||||||
#THREADS ?= $(shell python3 -c 'import multiprocessing as mp; print(max(1, mp.cpu_count() // 2))')
|
#THREADS ?= $(shell python3 -c 'import multiprocessing as mp; print(max(1, mp.cpu_count() // 2))')
|
||||||
@@ -53,27 +56,27 @@ VL_FLAGS += $(CONFIGS)
|
|||||||
# Debugigng
|
# Debugigng
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
VL_FLAGS += -DVCD_OUTPUT --trace --trace-structs $(DBG_FLAGS)
|
VL_FLAGS += -DVCD_OUTPUT --trace --trace-structs $(DBG_FLAGS)
|
||||||
CFLAGS += -DVCD_OUTPUT $(DBG_FLAGS)
|
CXXFLAGS += -DVCD_OUTPUT $(DBG_FLAGS)
|
||||||
else
|
else
|
||||||
VL_FLAGS += -DNDEBUG
|
VL_FLAGS += -DNDEBUG
|
||||||
CFLAGS += -DNDEBUG
|
CXXFLAGS += -DNDEBUG
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Enable scope analyzer
|
# Enable scope analyzer
|
||||||
ifdef SCOPE
|
ifdef SCOPE
|
||||||
VL_FLAGS += -DSCOPE
|
VL_FLAGS += -DSCOPE
|
||||||
CFLAGS += -DSCOPE
|
CXXFLAGS += -DSCOPE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Enable perf counters
|
# Enable perf counters
|
||||||
ifdef PERF
|
ifdef PERF
|
||||||
VL_FLAGS += -DPERF_ENABLE
|
VL_FLAGS += -DPERF_ENABLE
|
||||||
CFLAGS += -DPERF_ENABLE
|
CXXFLAGS += -DPERF_ENABLE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# use our OPAE shim
|
# use our OPAE shim
|
||||||
VL_FLAGS += -DNOPAE
|
VL_FLAGS += -DNOPAE
|
||||||
CFLAGS += -DNOPAE
|
CXXFLAGS += -DNOPAE
|
||||||
|
|
||||||
# ALU backend
|
# ALU backend
|
||||||
VL_FLAGS += -DIMUL_DPI
|
VL_FLAGS += -DIMUL_DPI
|
||||||
@@ -83,16 +86,31 @@ VL_FLAGS += -DIDIV_DPI
|
|||||||
FPU_CORE ?= FPU_DPI
|
FPU_CORE ?= FPU_DPI
|
||||||
VL_FLAGS += -D$(FPU_CORE)
|
VL_FLAGS += -D$(FPU_CORE)
|
||||||
|
|
||||||
PROJECT = libopae-c-vlsim.so
|
OBJS := $(patsubst %.cpp, obj_dir/%.o, $(notdir $(SRCS)))
|
||||||
|
VPATH := $(sort $(dir $(SRCS)))
|
||||||
|
|
||||||
all: $(PROJECT)
|
#$(info OBJS is $(OBJS))
|
||||||
|
#$(info VPATH is $(VPATH))
|
||||||
|
|
||||||
vortex_afu.h : $(RTL_DIR)/afu/vortex_afu.vh
|
PROJECT = libopae-c-vlsim
|
||||||
../../../hw/scripts/gen_config.py -i $(RTL_DIR)/afu/vortex_afu.vh -o vortex_afu.h
|
|
||||||
|
|
||||||
$(PROJECT): $(SRCS) vortex_afu.h
|
all: shared
|
||||||
verilator --exe --cc $(TOP) --top-module $(TOP) $(RTL_INCLUDE) $(VL_FLAGS) $(SRCS) -CFLAGS '$(CFLAGS)' -LDFLAGS '$(LDFLAGS)' -o ../$(PROJECT)
|
|
||||||
make -j -C obj_dir -f V$(TOP).mk
|
|
||||||
|
|
||||||
clean:
|
shared: $(SRCS)
|
||||||
rm -rf $(PROJECT) obj_dir ../scope-defs.h $(RTL_DIR)/scope-defs.vh vortex_afu.h
|
verilator --build --exe $(VL_FLAGS) $(SRCS) -CFLAGS '$(CXXFLAGS)' -LDFLAGS '$(LDFLAGS)' -o ../$(PROJECT).so
|
||||||
|
|
||||||
|
obj_dir/V$(TOP)__ALL.a:
|
||||||
|
verilator --build $(VL_FLAGS) -CFLAGS '$(CXXFLAGS)'
|
||||||
|
|
||||||
|
obj_dir/%.o: %.cpp
|
||||||
|
cd obj_dir && $(CXX) $(CXXFLAGS) -c ../$< -o $(notdir $@)
|
||||||
|
|
||||||
|
static: obj_dir/V$(TOP)__ALL.a $(OBJS)
|
||||||
|
cp obj_dir/V$(TOP)__ALL.a $(PROJECT).a
|
||||||
|
$(AR) rs $(PROJECT).a $(OBJS)
|
||||||
|
|
||||||
|
clean-objdir:
|
||||||
|
rm -rf obj_dir
|
||||||
|
|
||||||
|
clean: clean-objdir
|
||||||
|
rm -rf $(PROJECT).a $(PROJECT).so
|
||||||
@@ -1,7 +1,17 @@
|
|||||||
#include "opae_sim.h"
|
#include "opae_sim.h"
|
||||||
|
|
||||||
|
#include <verilated.h>
|
||||||
|
#include "Vvortex_afu_shim.h"
|
||||||
|
#include "Vvortex_afu_shim__Syms.h"
|
||||||
|
|
||||||
|
#ifdef VCD_OUTPUT
|
||||||
|
#include <verilated_vcd_c.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <mem.h>
|
||||||
|
|
||||||
#define CCI_LATENCY 8
|
#define CCI_LATENCY 8
|
||||||
#define CCI_RAND_MOD 8
|
#define CCI_RAND_MOD 8
|
||||||
@@ -34,6 +44,8 @@
|
|||||||
#define VERILATOR_RESET_VALUE 2
|
#define VERILATOR_RESET_VALUE 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using namespace vortex;
|
||||||
|
|
||||||
static uint64_t timestamp = 0;
|
static uint64_t timestamp = 0;
|
||||||
|
|
||||||
double sc_time_stamp() {
|
double sc_time_stamp() {
|
||||||
@@ -74,10 +86,19 @@ void sim_trace_enable(bool enable) {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
opae_sim::opae_sim()
|
namespace vortex {
|
||||||
: stop_(false)
|
class VL_OBJ {
|
||||||
, host_buffer_ids_(0)
|
public:
|
||||||
{
|
#ifdef AXI_BUS
|
||||||
|
VVortex_axi *device;
|
||||||
|
#else
|
||||||
|
Vvortex_afu_shim *device;
|
||||||
|
#endif
|
||||||
|
#ifdef VCD_OUTPUT
|
||||||
|
VerilatedVcdC *trace;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VL_OBJ() {
|
||||||
// force random values for unitialized signals
|
// force random values for unitialized signals
|
||||||
Verilated::randReset(VERILATOR_RESET_VALUE);
|
Verilated::randReset(VERILATOR_RESET_VALUE);
|
||||||
Verilated::randSeed(50);
|
Verilated::randSeed(50);
|
||||||
@@ -85,14 +106,37 @@ opae_sim::opae_sim()
|
|||||||
// Turn off assertion before reset
|
// Turn off assertion before reset
|
||||||
Verilated::assertOn(false);
|
Verilated::assertOn(false);
|
||||||
|
|
||||||
vortex_afu_ = new Vvortex_afu_shim();
|
#ifdef AXI_BUS
|
||||||
|
this->device = new Vvortex_afu_shim();
|
||||||
|
#else
|
||||||
|
this->device = new Vvortex_afu_shim();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef VCD_OUTPUT
|
#ifdef VCD_OUTPUT
|
||||||
Verilated::traceEverOn(true);
|
Verilated::traceEverOn(true);
|
||||||
trace_ = new VerilatedVcdC();
|
this->trace = new VerilatedVcdC();
|
||||||
vortex_afu_->trace(trace_, 99);
|
this->device->trace(this->trace, 99);
|
||||||
trace_->open("trace.vcd");
|
this->trace->open("trace.vcd");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
~VL_OBJ() {
|
||||||
|
#ifdef VCD_OUTPUT
|
||||||
|
this->trace->close();
|
||||||
|
delete this->trace;
|
||||||
|
#endif
|
||||||
|
delete this->device;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
opae_sim::opae_sim()
|
||||||
|
: stop_(false)
|
||||||
|
, host_buffer_ids_(0) {
|
||||||
|
vl_obj_ = new VL_OBJ();
|
||||||
|
ram_ = new RAM((1<<12), (1<<20));
|
||||||
|
|
||||||
// reset the device
|
// reset the device
|
||||||
this->reset();
|
this->reset();
|
||||||
@@ -111,14 +155,11 @@ opae_sim::~opae_sim() {
|
|||||||
if (future_.valid()) {
|
if (future_.valid()) {
|
||||||
future_.wait();
|
future_.wait();
|
||||||
}
|
}
|
||||||
#ifdef VCD_OUTPUT
|
|
||||||
trace_->close();
|
|
||||||
delete trace_;
|
|
||||||
#endif
|
|
||||||
for (auto& buffer : host_buffers_) {
|
for (auto& buffer : host_buffers_) {
|
||||||
__aligned_free(buffer.second.data);
|
__aligned_free(buffer.second.data);
|
||||||
}
|
}
|
||||||
delete vortex_afu_;
|
delete vl_obj_;
|
||||||
|
delete ram_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int opae_sim::prepare_buffer(uint64_t len, void **buf_addr, uint64_t *wsid, int flags) {
|
int opae_sim::prepare_buffer(uint64_t len, void **buf_addr, uint64_t *wsid, int flags) {
|
||||||
@@ -151,26 +192,26 @@ void opae_sim::get_io_address(uint64_t wsid, uint64_t *ioaddr) {
|
|||||||
void opae_sim::read_mmio64(uint32_t mmio_num, uint64_t offset, uint64_t *value) {
|
void opae_sim::read_mmio64(uint32_t mmio_num, uint64_t offset, uint64_t *value) {
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
|
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_mmioRdValid = 1;
|
vl_obj_->device->vcp2af_sRxPort_c0_mmioRdValid = 1;
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_address = offset / 4;
|
vl_obj_->device->vcp2af_sRxPort_c0_ReqMmioHdr_address = offset / 4;
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_length = 1;
|
vl_obj_->device->vcp2af_sRxPort_c0_ReqMmioHdr_length = 1;
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_tid = 0;
|
vl_obj_->device->vcp2af_sRxPort_c0_ReqMmioHdr_tid = 0;
|
||||||
this->step();
|
this->step();
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_mmioRdValid = 0;
|
vl_obj_->device->vcp2af_sRxPort_c0_mmioRdValid = 0;
|
||||||
assert(vortex_afu_->af2cp_sTxPort_c2_mmioRdValid);
|
assert(vl_obj_->device->af2cp_sTxPort_c2_mmioRdValid);
|
||||||
*value = vortex_afu_->af2cp_sTxPort_c2_data;
|
*value = vl_obj_->device->af2cp_sTxPort_c2_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void opae_sim::write_mmio64(uint32_t mmio_num, uint64_t offset, uint64_t value) {
|
void opae_sim::write_mmio64(uint32_t mmio_num, uint64_t offset, uint64_t value) {
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
|
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_mmioWrValid = 1;
|
vl_obj_->device->vcp2af_sRxPort_c0_mmioWrValid = 1;
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_address = offset / 4;
|
vl_obj_->device->vcp2af_sRxPort_c0_ReqMmioHdr_address = offset / 4;
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_length = 1;
|
vl_obj_->device->vcp2af_sRxPort_c0_ReqMmioHdr_length = 1;
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_tid = 0;
|
vl_obj_->device->vcp2af_sRxPort_c0_ReqMmioHdr_tid = 0;
|
||||||
memcpy(vortex_afu_->vcp2af_sRxPort_c0_data, &value, 8);
|
memcpy(vl_obj_->device->vcp2af_sRxPort_c0_data, &value, 8);
|
||||||
this->step();
|
this->step();
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_mmioWrValid = 0;
|
vl_obj_->device->vcp2af_sRxPort_c0_mmioWrValid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -178,29 +219,29 @@ void opae_sim::write_mmio64(uint32_t mmio_num, uint64_t offset, uint64_t value)
|
|||||||
void opae_sim::reset() {
|
void opae_sim::reset() {
|
||||||
cci_reads_.clear();
|
cci_reads_.clear();
|
||||||
cci_writes_.clear();
|
cci_writes_.clear();
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_mmioRdValid = 0;
|
vl_obj_->device->vcp2af_sRxPort_c0_mmioRdValid = 0;
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_mmioWrValid = 0;
|
vl_obj_->device->vcp2af_sRxPort_c0_mmioWrValid = 0;
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_rspValid = 0;
|
vl_obj_->device->vcp2af_sRxPort_c0_rspValid = 0;
|
||||||
vortex_afu_->vcp2af_sRxPort_c1_rspValid = 0;
|
vl_obj_->device->vcp2af_sRxPort_c1_rspValid = 0;
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_TxAlmFull = 0;
|
vl_obj_->device->vcp2af_sRxPort_c0_TxAlmFull = 0;
|
||||||
vortex_afu_->vcp2af_sRxPort_c1_TxAlmFull = 0;
|
vl_obj_->device->vcp2af_sRxPort_c1_TxAlmFull = 0;
|
||||||
|
|
||||||
for (int b = 0; b < MEMORY_BANKS; ++b) {
|
for (int b = 0; b < MEMORY_BANKS; ++b) {
|
||||||
mem_reads_[b].clear();
|
mem_reads_[b].clear();
|
||||||
vortex_afu_->avs_readdatavalid[b] = 0;
|
vl_obj_->device->avs_readdatavalid[b] = 0;
|
||||||
vortex_afu_->avs_waitrequest[b] = 0;
|
vl_obj_->device->avs_waitrequest[b] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vortex_afu_->reset = 1;
|
vl_obj_->device->reset = 1;
|
||||||
|
|
||||||
for (int i = 0; i < RESET_DELAY; ++i) {
|
for (int i = 0; i < RESET_DELAY; ++i) {
|
||||||
vortex_afu_->clk = 0;
|
vl_obj_->device->clk = 0;
|
||||||
this->eval();
|
this->eval();
|
||||||
vortex_afu_->clk = 1;
|
vl_obj_->device->clk = 1;
|
||||||
this->eval();
|
this->eval();
|
||||||
}
|
}
|
||||||
|
|
||||||
vortex_afu_->reset = 0;
|
vl_obj_->device->reset = 0;
|
||||||
|
|
||||||
// Turn on assertion after reset
|
// Turn on assertion after reset
|
||||||
Verilated::assertOn(true);
|
Verilated::assertOn(true);
|
||||||
@@ -211,9 +252,9 @@ void opae_sim::step() {
|
|||||||
this->sTxPort_bus();
|
this->sTxPort_bus();
|
||||||
this->avs_bus();
|
this->avs_bus();
|
||||||
|
|
||||||
vortex_afu_->clk = 0;
|
vl_obj_->device->clk = 0;
|
||||||
this->eval();
|
this->eval();
|
||||||
vortex_afu_->clk = 1;
|
vl_obj_->device->clk = 1;
|
||||||
this->eval();
|
this->eval();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@@ -222,10 +263,10 @@ void opae_sim::step() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void opae_sim::eval() {
|
void opae_sim::eval() {
|
||||||
vortex_afu_->eval();
|
vl_obj_->device->eval();
|
||||||
#ifdef VCD_OUTPUT
|
#ifdef VCD_OUTPUT
|
||||||
if (sim_trace_enabled()) {
|
if (sim_trace_enabled()) {
|
||||||
trace_->dump(timestamp);
|
vl_obj_->trace->dump(timestamp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
++timestamp;
|
++timestamp;
|
||||||
@@ -233,8 +274,8 @@ void opae_sim::eval() {
|
|||||||
|
|
||||||
void opae_sim::sRxPort_bus() {
|
void opae_sim::sRxPort_bus() {
|
||||||
// check mmio request
|
// check mmio request
|
||||||
bool mmio_req_enabled = vortex_afu_->vcp2af_sRxPort_c0_mmioRdValid
|
bool mmio_req_enabled = vl_obj_->device->vcp2af_sRxPort_c0_mmioRdValid
|
||||||
|| vortex_afu_->vcp2af_sRxPort_c0_mmioWrValid;
|
|| vl_obj_->device->vcp2af_sRxPort_c0_mmioWrValid;
|
||||||
|
|
||||||
// schedule CCI read responses
|
// schedule CCI read responses
|
||||||
std::list<cci_rd_req_t>::iterator cci_rd_it(cci_reads_.end());
|
std::list<cci_rd_req_t>::iterator cci_rd_it(cci_reads_.end());
|
||||||
@@ -257,22 +298,22 @@ void opae_sim::sRxPort_bus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send CCI write response
|
// send CCI write response
|
||||||
vortex_afu_->vcp2af_sRxPort_c1_rspValid = 0;
|
vl_obj_->device->vcp2af_sRxPort_c1_rspValid = 0;
|
||||||
if (cci_wr_it != cci_writes_.end()) {
|
if (cci_wr_it != cci_writes_.end()) {
|
||||||
vortex_afu_->vcp2af_sRxPort_c1_rspValid = 1;
|
vl_obj_->device->vcp2af_sRxPort_c1_rspValid = 1;
|
||||||
vortex_afu_->vcp2af_sRxPort_c1_hdr_resp_type = 0;
|
vl_obj_->device->vcp2af_sRxPort_c1_hdr_resp_type = 0;
|
||||||
vortex_afu_->vcp2af_sRxPort_c1_hdr_mdata = cci_wr_it->mdata;
|
vl_obj_->device->vcp2af_sRxPort_c1_hdr_mdata = cci_wr_it->mdata;
|
||||||
cci_writes_.erase(cci_wr_it);
|
cci_writes_.erase(cci_wr_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
// send CCI read response (ensure mmio disabled)
|
// send CCI read response (ensure mmio disabled)
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_rspValid = 0;
|
vl_obj_->device->vcp2af_sRxPort_c0_rspValid = 0;
|
||||||
if (!mmio_req_enabled
|
if (!mmio_req_enabled
|
||||||
&& (cci_rd_it != cci_reads_.end())) {
|
&& (cci_rd_it != cci_reads_.end())) {
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_rspValid = 1;
|
vl_obj_->device->vcp2af_sRxPort_c0_rspValid = 1;
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_hdr_resp_type = 0;
|
vl_obj_->device->vcp2af_sRxPort_c0_hdr_resp_type = 0;
|
||||||
memcpy(vortex_afu_->vcp2af_sRxPort_c0_data, cci_rd_it->data.data(), CACHE_BLOCK_SIZE);
|
memcpy(vl_obj_->device->vcp2af_sRxPort_c0_data, cci_rd_it->data.data(), CACHE_BLOCK_SIZE);
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_hdr_mdata = cci_rd_it->mdata;
|
vl_obj_->device->vcp2af_sRxPort_c0_hdr_mdata = cci_rd_it->mdata;
|
||||||
/*printf("%0ld: [sim] CCI Rd Rsp: addr=%ld, mdata=%d, data=", timestamp, cci_rd_it->addr, cci_rd_it->mdata);
|
/*printf("%0ld: [sim] CCI Rd Rsp: addr=%ld, mdata=%d, data=", timestamp, cci_rd_it->addr, cci_rd_it->mdata);
|
||||||
for (int i = 0; i < CACHE_BLOCK_SIZE; ++i)
|
for (int i = 0; i < CACHE_BLOCK_SIZE; ++i)
|
||||||
printf("%02x", cci_rd_it->data[CACHE_BLOCK_SIZE-1-i]);
|
printf("%02x", cci_rd_it->data[CACHE_BLOCK_SIZE-1-i]);
|
||||||
@@ -283,32 +324,32 @@ void opae_sim::sRxPort_bus() {
|
|||||||
|
|
||||||
void opae_sim::sTxPort_bus() {
|
void opae_sim::sTxPort_bus() {
|
||||||
// process read requests
|
// process read requests
|
||||||
if (vortex_afu_->af2cp_sTxPort_c0_valid) {
|
if (vl_obj_->device->af2cp_sTxPort_c0_valid) {
|
||||||
assert(!vortex_afu_->vcp2af_sRxPort_c0_TxAlmFull);
|
assert(!vl_obj_->device->vcp2af_sRxPort_c0_TxAlmFull);
|
||||||
cci_rd_req_t cci_req;
|
cci_rd_req_t cci_req;
|
||||||
cci_req.cycles_left = CCI_LATENCY + (timestamp % CCI_RAND_MOD);
|
cci_req.cycles_left = CCI_LATENCY + (timestamp % CCI_RAND_MOD);
|
||||||
cci_req.addr = vortex_afu_->af2cp_sTxPort_c0_hdr_address;
|
cci_req.addr = vl_obj_->device->af2cp_sTxPort_c0_hdr_address;
|
||||||
cci_req.mdata = vortex_afu_->af2cp_sTxPort_c0_hdr_mdata;
|
cci_req.mdata = vl_obj_->device->af2cp_sTxPort_c0_hdr_mdata;
|
||||||
auto host_ptr = (uint64_t*)(vortex_afu_->af2cp_sTxPort_c0_hdr_address * CACHE_BLOCK_SIZE);
|
auto host_ptr = (uint64_t*)(vl_obj_->device->af2cp_sTxPort_c0_hdr_address * CACHE_BLOCK_SIZE);
|
||||||
memcpy(cci_req.data.data(), host_ptr, CACHE_BLOCK_SIZE);
|
memcpy(cci_req.data.data(), host_ptr, CACHE_BLOCK_SIZE);
|
||||||
//printf("%0ld: [sim] CCI Rd Req: addr=%ld, mdata=%d\n", timestamp, vortex_afu_->af2cp_sTxPort_c0_hdr_address, cci_req.mdata);
|
//printf("%0ld: [sim] CCI Rd Req: addr=%ld, mdata=%d\n", timestamp, vl_obj_->device->af2cp_sTxPort_c0_hdr_address, cci_req.mdata);
|
||||||
cci_reads_.emplace_back(cci_req);
|
cci_reads_.emplace_back(cci_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
// process write requests
|
// process write requests
|
||||||
if (vortex_afu_->af2cp_sTxPort_c1_valid) {
|
if (vl_obj_->device->af2cp_sTxPort_c1_valid) {
|
||||||
assert(!vortex_afu_->vcp2af_sRxPort_c1_TxAlmFull);
|
assert(!vl_obj_->device->vcp2af_sRxPort_c1_TxAlmFull);
|
||||||
cci_wr_req_t cci_req;
|
cci_wr_req_t cci_req;
|
||||||
cci_req.cycles_left = CCI_LATENCY + (timestamp % CCI_RAND_MOD);
|
cci_req.cycles_left = CCI_LATENCY + (timestamp % CCI_RAND_MOD);
|
||||||
cci_req.mdata = vortex_afu_->af2cp_sTxPort_c1_hdr_mdata;
|
cci_req.mdata = vl_obj_->device->af2cp_sTxPort_c1_hdr_mdata;
|
||||||
auto host_ptr = (uint64_t*)(vortex_afu_->af2cp_sTxPort_c1_hdr_address * CACHE_BLOCK_SIZE);
|
auto host_ptr = (uint64_t*)(vl_obj_->device->af2cp_sTxPort_c1_hdr_address * CACHE_BLOCK_SIZE);
|
||||||
memcpy(host_ptr, vortex_afu_->af2cp_sTxPort_c1_data, CACHE_BLOCK_SIZE);
|
memcpy(host_ptr, vl_obj_->device->af2cp_sTxPort_c1_data, CACHE_BLOCK_SIZE);
|
||||||
cci_writes_.emplace_back(cci_req);
|
cci_writes_.emplace_back(cci_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check queues overflow
|
// check queues overflow
|
||||||
vortex_afu_->vcp2af_sRxPort_c0_TxAlmFull = (cci_reads_.size() >= (CCI_RQ_SIZE-1));
|
vl_obj_->device->vcp2af_sRxPort_c0_TxAlmFull = (cci_reads_.size() >= (CCI_RQ_SIZE-1));
|
||||||
vortex_afu_->vcp2af_sRxPort_c1_TxAlmFull = (cci_writes_.size() >= (CCI_WQ_SIZE-1));
|
vl_obj_->device->vcp2af_sRxPort_c1_TxAlmFull = (cci_writes_.size() >= (CCI_WQ_SIZE-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void opae_sim::avs_bus() {
|
void opae_sim::avs_bus() {
|
||||||
@@ -327,10 +368,10 @@ void opae_sim::avs_bus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send memory response
|
// send memory response
|
||||||
vortex_afu_->avs_readdatavalid[b] = 0;
|
vl_obj_->device->avs_readdatavalid[b] = 0;
|
||||||
if (mem_rd_it != mem_reads_[b].end()) {
|
if (mem_rd_it != mem_reads_[b].end()) {
|
||||||
vortex_afu_->avs_readdatavalid[b] = 1;
|
vl_obj_->device->avs_readdatavalid[b] = 1;
|
||||||
memcpy(vortex_afu_->avs_readdata[b], mem_rd_it->data.data(), MEM_BLOCK_SIZE);
|
memcpy(vl_obj_->device->avs_readdata[b], mem_rd_it->data.data(), MEM_BLOCK_SIZE);
|
||||||
uint32_t addr = mem_rd_it->addr;
|
uint32_t addr = mem_rd_it->addr;
|
||||||
mem_reads_[b].erase(mem_rd_it);
|
mem_reads_[b].erase(mem_rd_it);
|
||||||
/*printf("%0ld: [sim] MEM Rd Rsp: bank=%d, addr=%x, pending={", timestamp, b, addr * MEM_BLOCK_SIZE);
|
/*printf("%0ld: [sim] MEM Rd Rsp: bank=%d, addr=%x, pending={", timestamp, b, addr * MEM_BLOCK_SIZE);
|
||||||
@@ -356,14 +397,14 @@ void opae_sim::avs_bus() {
|
|||||||
|
|
||||||
// process memory requests
|
// process memory requests
|
||||||
if (!mem_stalled) {
|
if (!mem_stalled) {
|
||||||
assert(!vortex_afu_->avs_read[b] || !vortex_afu_->avs_write[b]);
|
assert(!vl_obj_->device->avs_read[b] || !vl_obj_->device->avs_write[b]);
|
||||||
if (vortex_afu_->avs_write[b]) {
|
if (vl_obj_->device->avs_write[b]) {
|
||||||
uint64_t byteen = vortex_afu_->avs_byteenable[b];
|
uint64_t byteen = vl_obj_->device->avs_byteenable[b];
|
||||||
unsigned base_addr = vortex_afu_->avs_address[b] * MEM_BLOCK_SIZE;
|
unsigned base_addr = vl_obj_->device->avs_address[b] * MEM_BLOCK_SIZE;
|
||||||
uint8_t* data = (uint8_t*)(vortex_afu_->avs_writedata[b]);
|
uint8_t* data = (uint8_t*)(vl_obj_->device->avs_writedata[b]);
|
||||||
for (int i = 0; i < MEM_BLOCK_SIZE; i++) {
|
for (int i = 0; i < MEM_BLOCK_SIZE; i++) {
|
||||||
if ((byteen >> i) & 0x1) {
|
if ((byteen >> i) & 0x1) {
|
||||||
ram_[base_addr + i] = data[i];
|
(*ram_)[base_addr + i] = data[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*printf("%0ld: [sim] MEM Wr Req: bank=%d, addr=%x, data=", timestamp, b, base_addr);
|
/*printf("%0ld: [sim] MEM Wr Req: bank=%d, addr=%x, data=", timestamp, b, base_addr);
|
||||||
@@ -372,10 +413,10 @@ void opae_sim::avs_bus() {
|
|||||||
}
|
}
|
||||||
printf("\n");*/
|
printf("\n");*/
|
||||||
}
|
}
|
||||||
if (vortex_afu_->avs_read[b]) {
|
if (vl_obj_->device->avs_read[b]) {
|
||||||
mem_rd_req_t mem_req;
|
mem_rd_req_t mem_req;
|
||||||
mem_req.addr = vortex_afu_->avs_address[b];
|
mem_req.addr = vl_obj_->device->avs_address[b];
|
||||||
ram_.read(vortex_afu_->avs_address[b] * MEM_BLOCK_SIZE, MEM_BLOCK_SIZE, mem_req.data.data());
|
ram_->read(mem_req.data.data(), vl_obj_->device->avs_address[b] * MEM_BLOCK_SIZE, MEM_BLOCK_SIZE);
|
||||||
mem_req.cycles_left = MEM_LATENCY;
|
mem_req.cycles_left = MEM_LATENCY;
|
||||||
for (auto& rsp : mem_reads_[b]) {
|
for (auto& rsp : mem_reads_[b]) {
|
||||||
if (mem_req.addr == rsp.addr) {
|
if (mem_req.addr == rsp.addr) {
|
||||||
@@ -396,6 +437,6 @@ void opae_sim::avs_bus() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vortex_afu_->avs_waitrequest[b] = mem_stalled;
|
vl_obj_->device->avs_waitrequest[b] = mem_stalled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <verilated.h>
|
|
||||||
#include "Vvortex_afu_shim.h"
|
|
||||||
#include "Vvortex_afu_shim__Syms.h"
|
|
||||||
|
|
||||||
#ifdef VCD_OUTPUT
|
|
||||||
#include <verilated_vcd_c.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <VX_config.h>
|
#include <VX_config.h>
|
||||||
#include "vortex_afu.h"
|
#include <vortex_afu.h>
|
||||||
#include "ram.h"
|
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <future>
|
#include <future>
|
||||||
@@ -30,6 +21,11 @@
|
|||||||
|
|
||||||
#define CACHE_BLOCK_SIZE 64
|
#define CACHE_BLOCK_SIZE 64
|
||||||
|
|
||||||
|
namespace vortex {
|
||||||
|
|
||||||
|
class VL_OBJ;
|
||||||
|
class RAM;
|
||||||
|
|
||||||
class opae_sim {
|
class opae_sim {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -96,9 +92,9 @@ private:
|
|||||||
|
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
|
|
||||||
RAM ram_;
|
RAM *ram_;
|
||||||
Vvortex_afu_shim *vortex_afu_;
|
|
||||||
#ifdef VCD_OUTPUT
|
VL_OBJ* vl_obj_;
|
||||||
VerilatedVcdC *trace_;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
|
||||||
CXXFLAGS += -std=c++11 -g -O0 -Wall -Wextra -Wfatal-errors
|
|
||||||
|
|
||||||
CXXFLAGS += -Wno-maybe-uninitialized
|
|
||||||
CXXFLAGS += -I. -I../hw
|
|
||||||
CXXFLAGS += -DDUMP_PERF_STATS
|
|
||||||
|
|
||||||
TOP = vx_cache_sim
|
|
||||||
|
|
||||||
RTL_DIR = ../hw/rtl
|
|
||||||
|
|
||||||
PROJECT = simX
|
|
||||||
|
|
||||||
SRCS = util.cpp args.cpp mem.cpp pipeline.cpp warp.cpp core.cpp decode.cpp execute.cpp main.cpp
|
|
||||||
|
|
||||||
# Debugigng
|
|
||||||
ifdef DEBUG
|
|
||||||
CXXFLAGS += -DDEBUG_LEVEL=$(DEBUG)
|
|
||||||
else
|
|
||||||
CXXFLAGS += -DNDEBUG
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(PROJECT)
|
|
||||||
|
|
||||||
$(PROJECT): $(SRCS)
|
|
||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
|
||||||
|
|
||||||
.depend: $(SRCS)
|
|
||||||
$(CXX) $(CXXFLAGS) -MM $^ > .depend;
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(PROJECT) *.o .depend
|
|
||||||
159
simX/mem.h
159
simX/mem.h
@@ -1,159 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <vector>
|
|
||||||
#include <queue>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
namespace vortex {
|
|
||||||
struct BadAddress {};
|
|
||||||
|
|
||||||
class MemDevice {
|
|
||||||
public:
|
|
||||||
virtual ~MemDevice() {}
|
|
||||||
virtual Size size() const = 0;
|
|
||||||
virtual void read(Addr addr, void *data, Size size) = 0;
|
|
||||||
virtual void write(Addr addr, const void *data, Size size) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class RamMemDevice : public MemDevice {
|
|
||||||
public:
|
|
||||||
RamMemDevice(Size size, Size wordSize);
|
|
||||||
RamMemDevice(const char *filename, Size wordSize);
|
|
||||||
~RamMemDevice() {}
|
|
||||||
|
|
||||||
void read(Addr addr, void *data, Size size) override;
|
|
||||||
void write(Addr addr, const void *data, Size size) override;
|
|
||||||
|
|
||||||
virtual Size size() const {
|
|
||||||
return contents_.size();
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::vector<Byte> contents_;
|
|
||||||
Size wordSize_;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class RomMemDevice : public RamMemDevice {
|
|
||||||
public:
|
|
||||||
RomMemDevice(const char *filename, Size wordSize)
|
|
||||||
: RamMemDevice(filename, wordSize)
|
|
||||||
{}
|
|
||||||
|
|
||||||
RomMemDevice(Size size, Size wordSize)
|
|
||||||
: RamMemDevice(size, wordSize)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~RomMemDevice();
|
|
||||||
|
|
||||||
void write(Addr addr, const void *data, Size size) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class MemoryUnit {
|
|
||||||
public:
|
|
||||||
|
|
||||||
struct PageFault {
|
|
||||||
PageFault(Addr a, bool nf)
|
|
||||||
: faultAddr(a)
|
|
||||||
, notFound(nf)
|
|
||||||
{}
|
|
||||||
Addr faultAddr;
|
|
||||||
bool notFound;
|
|
||||||
};
|
|
||||||
|
|
||||||
MemoryUnit(Size pageSize, Size addrBytes, bool disableVm = false);
|
|
||||||
|
|
||||||
void attach(MemDevice &m, Addr start, Addr end);
|
|
||||||
|
|
||||||
void read(Addr addr, void *data, Size size, bool sup);
|
|
||||||
void write(Addr addr, const void *data, Size size, bool sup);
|
|
||||||
|
|
||||||
void tlbAdd(Addr virt, Addr phys, Word flags);
|
|
||||||
void tlbRm(Addr va);
|
|
||||||
void tlbFlush() {
|
|
||||||
tlb_.clear();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
|
|
||||||
class ADecoder {
|
|
||||||
public:
|
|
||||||
ADecoder() {}
|
|
||||||
|
|
||||||
void read(Addr addr, void *data, Size size);
|
|
||||||
void write(Addr addr, const void *data, Size size);
|
|
||||||
|
|
||||||
void map(Addr start, Addr end, MemDevice &md);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
struct mem_accessor_t {
|
|
||||||
MemDevice* md;
|
|
||||||
Addr addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct entry_t {
|
|
||||||
MemDevice *md;
|
|
||||||
Addr start;
|
|
||||||
Addr end;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool lookup(Addr a, Size wordSize, mem_accessor_t*);
|
|
||||||
|
|
||||||
std::vector<entry_t> entries_;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TLBEntry {
|
|
||||||
TLBEntry() {}
|
|
||||||
TLBEntry(Word pfn, Word flags)
|
|
||||||
: pfn(pfn)
|
|
||||||
, flags(flags)
|
|
||||||
{}
|
|
||||||
Word pfn;
|
|
||||||
Word flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
TLBEntry tlbLookup(Addr vAddr, Word flagMask);
|
|
||||||
|
|
||||||
std::unordered_map<Addr, TLBEntry> tlb_;
|
|
||||||
Size pageSize_;
|
|
||||||
Size addrBytes_;
|
|
||||||
ADecoder decoder_;
|
|
||||||
bool disableVm_;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class RAM : public MemDevice {
|
|
||||||
public:
|
|
||||||
|
|
||||||
RAM(uint32_t num_pages, uint32_t page_size);
|
|
||||||
|
|
||||||
~RAM();
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
Size size() const override;
|
|
||||||
void read(Addr addr, void *data, Size size) override;
|
|
||||||
void write(Addr addr, const void *data, Size size) override;
|
|
||||||
|
|
||||||
void loadBinImage(const char* path);
|
|
||||||
|
|
||||||
void loadHexImage(const char* path);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
uint8_t *get(uint32_t address);
|
|
||||||
|
|
||||||
std::vector<uint8_t*> mem_;
|
|
||||||
uint32_t page_bits_;
|
|
||||||
uint32_t size_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace vortex
|
|
||||||
188
simX/util.cpp
188
simX/util.cpp
@@ -1,188 +0,0 @@
|
|||||||
#include <vector>
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <math.h>
|
|
||||||
#include <climits>
|
|
||||||
#include <string.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "types.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
using namespace vortex;
|
|
||||||
|
|
||||||
Word vortex::signExt(Word w, Size bit, Word mask) {
|
|
||||||
if (w >> (bit - 1))
|
|
||||||
w |= ~mask;
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vortex::wordToBytes(Byte *b, Word w, Size wordSize) {
|
|
||||||
while (wordSize--) {
|
|
||||||
*(b++) = w & 0xff;
|
|
||||||
w >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Word vortex::bytesToWord(const Byte *b, Size wordSize) {
|
|
||||||
Word w = 0;
|
|
||||||
b += wordSize-1;
|
|
||||||
while (wordSize--) {
|
|
||||||
w <<= 8;
|
|
||||||
w |= *(b--);
|
|
||||||
}
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
Word vortex::flagsToWord(bool r, bool w, bool x) {
|
|
||||||
Word word = 0;
|
|
||||||
if (r) word |= RD_USR;
|
|
||||||
if (w) word |= WR_USR;
|
|
||||||
if (x) word |= EX_USR;
|
|
||||||
return word;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vortex::wordToFlags(bool &r, bool &w, bool &x, Word f) {
|
|
||||||
r = f & RD_USR;
|
|
||||||
w = f & WR_USR;
|
|
||||||
x = f & EX_USR;
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte vortex::readByte(const std::vector<Byte> &b, Size &n) {
|
|
||||||
if (b.size() <= n)
|
|
||||||
throw std::out_of_range("out of range");
|
|
||||||
return b[n++];
|
|
||||||
}
|
|
||||||
|
|
||||||
Word vortex::readWord(const std::vector<Byte> &b, Size &n, Size wordSize) {
|
|
||||||
if (b.size() - n < wordSize)
|
|
||||||
throw std::out_of_range("out of range");
|
|
||||||
Word w(0);
|
|
||||||
n += wordSize;
|
|
||||||
// std::cout << "wordSize: " << wordSize << "\n";
|
|
||||||
for (Size i = 0; i < wordSize; i++) {
|
|
||||||
w <<= 8;
|
|
||||||
// cout << "index: " << n - i - 1 << "\n";
|
|
||||||
w |= b[n - i - 1];
|
|
||||||
}
|
|
||||||
// cout << "b[0]" << std::hex << w << "\n";
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vortex::writeByte(std::vector<Byte> &p, Size &n, Byte b) {
|
|
||||||
if (p.size() <= n) p.resize(n+1);
|
|
||||||
p[n++] = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vortex::writeWord(std::vector<Byte> &p, Size &n, Size wordSize, Word w) {
|
|
||||||
if (p.size() < (n+wordSize)) p.resize(n+wordSize);
|
|
||||||
while (wordSize--) {
|
|
||||||
p[n++] = w & 0xff;
|
|
||||||
w >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert 32-bit integer register file to IEEE-754 floating point number.
|
|
||||||
float vortex::intregToFloat(uint32_t input) {
|
|
||||||
// 31th bit
|
|
||||||
bool sign = input & 0x80000000;
|
|
||||||
// Exponent: 23th ~ 30th bits -> 8 bits in total
|
|
||||||
int32_t exp = ((input & 0x7F800000)>>23);
|
|
||||||
// printf("exp = %u\n", exp);
|
|
||||||
// 0th ~ 22th bits -> 23 bits fraction
|
|
||||||
uint32_t frac = input & 0x007FFFFF;
|
|
||||||
// Frac_value= 1 + sum{i = 1}{23}{b_{23-i}*2^{-i}}
|
|
||||||
double frac_value;
|
|
||||||
if (exp == 0) { // subnormal
|
|
||||||
if (frac == 0) {
|
|
||||||
// zero
|
|
||||||
if (sign)
|
|
||||||
return -0.0;
|
|
||||||
else
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
frac_value = 0.0;
|
|
||||||
} else
|
|
||||||
frac_value = 1.0;
|
|
||||||
|
|
||||||
for (int i = 0; i < 23; i++) {
|
|
||||||
int bi = frac & 0x1;
|
|
||||||
frac_value += static_cast<double>(bi * pow(2.0, i-23));
|
|
||||||
frac = (frac >> 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (float)((static_cast<double>(pow(-1.0, sign))) * (static_cast<double>(pow(2.0, exp - 127.0)))* frac_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert a floating point number to IEEE-754 32-bit representation,
|
|
||||||
// so that it could be stored in a 32-bit integer register file
|
|
||||||
// Reference: https://www.wikihow.com/Convert-a-Number-from-Decimal-to-IEEE-754-Floating-Point-Representation
|
|
||||||
// https://www.technical-recipes.com/2012/converting-between-binary-and-decimal-representations-of-ieee-754-floating-point-numbers-in-c/
|
|
||||||
uint32_t vortex::floatToBin(float in_value) {
|
|
||||||
union {
|
|
||||||
float input; // assumes sizeof(float) == sizeof(int)
|
|
||||||
int output;
|
|
||||||
} data;
|
|
||||||
|
|
||||||
data.input = in_value;
|
|
||||||
|
|
||||||
std::bitset<sizeof(float) * CHAR_BIT> bits(data.output);
|
|
||||||
std::string mystring = bits.to_string<char, std::char_traits<char>, std::allocator<char> >();
|
|
||||||
// Convert binary to uint32_t
|
|
||||||
Word result = stoul(mystring, nullptr, 2);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Single-precision_floating-point_format
|
|
||||||
// check floating-point number in binary format is NaN
|
|
||||||
uint8_t vortex::fpBinIsNan(uint32_t din) {
|
|
||||||
bool fsign = din & 0x80000000;
|
|
||||||
uint32_t expo = (din>>23) & 0x000000FF;
|
|
||||||
uint32_t fraction = din & 0x007FFFFF;
|
|
||||||
uint32_t bit_22 = din & 0x00400000;
|
|
||||||
|
|
||||||
if ((expo==0xFF) && (fraction!=0)) {
|
|
||||||
// if (!fsign && (fraction == 0x00400000))
|
|
||||||
if (!fsign && (bit_22))
|
|
||||||
return 1; // quiet NaN, return 1
|
|
||||||
else
|
|
||||||
return 2; // signaling NaN, return 2
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check floating-point number in binary format is zero
|
|
||||||
uint8_t vortex::fpBinIsZero(uint32_t din) {
|
|
||||||
bool fsign = din & 0x80000000;
|
|
||||||
uint32_t expo = (din>>23) & 0x000000FF;
|
|
||||||
uint32_t fraction = din & 0x007FFFFF;
|
|
||||||
|
|
||||||
if ((expo==0) && (fraction==0)) {
|
|
||||||
if (fsign)
|
|
||||||
return 1; // negative 0
|
|
||||||
else
|
|
||||||
return 2; // positive 0
|
|
||||||
}
|
|
||||||
return 0; // not zero
|
|
||||||
}
|
|
||||||
|
|
||||||
// check floating-point number in binary format is infinity
|
|
||||||
uint8_t vortex::fpBinIsInf(uint32_t din) {
|
|
||||||
bool fsign = din & 0x80000000;
|
|
||||||
uint32_t expo = (din>>23) & 0x000000FF;
|
|
||||||
uint32_t fraction = din & 0x007FFFFF;
|
|
||||||
|
|
||||||
if ((expo==0xFF) && (fraction==0)) {
|
|
||||||
if (fsign)
|
|
||||||
return 1; // negative infinity
|
|
||||||
else
|
|
||||||
return 2; // positive infinity
|
|
||||||
}
|
|
||||||
return 0; // not infinity
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* vortex::fileExtension(const char* filepath) {
|
|
||||||
const char *ext = strrchr(filepath, '.');
|
|
||||||
if (ext == NULL || ext == filepath)
|
|
||||||
return "";
|
|
||||||
return ext + 1;
|
|
||||||
}
|
|
||||||
@@ -31,13 +31,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -1,16 +1,25 @@
|
|||||||
LLVM_PREFIX ?= /opt/llvm-riscv
|
#LLVM_PREFIX ?= /opt/llvm-riscv
|
||||||
|
#LLVM_PREFIX=/home/blaise/dev/llvm-riscv/builddbg
|
||||||
|
#LLVM_PREFIX=/home/blaise/dev/llvm_rv12/build_dbg/release
|
||||||
|
LLVM_PREFIX=/home/blaise/dev/llvm-riscv/build_rel
|
||||||
|
|
||||||
RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
|
RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
|
||||||
SYSROOT ?= $(RISCV_TOOLCHAIN_PATH)/riscv32-unknown-elf
|
SYSROOT ?= $(RISCV_TOOLCHAIN_PATH)/riscv32-unknown-elf
|
||||||
POCL_CC_PATH ?= /opt/pocl/compiler
|
POCL_CC_PATH ?= /opt/pocl/compiler
|
||||||
POCL_RT_PATH ?= /opt/pocl/runtime
|
POCL_RT_PATH ?= /opt/pocl/runtime
|
||||||
|
|
||||||
OPTS ?= -n32
|
OPTS ?= -f -n16
|
||||||
|
|
||||||
VORTEX_DRV_PATH ?= $(realpath ../../../driver)
|
VORTEX_DRV_PATH ?= $(realpath ../../../driver)
|
||||||
VORTEX_RT_PATH ?= $(realpath ../../../runtime)
|
VORTEX_RT_PATH ?= $(realpath ../../../runtime)
|
||||||
|
|
||||||
K_LLCFLAGS += "-O3 -march=riscv32 -target-abi=ilp32f -mcpu=generic-rv32 -mattr=+m,+f -float-abi=hard -code-model=small"
|
#CC = ${CLANG_PATH}/bin/clang
|
||||||
K_CFLAGS += "-v -O3 --sysroot=$(SYSROOT) --gcc-toolchain=$(RISCV_TOOLCHAIN_PATH) -march=rv32imf -mabi=ilp32f -I$(VORTEX_RT_PATH)/include -fno-rtti -fno-exceptions -ffreestanding -nostartfiles -fdata-sections -ffunction-sections"
|
#AR = ${CLANG_PATH}/bin/llvm-ar
|
||||||
|
#DP = ${CLANG_PATH}/bin/llvm-objdump
|
||||||
|
#CP = ${CLANG_PATH}/bin/llvm-objcopy
|
||||||
|
|
||||||
|
K_LLCFLAGS += "-O3 -march=riscv32 -target-abi=ilp32f -mcpu=generic-rv32 -mattr=+m,+f -mattr=+vortex -float-abi=hard -code-model=small"
|
||||||
|
K_CFLAGS += "-v -O3 --sysroot=$(SYSROOT) --gcc-toolchain=$(RISCV_TOOLCHAIN_PATH) -march=rv32imf -mabi=ilp32f -Xclang -target-feature -Xclang +vortex -I$(VORTEX_RT_PATH)/include -fno-rtti -fno-exceptions -ffreestanding -nostartfiles -fdata-sections -ffunction-sections"
|
||||||
K_LDFLAGS += "-Wl,-Bstatic,-T$(VORTEX_RT_PATH)/linker/vx_link.ld -Wl,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a -lm"
|
K_LDFLAGS += "-Wl,-Bstatic,-T$(VORTEX_RT_PATH)/linker/vx_link.ld -Wl,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a -lm"
|
||||||
|
|
||||||
CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
CXXFLAGS += -std=c++11 -O2 -Wall -Wextra -Wfatal-errors
|
||||||
@@ -35,13 +44,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT)
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ $(PROJECT): $(SRCS)
|
|||||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.pocl
|
run-fpga: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.pocl
|
run-asesim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.pocl
|
run-vlsim: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-simx: $(PROJECT) kernel.pocl
|
run-simx: $(PROJECT) kernel.pocl
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ run-simx: $(PROJECT) kernel.bin
|
|||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/simx:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-fpga: $(PROJECT) kernel.bin
|
run-fpga: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/fpga:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-asesim: $(PROJECT) kernel.bin
|
run-asesim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/asesim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-vlsim: $(PROJECT) kernel.bin
|
run-vlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/opae/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/vlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT) kernel.bin
|
run-rtlsim: $(PROJECT) kernel.bin
|
||||||
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
LD_LIBRARY_PATH=$(POCL_RT_PATH)/lib:$(VORTEX_DRV_PATH)/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) $(OPTS)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ EXCLUDED_TESTS := $(V_TESTS) $(D_TESTS) rv32si-p-scall.hex rv32si-p-sbreak.hex r
|
|||||||
TESTS := $(filter-out $(EXCLUDED_TESTS), $(ALL_TESTS))
|
TESTS := $(filter-out $(EXCLUDED_TESTS), $(ALL_TESTS))
|
||||||
|
|
||||||
run-simx:
|
run-simx:
|
||||||
$(foreach test, $(TESTS), ../../../simX/simX -r -a rv32i -c 1 -i $(test) || exit;)
|
$(foreach test, $(TESTS), ../../../sim/simX/simX -r -a rv32i -c 1 -i $(test) || exit;)
|
||||||
|
|
||||||
run-rtlsim:
|
run-rtlsim:
|
||||||
$(foreach test, $(TESTS), ../../../hw/simulate/obj_dir/VVortex -r $(test) || exit;)
|
$(foreach test, $(TESTS), ../../../sim/rtlsim/rtlsim -r $(test) || exit;)
|
||||||
@@ -15,25 +15,25 @@ PROJECT = fibonacci
|
|||||||
|
|
||||||
SRCS = main.cpp
|
SRCS = main.cpp
|
||||||
|
|
||||||
all: $(PROJECT).elf $(PROJECT).hex $(PROJECT).dump
|
all: $(PROJECT).elf $(PROJECT).bin $(PROJECT).dump
|
||||||
|
|
||||||
$(PROJECT).dump: $(PROJECT).elf
|
$(PROJECT).dump: $(PROJECT).elf
|
||||||
$(DP) -D $(PROJECT).elf > $(PROJECT).dump
|
$(DP) -D $(PROJECT).elf > $(PROJECT).dump
|
||||||
|
|
||||||
$(PROJECT).hex: $(PROJECT).elf
|
$(PROJECT).bin: $(PROJECT).elf
|
||||||
$(CP) -O ihex $(PROJECT).elf $(PROJECT).hex
|
$(CP) -O binary $(PROJECT).elf $(PROJECT).bin
|
||||||
|
|
||||||
$(PROJECT).elf: $(SRCS)
|
$(PROJECT).elf: $(SRCS)
|
||||||
$(CC) $(CFLAGS) $(SRCS) $(LDFLAGS) -o $(PROJECT).elf
|
$(CC) $(CFLAGS) $(SRCS) $(LDFLAGS) -o $(PROJECT).elf
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT).hex
|
run-rtlsim: $(PROJECT).bin
|
||||||
../../../hw/simulate/obj_dir/VVortex $(PROJECT).hex
|
../../../sim/rtlsim/rtlsim $(PROJECT).bin
|
||||||
|
|
||||||
run-simx: $(PROJECT).hex
|
run-simx: $(PROJECT).bin
|
||||||
../../../simX/simX -a rv32i -c 1 -i $(PROJECT).hex
|
../../../sim/simX/simX -a rv32i -c 1 -i $(PROJECT).bin
|
||||||
|
|
||||||
.depend: $(SRCS)
|
.depend: $(SRCS)
|
||||||
$(CC) $(CFLAGS) -MM $^ > .depend;
|
$(CC) $(CFLAGS) -MM $^ > .depend;
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.elf *.hex *.dump .depend
|
rm -rf *.elf *.bin *.dump .depend
|
||||||
|
|||||||
@@ -15,25 +15,25 @@ PROJECT = hello
|
|||||||
|
|
||||||
SRCS = main.cpp
|
SRCS = main.cpp
|
||||||
|
|
||||||
all: $(PROJECT).elf $(PROJECT).hex $(PROJECT).dump
|
all: $(PROJECT).elf $(PROJECT).bin $(PROJECT).dump
|
||||||
|
|
||||||
$(PROJECT).dump: $(PROJECT).elf
|
$(PROJECT).dump: $(PROJECT).elf
|
||||||
$(DP) -D $(PROJECT).elf > $(PROJECT).dump
|
$(DP) -D $(PROJECT).elf > $(PROJECT).dump
|
||||||
|
|
||||||
$(PROJECT).hex: $(PROJECT).elf
|
$(PROJECT).bin: $(PROJECT).elf
|
||||||
$(CP) -O ihex $(PROJECT).elf $(PROJECT).hex
|
$(CP) -O binary $(PROJECT).elf $(PROJECT).bin
|
||||||
|
|
||||||
$(PROJECT).elf: $(SRCS)
|
$(PROJECT).elf: $(SRCS)
|
||||||
$(CC) $(CFLAGS) $(SRCS) $(LDFLAGS) -o $(PROJECT).elf
|
$(CC) $(CFLAGS) $(SRCS) $(LDFLAGS) -o $(PROJECT).elf
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT).hex
|
run-rtlsim: $(PROJECT).bin
|
||||||
../../../hw/simulate/obj_dir/VVortex $(PROJECT).hex
|
../../../sim/rtlsim/rtlsim $(PROJECT).bin
|
||||||
|
|
||||||
run-simx: $(PROJECT).hex
|
run-simx: $(PROJECT).bin
|
||||||
../../../simX/simX -a rv32i -c 1 -i $(PROJECT).hex
|
../../../sim/simX/simX -a rv32i -c 1 -i $(PROJECT).bin
|
||||||
|
|
||||||
.depend: $(SRCS)
|
.depend: $(SRCS)
|
||||||
$(CC) $(CFLAGS) -MM $^ > .depend;
|
$(CC) $(CFLAGS) -MM $^ > .depend;
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.elf *.hex *.dump .depend
|
rm -rf *.elf *.bin *.dump .depend
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ AR = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-gcc-ar
|
|||||||
DP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objdump
|
DP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objdump
|
||||||
CP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objcopy
|
CP = $(RISCV_TOOLCHAIN_PATH)/bin/riscv32-unknown-elf-objcopy
|
||||||
|
|
||||||
CFLAGS += -march=rv32imf -mabi=ilp32f -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections
|
CFLAGS += -march=rv32imf -mabi=ilp32f -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections -fpermissive
|
||||||
CFLAGS += -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw
|
CFLAGS += -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw
|
||||||
|
|
||||||
LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link.ld -Wl,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a
|
LDFLAGS += -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link.ld -Wl,--gc-sections $(VORTEX_RT_PATH)/libvortexrt.a
|
||||||
@@ -15,25 +15,25 @@ PROJECT = simple
|
|||||||
|
|
||||||
SRCS = main.cpp tests.cpp
|
SRCS = main.cpp tests.cpp
|
||||||
|
|
||||||
all: $(PROJECT).elf $(PROJECT).hex $(PROJECT).dump
|
all: $(PROJECT).elf $(PROJECT).bin $(PROJECT).dump
|
||||||
|
|
||||||
$(PROJECT).dump: $(PROJECT).elf
|
$(PROJECT).dump: $(PROJECT).elf
|
||||||
$(DP) -D $(PROJECT).elf > $(PROJECT).dump
|
$(DP) -D $(PROJECT).elf > $(PROJECT).dump
|
||||||
|
|
||||||
$(PROJECT).hex: $(PROJECT).elf
|
$(PROJECT).bin: $(PROJECT).elf
|
||||||
$(CP) -O ihex $(PROJECT).elf $(PROJECT).hex
|
$(CP) -O binary $(PROJECT).elf $(PROJECT).bin
|
||||||
|
|
||||||
$(PROJECT).elf: $(SRCS)
|
$(PROJECT).elf: $(SRCS)
|
||||||
$(CC) $(CFLAGS) $(SRCS) $(LDFLAGS) -o $(PROJECT).elf
|
$(CC) $(CFLAGS) $(SRCS) $(LDFLAGS) -o $(PROJECT).elf
|
||||||
|
|
||||||
run-rtlsim: $(PROJECT).hex
|
run-rtlsim: $(PROJECT).bin
|
||||||
../../../hw/simulate/obj_dir/VVortex $(PROJECT).hex
|
../../../sim/rtlsim/rtlsim $(PROJECT).bin
|
||||||
|
|
||||||
run-simx: $(PROJECT).hex
|
run-simx: $(PROJECT).bin
|
||||||
../../../simX/simX -a rv32i -c 1 -i $(PROJECT).hex
|
../../../sim/simX/simX -a rv32i -c 1 -i $(PROJECT).bin
|
||||||
|
|
||||||
.depend: $(SRCS)
|
.depend: $(SRCS)
|
||||||
$(CC) $(CFLAGS) -MM $^ > .depend;
|
$(CC) $(CFLAGS) -MM $^ > .depend;
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.elf *.hex *.dump .depend
|
rm -rf *.elf *.bin *.dump .depend
|
||||||
|
|||||||
Reference in New Issue
Block a user