mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-20 12:17:19 -04:00
Randomise I$ interface on TB
This commit is contained in:
parent
31eaa9624a
commit
31bfa5f3d3
6 changed files with 263 additions and 38 deletions
|
@ -15,9 +15,6 @@ test_alu:
|
|||
script:
|
||||
- make alu library=alu_lib
|
||||
- vcover-10.6 report alu.ucdb
|
||||
artifacts:
|
||||
paths:
|
||||
- covhtmlreport
|
||||
|
||||
test_fifo:
|
||||
stage: test
|
||||
|
@ -26,9 +23,6 @@ test_fifo:
|
|||
script:
|
||||
- make fifo library=fifo_lib
|
||||
- vcover-10.6 report fifo.ucdb
|
||||
artifacts:
|
||||
paths:
|
||||
- covhtmlreport
|
||||
|
||||
test_scoreboard:
|
||||
stage: test
|
||||
|
@ -37,9 +31,6 @@ test_scoreboard:
|
|||
script:
|
||||
- make scoreboard library=scoreboard_lib
|
||||
- vcover-10.6 report scoreboard.ucdb
|
||||
artifacts:
|
||||
paths:
|
||||
- covhtmlreport
|
||||
|
||||
test_dcache_arbiter:
|
||||
stage: test
|
||||
|
@ -48,9 +39,6 @@ test_dcache_arbiter:
|
|||
script:
|
||||
- make dcache_arbiter library=dcache_arbiter_lib
|
||||
- vcover-10.6 report dcache_arbiter.ucdb
|
||||
artifacts:
|
||||
paths:
|
||||
- covhtmlreport
|
||||
|
||||
test_store_queue:
|
||||
stage: test
|
||||
|
@ -59,9 +47,6 @@ test_store_queue:
|
|||
script:
|
||||
- make store_queue library=store_queue_lib
|
||||
- vcover-10.6 report store_queue.ucdb
|
||||
artifacts:
|
||||
paths:
|
||||
- covhtmlreport
|
||||
|
||||
test_core_asm:
|
||||
stage: test
|
||||
|
@ -72,9 +57,18 @@ test_core_asm:
|
|||
script:
|
||||
- make run-asm-tests library=core_lib
|
||||
- vcover-10.6 report run-asm-tests.ucdb
|
||||
artifacts:
|
||||
paths:
|
||||
- covhtmlreport
|
||||
|
||||
# test with the randomized memory interfaces
|
||||
test_core_asm_rand:
|
||||
stage: test
|
||||
before_script:
|
||||
- git submodule update --init --recursive
|
||||
- make build-tests
|
||||
- make build library=core_rand_lib
|
||||
script:
|
||||
# same as above but pass the rand_mem_if flag
|
||||
- make run-asm-tests library=core_rand_lib uvm-flags=+rand_mem_if
|
||||
- vcover-10.6 report run-asm-rand-tests.ucdb
|
||||
|
||||
test_failed_tests:
|
||||
stage: test
|
||||
|
@ -84,9 +78,6 @@ test_failed_tests:
|
|||
script:
|
||||
- make run-failed-tests library=failed_tests_lib
|
||||
- vcover-10.6 report run-failed-tests.ucdb
|
||||
artifacts:
|
||||
paths:
|
||||
- covhtmlreport
|
||||
|
||||
# test_lsu:
|
||||
# stage: test
|
||||
|
@ -104,10 +95,7 @@ test_failed_tests:
|
|||
pages:
|
||||
stage: deploy
|
||||
dependencies:
|
||||
- test_alu
|
||||
- test_fifo
|
||||
- test_scoreboard
|
||||
- test_dcache_arbiter
|
||||
- build_rtl
|
||||
script:
|
||||
- mkdir public
|
||||
- mkdocs build -d public
|
||||
|
|
9
Makefile
9
Makefile
|
@ -67,6 +67,7 @@ questa_version = -10.6
|
|||
compile_flag = +cover=bcfst+/dut -incr -64 -nologo -quiet -suppress 13262 -permissive
|
||||
# Moore binary
|
||||
moore = ~fschuiki/bin/moore
|
||||
uvm-flags =
|
||||
# Iterate over all include directories and write them with +incdir+ prefixed
|
||||
# +incdir+ works for Verilator and QuestaSim
|
||||
list_incdir = $(foreach dir, ${incdir}, +incdir+$(dir))
|
||||
|
@ -115,15 +116,15 @@ $(library):
|
|||
|
||||
sim: build
|
||||
vsim${questa_version} -lib ${library} ${top_level}_optimized +UVM_TESTNAME=${test_case} +BASEDIR=$(riscv-test-dir) \
|
||||
+ASMTEST=$(riscv-test) +UVM_VERBOSITY=HIGH -coverage -classdebug -do "do tb/wave/wave_core.do"
|
||||
+ASMTEST=$(riscv-test) $(uvm-flags) +UVM_VERBOSITY=HIGH -coverage -classdebug -do "do tb/wave/wave_core.do"
|
||||
|
||||
simc: build
|
||||
vsim${questa_version} -c -lib ${library} ${top_level}_optimized +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \
|
||||
+BASEDIR=$(riscv-test-dir) +UVM_VERBOSITY=HIGH +ASMTEST=$(riscv-test) -coverage -classdebug -do "do tb/wave/wave_core.do"
|
||||
+BASEDIR=$(riscv-test-dir) +UVM_VERBOSITY=HIGH $(uvm-flags) +ASMTEST=$(riscv-test) -coverage -classdebug -do "do tb/wave/wave_core.do"
|
||||
|
||||
run-asm-tests: build
|
||||
$(foreach test, $(riscv-tests), vsim$(questa_version) +BASEDIR=$(riscv-test-dir) +max-cycles=$(max_cycles) \
|
||||
+UVM_TESTNAME=$(test_case) +UVM_VERBOSITY=LOW +ASMTEST=$(test) +uvm_set_action="*,_ALL_,UVM_ERROR,UVM_DISPLAY|UVM_STOP" -c +UVM_VERBOSITY=LOW\
|
||||
+UVM_TESTNAME=$(test_case) +UVM_VERBOSITY=LOW $(uvm-flags) +ASMTEST=$(test) +uvm_set_action="*,_ALL_,UVM_ERROR,UVM_DISPLAY|UVM_STOP" -c +UVM_VERBOSITY=LOW\
|
||||
-coverage -classdebug -do "coverage save -onexit $@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \
|
||||
$(library).$(test_top_level)_optimized;)
|
||||
|
||||
|
@ -132,7 +133,7 @@ run-failed-tests: build
|
|||
cd failedtests && make
|
||||
# run the RTL simulation
|
||||
$(foreach test, $(failed-tests:.S=), vsim$(questa_version) +BASEDIR=. +max-cycles=$(max_cycles) \
|
||||
+UVM_TESTNAME=$(test_case) +ASMTEST=$(test) +signature=$(test).rtlsim.sig +uvm_set_action="*,_ALL_,UVM_ERROR,UVM_DISPLAY|UVM_STOP" -c \
|
||||
+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 -do "coverage save -onexit $@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \
|
||||
$(library).$(test_top_level)_optimized;)
|
||||
# run it on spike
|
||||
|
|
|
@ -61,7 +61,8 @@ module if_stage (
|
|||
//---------------------------------
|
||||
// we are busy if we are either waiting for a grant
|
||||
// or if the FIFO is full
|
||||
assign if_busy_o = (CS == WAIT_GNT) || !fifo_ready;
|
||||
// or if we are waiting for a rvalid and we didn't receive one yet
|
||||
assign if_busy_o = (CS == WAIT_GNT) || !fifo_ready || (CS == WAIT_RVALID && !instr_rvalid_i);
|
||||
assign fetch_address = {fetch_address_i[63:2], 2'b0};
|
||||
|
||||
//---------------------------------
|
||||
|
@ -138,6 +139,10 @@ module if_stage (
|
|||
// we wait for rvalid, after that we are ready to serve a new request
|
||||
WAIT_RVALID: begin
|
||||
instr_addr_o = fetch_address;
|
||||
|
||||
// we are waiting for a rvalid and in case we don't receive one, wait in the aborted state if we flushed
|
||||
if (flush_i)
|
||||
NS = WAIT_ABORTED;
|
||||
// prepare for next request
|
||||
if (fifo_ready && fetch_valid_i) begin
|
||||
// wait for the valid signal
|
||||
|
@ -147,7 +152,7 @@ module if_stage (
|
|||
addr_valid = 1'b1;
|
||||
|
||||
if (instr_gnt_i) begin
|
||||
// we have one outstanding rvalid: wait for it
|
||||
// we have one outstanding rvalid -> wait for it
|
||||
// if we are receiving a data item during a flush ignore it
|
||||
if (flush_i)
|
||||
NS = WAIT_ABORTED;
|
||||
|
@ -220,11 +225,11 @@ module if_stage (
|
|||
//-------------
|
||||
always_ff @(posedge clk_i, negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
CS <= IDLE;
|
||||
instr_addr_q <= '0;
|
||||
branchpredict_q <= '{default: 0};
|
||||
CS <= IDLE;
|
||||
instr_addr_q <= '0;
|
||||
branchpredict_q <= '{default: 0};
|
||||
end else begin
|
||||
CS <= NS;
|
||||
CS <= NS;
|
||||
if (addr_valid) begin
|
||||
instr_addr_q <= fetch_address_i;
|
||||
branchpredict_q <= branch_predict_i;
|
||||
|
|
|
@ -57,7 +57,7 @@ module core_mem (
|
|||
|
||||
assign data_address = {data_if_address_tag_i, index[11:3]};
|
||||
|
||||
assign #($urandom_range(0,40)) delayed_instr_request = instr_if_data_req_i;
|
||||
assign delayed_instr_request = instr_if_data_req_i;
|
||||
// we always grant the request
|
||||
assign instr_if_data_gnt_o = delayed_instr_request;
|
||||
assign instr_address = instr_if_address_i[ADDRESS_WIDTH-1+3:3];
|
||||
|
|
197
tb/common/random_stalls.sv
Executable file
197
tb/common/random_stalls.sv
Executable file
|
@ -0,0 +1,197 @@
|
|||
// Author: Andreas Traber, ACP
|
||||
// Date: 22/02/2016
|
||||
// Description: Randomly inject stalls in the instruction interface
|
||||
//
|
||||
// Copyright (C) 2017 ETH Zurich, University of Bologna
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is under development and not yet released to the public.
|
||||
// Until it is released, the code is under the copyright of ETH Zurich and
|
||||
// the University of Bologna, and may contain confidential and/or unpublished
|
||||
// work. Any reuse/redistribution is strictly forbidden without written
|
||||
// permission from ETH Zurich.
|
||||
//
|
||||
// Bug fixes and contributions will eventually be released under the
|
||||
// SolderPad open hardware license in the context of the PULP platform
|
||||
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
|
||||
// University of Bologna.
|
||||
//
|
||||
|
||||
module random_stalls
|
||||
(
|
||||
input logic clk_i,
|
||||
|
||||
input logic core_req_i,
|
||||
output logic core_gnt_o,
|
||||
input logic [63:0] core_addr_i,
|
||||
input logic core_we_i,
|
||||
input logic [ 3:0] core_be_i,
|
||||
input logic [31:0] core_wdata_i,
|
||||
output logic [31:0] core_rdata_o,
|
||||
output logic core_rvalid_o,
|
||||
|
||||
output logic data_req_o,
|
||||
input logic data_gnt_i,
|
||||
output logic [63:0] data_addr_o,
|
||||
output logic data_we_o,
|
||||
output logic [ 3:0] data_be_o,
|
||||
output logic [31:0] data_wdata_o,
|
||||
input logic [31:0] data_rdata_i,
|
||||
input logic data_rvalid_i
|
||||
);
|
||||
|
||||
class rand_wait_cycles;
|
||||
rand int n;
|
||||
constraint default_c { n >= 0 ; n < 6;}
|
||||
endclass
|
||||
|
||||
// random staller
|
||||
typedef struct {
|
||||
logic [63:0] addr;
|
||||
logic we;
|
||||
logic [ 3:0] be;
|
||||
logic [31:0] wdata;
|
||||
logic [31:0] rdata;
|
||||
} stall_mem_t;
|
||||
|
||||
mailbox core_reqs = new (4);
|
||||
mailbox core_resps = new (4);
|
||||
mailbox core_resps_granted = new (4);
|
||||
mailbox platform_transfers = new (4);
|
||||
semaphore req_served = new (1);
|
||||
// ------------------
|
||||
// Core Request Side
|
||||
// ------------------
|
||||
// Waits for requests and puts them in a queue, does not perform actual
|
||||
// requests to the platform
|
||||
initial begin
|
||||
|
||||
stall_mem_t mem_acc;
|
||||
automatic rand_wait_cycles wait_cycles = new ();
|
||||
int temp;
|
||||
|
||||
forever begin
|
||||
core_gnt_o = 1'b0;
|
||||
|
||||
#1;
|
||||
if (!core_req_i)
|
||||
continue;
|
||||
|
||||
// we got a request, now let's wait for a random number of cycles before
|
||||
// we give the grant
|
||||
temp = wait_cycles.randomize();
|
||||
|
||||
while(wait_cycles.n != 0) begin
|
||||
@(posedge clk_i);
|
||||
wait_cycles.n--;
|
||||
#1;
|
||||
end
|
||||
|
||||
// block until the we served all outstanding requests
|
||||
req_served.get();
|
||||
|
||||
// we waited for a random number of cycles, let's give the grant
|
||||
core_gnt_o = 1'b1;
|
||||
|
||||
mem_acc.addr = core_addr_i;
|
||||
mem_acc.be = core_be_i;
|
||||
mem_acc.we = core_we_i;
|
||||
mem_acc.wdata = core_wdata_i;
|
||||
|
||||
core_reqs.put(mem_acc);
|
||||
|
||||
@(posedge clk_i);
|
||||
|
||||
core_resps_granted.put(1'b1);
|
||||
end
|
||||
end
|
||||
|
||||
// ------------------
|
||||
// Core Response Side
|
||||
// ------------------
|
||||
// Waits for a response from the platform and then waits for a random number
|
||||
// of cycles before giving the rvalid
|
||||
initial begin
|
||||
stall_mem_t mem_acc;
|
||||
automatic rand_wait_cycles wait_cycles = new ();
|
||||
logic granted;
|
||||
int temp;
|
||||
|
||||
forever begin
|
||||
@(posedge clk_i);
|
||||
core_rvalid_o = 1'b0;
|
||||
core_rdata_o = 'x;
|
||||
|
||||
core_resps_granted.get(granted);
|
||||
core_resps.get(mem_acc);
|
||||
|
||||
// we got a response, now let's wait for a random amount of cycles
|
||||
// we give the grant
|
||||
temp = wait_cycles.randomize();
|
||||
|
||||
while(wait_cycles.n != 0) begin
|
||||
@(posedge clk_i);
|
||||
wait_cycles.n--;
|
||||
end
|
||||
|
||||
// put back the semaphore
|
||||
req_served.put();
|
||||
// we waited for a random number of cycles, let's give the rvalid
|
||||
core_rdata_o = mem_acc.rdata;
|
||||
core_rvalid_o = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// platform request side
|
||||
// Waits for requests from the core and then performs the request on the
|
||||
// platform immediately
|
||||
// Simulates a "virtual" core
|
||||
initial begin
|
||||
stall_mem_t mem_acc;
|
||||
|
||||
forever begin
|
||||
@(posedge clk_i);
|
||||
data_req_o = 1'b0;
|
||||
data_addr_o = '0;
|
||||
data_we_o = 1'b0;
|
||||
data_be_o = 4'b0;
|
||||
data_wdata_o = 'x;
|
||||
|
||||
core_reqs.get(mem_acc);
|
||||
|
||||
data_req_o = 1'b1;
|
||||
data_addr_o = mem_acc.addr;
|
||||
data_we_o = mem_acc.we;
|
||||
data_be_o = mem_acc.be;
|
||||
data_wdata_o = mem_acc.wdata;
|
||||
|
||||
#1;
|
||||
while(!data_gnt_i) begin
|
||||
@(posedge clk_i);
|
||||
#1;
|
||||
end
|
||||
|
||||
platform_transfers.put(mem_acc);
|
||||
end
|
||||
end
|
||||
|
||||
// platform response side
|
||||
// Waits for rvalids and puts the responses into the core response mailbox
|
||||
initial begin
|
||||
stall_mem_t mem_acc;
|
||||
|
||||
forever begin
|
||||
@(posedge clk_i);
|
||||
|
||||
platform_transfers.get(mem_acc);
|
||||
|
||||
while(!data_rvalid_i) begin
|
||||
@(posedge clk_i);
|
||||
end
|
||||
|
||||
mem_acc.rdata = data_rdata_i;
|
||||
|
||||
core_resps.put(mem_acc);
|
||||
end
|
||||
end
|
||||
endmodule
|
|
@ -80,6 +80,40 @@ module core_tb;
|
|||
assign dcache_if.data_rvalid = data_if_data_rvalid_o;
|
||||
assign dcache_if.data_rdata = data_if_data_rdata_o;
|
||||
|
||||
random_stalls instr_stalls_i (
|
||||
.clk_i ( clk_i ),
|
||||
.core_req_i ( dut.instr_if_data_req_o ),
|
||||
.core_addr_i ( dut.instr_if_address_o ),
|
||||
.core_we_i ( ),
|
||||
.core_be_i ( ),
|
||||
.core_wdata_i ( ),
|
||||
.core_gnt_o ( ),
|
||||
.core_rdata_o ( ),
|
||||
.core_rvalid_o ( ),
|
||||
|
||||
.data_req_o ( ),
|
||||
.data_addr_o ( ),
|
||||
.data_we_o ( ),
|
||||
.data_be_o ( ),
|
||||
.data_wdata_o ( ),
|
||||
.data_gnt_i ( instr_if_data_gnt ),
|
||||
.data_rdata_i ( instr_if_data_rdata ),
|
||||
.data_rvalid_i ( instr_if_data_rvalid )
|
||||
);
|
||||
|
||||
initial begin
|
||||
string rand_mem;
|
||||
// if the randomize memory interface is set to 1 do so
|
||||
if(uvcl.get_arg_value("+rand_mem_if", rand_mem) != 0) begin
|
||||
force dut.instr_if_data_gnt_i = instr_stalls_i.core_gnt_o;
|
||||
force dut.instr_if_data_rvalid_i = instr_stalls_i.core_rvalid_o;
|
||||
force dut.instr_if_data_rdata_i = instr_stalls_i.core_rdata_o;
|
||||
|
||||
force instr_if_data_req = instr_stalls_i.data_req_o;
|
||||
force instr_if_address = instr_stalls_i.data_addr_o;
|
||||
end
|
||||
end
|
||||
|
||||
core_mem core_mem_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -116,9 +150,9 @@ module core_tb;
|
|||
.core_id_i ( core_if.core_id ),
|
||||
.cluster_id_i ( core_if.cluster_id ),
|
||||
|
||||
.instr_if_address_o ( instr_if_address ),
|
||||
.instr_if_data_req_o ( instr_if_data_req ),
|
||||
.instr_if_data_be_o ( instr_if_data_be ),
|
||||
.instr_if_address_o ( instr_if_address ),
|
||||
.instr_if_data_be_o ( ),
|
||||
.instr_if_data_gnt_i ( instr_if_data_gnt ),
|
||||
.instr_if_data_rvalid_i ( instr_if_data_rvalid ),
|
||||
.instr_if_data_rdata_i ( instr_if_data_rdata ),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue