Refine uriscv to verilator.
This commit is contained in:
parent
ded2df85f8
commit
11312aee91
|
@ -1,2 +1,3 @@
|
||||||
tb/build
|
demo/build
|
||||||
tb/*.vcd
|
demo/*.vcd
|
||||||
|
demo/obj_dir
|
|
@ -0,0 +1,80 @@
|
||||||
|
export RV_ROOT = ${PWD}/..
|
||||||
|
GCC_PREFIX = /opt/riscv/bin/riscv32-unknown-elf
|
||||||
|
GDB_PREFIX = /opt/riscv/bin/riscv32-unknown-elf-gdb
|
||||||
|
|
||||||
|
ABI = -mabi=ilp32 -march=rv32imc
|
||||||
|
|
||||||
|
DEMODIR = ${PWD}
|
||||||
|
BUILD_DIR = ${DEMODIR}/build
|
||||||
|
|
||||||
|
RV_SOC = ${RV_ROOT}/soc
|
||||||
|
|
||||||
|
TEST = demo
|
||||||
|
|
||||||
|
ifdef debug
|
||||||
|
DEBUG_PLUS = +dumpon
|
||||||
|
VERILATOR_DEBUG = --trace
|
||||||
|
endif
|
||||||
|
|
||||||
|
LINK = $(DEMODIR)/link.ld
|
||||||
|
LINKPRO = $(DEMODIR)/link.ld
|
||||||
|
|
||||||
|
# CFLAGS for verilator generated Makefiles. Without -std=c++11 it complains for `auto` variables
|
||||||
|
CFLAGS += "-std=c++11"
|
||||||
|
# Optimization for better performance; alternative is nothing for slower runtime (faster compiles)
|
||||||
|
# -O2 for faster runtime (slower compiles), or -O for balance.
|
||||||
|
VERILATOR_MAKE_FLAGS = OPT_FAST="-Os"
|
||||||
|
|
||||||
|
# Targets
|
||||||
|
all: clean verilator
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf build obj_dir
|
||||||
|
|
||||||
|
##################### Verilog Builds #####################################
|
||||||
|
|
||||||
|
verilator-build:
|
||||||
|
verilator --cc -CFLAGS ${CFLAGS} \
|
||||||
|
-Wno-WIDTH \
|
||||||
|
-Wno-UNOPTFLAT \
|
||||||
|
-Wno-LATCH \
|
||||||
|
-I../src \
|
||||||
|
-F ./soc.mk \
|
||||||
|
soc_sim.v \
|
||||||
|
--top-module soc_sim -exe test_soc_sim.cpp --autoflush $(VERILATOR_DEBUG)
|
||||||
|
cp ${DEMODIR}/test_soc_sim.cpp obj_dir
|
||||||
|
$(MAKE) -j -e -C obj_dir/ -f Vsoc_sim.mk $(VERILATOR_MAKE_FLAGS)
|
||||||
|
|
||||||
|
##################### Simulation Runs #####################################
|
||||||
|
|
||||||
|
verilator: program.hex verilator-build bin
|
||||||
|
cd build && ../obj_dir/Vsoc_sim ${DEBUG_PLUS}
|
||||||
|
|
||||||
|
sim:
|
||||||
|
cd build && ../obj_dir/Vsoc_sim ${DEBUG_PLUS}
|
||||||
|
|
||||||
|
##################### Test hex Build #####################################
|
||||||
|
|
||||||
|
program.hex: $(TEST).o $(LINK)
|
||||||
|
@echo Building $(TEST)
|
||||||
|
$(GCC_PREFIX)-gcc $(ABI) -Wl,-Map=$(BUILD_DIR)/$(TEST).map -lgcc -T$(LINKPRO) -o $(BUILD_DIR)/$(TEST).bin $(BUILD_DIR)/$(TEST).o -nostartfiles $(TEST_LIBS)
|
||||||
|
$(GCC_PREFIX)-objcopy -O verilog $(BUILD_DIR)/$(TEST).bin $(BUILD_DIR)/program.hex
|
||||||
|
$(GCC_PREFIX)-gcc $(ABI) -Wl,-Map=$(BUILD_DIR)/$(TEST).map -lgcc -T$(LINK) -o $(BUILD_DIR)/$(TEST).bin $(BUILD_DIR)/$(TEST).o -nostartfiles $(TEST_LIBS)
|
||||||
|
$(GCC_PREFIX)-objdump -S $(BUILD_DIR)/$(TEST).bin > $(BUILD_DIR)/$(TEST).dis
|
||||||
|
@echo Completed building $(TEST)
|
||||||
|
|
||||||
|
%.o : %.s
|
||||||
|
@mkdir -p $(BUILD_DIR)
|
||||||
|
$(GCC_PREFIX)-cpp -g $< > $(BUILD_DIR)/$*.cpp.s
|
||||||
|
$(GCC_PREFIX)-as -g $(ABI) $(BUILD_DIR)/$*.cpp.s -o $(BUILD_DIR)/$@
|
||||||
|
|
||||||
|
##################### openocd #####################################
|
||||||
|
|
||||||
|
|
||||||
|
bin: $(ELF_FILE)
|
||||||
|
$(GCC_PREFIX)-objcopy -O verilog test.elf $(BUILD_DIR)/test.hex
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo Possible targets: verilator help clean all verilator-build program.hex
|
||||||
|
|
||||||
|
.PHONY: help clean verilator
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -0,0 +1,75 @@
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Assembly code for Hello World
|
||||||
|
// Not using only ALU ops for creating the string
|
||||||
|
|
||||||
|
|
||||||
|
; #include "defines.h"
|
||||||
|
|
||||||
|
#define STDOUT 0xd0580000
|
||||||
|
|
||||||
|
|
||||||
|
// Code to execute
|
||||||
|
.section .text
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
|
||||||
|
// Enable Caches in MRAC
|
||||||
|
li x1, 0x5f555555
|
||||||
|
csrw 0x7c0, x1
|
||||||
|
|
||||||
|
// Load string from hw_data
|
||||||
|
// and write to stdout address
|
||||||
|
|
||||||
|
li x3, STDOUT
|
||||||
|
la x4, hw_data
|
||||||
|
|
||||||
|
loop:
|
||||||
|
lb x5, 0(x4)
|
||||||
|
sb x5, 0(x3)
|
||||||
|
addi x4, x4, 1
|
||||||
|
bnez x5, loop
|
||||||
|
|
||||||
|
li x3, STDOUT
|
||||||
|
la x4, hw_data
|
||||||
|
|
||||||
|
loop2:
|
||||||
|
lb x5, 0(x4)
|
||||||
|
sb x5, 0(x3)
|
||||||
|
addi x4, x4, 1
|
||||||
|
bnez x5, loop2
|
||||||
|
|
||||||
|
loop3:
|
||||||
|
beq x0, x0, loop3
|
||||||
|
|
||||||
|
// Write 0xff to STDOUT for TB to terminate test.
|
||||||
|
_finish:
|
||||||
|
li x3, STDOUT
|
||||||
|
addi x5, x0, 0xff
|
||||||
|
sb x5, 0(x3)
|
||||||
|
beq x0, x0, _finish
|
||||||
|
.rept 100
|
||||||
|
nop
|
||||||
|
.endr
|
||||||
|
|
||||||
|
.global hw_data
|
||||||
|
.data
|
||||||
|
hw_data:
|
||||||
|
.ascii "----------------------------------\n"
|
||||||
|
.ascii "Hello World Colin.liang EL2@WDC !!\n"
|
||||||
|
.ascii "----------------------------------\n"
|
||||||
|
.byte 0
|
|
@ -1,104 +0,0 @@
|
||||||
[*]
|
|
||||||
[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI
|
|
||||||
[*] Sat Jul 17 10:54:57 2021
|
|
||||||
[*]
|
|
||||||
[timestart] 0
|
|
||||||
[size] 2560 1385
|
|
||||||
[pos] -1 -1
|
|
||||||
*-14.000000 146555 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
|
||||||
[treeopen] tb_top.
|
|
||||||
[treeopen] tb_top.u_dut.
|
|
||||||
[sst_width] 202
|
|
||||||
[signals_width] 245
|
|
||||||
[sst_expanded] 1
|
|
||||||
[sst_vpaned_height] 420
|
|
||||||
@28
|
|
||||||
tb_top.u_dut.clk_i
|
|
||||||
tb_top.u_dut.rst_i
|
|
||||||
@200
|
|
||||||
-
|
|
||||||
@800200
|
|
||||||
-MEM_I
|
|
||||||
@200
|
|
||||||
-REQ
|
|
||||||
@28
|
|
||||||
tb_top.u_dut.mem_i_rd_o
|
|
||||||
@22
|
|
||||||
tb_top.u_dut.mem_i_pc_o[31:0]
|
|
||||||
@28
|
|
||||||
tb_top.u_dut.mem_i_accept_i
|
|
||||||
@200
|
|
||||||
-RESP
|
|
||||||
@28
|
|
||||||
tb_top.u_dut.mem_i_valid_i
|
|
||||||
@22
|
|
||||||
tb_top.u_dut.mem_i_inst_i[31:0]
|
|
||||||
@1000200
|
|
||||||
-MEM_I
|
|
||||||
@200
|
|
||||||
-
|
|
||||||
@800200
|
|
||||||
-MEM_D
|
|
||||||
@200
|
|
||||||
-REQ
|
|
||||||
@28
|
|
||||||
tb_top.u_dut.mem_d_rd_o
|
|
||||||
@22
|
|
||||||
tb_top.u_dut.mem_d_wr_o[3:0]
|
|
||||||
tb_top.u_dut.mem_d_addr_o[31:0]
|
|
||||||
tb_top.u_dut.mem_d_data_wr_o[31:0]
|
|
||||||
@28
|
|
||||||
tb_top.u_dut.mem_d_accept_i
|
|
||||||
@200
|
|
||||||
-RESP
|
|
||||||
@28
|
|
||||||
tb_top.u_dut.mem_d_ack_i
|
|
||||||
@22
|
|
||||||
tb_top.u_dut.mem_d_data_rd_i[31:0]
|
|
||||||
@1000200
|
|
||||||
-MEM_D
|
|
||||||
@200
|
|
||||||
-
|
|
||||||
@23
|
|
||||||
tb_top.u_dut.pc_q[31:0]
|
|
||||||
@200
|
|
||||||
-
|
|
||||||
@800200
|
|
||||||
-REGFILE
|
|
||||||
@22
|
|
||||||
tb_top.u_dut.x0_zero_w[31:0]
|
|
||||||
tb_top.u_dut.x1_ra_w[31:0]
|
|
||||||
tb_top.u_dut.x2_sp_w[31:0]
|
|
||||||
tb_top.u_dut.x3_gp_w[31:0]
|
|
||||||
tb_top.u_dut.x4_tp_w[31:0]
|
|
||||||
tb_top.u_dut.x5_t0_w[31:0]
|
|
||||||
tb_top.u_dut.x6_t1_w[31:0]
|
|
||||||
tb_top.u_dut.x7_t2_w[31:0]
|
|
||||||
tb_top.u_dut.x8_s0_w[31:0]
|
|
||||||
tb_top.u_dut.x9_s1_w[31:0]
|
|
||||||
tb_top.u_dut.x10_a0_w[31:0]
|
|
||||||
tb_top.u_dut.x11_a1_w[31:0]
|
|
||||||
tb_top.u_dut.x12_a2_w[31:0]
|
|
||||||
tb_top.u_dut.x13_a3_w[31:0]
|
|
||||||
tb_top.u_dut.x14_a4_w[31:0]
|
|
||||||
tb_top.u_dut.x15_a5_w[31:0]
|
|
||||||
tb_top.u_dut.x16_a6_w[31:0]
|
|
||||||
tb_top.u_dut.x17_a7_w[31:0]
|
|
||||||
tb_top.u_dut.x18_s2_w[31:0]
|
|
||||||
tb_top.u_dut.x19_s3_w[31:0]
|
|
||||||
tb_top.u_dut.x20_s4_w[31:0]
|
|
||||||
tb_top.u_dut.x21_s5_w[31:0]
|
|
||||||
tb_top.u_dut.x22_s6_w[31:0]
|
|
||||||
tb_top.u_dut.x23_s7_w[31:0]
|
|
||||||
tb_top.u_dut.x24_s8_w[31:0]
|
|
||||||
tb_top.u_dut.x25_s9_w[31:0]
|
|
||||||
tb_top.u_dut.x26_s10_w[31:0]
|
|
||||||
tb_top.u_dut.x27_s11_w[31:0]
|
|
||||||
tb_top.u_dut.x28_t3_w[31:0]
|
|
||||||
tb_top.u_dut.x29_t4_w[31:0]
|
|
||||||
tb_top.u_dut.x30_t5_w[31:0]
|
|
||||||
tb_top.u_dut.x31_t6_w[31:0]
|
|
||||||
@1000200
|
|
||||||
-REGFILE
|
|
||||||
[pattern_trace] 1
|
|
||||||
[pattern_trace] 0
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x0000;
|
||||||
|
.text_init : { *(.text_init*) }
|
||||||
|
.text : { *(.text*) }
|
||||||
|
_end = .;
|
||||||
|
. = 0x800;
|
||||||
|
.data : ALIGN(0x800) { *(.*data) *(.rodata*) STACK = ALIGN(16) + 0x8000; }
|
||||||
|
.bss : { *(.bss) }
|
||||||
|
. = 0xd0580000;
|
||||||
|
.data.io : { *(.data.io) }
|
||||||
|
}
|
|
@ -1,62 +0,0 @@
|
||||||
###############################################################################
|
|
||||||
# Variables: Program ELF
|
|
||||||
###############################################################################
|
|
||||||
ELF_FILE ?= test.elf
|
|
||||||
|
|
||||||
OBJCOPY ?= /opt/riscv/bin/riscv32-unknown-elf-objcopy
|
|
||||||
ifeq ($(shell which $(OBJCOPY)),)
|
|
||||||
${error $(OBJCOPY) missing from PATH}
|
|
||||||
endif
|
|
||||||
ifeq ($(shell which iverilog),)
|
|
||||||
${error iverilog missing from PATH - Icarus Verilog required}
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Variables: Defaults
|
|
||||||
###############################################################################
|
|
||||||
TRACE ?= 1
|
|
||||||
|
|
||||||
SRC_V_DIR ?= ../src .
|
|
||||||
SRC_DIR ?= .
|
|
||||||
|
|
||||||
EXE ?= output.out
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Variables: Verilog
|
|
||||||
###############################################################################
|
|
||||||
SRC_V ?= $(foreach src,$(SRC_V_DIR),$(wildcard $(src)/*.v))
|
|
||||||
|
|
||||||
VFLAGS += $(patsubst %,-I%,$(SRC_V_DIR))
|
|
||||||
VFLAGS += -DTRACE=$(TRACE)
|
|
||||||
VFLAGS += -Dverilog_sim
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Variables: Lists of objects, source and deps
|
|
||||||
###############################################################################
|
|
||||||
BUILD_DIR ?= build/
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Rules
|
|
||||||
###############################################################################
|
|
||||||
all: run
|
|
||||||
|
|
||||||
$(BUILD_DIR):
|
|
||||||
@mkdir -p $@
|
|
||||||
|
|
||||||
$(BUILD_DIR)/tcm.bin: $(ELF_FILE) | $(BUILD_DIR)
|
|
||||||
$(OBJCOPY) $< -O binary $@
|
|
||||||
|
|
||||||
$(BUILD_DIR)/$(EXE): $(SRC_V) | $(BUILD_DIR)
|
|
||||||
@echo "# Compiling verilog"
|
|
||||||
iverilog $(VFLAGS) -o $@ $(SRC_V)
|
|
||||||
|
|
||||||
run: $(BUILD_DIR)/$(EXE) $(BUILD_DIR)/tcm.bin
|
|
||||||
vvp $(BUILD_DIR)/$(EXE) -vcd
|
|
||||||
|
|
||||||
view:
|
|
||||||
gtkwave waveform.vcd gtksettings.sav
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(BUILD_DIR) *.vcd
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
../src/riscv_core.v
|
||||||
|
../src/uriscv_alu.v
|
||||||
|
../src/uriscv_branch.v
|
||||||
|
../src/uriscv_csr.v
|
||||||
|
../src/uriscv_defs.v
|
||||||
|
../src/uriscv_lsu.v
|
||||||
|
../src/uriscv_muldiv.v
|
||||||
|
|
||||||
|
./soc_top.v
|
||||||
|
./tcm_mem_ram.v
|
||||||
|
./tcm_mem.v
|
|
@ -0,0 +1,27 @@
|
||||||
|
module soc_sim (
|
||||||
|
input bit core_clk
|
||||||
|
);
|
||||||
|
logic rst_l;
|
||||||
|
|
||||||
|
parameter MAX_CYCLES = 1000;
|
||||||
|
// parameter MAX_CYCLES = 10_000_000_0;
|
||||||
|
int cycleCnt;
|
||||||
|
|
||||||
|
always @(posedge core_clk) begin
|
||||||
|
cycleCnt <= cycleCnt + 1;
|
||||||
|
|
||||||
|
if (cycleCnt == MAX_CYCLES) begin
|
||||||
|
$display("Hit max cycle count (%0d) .. stopping", cycleCnt);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign rst_l = cycleCnt > 5;
|
||||||
|
|
||||||
|
soc_top rvsoc (
|
||||||
|
.clk(core_clk),
|
||||||
|
.rst(rst_l)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,113 @@
|
||||||
|
module soc_top (
|
||||||
|
input bit clk,
|
||||||
|
input bit rst
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
reg [7:0] mem[65535:0];
|
||||||
|
integer i;
|
||||||
|
integer f;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("Starting bench");
|
||||||
|
|
||||||
|
// Load TCM memory
|
||||||
|
for (i = 0; i < 65535; i = i + 1) mem[i] = 0;
|
||||||
|
|
||||||
|
// $readmemh("test.hex", mem);
|
||||||
|
$readmemh("program.hex", mem);
|
||||||
|
|
||||||
|
for (i = 0; i < 65535; i = i + 1) u_mem.write(i, mem[i]);
|
||||||
|
end
|
||||||
|
|
||||||
|
wire mem_i_rd_w;
|
||||||
|
wire mem_i_flush_w;
|
||||||
|
wire mem_i_invalidate_w;
|
||||||
|
wire [31:0] mem_i_pc_w;
|
||||||
|
wire [31:0] mem_d_addr_w;
|
||||||
|
wire [31:0] mem_d_data_wr_w;
|
||||||
|
wire mem_d_rd_w;
|
||||||
|
wire [ 3:0] mem_d_wr_w;
|
||||||
|
wire mem_d_cacheable_w;
|
||||||
|
wire [10:0] mem_d_req_tag_w;
|
||||||
|
wire mem_d_invalidate_w;
|
||||||
|
wire mem_d_writeback_w;
|
||||||
|
wire mem_d_flush_w;
|
||||||
|
wire mem_i_accept_w;
|
||||||
|
wire mem_i_valid_w;
|
||||||
|
wire mem_i_error_w;
|
||||||
|
wire [31:0] mem_i_inst_w;
|
||||||
|
wire [31:0] mem_d_data_rd_w;
|
||||||
|
wire mem_d_accept_w;
|
||||||
|
wire mem_d_ack_w;
|
||||||
|
wire mem_d_error_w;
|
||||||
|
wire [10:0] mem_d_resp_tag_w;
|
||||||
|
|
||||||
|
riscv_core u_dut
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
// Ports
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
(
|
||||||
|
// Inputs
|
||||||
|
.clk_i(clk),
|
||||||
|
.rst_i(rst),
|
||||||
|
.mem_d_data_rd_i(mem_d_data_rd_w),
|
||||||
|
.mem_d_accept_i(mem_d_accept_w),
|
||||||
|
.mem_d_ack_i(mem_d_ack_w),
|
||||||
|
.mem_d_error_i(mem_d_error_w),
|
||||||
|
.mem_d_resp_tag_i(mem_d_resp_tag_w),
|
||||||
|
.mem_i_accept_i(mem_i_accept_w),
|
||||||
|
.mem_i_valid_i(mem_i_valid_w),
|
||||||
|
.mem_i_error_i(mem_i_error_w),
|
||||||
|
.mem_i_inst_i(mem_i_inst_w),
|
||||||
|
.intr_i(1'b0),
|
||||||
|
.reset_vector_i(32'h80000000),
|
||||||
|
.cpu_id_i('b0)
|
||||||
|
|
||||||
|
// Outputs
|
||||||
|
, .mem_d_addr_o(mem_d_addr_w),
|
||||||
|
.mem_d_data_wr_o(mem_d_data_wr_w),
|
||||||
|
.mem_d_rd_o(mem_d_rd_w),
|
||||||
|
.mem_d_wr_o(mem_d_wr_w),
|
||||||
|
.mem_d_cacheable_o(mem_d_cacheable_w),
|
||||||
|
.mem_d_req_tag_o(mem_d_req_tag_w),
|
||||||
|
.mem_d_invalidate_o(mem_d_invalidate_w),
|
||||||
|
.mem_d_writeback_o(mem_d_writeback_w),
|
||||||
|
.mem_d_flush_o(mem_d_flush_w),
|
||||||
|
.mem_i_rd_o(mem_i_rd_w),
|
||||||
|
.mem_i_flush_o(mem_i_flush_w),
|
||||||
|
.mem_i_invalidate_o(mem_i_invalidate_w),
|
||||||
|
.mem_i_pc_o(mem_i_pc_w)
|
||||||
|
);
|
||||||
|
|
||||||
|
tcm_mem u_mem (
|
||||||
|
// Inputs
|
||||||
|
.clk_i(clk),
|
||||||
|
.rst_i(rst),
|
||||||
|
.mem_i_rd_i(mem_i_rd_w),
|
||||||
|
.mem_i_flush_i(mem_i_flush_w),
|
||||||
|
.mem_i_invalidate_i(mem_i_invalidate_w),
|
||||||
|
.mem_i_pc_i(mem_i_pc_w),
|
||||||
|
.mem_d_addr_i(mem_d_addr_w),
|
||||||
|
.mem_d_data_wr_i(mem_d_data_wr_w),
|
||||||
|
.mem_d_rd_i(mem_d_rd_w),
|
||||||
|
.mem_d_wr_i(mem_d_wr_w),
|
||||||
|
.mem_d_cacheable_i(mem_d_cacheable_w),
|
||||||
|
.mem_d_req_tag_i(mem_d_req_tag_w),
|
||||||
|
.mem_d_invalidate_i(mem_d_invalidate_w),
|
||||||
|
.mem_d_writeback_i(mem_d_writeback_w),
|
||||||
|
.mem_d_flush_i(mem_d_flush_w)
|
||||||
|
|
||||||
|
// Outputs
|
||||||
|
, .mem_i_accept_o(mem_i_accept_w),
|
||||||
|
.mem_i_valid_o(mem_i_valid_w),
|
||||||
|
.mem_i_error_o(mem_i_error_w),
|
||||||
|
.mem_i_inst_o(mem_i_inst_w),
|
||||||
|
.mem_d_data_rd_o(mem_d_data_rd_w),
|
||||||
|
.mem_d_accept_o(mem_d_accept_w),
|
||||||
|
.mem_d_ack_o(mem_d_ack_w),
|
||||||
|
.mem_d_error_o(mem_d_error_w),
|
||||||
|
.mem_d_resp_tag_o(mem_d_resp_tag_w)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -1,137 +0,0 @@
|
||||||
module tb_top;
|
|
||||||
|
|
||||||
reg clk;
|
|
||||||
reg rst;
|
|
||||||
|
|
||||||
reg [7:0] mem[65535:0];
|
|
||||||
integer i;
|
|
||||||
integer f;
|
|
||||||
|
|
||||||
initial
|
|
||||||
begin
|
|
||||||
$display("Starting bench");
|
|
||||||
|
|
||||||
if (`TRACE)
|
|
||||||
begin
|
|
||||||
$dumpfile("waveform.vcd");
|
|
||||||
$dumpvars(0, tb_top);
|
|
||||||
end
|
|
||||||
|
|
||||||
// Reset
|
|
||||||
clk = 0;
|
|
||||||
rst = 1;
|
|
||||||
repeat (5) @(posedge clk);
|
|
||||||
rst = 0;
|
|
||||||
|
|
||||||
// Load TCM memory
|
|
||||||
for (i=0;i<65535;i=i+1)
|
|
||||||
mem[i] = 0;
|
|
||||||
|
|
||||||
f = $fopenr("./build/tcm.bin");
|
|
||||||
i = $fread(mem, f);
|
|
||||||
for (i=0;i<65535;i=i+1)
|
|
||||||
u_mem.write(i, mem[i]);
|
|
||||||
end
|
|
||||||
|
|
||||||
initial
|
|
||||||
begin
|
|
||||||
forever
|
|
||||||
begin
|
|
||||||
clk = #5 ~clk;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
wire mem_i_rd_w;
|
|
||||||
wire mem_i_flush_w;
|
|
||||||
wire mem_i_invalidate_w;
|
|
||||||
wire [ 31:0] mem_i_pc_w;
|
|
||||||
wire [ 31:0] mem_d_addr_w;
|
|
||||||
wire [ 31:0] mem_d_data_wr_w;
|
|
||||||
wire mem_d_rd_w;
|
|
||||||
wire [ 3:0] mem_d_wr_w;
|
|
||||||
wire mem_d_cacheable_w;
|
|
||||||
wire [ 10:0] mem_d_req_tag_w;
|
|
||||||
wire mem_d_invalidate_w;
|
|
||||||
wire mem_d_writeback_w;
|
|
||||||
wire mem_d_flush_w;
|
|
||||||
wire mem_i_accept_w;
|
|
||||||
wire mem_i_valid_w;
|
|
||||||
wire mem_i_error_w;
|
|
||||||
wire [ 31:0] mem_i_inst_w;
|
|
||||||
wire [ 31:0] mem_d_data_rd_w;
|
|
||||||
wire mem_d_accept_w;
|
|
||||||
wire mem_d_ack_w;
|
|
||||||
wire mem_d_error_w;
|
|
||||||
wire [ 10:0] mem_d_resp_tag_w;
|
|
||||||
|
|
||||||
riscv_core
|
|
||||||
u_dut
|
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// Ports
|
|
||||||
//-----------------------------------------------------------------
|
|
||||||
(
|
|
||||||
// Inputs
|
|
||||||
.clk_i(clk)
|
|
||||||
,.rst_i(rst)
|
|
||||||
,.mem_d_data_rd_i(mem_d_data_rd_w)
|
|
||||||
,.mem_d_accept_i(mem_d_accept_w)
|
|
||||||
,.mem_d_ack_i(mem_d_ack_w)
|
|
||||||
,.mem_d_error_i(mem_d_error_w)
|
|
||||||
,.mem_d_resp_tag_i(mem_d_resp_tag_w)
|
|
||||||
,.mem_i_accept_i(mem_i_accept_w)
|
|
||||||
,.mem_i_valid_i(mem_i_valid_w)
|
|
||||||
,.mem_i_error_i(mem_i_error_w)
|
|
||||||
,.mem_i_inst_i(mem_i_inst_w)
|
|
||||||
,.intr_i(1'b0)
|
|
||||||
,.reset_vector_i(32'h80000000)
|
|
||||||
,.cpu_id_i('b0)
|
|
||||||
|
|
||||||
// Outputs
|
|
||||||
,.mem_d_addr_o(mem_d_addr_w)
|
|
||||||
,.mem_d_data_wr_o(mem_d_data_wr_w)
|
|
||||||
,.mem_d_rd_o(mem_d_rd_w)
|
|
||||||
,.mem_d_wr_o(mem_d_wr_w)
|
|
||||||
,.mem_d_cacheable_o(mem_d_cacheable_w)
|
|
||||||
,.mem_d_req_tag_o(mem_d_req_tag_w)
|
|
||||||
,.mem_d_invalidate_o(mem_d_invalidate_w)
|
|
||||||
,.mem_d_writeback_o(mem_d_writeback_w)
|
|
||||||
,.mem_d_flush_o(mem_d_flush_w)
|
|
||||||
,.mem_i_rd_o(mem_i_rd_w)
|
|
||||||
,.mem_i_flush_o(mem_i_flush_w)
|
|
||||||
,.mem_i_invalidate_o(mem_i_invalidate_w)
|
|
||||||
,.mem_i_pc_o(mem_i_pc_w)
|
|
||||||
);
|
|
||||||
|
|
||||||
tcm_mem
|
|
||||||
u_mem
|
|
||||||
(
|
|
||||||
// Inputs
|
|
||||||
.clk_i(clk)
|
|
||||||
,.rst_i(rst)
|
|
||||||
,.mem_i_rd_i(mem_i_rd_w)
|
|
||||||
,.mem_i_flush_i(mem_i_flush_w)
|
|
||||||
,.mem_i_invalidate_i(mem_i_invalidate_w)
|
|
||||||
,.mem_i_pc_i(mem_i_pc_w)
|
|
||||||
,.mem_d_addr_i(mem_d_addr_w)
|
|
||||||
,.mem_d_data_wr_i(mem_d_data_wr_w)
|
|
||||||
,.mem_d_rd_i(mem_d_rd_w)
|
|
||||||
,.mem_d_wr_i(mem_d_wr_w)
|
|
||||||
,.mem_d_cacheable_i(mem_d_cacheable_w)
|
|
||||||
,.mem_d_req_tag_i(mem_d_req_tag_w)
|
|
||||||
,.mem_d_invalidate_i(mem_d_invalidate_w)
|
|
||||||
,.mem_d_writeback_i(mem_d_writeback_w)
|
|
||||||
,.mem_d_flush_i(mem_d_flush_w)
|
|
||||||
|
|
||||||
// Outputs
|
|
||||||
,.mem_i_accept_o(mem_i_accept_w)
|
|
||||||
,.mem_i_valid_o(mem_i_valid_w)
|
|
||||||
,.mem_i_error_o(mem_i_error_w)
|
|
||||||
,.mem_i_inst_o(mem_i_inst_w)
|
|
||||||
,.mem_d_data_rd_o(mem_d_data_rd_w)
|
|
||||||
,.mem_d_accept_o(mem_d_accept_w)
|
|
||||||
,.mem_d_ack_o(mem_d_ack_w)
|
|
||||||
,.mem_d_error_o(mem_d_error_w)
|
|
||||||
,.mem_d_resp_tag_o(mem_d_resp_tag_w)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
|
@ -1,23 +1,26 @@
|
||||||
|
|
||||||
module tcm_mem_ram
|
module tcm_mem_ram (
|
||||||
(
|
|
||||||
// Inputs
|
// Inputs
|
||||||
input clk0_i
|
input clk0_i,
|
||||||
,input rst0_i
|
input rst0_i,
|
||||||
,input [ 13:0] addr0_i
|
input [13:0] addr0_i,
|
||||||
,input [ 31:0] data0_i
|
input [31:0] data0_i,
|
||||||
,input [ 3:0] wr0_i
|
input [ 3:0] wr0_i,
|
||||||
,input clk1_i
|
input clk1_i,
|
||||||
,input rst1_i
|
input rst1_i,
|
||||||
,input [ 13:0] addr1_i
|
input [13:0] addr1_i,
|
||||||
,input [ 31:0] data1_i
|
input [31:0] data1_i,
|
||||||
,input [ 3:0] wr1_i
|
input [ 3:0] wr1_i
|
||||||
|
|
||||||
// Outputs
|
// Outputs
|
||||||
,output [ 31:0] data0_o
|
, output [31:0] data0_o,
|
||||||
,output [ 31:0] data1_o
|
output [31:0] data1_o
|
||||||
);
|
);
|
||||||
|
|
||||||
|
integer memlog;
|
||||||
|
initial begin
|
||||||
|
memlog = $fopen("mem.log", "w");
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
@ -31,34 +34,26 @@ reg [31:0] ram [16383:0] /*verilator public*/;
|
||||||
reg [31:0] ram_read0_q;
|
reg [31:0] ram_read0_q;
|
||||||
reg [31:0] ram_read1_q;
|
reg [31:0] ram_read1_q;
|
||||||
|
|
||||||
|
|
||||||
// Synchronous write
|
// Synchronous write
|
||||||
always @ (posedge clk0_i)
|
always @(posedge clk0_i) begin
|
||||||
begin
|
if (wr0_i[0]) ram[addr0_i][7:0] <= data0_i[7:0];
|
||||||
if (wr0_i[0])
|
if (wr0_i[1]) ram[addr0_i][15:8] <= data0_i[15:8];
|
||||||
ram[addr0_i][7:0] <= data0_i[7:0];
|
if (wr0_i[2]) ram[addr0_i][23:16] <= data0_i[23:16];
|
||||||
if (wr0_i[1])
|
if (wr0_i[3]) ram[addr0_i][31:24] <= data0_i[31:24];
|
||||||
ram[addr0_i][15:8] <= data0_i[15:8];
|
|
||||||
if (wr0_i[2])
|
|
||||||
ram[addr0_i][23:16] <= data0_i[23:16];
|
|
||||||
if (wr0_i[3])
|
|
||||||
ram[addr0_i][31:24] <= data0_i[31:24];
|
|
||||||
|
|
||||||
ram_read0_q <= ram[addr0_i];
|
ram_read0_q <= ram[addr0_i];
|
||||||
|
|
||||||
|
$fwrite(memlog, "addr0: 0x%0h data: 0x%0h \n", addr0_i, ram[addr0_i]);
|
||||||
end
|
end
|
||||||
|
|
||||||
always @ (posedge clk1_i)
|
always @(posedge clk1_i) begin
|
||||||
begin
|
if (wr1_i[0]) ram[addr1_i][7:0] <= data1_i[7:0];
|
||||||
if (wr1_i[0])
|
if (wr1_i[1]) ram[addr1_i][15:8] <= data1_i[15:8];
|
||||||
ram[addr1_i][7:0] <= data1_i[7:0];
|
if (wr1_i[2]) ram[addr1_i][23:16] <= data1_i[23:16];
|
||||||
if (wr1_i[1])
|
if (wr1_i[3]) ram[addr1_i][31:24] <= data1_i[31:24];
|
||||||
ram[addr1_i][15:8] <= data1_i[15:8];
|
|
||||||
if (wr1_i[2])
|
|
||||||
ram[addr1_i][23:16] <= data1_i[23:16];
|
|
||||||
if (wr1_i[3])
|
|
||||||
ram[addr1_i][31:24] <= data1_i[31:24];
|
|
||||||
|
|
||||||
ram_read1_q <= ram[addr1_i];
|
ram_read1_q <= ram[addr1_i];
|
||||||
|
$fwrite(memlog, "addr1: 0x%0h data: 0x%0h \n", addr1_i, ram[addr1_i]);
|
||||||
end
|
end
|
||||||
|
|
||||||
assign data0_o = ram_read0_q;
|
assign data0_o = ram_read0_q;
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||||
|
//
|
||||||
|
// 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 <stdlib.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "Vsoc_sim.h"
|
||||||
|
#include "verilated.h"
|
||||||
|
#include "verilated_vcd_c.h"
|
||||||
|
|
||||||
|
vluint64_t main_time = 0;
|
||||||
|
|
||||||
|
double sc_time_stamp() { return main_time; }
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
std::cout << "\nVerilatorTB: Start of sim\n" << std::endl;
|
||||||
|
|
||||||
|
Verilated::commandArgs(argc, argv);
|
||||||
|
|
||||||
|
Vsoc_sim* soc = new Vsoc_sim;
|
||||||
|
|
||||||
|
// init trace dump
|
||||||
|
VerilatedVcdC* tfp = NULL;
|
||||||
|
|
||||||
|
#if VM_TRACE
|
||||||
|
Verilated::traceEverOn(true);
|
||||||
|
tfp = new VerilatedVcdC;
|
||||||
|
soc->trace(tfp, 24);
|
||||||
|
tfp->open("sim.vcd");
|
||||||
|
#endif
|
||||||
|
// Simulate
|
||||||
|
while (!Verilated::gotFinish()) {
|
||||||
|
#if VM_TRACE
|
||||||
|
tfp->dump(main_time);
|
||||||
|
#endif
|
||||||
|
main_time += 5;
|
||||||
|
soc->core_clk = !soc->core_clk;
|
||||||
|
soc->eval();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if VM_TRACE
|
||||||
|
tfp->close();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::cout << "\nVerilatorTB: End of sim" << std::endl;
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
840918
uriscv/demo/waveform.vcd
840918
uriscv/demo/waveform.vcd
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue