Fix Modelsim flow

This commit is contained in:
Florian Zaruba 2018-07-16 23:53:18 +02:00
parent d35c9a1145
commit bc8cff782f
12 changed files with 143 additions and 362 deletions

View file

@ -5,8 +5,8 @@
# compile everything in the following library
library ?= work
# Top level module to compile
top_level ?= core_tb
test_top_level ?= core_tb
top_level ?= ariane_tb
test_top_level ?= ariane_tb
# Maximum amount of cycles for a successful simulation run
max_cycles ?= 10000000
# Test case to run
@ -38,10 +38,13 @@ test_pkg := $(wildcard tb/test/*/*sequence_pkg.sv*) $(wildcard tb/test/*/*_pkg.s
# DPI
dpi := $(wildcard tb/dpi/*)
# this list contains the standalone components
src := $(wildcard src/*.sv) $(wildcard tb/common/*.sv) $(wildcard src/axi2per/*.sv) $(wildcard src/axi_slice/*.sv) \
$(wildcard src/axi_node/*.sv) $(wildcard src/axi_mem_if/src/*.sv) $(filter-out src/debug/dm_pkg.sv, $(wildcard src/debug/*.sv))
src := $(wildcard src/*.sv) $(wildcard tb/common/*.sv) $(wildcard tb/common/*.v) $(wildcard src/axi2per/*.sv) \
$(wildcard src/axi_slice/*.sv) \
$(wildcard src/axi_node/*.sv) $(wildcard src/axi_mem_if/src/*.sv) \
$(filter-out src/debug/dm_pkg.sv, $(wildcard src/debug/*.sv)) $(wildcard bootrom/*.sv) \
$(wildcard src/debug/debug_rom/*.sv)
# look for testbenches
tbs := tb/alu_tb.sv tb/core_tb.sv tb/dcache_arbiter_tb.sv tb/store_queue_tb.sv tb/scoreboard_tb.sv tb/fifo_tb.sv
tbs := tb/alu_tb.sv tb/ariane_tb.sv tb/ariane_testharness.sv tb/dcache_arbiter_tb.sv tb/store_queue_tb.sv tb/scoreboard_tb.sv tb/fifo_tb.sv
# RISCV-tests path
riscv-test-dir := tmp/riscv-tests/build/isa
@ -96,14 +99,15 @@ $(library)/.build-srcs: $(util) $(src)
# build TBs
$(library)/.build-tb: $(dpi) $(tbs)
# Compile top level
vlog$(questa_version) -sv $(tbs) -work $(library) $(filter %.c %.cc, $(dpi)) -ccflags "-g -std=c++11 " -dpiheader tb/dpi/elfdpi.h
vlog$(questa_version) -sv $(tbs) -work $(library)
touch $(library)/.build-tb
# compile DPIs
$(library)/.build-dpi: $(dpi)
# Compile C-code and generate .so file
g++ -c -fPIC -m64 -std=c++0x -I$(QUESTASIM_HOME)/include -shared -o $(library)/elf_dpi.o -c $(filter %.c %.cc, $(dpi))
g++ -shared -m64 -o $(library)/elf_dpi.so $(library)/elf_dpi.o
# g++ -lfesvr -c -fPIC -m64 -std=c++0x -I$(QUESTASIM_HOME)/include -o $(library)/ariane_dpi.o tb/dpi/SimDTM.cc
# g++ -shared -m64 -o $(library)/ariane_dpi.so $(library)/ariane_dpi.o -lfesvr
gcc -shared -fPIC -std=c++0x -Bsymbolic -I$(QUESTASIM_HOME)/include -o work/ariane_dpi.so tb/dpi/SimDTM.cc -lfesvr -lstdc++
touch $(library)/.build-dpi
# Compile Sequences and Tests
@ -127,34 +131,35 @@ $(library):
vlib${questa_version} ${library}
sim: build
vsim${questa_version} -64 -lib ${library} ${top_level}_optimized +UVM_TESTNAME=${test_case} +BASEDIR=$(riscv-test-dir) -noautoldlibpath \
+ASMTEST=$(riscv-test) $(uvm-flags) +UVM_VERBOSITY=HIGH -coverage -classdebug -sv_lib $(library)/elf_dpi -do "do tb/wave/wave_core.do"
vsim${questa_version} -64 -lib ${library} ${top_level}_optimized +UVM_TESTNAME=${test_case} +BASEDIR=$(riscv-test-dir) \
+ASMTEST=$(riscv-test) $(uvm-flags) +UVM_VERBOSITY=HIGH -coverage -classdebug -sv_lib $(library)/ariane_dpi -do "do tb/wave/wave_core.do"
sim_nopt: build
vsim${questa_version} -64 -novopt -lib ${library} ${top_level} +UVM_TESTNAME=${test_case} +BASEDIR=$(riscv-test-dir) \
+ASMTEST=$(riscv-test) $(uvm-flags) +UVM_VERBOSITY=HIGH -coverage -classdebug -sv_lib $(library)/elf_dpi -do "do tb/wave/wave_core.do"
vsim${questa_version} -64 -novopt -lib ${library} ${top_level} +UVM_TESTNAME=${test_case} +BASEDIR=$(riscv-test-dir) \
+ASMTEST=$(riscv-test) $(uvm-flags) +UVM_VERBOSITY=HIGH -coverage -classdebug -sv_lib $(library)/ariane_dpi -do "do tb/wave/wave_core.do"
simc: build
vsim${questa_version} -64 -c -lib ${library} ${top_level}_optimized +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} -noautoldlibpath \
+BASEDIR=$(riscv-test-dir) $(uvm-flags) +ASMTEST=$(riscv-test) "+UVM_VERBOSITY=HIGH" -coverage -classdebug -sv_lib $(library)/elf_dpi -do "run -all; do tb/wave/wave_core.do; exit"
vsim${questa_version} +permissive -64 -c -lib ${library} +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \
+BASEDIR=$(riscv-test-dir) $(uvm-flags) "+UVM_VERBOSITY=HIGH" -coverage -classdebug\
-gblso $(RISCV)/lib/libfesvr.so -sv_lib $(library)/ariane_dpi -do "run -all; do tb/wave/wave_core.do; exit" +permissive-off ${top_level}_optimized
run-asm-tests: build
$(foreach test, $(riscv-tests), vsim$(questa_version) -64 +BASEDIR=$(riscv-test-dir) +max-cycles=$(max_cycles) \
+UVM_TESTNAME=$(test_case) $(uvm-flags) +ASMTEST=$(test) +uvm_set_action="*,_ALL_,UVM_ERROR,UVM_DISPLAY|UVM_STOP" -c \
-coverage -classdebug -sv_lib $(library)/elf_dpi -do "coverage save -onexit $@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \
-coverage -classdebug -sv_lib $(library)/ariane_dpi -do "coverage save -onexit $@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \
$(library).$(test_top_level)_optimized;)
run-asm-tests-verilator: verilate
$(foreach test, $(riscv-tests), obj_dir/Variane_wrapped --label="Starting: $(riscv-test-dir)/$(test)" $(riscv-test-dir)/$(test);)
$(foreach test, $(riscv-tests), obj_dir/Variane_testharness --label="Starting: $(riscv-test-dir)/$(test)" $(riscv-test-dir)/$(test);)
run-failed-tests: build
# make the tests
cd failedtests && make
# run the RTL simulation
$(foreach test, $(failed-tests:.S=), vsim$(questa_version) -64 +BASEDIR=. +max-cycles=$(max_cycles) \
+UVM_TESTNAME=$(test_case) $(uvm-flags) +ASMTEST=$(test) +signature=$(test).rtlsim.sig +uvm_set_action="*,_ALL_,UVM_ERROR,UVM_DISPLAY|UVM_STOP" -c \
-coverage -classdebug -sv_lib $(library)/elf_dpi -do "coverage save -onexit $@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \
+UVM_TESTNAME=$(test_case) $(uvm-flags) +ASMTEST=$(test) +signature=$(test).rtlsim.sig +uvm_set_action="*,_ALL_,UVM_ERROR,UVM_DISPLAY|UVM_STOP" -c \
-coverage -classdebug -sv_lib $(library)/ariane_dpi -do "coverage save -onexit $@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \
$(library).$(test_top_level)_optimized;)
# run it on spike
$(foreach test, $(failed-tests:.S=), spike +signature=$(test).spike.sig $(test);)
@ -168,7 +173,7 @@ $(tests): build
# vsim${questa_version} $@_tb_optimized
# vsim${questa_version} +UVM_TESTNAME=$@_test -coverage -classdebug $@_tb_optimized
vsim${questa_version} -64 +UVM_TESTNAME=$@_test +ASMTEST=$(riscv-test-dir)/$(riscv-test) \
+uvm_set_action="*,_ALL_,UVM_ERROR,UVM_DISPLAY|UVM_STOP" -c -coverage -classdebug -sv_lib $(library)/elf_dpi \
+uvm_set_action="*,_ALL_,UVM_ERROR,UVM_DISPLAY|UVM_STOP" -c -coverage -classdebug -sv_lib $(library)/ariane_dpi \
-do "coverage save -onexit $@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \
${library}.$@_tb_optimized
@ -176,12 +181,13 @@ $(tests): build
verilate:
$(verilator) \
$(ariane_pkg) \
tb/ariane_testharness.sv \
$(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \
$(wildcard src/axi_slice/*.sv) \
$(filter-out src/debug/dm_pkg.sv, $(wildcard src/debug/*.sv)) \
src/debug/debug_rom/debug_rom.sv \
src/util/generic_fifo.sv \
tb/common/SimDTM.v \
tb/common/SimDTM.sv \
bootrom/bootrom.sv \
src/util/cluster_clock_gating.sv \
src/util/behav_sram.sv \
@ -199,8 +205,8 @@ verilate:
-Wno-UNUSED \
-Wno-ASSIGNDLY \
-LDFLAGS "-lfesvr" -CFLAGS "-std=c++11" -Wall --cc --trace --vpi --trace-structs \
$(list_incdir) --top-module ariane_wrapped --exe tb/ariane_tb.cpp tb/dpi/SimDTM.cc
cd obj_dir && make -j8 -f Variane_wrapped.mk
$(list_incdir) --top-module ariane_testharness --exe tb/ariane_tb.cpp tb/dpi/SimDTM.cc
cd obj_dir && make -j8 -f Variane_testharness.mk
# -Werror-UNDRIVEN
# -Werror-BLKSEQ

View file

@ -16,7 +16,6 @@ import ariane_pkg::*;
`ifndef verilator
`ifndef SYNTHESIS
import instruction_tracer_pkg::*;
`timescale 1ns / 1ps
`endif
`endif

View file

@ -1,238 +0,0 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
// Author: Florian Zaruba, ETH Zurich
// Date: 19.03.2017
// Description: Test-harness for Ariane
// Instantiates an AXI-Bus and memories
import ariane_pkg::*;
module ariane_wrapped #(
parameter logic [63:0] CACHE_START_ADDR = 64'h8000_0000, // address on which to decide whether the request is cache-able or not
parameter int unsigned AXI_ID_WIDTH = 10,
parameter int unsigned AXI_USER_WIDTH = 1,
parameter int unsigned AXI_ADDRESS_WIDTH = 64,
parameter int unsigned AXI_DATA_WIDTH = 64,
parameter int unsigned NUM_WORDS = 2**24 // memory size
)(
input logic clk_i,
input logic rst_ni,
output logic [31:0] exit_o
);
// disable test-enable
logic test_en;
logic ndmreset;
logic ndmreset_n;
logic debug_req;
logic debug_req_valid;
logic debug_req_ready;
logic [6:0] debug_req_bits_addr;
logic [1:0] debug_req_bits_op;
logic [31:0] debug_req_bits_data;
logic debug_resp_valid;
logic debug_resp_ready;
logic [1:0] debug_resp_bits_resp;
logic [31:0] debug_resp_bits_data;
assign test_en = 1'b0;
assign ndmreset_n = ~ndmreset ;
localparam NB_SLAVE = 3;
localparam NB_MASTER = 3;
localparam AXI_ID_WIDTH_SLAVES = AXI_ID_WIDTH + $clog2(NB_SLAVE);
AXI_BUS #(
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_ID_WIDTH ( AXI_ID_WIDTH ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) slave[NB_SLAVE-1:0]();
AXI_BUS #(
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_ID_WIDTH ( AXI_ID_WIDTH_SLAVES ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) master[NB_MASTER-1:0]();
// ---------------
// Debug
// ---------------
// SiFive's SimDTM Module
// Converts to DPI calls
SimDTM i_SimDTM (
.clk ( clk_i ),
.reset ( ~rst_ni ),
.debug_req_valid ( debug_req_valid ),
.debug_req_ready ( debug_req_ready ),
.debug_req_bits_addr ( debug_req_bits_addr ),
.debug_req_bits_op ( debug_req_bits_op ),
.debug_req_bits_data ( debug_req_bits_data ),
.debug_resp_valid ( debug_resp_valid ),
.debug_resp_ready ( debug_resp_ready ),
.debug_resp_bits_resp ( debug_resp_bits_resp ),
.debug_resp_bits_data ( debug_resp_bits_data ),
.exit ( exit_o )
);
// debug module
dm_top #(
.NrHarts ( 1 ), // current implementation only supports 1 hart
.AxiIdWidth ( AXI_ID_WIDTH_SLAVES ),
.AxiAddrWidth ( AXI_ADDRESS_WIDTH ),
.AxiDataWidth ( AXI_DATA_WIDTH ),
.AxiUserWidth ( AXI_USER_WIDTH )
) i_dm_top (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ), // PoR
.ndmreset_o ( ndmreset ),
.dmactive_o ( ), // active debug session
.debug_req_o ( debug_req ),
.axi_slave ( master[2] ),
.dmi_rst_ni ( rst_ni ),
.dmi_req_valid_i ( debug_req_valid ),
.dmi_req_ready_o ( debug_req_ready ),
.dmi_req_bits_addr_i ( debug_req_bits_addr ),
.dmi_req_bits_op_i ( debug_req_bits_op ),
.dmi_req_bits_data_i ( debug_req_bits_data ),
.dmi_resp_valid_o ( debug_resp_valid ),
.dmi_resp_ready_i ( debug_resp_ready ),
.dmi_resp_bits_resp_o ( debug_resp_bits_resp ),
.dmi_resp_bits_data_o ( debug_resp_bits_data )
);
// ---------------
// ROM
// ---------------
logic rom_req;
logic [AXI_ADDRESS_WIDTH-1:0] rom_addr;
logic [AXI_DATA_WIDTH-1:0] rom_rdata;
axi2mem #(
.AXI_ID_WIDTH ( AXI_ID_WIDTH_SLAVES ),
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) i_axi2rom (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
.slave ( master[1] ),
.req_o ( rom_req ),
.we_o ( ),
.addr_o ( rom_addr ),
.be_o ( ),
.data_o ( ),
.data_i ( rom_rdata )
);
bootrom i_bootrom (
.clk_i ( clk_i ),
.req_i ( rom_req ),
.addr_i ( rom_addr ),
.rdata_o ( rom_rdata )
);
// ---------------
// Memory
// ---------------
logic req;
logic we;
logic [AXI_ADDRESS_WIDTH-1:0] addr;
logic [AXI_DATA_WIDTH/8-1:0] be;
logic [AXI_DATA_WIDTH-1:0] wdata;
logic [AXI_DATA_WIDTH-1:0] rdata;
logic [AXI_DATA_WIDTH-1:0] bit_en;
// convert byte enable to bit enable
for (genvar i = 0; i < AXI_DATA_WIDTH/8; i++) begin
assign bit_en[i*8 +: 8] = {8{be[i]}};
end
axi2mem #(
.AXI_ID_WIDTH ( AXI_ID_WIDTH_SLAVES ),
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) i_axi2mem (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
.slave ( master[0] ),
.req_o ( req ),
.we_o ( we ),
.addr_o ( addr ),
.be_o ( be ),
.data_o ( wdata ),
.data_i ( rdata )
);
sram #(
.DATA_WIDTH ( AXI_DATA_WIDTH ),
.NUM_WORDS ( NUM_WORDS )
) i_sram (
.clk_i ( clk_i ),
.req_i ( req ),
.we_i ( we ),
.addr_i ( addr[$clog2(NUM_WORDS)-1+$clog2(AXI_DATA_WIDTH/8):$clog2(AXI_DATA_WIDTH/8)] ),
.wdata_i ( wdata ),
.be_i ( bit_en ),
.rdata_o ( rdata )
);
// ---------------
// AXI Xbar
// ---------------
axi_node_intf_wrap #(
// three ports from Ariane (instruction, data and bypass)
.NB_SLAVE ( NB_SLAVE ),
.NB_MASTER ( NB_MASTER ), // debug unit, memory unit
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH ),
.AXI_ID_WIDTH ( AXI_ID_WIDTH )
) i_axi_xbar (
.clk ( clk_i ),
.rst_n ( ndmreset_n ),
.test_en_i ( test_en ),
.slave ( slave ),
.master ( master ),
.start_addr_i ( {64'h0, 64'h10000, CACHE_START_ADDR} ),
.end_addr_i ( {64'hFFF, 64'h1FFFF, CACHE_START_ADDR + 2**24} )
);
// ---------------
// Core
// ---------------
ariane #(
.CACHE_START_ADDR ( CACHE_START_ADDR ),
.AXI_ID_WIDTH ( AXI_ID_WIDTH ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
) i_ariane (
.clk_i ( clk_i ),
.rst_ni ( ndmreset_n ),
.test_en_i ( test_en ),
.boot_addr_i ( 64'h10040 ), // start fetching from ROM
.core_id_i ( '0 ),
.cluster_id_i ( '0 ),
.irq_i ( '0 ),
.ipi_i ( '0 ),
.time_i ( '0 ),
.time_irq_i ( '0 ),
.debug_req_i ( debug_req ),
.flush_dcache_i ( 1'b0 ),
.flush_dcache_ack_o ( ),
.data_if ( slave[2] ),
.bypass_if ( slave[1] ),
.instr_if ( slave[0] )
);
endmodule

View file

@ -55,8 +55,8 @@ module dm_csrs #(
output logic [dm::ProgBufSize-1:0][31:0] progbuf_o, // to system bus
output logic [dm::DataCount-1:0][31:0] data_o,
output logic [dm::DataCount-1:0][31:0] data_i,
output logic data_valid_i
input logic [dm::DataCount-1:0][31:0] data_i,
input logic data_valid_i
);
// the amount of bits we need to represent all harts
localparam HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
@ -68,11 +68,15 @@ module dm_csrs #(
logic resp_queue_push;
logic [31:0] resp_queue_data;
localparam dm::dm_csr_t DataEnd = dm::dm_csr_t'((dm::Data0 + dm::DataCount));
localparam dm::dm_csr_t ProgBufEnd = dm::dm_csr_t'((dm::ProgBuf0 + dm::ProgBufSize));
assign hartsel_o = {dmcontrol_q.hartselhi, dmcontrol_q.hartsello};
logic [31:0] haltsum0, haltsum1, haltsum2, haltsum3;
// TODO(zarubaf) Need an elegant way to calculate haltsums
for (genvar i = 0; i < 32; i++) begin
assign haltsum0[i] = halted_i[i];
// assign haltsum0[i] = halted_i[i];
// TODO(zarubaf) Implement correct haltsum logic
// assign haltsum0[i] = halted_i[hartsel[19:5]];
// assign haltsum1[i] = (NrHarts > 32) ? &halted_i[hartsel[19:10] +: 32] : 1'b0;
@ -143,14 +147,14 @@ module dm_csrs #(
progbuf_d = progbuf_q;
data_d = data_q;
resp_queue_data = 32'0;
resp_queue_data = 32'b0;
cmd_valid_o = 1'b0;
ackhavereset_o = 'b0;
// read
if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin
unique case (dm::dm_csr_t'({1'b0, dmi_req_bits_addr_i})) inside
[(dm::Data0):(dm::Data0 + dm::DataCount)]: begin
unique case ({1'b0, dmi_req_bits_addr_i}) inside
[(dm::Data0):DataEnd]: begin
if (dm::DataCount > 0)
resp_queue_data = data_q[dmi_req_bits_addr_i[4:0]];
end
@ -160,7 +164,7 @@ module dm_csrs #(
dm::AbstractCS: resp_queue_data = abstractcs;
// command is read-only
dm::Command: resp_queue_data = '0;
[(dm::ProgBuf0):(dm::ProgBuf0 + dm::ProgBufSize)]: begin
[(dm::ProgBuf0):ProgBufEnd]: begin
resp_queue_data = progbuf_q[dmi_req_bits_addr_i[4:0]];
end
dm::HaltSum0: resp_queue_data = haltsum0;
@ -174,7 +178,7 @@ module dm_csrs #(
// write
if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_WRITE) begin
unique case (dm::dm_csr_t'({1'b0, dmi_req_bits_addr_i})) inside
[(dm::Data0):(dm::Data0 + dm::DataCount)]: begin
[(dm::Data0):DataEnd]: begin
// attempts to write them while busy is set does not change their value
if (!cmdbusy_i && dm::DataCount > 0) begin
data_d[dmi_req_bits_addr_i[4:0]] = dmi_req_bits_data_i;
@ -198,7 +202,7 @@ module dm_csrs #(
abstractcs = dm::abstractcs_t'(dmi_req_bits_data_i);
// reads during abstract command execution are not allowed
if (!cmdbusy_i) begin
cmderr_d = ~abstractcs.cmderr & cmderr_q;
cmderr_d = dm::cmderr_t'(~abstractcs.cmderr & cmderr_q);
end else if (cmderr_q == dm::CmdErrNone) begin
cmderr_d = dm::CmdErrBusy;
end
@ -215,7 +219,7 @@ module dm_csrs #(
cmderr_d = dm::CmdErrBusy;
end
end
[(dm::ProgBuf0):(dm::ProgBuf0 + dm::ProgBufSize)]: begin
[(dm::ProgBuf0):ProgBufEnd]: begin
// attempts to write them while busy is set does not change their value
if (!cmdbusy_i) begin
progbuf_d[dmi_req_bits_addr_i[4:0]] = dmi_req_bits_data_i;

View file

@ -34,7 +34,7 @@ module dm_mem #(
input logic [dm::ProgBufSize-1:0][31:0] progbuf_i, // program buffer to expose
output logic [dm::DataCount-1:0][31:0] data_i, // data in
input logic [dm::DataCount-1:0][31:0] data_i, // data in
output logic [dm::DataCount-1:0][31:0] data_o, // data out
output logic data_valid_o, // data out is valid
// abstract command interface
@ -96,7 +96,7 @@ module dm_mem #(
// hart ctrl queue
always_comb begin
cmderror_valid_o = 1'b0;
cmderror_o = '0;
cmderror_o = dm::CmdErrNone;
state_d = state_q;
go = 1'b0;
resume = 1'b0;

View file

@ -37,6 +37,16 @@ package dm;
// debug registers
typedef enum logic [7:0] {
Data0 = 8'h04,
Data1 = 8'h05,
Data2 = 8'h06,
Data3 = 8'h07,
Data4 = 8'h08,
Data5 = 8'h09,
Data6 = 8'h0A,
Data7 = 8'h0B,
Data8 = 8'h0C,
Data9 = 8'h0D,
Data10 = 8'h0E,
Data11 = 8'h0F,
DMControl = 8'h10,
DMStatus = 8'h11, // r/o

View file

@ -293,7 +293,7 @@ module icache #(
evict_way_d = random_way;
// shift the lfsr
update_lfsr = 1'b1;
end else if (!|hit) begin
end else if (!(|hit)) begin
evict_way_d[repl_invalid] = 1'b1;
end
end

View file

@ -31,7 +31,7 @@ class instruction_trace_item;
logic [4:0] rs1, rs2, rs3, rd;
// constructor creating a new instruction trace item, e.g.: a single instruction with all relevant information
function new (time simtime, longint unsigned cycle, scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] reg_file [32], logic [63:0] result, logic [63:0] paddr, priv_lvl_t priv_lvl, branchpredict_t bp);
function new (time simtime, longint unsigned cycle, scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] reg_file [32], logic [63:0] result, logic [63:0] paddr, riscv::priv_lvl_t priv_lvl, branchpredict_t bp);
this.simtime = simtime;
this.cycle = cycle;
this.pc = sbe.pc;
@ -97,10 +97,10 @@ class instruction_trace_item;
riscv::CSR_MCYCLE: return "mcycle";
riscv::CSR_MINSTRET: return "minstret";
riscv::CSR_DCSR return "dcsr";
riscv::CSR_DPC return "dpc";
riscv::CSR_DSCRATCH0 return "dscratch0";
riscv::CSR_DSCRATCH1 return "dscratch0";
riscv::CSR_DCSR: return "dcsr";
riscv::CSR_DPC: return "dpc";
riscv::CSR_DSCRATCH0: return "dscratch0";
riscv::CSR_DSCRATCH1: return "dscratch0";
riscv::CSR_CYCLE: return "cycle";
riscv::CSR_TIME: return "time";
@ -239,11 +239,11 @@ class instruction_trace_item;
endfunction : printInstr
// Return the current privilege level as a string
function string getPrivLevel(input priv_lvl_t priv_lvl);
function string getPrivLevel(input riscv::priv_lvl_t priv_lvl);
case (priv_lvl)
PRIV_LVL_M: return "M";
PRIV_LVL_S: return "S";
PRIV_LVL_U: return "U";
riscv::PRIV_LVL_M: return "M";
riscv::PRIV_LVL_S: return "S";
riscv::PRIV_LVL_U: return "U";
endcase
endfunction : getPrivLevel
@ -303,7 +303,7 @@ class instruction_trace_item;
function string printJump();
string mnemonic;
case (instr[6:0])
OpcodeJalr: begin
riscv::OpcodeJalr: begin
// is this a return?
if (rd == 'b0 && (rs1 == 'h1 || rs1 == 'h5)) begin
return this.printMnemonic("ret");
@ -312,7 +312,7 @@ class instruction_trace_item;
end
end
OpcodeJal: begin
riscv::OpcodeJal: begin
if (rd == 'b0)
return this.printUJInstr("j");
else

View file

@ -177,7 +177,7 @@ class instruction_tracer;
bp = {};
endfunction
function void printInstr(scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] result, logic [63:0] paddr, priv_lvl_t priv_lvl, branchpredict_t bp);
function void printInstr(scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] result, logic [63:0] paddr, riscv::priv_lvl_t priv_lvl, branchpredict_t bp);
instruction_trace_item iti = new ($time, clk_ticks, sbe, instr, this.reg_file, result, paddr, priv_lvl, bp);
// print instruction to console
string print_instr = iti.printInstr();

View file

@ -12,95 +12,95 @@
// Date: 16.05.2017
// Description: Instruction Tracer Defines
parameter INSTR_LUI = { 25'b?, OpcodeLui };
parameter INSTR_AUIPC = { 25'b?, OpcodeAuipc };
parameter INSTR_JAL = { 25'b?, OpcodeJal };
parameter INSTR_JALR = { 17'b?, 3'b000, 5'b?, OpcodeJalr };
parameter INSTR_LUI = { 25'b?, riscv::OpcodeLui };
parameter INSTR_AUIPC = { 25'b?, riscv::OpcodeAuipc };
parameter INSTR_JAL = { 25'b?, riscv::OpcodeJal };
parameter INSTR_JALR = { 17'b?, 3'b000, 5'b?, riscv::OpcodeJalr };
// BRANCH
parameter INSTR_BEQZ = { 7'b?, 5'b0, 5'b?, 3'b000, 5'b?, OpcodeBranch };
parameter INSTR_BEQ = { 7'b?, 5'b?, 5'b?, 3'b000, 5'b?, OpcodeBranch };
parameter INSTR_BNEZ = { 7'b?, 5'b0, 5'b?, 3'b001, 5'b?, OpcodeBranch };
parameter INSTR_BNE = { 7'b?, 5'b?, 5'b?, 3'b001, 5'b?, OpcodeBranch };
parameter INSTR_BLTZ = { 7'b?, 5'b0, 5'b?, 3'b100, 5'b?, OpcodeBranch };
parameter INSTR_BLT = { 7'b?, 5'b?, 5'b?, 3'b100, 5'b?, OpcodeBranch };
parameter INSTR_BGEZ = { 7'b?, 5'b0, 5'b?, 3'b101, 5'b?, OpcodeBranch };
parameter INSTR_BGE = { 7'b?, 5'b?, 5'b?, 3'b101, 5'b?, OpcodeBranch };
parameter INSTR_BLTU = { 7'b?, 5'b?, 5'b?, 3'b110, 5'b?, OpcodeBranch };
parameter INSTR_BGEU = { 7'b?, 5'b?, 5'b?, 3'b111, 5'b?, OpcodeBranch };
parameter INSTR_BEQZ = { 7'b?, 5'b0, 5'b?, 3'b000, 5'b?, riscv::OpcodeBranch };
parameter INSTR_BEQ = { 7'b?, 5'b?, 5'b?, 3'b000, 5'b?, riscv::OpcodeBranch };
parameter INSTR_BNEZ = { 7'b?, 5'b0, 5'b?, 3'b001, 5'b?, riscv::OpcodeBranch };
parameter INSTR_BNE = { 7'b?, 5'b?, 5'b?, 3'b001, 5'b?, riscv::OpcodeBranch };
parameter INSTR_BLTZ = { 7'b?, 5'b0, 5'b?, 3'b100, 5'b?, riscv::OpcodeBranch };
parameter INSTR_BLT = { 7'b?, 5'b?, 5'b?, 3'b100, 5'b?, riscv::OpcodeBranch };
parameter INSTR_BGEZ = { 7'b?, 5'b0, 5'b?, 3'b101, 5'b?, riscv::OpcodeBranch };
parameter INSTR_BGE = { 7'b?, 5'b?, 5'b?, 3'b101, 5'b?, riscv::OpcodeBranch };
parameter INSTR_BLTU = { 7'b?, 5'b?, 5'b?, 3'b110, 5'b?, riscv::OpcodeBranch };
parameter INSTR_BGEU = { 7'b?, 5'b?, 5'b?, 3'b111, 5'b?, riscv::OpcodeBranch };
// OPIMM
parameter INSTR_LI = { 12'b?, 5'b0, 3'b000, 5'b?, OpcodeOpimm };
parameter INSTR_ADDI = { 17'b?, 3'b000, 5'b?, OpcodeOpimm };
parameter INSTR_SLTI = { 17'b?, 3'b010, 5'b?, OpcodeOpimm };
parameter INSTR_SLTIU = { 17'b?, 3'b011, 5'b?, OpcodeOpimm };
parameter INSTR_XORI = { 17'b?, 3'b100, 5'b?, OpcodeOpimm };
parameter INSTR_ORI = { 17'b?, 3'b110, 5'b?, OpcodeOpimm };
parameter INSTR_ANDI = { 17'b?, 3'b111, 5'b?, OpcodeOpimm };
parameter INSTR_SLLI = { 6'b000000, 11'b?, 3'b001, 5'b?, OpcodeOpimm };
parameter INSTR_SRLI = { 6'b000000, 11'b?, 3'b101, 5'b?, OpcodeOpimm };
parameter INSTR_SRAI = { 6'b010000, 11'b?, 3'b101, 5'b?, OpcodeOpimm };
parameter INSTR_LI = { 12'b?, 5'b0, 3'b000, 5'b?, riscv::OpcodeOpimm };
parameter INSTR_ADDI = { 17'b?, 3'b000, 5'b?, riscv::OpcodeOpimm };
parameter INSTR_SLTI = { 17'b?, 3'b010, 5'b?, riscv::OpcodeOpimm };
parameter INSTR_SLTIU = { 17'b?, 3'b011, 5'b?, riscv::OpcodeOpimm };
parameter INSTR_XORI = { 17'b?, 3'b100, 5'b?, riscv::OpcodeOpimm };
parameter INSTR_ORI = { 17'b?, 3'b110, 5'b?, riscv::OpcodeOpimm };
parameter INSTR_ANDI = { 17'b?, 3'b111, 5'b?, riscv::OpcodeOpimm };
parameter INSTR_SLLI = { 6'b000000, 11'b?, 3'b001, 5'b?, riscv::OpcodeOpimm };
parameter INSTR_SRLI = { 6'b000000, 11'b?, 3'b101, 5'b?, riscv::OpcodeOpimm };
parameter INSTR_SRAI = { 6'b010000, 11'b?, 3'b101, 5'b?, riscv::OpcodeOpimm };
// OPIMM32
parameter INSTR_ADDIW = { 17'b?, 3'b000, 5'b?, OpcodeOpimm32 };
parameter INSTR_SLLIW = { 7'b0000000, 10'b?, 3'b001, 5'b?, OpcodeOpimm32 };
parameter INSTR_SRLIW = { 7'b0000000, 10'b?, 3'b101, 5'b?, OpcodeOpimm32 };
parameter INSTR_SRAIW = { 7'b0100000, 10'b?, 3'b101, 5'b?, OpcodeOpimm32 };
parameter INSTR_ADDIW = { 17'b?, 3'b000, 5'b?, riscv::OpcodeOpimm32 };
parameter INSTR_SLLIW = { 7'b0000000, 10'b?, 3'b001, 5'b?, riscv::OpcodeOpimm32 };
parameter INSTR_SRLIW = { 7'b0000000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOpimm32 };
parameter INSTR_SRAIW = { 7'b0100000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOpimm32 };
// OP
parameter INSTR_ADD = { 7'b0000000, 10'b?, 3'b000, 5'b?, OpcodeOp };
parameter INSTR_SUB = { 7'b0100000, 10'b?, 3'b000, 5'b?, OpcodeOp };
parameter INSTR_SLL = { 7'b0000000, 10'b?, 3'b001, 5'b?, OpcodeOp };
parameter INSTR_SLT = { 7'b0000000, 10'b?, 3'b010, 5'b?, OpcodeOp };
parameter INSTR_SLTU = { 7'b0000000, 10'b?, 3'b011, 5'b?, OpcodeOp };
parameter INSTR_XOR = { 7'b0000000, 10'b?, 3'b100, 5'b?, OpcodeOp };
parameter INSTR_SRL = { 7'b0000000, 10'b?, 3'b101, 5'b?, OpcodeOp };
parameter INSTR_SRA = { 7'b0100000, 10'b?, 3'b101, 5'b?, OpcodeOp };
parameter INSTR_OR = { 7'b0000000, 10'b?, 3'b110, 5'b?, OpcodeOp };
parameter INSTR_AND = { 7'b0000000, 10'b?, 3'b111, 5'b?, OpcodeOp };
parameter INSTR_MUL = { 7'b0000001, 10'b?, 3'b???, 5'b?, OpcodeOp };
parameter INSTR_ADD = { 7'b0000000, 10'b?, 3'b000, 5'b?, riscv::OpcodeOp };
parameter INSTR_SUB = { 7'b0100000, 10'b?, 3'b000, 5'b?, riscv::OpcodeOp };
parameter INSTR_SLL = { 7'b0000000, 10'b?, 3'b001, 5'b?, riscv::OpcodeOp };
parameter INSTR_SLT = { 7'b0000000, 10'b?, 3'b010, 5'b?, riscv::OpcodeOp };
parameter INSTR_SLTU = { 7'b0000000, 10'b?, 3'b011, 5'b?, riscv::OpcodeOp };
parameter INSTR_XOR = { 7'b0000000, 10'b?, 3'b100, 5'b?, riscv::OpcodeOp };
parameter INSTR_SRL = { 7'b0000000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOp };
parameter INSTR_SRA = { 7'b0100000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOp };
parameter INSTR_OR = { 7'b0000000, 10'b?, 3'b110, 5'b?, riscv::OpcodeOp };
parameter INSTR_AND = { 7'b0000000, 10'b?, 3'b111, 5'b?, riscv::OpcodeOp };
parameter INSTR_MUL = { 7'b0000001, 10'b?, 3'b???, 5'b?, riscv::OpcodeOp };
// OP32
parameter INSTR_ADDW = { 7'b0000000, 10'b?, 3'b000, 5'b?, OpcodeOp32 };
parameter INSTR_SUBW = { 7'b0100000, 10'b?, 3'b000, 5'b?, OpcodeOp32 };
parameter INSTR_SLLW = { 7'b0000000, 10'b?, 3'b001, 5'b?, OpcodeOp32 };
parameter INSTR_SRLW = { 7'b0000000, 10'b?, 3'b101, 5'b?, OpcodeOp32 };
parameter INSTR_SRAW = { 7'b0100000, 10'b?, 3'b101, 5'b?, OpcodeOp32 };
parameter INSTR_MULW = { 7'b0000001, 10'b?, 3'b???, 5'b?, OpcodeOp32 };
parameter INSTR_ADDW = { 7'b0000000, 10'b?, 3'b000, 5'b?, riscv::OpcodeOp32 };
parameter INSTR_SUBW = { 7'b0100000, 10'b?, 3'b000, 5'b?, riscv::OpcodeOp32 };
parameter INSTR_SLLW = { 7'b0000000, 10'b?, 3'b001, 5'b?, riscv::OpcodeOp32 };
parameter INSTR_SRLW = { 7'b0000000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOp32 };
parameter INSTR_SRAW = { 7'b0100000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOp32 };
parameter INSTR_MULW = { 7'b0000001, 10'b?, 3'b???, 5'b?, riscv::OpcodeOp32 };
// FENCE
parameter INSTR_FENCE = { 4'b0, 8'b?, 13'b0, OpcodeFence };
parameter INSTR_FENCEI = { 17'b0, 3'b001, 5'b0, OpcodeFence };
parameter INSTR_FENCE = { 4'b0, 8'b?, 13'b0, riscv::OpcodeFence };
parameter INSTR_FENCEI = { 17'b0, 3'b001, 5'b0, riscv::OpcodeFence };
// SYSTEM
parameter INSTR_CSRW = { 12'b?, 5'b?, 3'b001, 5'b0, OpcodeSystem };
parameter INSTR_CSRRW = { 12'b?, 5'b?, 3'b001, 5'b?, OpcodeSystem };
parameter INSTR_CSRR = { 12'b?, 5'b0, 3'b010, 5'b?, OpcodeSystem };
parameter INSTR_CSRRS = { 12'b?, 5'b?, 3'b010, 5'b?, OpcodeSystem };
parameter INSTR_CSRS = { 12'b?, 5'b?, 3'b010, 5'b0, OpcodeSystem };
parameter INSTR_CSRRC = { 12'b?, 5'b?, 3'b011, 5'b?, OpcodeSystem };
parameter INSTR_CSRC = { 12'b?, 5'b?, 3'b011, 5'b0, OpcodeSystem };
parameter INSTR_CSRW = { 12'b?, 5'b?, 3'b001, 5'b0, riscv::OpcodeSystem };
parameter INSTR_CSRRW = { 12'b?, 5'b?, 3'b001, 5'b?, riscv::OpcodeSystem };
parameter INSTR_CSRR = { 12'b?, 5'b0, 3'b010, 5'b?, riscv::OpcodeSystem };
parameter INSTR_CSRRS = { 12'b?, 5'b?, 3'b010, 5'b?, riscv::OpcodeSystem };
parameter INSTR_CSRS = { 12'b?, 5'b?, 3'b010, 5'b0, riscv::OpcodeSystem };
parameter INSTR_CSRRC = { 12'b?, 5'b?, 3'b011, 5'b?, riscv::OpcodeSystem };
parameter INSTR_CSRC = { 12'b?, 5'b?, 3'b011, 5'b0, riscv::OpcodeSystem };
parameter INSTR_CSRWI = { 17'b?, 3'b101, 5'b0, OpcodeSystem };
parameter INSTR_CSRRWI = { 17'b?, 3'b101, 5'b?, OpcodeSystem };
parameter INSTR_CSRSI = { 17'b?, 3'b110, 5'b0, OpcodeSystem };
parameter INSTR_CSRRSI = { 17'b?, 3'b110, 5'b?, OpcodeSystem };
parameter INSTR_CSRCI = { 17'b?, 3'b111, 5'b0, OpcodeSystem };
parameter INSTR_CSRRCI = { 17'b?, 3'b111, 5'b?, OpcodeSystem };
parameter INSTR_CSRWI = { 17'b?, 3'b101, 5'b0, riscv::OpcodeSystem };
parameter INSTR_CSRRWI = { 17'b?, 3'b101, 5'b?, riscv::OpcodeSystem };
parameter INSTR_CSRSI = { 17'b?, 3'b110, 5'b0, riscv::OpcodeSystem };
parameter INSTR_CSRRSI = { 17'b?, 3'b110, 5'b?, riscv::OpcodeSystem };
parameter INSTR_CSRCI = { 17'b?, 3'b111, 5'b0, riscv::OpcodeSystem };
parameter INSTR_CSRRCI = { 17'b?, 3'b111, 5'b?, riscv::OpcodeSystem };
parameter INSTR_ECALL = { 12'b000000000000, 13'b0, OpcodeSystem };
parameter INSTR_EBREAK = { 12'b000000000001, 13'b0, OpcodeSystem };
parameter INSTR_MRET = { 12'b001100000010, 13'b0, OpcodeSystem };
parameter INSTR_SRET = { 12'b000100000010, 13'b0, OpcodeSystem };
parameter INSTR_DRET = { 12'b011110110010, 13'b0, OpcodeSystem };
parameter INSTR_WFI = { 12'b000100000101, 13'b0, OpcodeSystem };
parameter INSTR_SFENCE = { 12'b0001001?????, 13'b?, OpcodeSystem };
parameter INSTR_ECALL = { 12'b000000000000, 13'b0, riscv::OpcodeSystem };
parameter INSTR_EBREAK = { 12'b000000000001, 13'b0, riscv::OpcodeSystem };
parameter INSTR_MRET = { 12'b001100000010, 13'b0, riscv::OpcodeSystem };
parameter INSTR_SRET = { 12'b000100000010, 13'b0, riscv::OpcodeSystem };
parameter INSTR_DRET = { 12'b011110110010, 13'b0, riscv::OpcodeSystem };
parameter INSTR_WFI = { 12'b000100000101, 13'b0, riscv::OpcodeSystem };
parameter INSTR_SFENCE = { 12'b0001001?????, 13'b?, riscv::OpcodeSystem };
// RV32M
parameter INSTR_PMUL = { 7'b0000001, 10'b?, 3'b000, 5'b?, OpcodeOp };
parameter INSTR_DIV = { 7'b0000001, 10'b?, 3'b100, 5'b?, OpcodeOp };
parameter INSTR_DIVU = { 7'b0000001, 10'b?, 3'b101, 5'b?, OpcodeOp };
parameter INSTR_REM = { 7'b0000001, 10'b?, 3'b110, 5'b?, OpcodeOp };
parameter INSTR_REMU = { 7'b0000001, 10'b?, 3'b111, 5'b?, OpcodeOp };
parameter INSTR_PMUL = { 7'b0000001, 10'b?, 3'b000, 5'b?, riscv::OpcodeOp };
parameter INSTR_DIV = { 7'b0000001, 10'b?, 3'b100, 5'b?, riscv::OpcodeOp };
parameter INSTR_DIVU = { 7'b0000001, 10'b?, 3'b101, 5'b?, riscv::OpcodeOp };
parameter INSTR_REM = { 7'b0000001, 10'b?, 3'b110, 5'b?, riscv::OpcodeOp };
parameter INSTR_REMU = { 7'b0000001, 10'b?, 3'b111, 5'b?, riscv::OpcodeOp };
// Load/Stores
parameter INSTR_LOAD = {25'b?, OpcodeLoad };
parameter INSTR_STORE = {25'b?, OpcodeStore };
parameter INSTR_LOAD = {25'b?, riscv::OpcodeLoad };
parameter INSTR_STORE = {25'b?, riscv::OpcodeStore };

View file

@ -50,7 +50,7 @@ interface instruction_tracer_if (
// exceptions
exception_t exception;
// current privilege level
priv_lvl_t priv_lvl;
riscv::priv_lvl_t priv_lvl;
// the tracer just has a passive interface we do not drive anything with it
`ifndef SYNTHESIS
clocking pck @(posedge clk);

2
tb

@ -1 +1 @@
Subproject commit b5396a3db9b3536fadf1ed4c63e44f11aa7e0f66
Subproject commit 569685a42f2de5732fafcbb3eaaebdb739746e07