Vortex 2.0 changes:

+ Microarchitecture optimizations
+ 64-bit support
+ Xilinx FPGA support
+ LLVM-16 support
+ Refactoring and quality control fixes
This commit is contained in:
Blaise Tine
2023-10-19 20:51:22 -07:00
parent d69a64c32c
commit d47cccc157
1300 changed files with 247321 additions and 311189 deletions

2
hw/syn/xilinx/test/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/project_1/*
/.Xil/*

View File

@@ -0,0 +1,49 @@
VIVADO = $(XILINX_VIVADO)/bin/vivado
RTL_DIR = ../../../rtl
AFU_DIR = $(RTL_DIR)/afu/xrt
SCRIPT_DIR = ../../../scripts
THIRD_PARTY_DIR = ../../../../third_party
# include paths
FPU_INCLUDE = -I$(RTL_DIR)/fpu
ifneq (,$(findstring FPU_FPNEW,$(CONFIGS)))
FPU_INCLUDE += -I$(THIRD_PARTY_DIR)/fpnew/src/common_cells/include -I$(THIRD_PARTY_DIR)/fpnew/src/common_cells/src -I$(THIRD_PARTY_DIR)/fpnew/src/fpu_div_sqrt_mvp/hdl -I$(THIRD_PARTY_DIR)/fpnew/src
endif
RTL_INCLUDE = -I$(RTL_DIR) -I$(RTL_DIR)/libs -I$(RTL_DIR)/interfaces -I$(RTL_DIR)/core -I$(RTL_DIR)/mem -I$(RTL_DIR)/cache
RTL_INCLUDE += $(FPU_INCLUDE)
RTL_INCLUDE += -Iproject_1_files
# compilation flags
CFLAGS += -DNDEBUG -DSYNTHESIS -DVIVADO
CFLAGS += $(CONFIGS)
CFLAGS += $(RTL_INCLUDE)
CFLAGS += -DEXT_F_DISABLE
#CFLAGS += -DNUM_CORES 4
# update memory layout for 2MB RAM
CFLAGS += -DSTARTUP_ADDR=32\'h80000
CFLAGS += -DIO_BASE_ADDR=32\'hFF000
COE_FILE := $(realpath project_1_files)/kernel.bin.coe
ESCAPED_COE_FILE := $(shell echo "$(COE_FILE)" | sed -e 's/[\/&]/\\&/g')
all: build
gen-sources: project_1/sources.txt
project_1/sources.txt:
mkdir -p project_1
$(SCRIPT_DIR)/gen_sources.sh $(CFLAGS) -P -Cproject_1/src -Oproject_1/sources.txt
project.tcl: project.tcl.in
sed -e 's/%COE_FILE%/$(ESCAPED_COE_FILE)/g' < $< > $@
build: project_1/vortex.xpr
project_1/vortex.xpr: project_1/sources.txt project.tcl
$(VIVADO) -mode batch -source project.tcl -tclargs project_1/sources.txt project_1/src $(SCRIPT_DIR)
run: project_1/vortex.xpr
$(VIVADO) project_1/vortex.xpr &
clean:
rm -rf project_1 project.tcl

View File

@@ -0,0 +1,51 @@
XLEN ?= 32
ifeq ($(XLEN),64)
RISCV_TOOLCHAIN_PATH ?= /opt/riscv64-gnu-toolchain
CFLAGS += -march=rv64imafd -mabi=lp64d
else
RISCV_TOOLCHAIN_PATH ?= /opt/riscv-gnu-toolchain
CFLAGS += -march=rv32imaf -mabi=ilp32f
endif
RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf
VORTEX_RT_PATH ?= $(realpath ../../../../../kernel)
BIN2COE_PATH ?= ../../../../../../bin2coe
CC = $(RISCV_TOOLCHAIN_PATH)/bin/$(RISCV_PREFIX)-gcc
AR = $(RISCV_TOOLCHAIN_PATH)/bin/$(RISCV_PREFIX)-gcc-ar
DP = $(RISCV_TOOLCHAIN_PATH)/bin/$(RISCV_PREFIX)-objdump
CP = $(RISCV_TOOLCHAIN_PATH)/bin/$(RISCV_PREFIX)-objcopy
CFLAGS += -O3 -Wstack-usage=1024 -ffreestanding -nostartfiles -fdata-sections -ffunction-sections
CFLAGS += -I$(VORTEX_RT_PATH)/include -I$(VORTEX_RT_PATH)/../hw
LDFLAGS += -lm -Wl,-Bstatic,-T,$(VORTEX_RT_PATH)/linker/vx_link$(XLEN).ld,--defsym=STARTUP_ADDR=0x80000000
PROJECT = kernel
SRCS = main.c start.S
all: $(PROJECT).elf $(PROJECT).hex $(PROJECT).bin $(PROJECT).dump $(PROJECT).bin.coe
$(PROJECT).dump: $(PROJECT).elf
$(DP) -D $(PROJECT).elf > $(PROJECT).dump
$(PROJECT).hex: $(PROJECT).elf
$(CP) -O ihex $(PROJECT).elf $(PROJECT).hex
$(PROJECT).bin: $(PROJECT).elf
$(CP) -O binary $(PROJECT).elf $(PROJECT).bin
$(PROJECT).bin.coe: $(PROJECT).bin
$(BIN2COE_PATH)/bin2coe $(PROJECT).bin --out=$(PROJECT).bin.coe --binary=$(PROJECT).bin --data=$(PROJECT).dat --binaddr=8192 --depth=16384 --wordsize=64
$(PROJECT).elf: $(SRCS)
$(CC) $(CFLAGS) $(SRCS) $(LDFLAGS) -o $(PROJECT).elf
.depend: $(SRCS)
$(CC) $(CFLAGS) -MM $^ > .depend;
clean:
rm -rf *.bin *.elf *.hex *.dump *.coe .depend

View File

@@ -0,0 +1,3 @@
@1
000000C00000008000000002,
00000003000000020000000100000000,

View File

@@ -0,0 +1,38 @@
// Copyright © 2019-2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <vx_intrinsics.h>
#define KERNEL_ARG_DEV_MEM_ADDR 0x40
typedef struct {
uint32_t count;
uint32_t src_addr;
uint32_t dst_addr;
} kernel_arg_t;
int main() {
kernel_arg_t* arg = (kernel_arg_t*)KERNEL_ARG_DEV_MEM_ADDR;
uint32_t count = arg->count;
int32_t* src_ptr = (int32_t*)arg->src_addr;
int32_t* dst_ptr = (int32_t*)arg->dst_addr;
uint32_t offset = vx_core_id() * count;
for (uint32_t i = 0; i < count; ++i) {
dst_ptr[offset + i] = src_ptr[offset + i];
}
return 0;
}

View File

@@ -0,0 +1,23 @@
// Copyright © 2019-2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
.section .init, "ax"
.global _start
.type _start, @function
_start:
# call main routine
call main
# end execution
.insn r 0x0b, 0, 0, x0, x0, x0
.size _start, .-_start

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,208 @@
// Copyright © 2019-2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
`include "VX_define.vh"
module Vortex_top #(
parameter C_M_AXI_GMEM_DATA_WIDTH = 512,
parameter C_M_AXI_GMEM_ADDR_WIDTH = `XLEN,
parameter C_M_AXI_GMEM_ID_WIDTH = 32,
parameter C_M_AXI_MEM_NUM_BANKS = 1
) (
input wire clk,
input wire reset,
// AXI4 memory interface
output wire m_axi_mem_awvalid,
input wire m_axi_mem_awready,
output wire [C_M_AXI_GMEM_ADDR_WIDTH-1:0] m_axi_mem_awaddr,
output wire [C_M_AXI_GMEM_ID_WIDTH - 1:0] m_axi_mem_awid,
output wire [7:0] m_axi_mem_awlen,
output wire [2:0] m_axi_mem_awsize,
output wire [1:0] m_axi_mem_awburst,
output wire [1:0] m_axi_mem_awlock,
output wire [3:0] m_axi_mem_awcache,
output wire [2:0] m_axi_mem_awprot,
output wire [3:0] m_axi_mem_awqos,
output wire m_axi_mem_wvalid,
input wire m_axi_mem_wready,
output wire [C_M_AXI_GMEM_DATA_WIDTH-1:0] m_axi_mem_wdata,
output wire [C_M_AXI_GMEM_DATA_WIDTH/8-1:0] m_axi_mem_wstrb,
output wire m_axi_mem_wlast,
output wire m_axi_mem_arvalid,
input wire m_axi_mem_arready,
output wire [C_M_AXI_GMEM_ADDR_WIDTH-1:0] m_axi_mem_araddr,
output wire [C_M_AXI_GMEM_ID_WIDTH-1:0] m_axi_mem_arid,
output wire [7:0] m_axi_mem_arlen,
output wire [2:0] m_axi_mem_arsize,
output wire [1:0] m_axi_mem_arburst,
output wire [1:0] m_axi_mem_arlock,
output wire [3:0] m_axi_mem_arcache,
output wire [2:0] m_axi_mem_arprot,
output wire [3:0] m_axi_mem_arqos,
input wire m_axi_mem_rvalid,
output wire m_axi_mem_rready,
input wire [C_M_AXI_GMEM_DATA_WIDTH - 1:0] m_axi_mem_rdata,
input wire m_axi_mem_rlast,
input wire [C_M_AXI_GMEM_ID_WIDTH - 1:0] m_axi_mem_rid,
input wire [1:0] m_axi_mem_rresp,
input wire m_axi_mem_bvalid,
output wire m_axi_mem_bready,
input wire [1:0] m_axi_mem_bresp,
input wire [C_M_AXI_GMEM_ID_WIDTH - 1:0] m_axi_mem_bid,
input wire dcr_wr_valid,
input wire [`VX_DCR_ADDR_WIDTH-1:0] dcr_wr_addr,
input wire [`VX_DCR_DATA_WIDTH-1:0] dcr_wr_data,
output wire busy
);
wire m_axi_mem_awvalid_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_awready_a [C_M_AXI_MEM_NUM_BANKS];
wire [C_M_AXI_GMEM_ADDR_WIDTH-1:0] m_axi_mem_awaddr_a [C_M_AXI_MEM_NUM_BANKS];
wire [C_M_AXI_GMEM_ID_WIDTH - 1:0] m_axi_mem_awid_a [C_M_AXI_MEM_NUM_BANKS];
wire [7:0] m_axi_mem_awlen_a [C_M_AXI_MEM_NUM_BANKS];
wire [2:0] m_axi_mem_awsize_a [C_M_AXI_MEM_NUM_BANKS];
wire [1:0] m_axi_mem_awburst_a [C_M_AXI_MEM_NUM_BANKS];
wire [1:0] m_axi_mem_awlock_a [C_M_AXI_MEM_NUM_BANKS];
wire [3:0] m_axi_mem_awcache_a [C_M_AXI_MEM_NUM_BANKS];
wire [2:0] m_axi_mem_awprot_a [C_M_AXI_MEM_NUM_BANKS];
wire [3:0] m_axi_mem_awqos_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_wvalid_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_wready_a [C_M_AXI_MEM_NUM_BANKS];
wire [C_M_AXI_GMEM_DATA_WIDTH-1:0] m_axi_mem_wdata_a [C_M_AXI_MEM_NUM_BANKS];
wire [C_M_AXI_GMEM_DATA_WIDTH/8-1:0] m_axi_mem_wstrb_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_wlast_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_arvalid_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_arready_a [C_M_AXI_MEM_NUM_BANKS];
wire [C_M_AXI_GMEM_ADDR_WIDTH-1:0] m_axi_mem_araddr_a [C_M_AXI_MEM_NUM_BANKS];
wire [C_M_AXI_GMEM_ID_WIDTH-1:0] m_axi_mem_arid_a [C_M_AXI_MEM_NUM_BANKS];
wire [7:0] m_axi_mem_arlen_a [C_M_AXI_MEM_NUM_BANKS];
wire [2:0] m_axi_mem_arsize_a [C_M_AXI_MEM_NUM_BANKS];
wire [1:0] m_axi_mem_arburst_a [C_M_AXI_MEM_NUM_BANKS];
wire [1:0] m_axi_mem_arlock_a [C_M_AXI_MEM_NUM_BANKS];
wire [3:0] m_axi_mem_arcache_a [C_M_AXI_MEM_NUM_BANKS];
wire [2:0] m_axi_mem_arprot_a [C_M_AXI_MEM_NUM_BANKS];
wire [3:0] m_axi_mem_arqos_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_rvalid_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_rready_a [C_M_AXI_MEM_NUM_BANKS];
wire [C_M_AXI_GMEM_DATA_WIDTH - 1:0] m_axi_mem_rdata_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_rlast_a [C_M_AXI_MEM_NUM_BANKS];
wire [C_M_AXI_GMEM_ID_WIDTH - 1:0] m_axi_mem_rid_a [C_M_AXI_MEM_NUM_BANKS];
wire [1:0] m_axi_mem_rresp_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_bvalid_a [C_M_AXI_MEM_NUM_BANKS];
wire m_axi_mem_bready_a [C_M_AXI_MEM_NUM_BANKS];
wire [1:0] m_axi_mem_bresp_a [C_M_AXI_MEM_NUM_BANKS];
wire [C_M_AXI_GMEM_ID_WIDTH - 1:0] m_axi_mem_bid_a [C_M_AXI_MEM_NUM_BANKS];
assign m_axi_mem_awvalid = m_axi_mem_awvalid_a[0];
assign m_axi_mem_awready_a[0] = m_axi_mem_awready;
assign m_axi_mem_awaddr = m_axi_mem_awaddr_a[0];
assign m_axi_mem_awid = m_axi_mem_awid_a[0];
assign m_axi_mem_awlen = m_axi_mem_awlen_a[0];
assign m_axi_mem_awsize = m_axi_mem_awsize_a[0];
assign m_axi_mem_awburst = m_axi_mem_awburst_a[0];
assign m_axi_mem_awlock = m_axi_mem_awlock_a[0];
assign m_axi_mem_awcache = m_axi_mem_awcache_a[0];
assign m_axi_mem_awprot = m_axi_mem_awprot_a[0];
assign m_axi_mem_awqos = m_axi_mem_awqos_a[0];
assign m_axi_mem_wvalid = m_axi_mem_wvalid_a[0];
assign m_axi_mem_wready_a[0] = m_axi_mem_wready;
assign m_axi_mem_wdata = m_axi_mem_wdata_a[0];
assign m_axi_mem_wstrb = m_axi_mem_wstrb_a[0];
assign m_axi_mem_wlast = m_axi_mem_wlast_a[0];
assign m_axi_mem_arvalid = m_axi_mem_arvalid_a[0];
assign m_axi_mem_arready_a[0] = m_axi_mem_arready;
assign m_axi_mem_araddr = m_axi_mem_araddr_a[0];
assign m_axi_mem_arid = m_axi_mem_arid_a[0];
assign m_axi_mem_arlen = m_axi_mem_arlen_a[0];
assign m_axi_mem_arsize = m_axi_mem_arsize_a[0];
assign m_axi_mem_arburst = m_axi_mem_arburst_a[0];
assign m_axi_mem_arlock = m_axi_mem_arlock_a[0];
assign m_axi_mem_arcache = m_axi_mem_arcache_a[0];
assign m_axi_mem_arprot = m_axi_mem_arprot_a[0];
assign m_axi_mem_arqos = m_axi_mem_arqos_a[0];
assign m_axi_mem_rvalid_a[0] = m_axi_mem_rvalid;
assign m_axi_mem_rready = m_axi_mem_rready_a[0];
assign m_axi_mem_rdata_a[0] = m_axi_mem_rdata;
assign m_axi_mem_rlast_a[0] = m_axi_mem_rlast;
assign m_axi_mem_rid_a[0] = m_axi_mem_rid;
assign m_axi_mem_rresp_a[0] = m_axi_mem_rresp;
assign m_axi_mem_bvalid_a[0] = m_axi_mem_bvalid;
assign m_axi_mem_bready = m_axi_mem_bready_a[0];
assign m_axi_mem_bresp_a[0] = m_axi_mem_bresp;
assign m_axi_mem_bid_a[0] = m_axi_mem_bid;
Vortex_axi #(
.AXI_DATA_WIDTH (C_M_AXI_GMEM_DATA_WIDTH),
.AXI_ADDR_WIDTH (C_M_AXI_GMEM_ADDR_WIDTH),
.AXI_TID_WIDTH (C_M_AXI_GMEM_ID_WIDTH)
) inst (
.clk (clk),
.reset (reset),
.m_axi_awvalid (m_axi_mem_awvalid_a),
.m_axi_awready (m_axi_mem_awready_a),
.m_axi_awaddr (m_axi_mem_awaddr_a),
.m_axi_awid (m_axi_mem_awid_a),
.m_axi_awlen (m_axi_mem_awlen_a),
.m_axi_awsize (m_axi_mem_awsize_a),
.m_axi_awburst (m_axi_mem_awburst_a),
.m_axi_awlock (m_axi_mem_awlock_a),
.m_axi_awcache (m_axi_mem_awcache_a),
.m_axi_awprot (m_axi_mem_awprot_a),
.m_axi_awqos (m_axi_mem_awqos_a),
.m_axi_wvalid (m_axi_mem_wvalid_a),
.m_axi_wready (m_axi_mem_wready_a),
.m_axi_wdata (m_axi_mem_wdata_a),
.m_axi_wstrb (m_axi_mem_wstrb_a),
.m_axi_wlast (m_axi_mem_wlast_a),
.m_axi_bvalid (m_axi_mem_bvalid_a),
.m_axi_bready (m_axi_mem_bready_a),
.m_axi_bid (m_axi_mem_bid_a),
.m_axi_bresp (m_axi_mem_bresp_a),
.m_axi_arvalid (m_axi_mem_arvalid_a),
.m_axi_arready (m_axi_mem_arready_a),
.m_axi_araddr (m_axi_mem_araddr_a),
.m_axi_arid (m_axi_mem_arid_a),
.m_axi_arlen (m_axi_mem_arlen_a),
.m_axi_arsize (m_axi_mem_arsize_a),
.m_axi_arburst (m_axi_mem_arburst_a),
.m_axi_arlock (m_axi_mem_arlock_a),
.m_axi_arcache (m_axi_mem_arcache_a),
.m_axi_arprot (m_axi_mem_arprot_a),
.m_axi_arqos (m_axi_mem_arqos_a),
.m_axi_rvalid (m_axi_mem_rvalid_a),
.m_axi_rready (m_axi_mem_rready_a),
.m_axi_rdata (m_axi_mem_rdata_a),
.m_axi_rid (m_axi_mem_rid_a),
.m_axi_rresp (m_axi_mem_rresp_a),
.m_axi_rlast (m_axi_mem_rlast_a),
.dcr_wr_valid (dcr_wr_valid),
.dcr_wr_addr (dcr_wr_addr),
.dcr_wr_data (dcr_wr_data),
.busy (busy)
);
endmodule

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,119 @@
// Copyright © 2019-2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
`include "VX_define.vh"
`timescale 10ns / 1ns
`define CYCLE_TIME 4
module testbench;
reg clk;
reg resetn;
reg [43:0] cycles;
reg vx_running;
reg vx_reset_wait;
reg vx_busy_wait;
wire vx_busy;
reg dcr_wr_valid;
reg [11:0] dcr_wr_addr;
reg [31:0] dcr_wr_data;
design_1_wrapper UUD(
.clk_100MHz (clk),
.resetn (resetn),
.vx_reset (~resetn || ~vx_running),
.dcr_wr_valid (dcr_wr_valid),
.dcr_wr_addr (dcr_wr_addr),
.dcr_wr_data (dcr_wr_data),
.vx_busy (vx_busy)
);
always #(`CYCLE_TIME/2)
clk = ~clk;
initial begin
clk = 1'b0;
resetn = 1'b0;
#4 resetn = 1'b1;
end
always @(posedge clk) begin
if (~resetn) begin
cycles <= 0;
end else begin
cycles <= cycles + 1;
end
end
reg [7:0] vx_reset_ctr;
always @(posedge clk) begin
if (vx_reset_wait) begin
vx_reset_ctr <= vx_reset_ctr + 1;
end else begin
vx_reset_ctr <= 0;
end
end
always @(posedge clk) begin
if (~resetn) begin
vx_running <= 0;
vx_reset_wait <= 0;
vx_busy_wait <= 0;
dcr_wr_valid <= 0;
dcr_wr_addr <= 0;
dcr_wr_data <= 0;
end else begin
case (cycles)
1: begin
dcr_wr_valid <= 1;
dcr_wr_addr <= `VX_DCR_BASE_STARTUP_ADDR0;
dcr_wr_data <= `STARTUP_ADDR;
end
2: begin
dcr_wr_valid <= 0;
dcr_wr_addr <= 0;
dcr_wr_data <= 0;
end
3: begin
vx_reset_wait <= 1;
end
default:;
endcase
if (vx_running) begin
if (vx_busy_wait) begin
if (vx_busy) begin
vx_busy_wait <= 0;
end
end else begin
if (~vx_busy) begin
vx_running <= 0;
$display("done!");
$finish;
end
end
end else begin
if (vx_reset_wait && vx_reset_ctr == (`RESET_DELAY-1)) begin
$display("start!");
vx_reset_wait <= 0;
vx_running <= 1;
vx_busy_wait <= 1;
end
end
end
end
endmodule