init
This commit is contained in:
70
code/vezba10/Makefile
Normal file
70
code/vezba10/Makefile
Normal file
@@ -0,0 +1,70 @@
|
||||
# ============================================================================
|
||||
# Terminal-only (batch) Vivado/xsim flow for the Calc1 UVM environment.
|
||||
#
|
||||
# make # compile + elaborate + run the default test (test_sanity)
|
||||
# make TEST=test_corner
|
||||
# make run TEST=test_random VERB=UVM_HIGH
|
||||
# make WAVES=1 # also dump calc.vcd
|
||||
# make clean
|
||||
#
|
||||
# Override the tool location if needed: make VIVADO=/path/to/Vivado/2022.2
|
||||
# ============================================================================
|
||||
|
||||
SHELL := /bin/bash
|
||||
VIVADO ?= /tools/Xilinx/Vivado/2022.2
|
||||
SETTINGS := $(VIVADO)/settings64.sh
|
||||
|
||||
TEST ?= test_sanity
|
||||
VERB ?= UVM_LOW
|
||||
SEED ?= random
|
||||
SNAP := calc_sim
|
||||
TOP := calc_verif_top
|
||||
|
||||
# run xsim until UVM calls $finish; the driver/monitor have response timeouts
|
||||
# so a non-responding DUT is reported, never hung on
|
||||
RUN := -R
|
||||
|
||||
# optional waveform dump
|
||||
ifeq ($(WAVES),1)
|
||||
WAVEARG := -testplusarg WAVES
|
||||
else
|
||||
WAVEARG :=
|
||||
endif
|
||||
|
||||
DUT_SRCS := $(wildcard dut/*.v)
|
||||
INCDIRS := -i ./verif -i ./verif/Agent -i ./verif/Sequences -i ./verif/Configurations
|
||||
TB_SRCS := ./verif/Configurations/configurations_pkg.sv \
|
||||
./verif/Agent/calc_agent_pkg.sv \
|
||||
./verif/Sequences/calc_seq_pkg.sv \
|
||||
./verif/calc_test_pkg.sv \
|
||||
./verif/calc_if.sv \
|
||||
./verif/calc_verif_top.sv
|
||||
|
||||
.PHONY: all run comp elab sim clean
|
||||
|
||||
all: run
|
||||
|
||||
# ---- compile ---------------------------------------------------------------
|
||||
comp:
|
||||
@bash -c 'source $(SETTINGS) && \
|
||||
xvlog --nolog $(DUT_SRCS) && \
|
||||
xvlog --nolog --sv -L uvm $(INCDIRS) $(TB_SRCS)'
|
||||
|
||||
# ---- elaborate -------------------------------------------------------------
|
||||
elab: comp
|
||||
@bash -c 'source $(SETTINGS) && \
|
||||
xelab --nolog -L uvm -timescale 1ns/10ps $(TOP) -s $(SNAP)'
|
||||
|
||||
# ---- simulate --------------------------------------------------------------
|
||||
sim:
|
||||
@bash -c 'source $(SETTINGS) && \
|
||||
xsim --nolog $(SNAP) $(RUN) \
|
||||
-testplusarg UVM_TESTNAME=$(TEST) \
|
||||
-testplusarg UVM_VERBOSITY=$(VERB) \
|
||||
$(WAVEARG) -sv_seed $(SEED)'
|
||||
|
||||
run: elab sim
|
||||
|
||||
clean:
|
||||
@rm -rf xsim.dir xsim.covdb .Xil *.jou *.log *.pb *.wdb *.vcd xelab.* xvlog.* \
|
||||
webtalk* usage_statistics_webtalk.* 2>/dev/null; echo "cleaned"
|
||||
133
code/vezba10/README.md
Normal file
133
code/vezba10/README.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# Calc1 UVM Verification Environment
|
||||
|
||||
A complete, self-checking UVM environment for the **Calc1** calculator DUT,
|
||||
built on top of the lecture skeleton (Vežbe 5–11). It drives real stimulus,
|
||||
reconstructs transactions, checks them against a golden reference model and
|
||||
collects functional coverage.
|
||||
|
||||
```
|
||||
calc_verif_top (dut + interface + clock/reset)
|
||||
└── uvm_test_top (test_base → test_simple / test_sanity / test_random / test_corner / test_no_sub …)
|
||||
└── calc_env
|
||||
├── calc_agent
|
||||
│ ├── calc_sequencer ← sequences (calc_*_seq)
|
||||
│ ├── calc_driver → drives req{1..4}_cmd/data
|
||||
│ └── calc_monitor ← samples pins, functional coverage
|
||||
└── calc_scoreboard ← reference model + checking
|
||||
```
|
||||
|
||||
## DUT recap (functional spec — Vežba 5)
|
||||
|
||||
| Command | cmd | Result |
|
||||
|---------|-----|--------|
|
||||
| NOP | `0000` | none |
|
||||
| ADD | `0001` | `op1 + op2` |
|
||||
| SUB | `0010` | `op1 - op2` |
|
||||
| SHL | `0101` | `op1 << op2[4:0]` (zero fill) |
|
||||
| SHR | `0110` | `op1 >> op2[4:0]` (zero fill) |
|
||||
| invalid | other | error |
|
||||
|
||||
* **Protocol:** `cmd` + `op1` are driven in one cycle, `op2` in the next; the
|
||||
response appears `≥3` cycles later. Only one operation may be outstanding per
|
||||
port; the 4 ports are independent.
|
||||
* **Response (`out_respX`):** `00` none, `01` success (data on `out_dataX`),
|
||||
`10` overflow/underflow/invalid, `11` unused.
|
||||
* **Reset:** active-high on all 7 lines, held ≥7 cycles, inputs 0 during reset.
|
||||
|
||||
## What was implemented (on top of the skeleton)
|
||||
|
||||
* **`Agent/calc_seq_item.sv`** – transaction: `port, cmd, op1, op2, delay`
|
||||
(rand) + observed `resp, result`; `calc_cmd_e` / `calc_resp_e` enums;
|
||||
command distribution constraints; `convert2string`.
|
||||
* **`Agent/calc_driver.sv`** – two-cycle request protocol, per-port selection,
|
||||
waits for reset release and for the port's response before completing an item
|
||||
(bidirectional non-pipelined model, Vežba 6). Uses non-blocking drives to stay
|
||||
race-free against the monitor.
|
||||
* **`Agent/calc_monitor.sv`** – one collector thread per port reconstructs each
|
||||
request/response pair, broadcasts it on the analysis port and samples the
|
||||
**functional coverage** model (cmd, port, resp, operand corners, cmd×port and
|
||||
cmd×resp crosses — Vežba 11).
|
||||
* **`calc_scoreboard.sv`** – embedded **reference model / predictor** computes
|
||||
the expected `resp`/`data` per spec and compares against the DUT; counts
|
||||
pass/fail and reports them (Vežba 10).
|
||||
* **`Configurations/calc_config.sv`** – `is_active`, `checks_enable`,
|
||||
`coverage_enable`; pushed to mon/scbd by the env.
|
||||
* **Sequences (`Sequences/`)** – `calc_simple_seq` (random N), and in
|
||||
`calc_seq_lib.sv`: `single`, `same_port`, `diff_port`, `alu` (ALU1 only),
|
||||
`shift` (ALU2 only), `shift_amounts`, `corner` (overflow/underflow/equal),
|
||||
`invalid`, and `clean` (guaranteed spec-conformant).
|
||||
* **Tests (`test_lib.sv`)** – `test_sanity`, `test_random`, `test_corner`,
|
||||
`test_no_sub` (factory override demo, Vežba 9) plus the original
|
||||
`test_simple` / `test_simple_2`.
|
||||
* **`calc_verif_top.sv`** – fixed reset to be spec-compliant (all-ones, ≥7
|
||||
cycles) and added an optional `+WAVES` dump.
|
||||
|
||||
## How to run
|
||||
|
||||
**Cadence Xcelium** (lab tool, paths in `v10_run.f`):
|
||||
|
||||
```sh
|
||||
cd code/vezba10
|
||||
xrun -f v10_run.f # default: test_sanity
|
||||
xrun -f v10_run.f +UVM_TESTNAME=test_corner # pick another test
|
||||
xrun -f v10_run.f +UVM_TESTNAME=test_random +UVM_VERBOSITY=UVM_HIGH
|
||||
```
|
||||
|
||||
**QuestaSim / ModelSim:**
|
||||
|
||||
```sh
|
||||
cd code/vezba10
|
||||
vsim -do run.do # default: test_sanity
|
||||
vsim -do "set TEST test_corner; do run.do"
|
||||
```
|
||||
|
||||
**Vivado / xsim (batch, terminal-only)** — verified on Vivado 2022.2:
|
||||
|
||||
```sh
|
||||
cd code/vezba10
|
||||
make # compile + elaborate + run test_sanity
|
||||
make TEST=test_corner
|
||||
make TEST=test_random VERB=UVM_HIGH
|
||||
make WAVES=1 # also dump calc.vcd
|
||||
make clean
|
||||
# override tool path: make VIVADO=/tools/Xilinx/Vivado/2022.2
|
||||
```
|
||||
|
||||
Equivalent without `make`:
|
||||
|
||||
```sh
|
||||
./run_vivado.sh # default test_sanity
|
||||
./run_vivado.sh test_corner
|
||||
```
|
||||
|
||||
Both wrap the raw flow `xvlog dut/*.v` → `xvlog --sv -L uvm <pkgs+top>` →
|
||||
`xelab -L uvm` → `xsim -R -testplusarg UVM_TESTNAME=<test>`.
|
||||
|
||||
## Expected results
|
||||
|
||||
The scoreboard models the **specification** (golden model). Running it on the
|
||||
provided RTL (verified on Vivado 2022.2) gives:
|
||||
|
||||
* **`test_sanity` → 36/36 pass, 0 UVM_ERRORs.** It drives directed *known-good*
|
||||
vectors (verified against the DUT) covering every port and command, so it
|
||||
proves the environment / reference model has **no false positives**.
|
||||
* **`test_corner` / `test_random` / `test_simple` / `test_simple_2` → the
|
||||
scoreboard flags real DUT defects** and the run still terminates cleanly
|
||||
(driver/monitor use a bounded response wait, so a non-responding port is
|
||||
reported, never hung on). The defects this DUT exhibits:
|
||||
* ADD overflow / SUB underflow are **not** reported (`resp` stays `01`, wrapped
|
||||
data returned) and **invalid** commands execute instead of erroring — root
|
||||
cause: `error_found` tied to `0` in `dut/calc_top.v:90`.
|
||||
* **Port 4 ADD/SUB never responds** — `dut/priority.v:73-76` only asserts the
|
||||
ALU1 valid for port 4 when `local_error_found` (which is 0). The environment
|
||||
times out and reports it instead of deadlocking.
|
||||
* **Data-dependent arithmetic errors** in the adder/shifter (e.g.
|
||||
`0x08EA14DC + 0x036BA248` gives `0x0C55D724` instead of `0x0C55B724`).
|
||||
* **Shift by 0** returns `0` instead of the operand.
|
||||
|
||||
* **`test_no_sub`** demonstrates a factory override (a transaction subtype that
|
||||
never issues SUB) applied across the whole environment.
|
||||
|
||||
All of the above was confirmed by actually building and simulating the
|
||||
environment in Vivado xsim; `test_sanity` is green and the bug-finding tests
|
||||
report the defects above while always reaching `$finish`.
|
||||
BIN
code/vezba10/calc_sim.wdb
Normal file
BIN
code/vezba10/calc_sim.wdb
Normal file
Binary file not shown.
36
code/vezba10/dut/alu_input_stage.v
Normal file
36
code/vezba10/dut/alu_input_stage.v
Normal file
@@ -0,0 +1,36 @@
|
||||
// Library: calc1
|
||||
// Module: ALU Input Stage
|
||||
// Author: Naseer SIddique
|
||||
|
||||
module alu_input_stage (alu_data1, alu_data2, hold1_data1, hold1_data2, hold2_data1, hold2_data2, hold3_data1, hold3_data2, hold4_data1, hold4_data2, prio_alu_in_cmd, prio_alu_in_req_id);
|
||||
|
||||
output [0:63] alu_data1, alu_data2;
|
||||
|
||||
wire [0:63] alu_data1, alu_data2;
|
||||
|
||||
input [0:31] hold1_data1, hold1_data2,
|
||||
hold2_data1, hold2_data2,
|
||||
hold3_data1, hold3_data2,
|
||||
hold4_data1, hold4_data2;
|
||||
|
||||
input [0:3] prio_alu_in_cmd;
|
||||
input [0:1] prio_alu_in_req_id;
|
||||
|
||||
assign alu_data1[32:63] =
|
||||
prio_alu_in_req_id[0:1] == 2'b00 ? hold1_data1[0:31] :
|
||||
prio_alu_in_req_id[0:1] == 2'b01 ? hold2_data1[0:31] :
|
||||
prio_alu_in_req_id[0:1] == 2'b10 ? hold3_data1[0:31] :
|
||||
prio_alu_in_req_id[0:1] == 2'b11 ? hold4_data1[0:31] :
|
||||
32'b0;
|
||||
|
||||
assign alu_data2[32:63] =
|
||||
prio_alu_in_req_id[0:1] == 2'b00 ? hold1_data2[0:31] :
|
||||
prio_alu_in_req_id[0:1] == 2'b01 ? hold2_data2[0:31] :
|
||||
prio_alu_in_req_id[0:1] == 2'b10 ? hold3_data2[0:31] :
|
||||
prio_alu_in_req_id[0:1] == 2'b11 ? hold4_data2[0:31] :
|
||||
32'b0;
|
||||
|
||||
assign alu_data1[0:31] = 32'b0;
|
||||
assign alu_data2[0:31] = 32'b0;
|
||||
|
||||
endmodule // alu_input_stage
|
||||
47
code/vezba10/dut/alu_output_stage.v
Normal file
47
code/vezba10/dut/alu_output_stage.v
Normal file
@@ -0,0 +1,47 @@
|
||||
// Library: calc1
|
||||
// Module: ALU Output Stage
|
||||
// Author: Naseer Siddique
|
||||
|
||||
module alu_output_stage(out_data1, out_data2, out_data3, out_data4, out_resp1, out_resp2, out_resp3, out_resp4, c_clk,alu_overflow, alu_result, local_error_found, prio_alu_out_req_id, prio_alu_out_vld, reset);
|
||||
|
||||
output [0:31] out_data1, out_data2, out_data3, out_data4;
|
||||
output [0:1] out_resp1, out_resp2, out_resp3, out_resp4;
|
||||
|
||||
input [0:63] alu_result;
|
||||
input [0:1] prio_alu_out_req_id;
|
||||
input [1:7] reset;
|
||||
input c_clk,
|
||||
alu_overflow,
|
||||
local_error_found,
|
||||
prio_alu_out_vld;
|
||||
|
||||
wire [0:31] hold_data;
|
||||
wire [0:1] hold_resp, hold_id;
|
||||
|
||||
assign hold_id[0:1] = prio_alu_out_req_id[0:1];
|
||||
|
||||
assign hold_resp[0:1] =
|
||||
(~prio_alu_out_vld) ? 2'b00 :
|
||||
(~local_error_found) ? 2'b01 :
|
||||
(alu_result[31]) ? 2'b10 :
|
||||
2'b01;
|
||||
|
||||
assign hold_data[0:31] = (prio_alu_out_vld) ? alu_result[32:63] : 32'b0;
|
||||
|
||||
assign out_resp1[0:1] = (hold_id[0:1] == 2'b00) ? hold_resp[0:1] : 2'b00;
|
||||
|
||||
assign out_resp2[0:1] = (hold_id[0:1] == 2'b01) ? hold_resp[0:1] : 2'b00;
|
||||
|
||||
assign out_resp3[0:1] = (hold_id[0:1] == 2'b10) ? hold_resp[0:1] : 2'b00;
|
||||
|
||||
assign out_resp4[0:1] = (hold_id[0:1] == 2'b11) ? hold_resp[0:1] : 2'b00;
|
||||
|
||||
assign out_data1[0:31] = (hold_id[0:1] == 2'b00) ? hold_data[0:31] : 32'b0;
|
||||
|
||||
assign out_data2[0:31] = (hold_id[0:1] == 2'b01) ? hold_data[0:31] : 32'b0;
|
||||
|
||||
assign out_data3[0:31] = (hold_id[0:1] == 2'b10) ? hold_data[0:31] : 32'b0;
|
||||
|
||||
assign out_data4[0:31] = (hold_id[0:1] == 2'b11) ? hold_data[0:31] : 32'b0;
|
||||
|
||||
endmodule
|
||||
278
code/vezba10/dut/calc_top.v
Normal file
278
code/vezba10/dut/calc_top.v
Normal file
@@ -0,0 +1,278 @@
|
||||
// Library: calc1
|
||||
// Module: Top-level wiring
|
||||
// Author: Naseer Siddique
|
||||
|
||||
//`include "alu_input_stage.v"
|
||||
//`include "alu_output_stage.v"
|
||||
//`include "exdbin_mac.v"
|
||||
//`include "holdreg.v"
|
||||
//`include "mux_out.v"
|
||||
//`include "shifter.v"
|
||||
//`include "priority.v"
|
||||
|
||||
module calc_top (out_data1, out_data2, out_data3, out_data4, out_resp1, out_resp2, out_resp3, out_resp4, c_clk, req1_cmd_in, req1_data_in, req2_cmd_in, req2_data_in, req3_cmd_in, req3_data_in, req4_cmd_in, req4_data_in, reset);
|
||||
|
||||
output [0:31] out_data1,
|
||||
out_data2,
|
||||
out_data3,
|
||||
out_data4;
|
||||
|
||||
output [0:1] out_resp1,
|
||||
out_resp2,
|
||||
out_resp3,
|
||||
out_resp4;
|
||||
|
||||
|
||||
input c_clk;
|
||||
|
||||
input [0:3] req1_cmd_in,
|
||||
req2_cmd_in,
|
||||
req3_cmd_in,
|
||||
req4_cmd_in;
|
||||
|
||||
input [0:31] req1_data_in,
|
||||
req2_data_in,
|
||||
req3_data_in,
|
||||
req4_data_in;
|
||||
|
||||
input [1:7] reset;
|
||||
|
||||
wire [0:63] add_sum,
|
||||
fxu_areg_q,
|
||||
fxu_breg_q,
|
||||
shift_out,
|
||||
shift_places,
|
||||
shift_val;
|
||||
|
||||
wire [0:31] hold1_data1,
|
||||
hold1_data2,
|
||||
hold2_data1,
|
||||
hold2_data2,
|
||||
hold3_data1,
|
||||
hold3_data2,
|
||||
hold4_data1,
|
||||
hold4_data2,
|
||||
mux1_req_data1,
|
||||
mux1_req_data2,
|
||||
mux2_req_data1,
|
||||
mux2_req_data2,
|
||||
mux3_req_data1,
|
||||
mux3_req_data2,
|
||||
mux4_req_data1,
|
||||
mux4_req_data2;
|
||||
|
||||
wire [0:3] hold1_prio_req,
|
||||
hold2_prio_req,
|
||||
hold3_prio_req,
|
||||
hold4_prio_req,
|
||||
prio_alu1_in_cmd,
|
||||
prio_alu2_in_cmd;
|
||||
|
||||
wire [0:1] mux1_req_resp1,
|
||||
mux1_req_resp2,
|
||||
mux2_req_resp1,
|
||||
mux2_req_resp2,
|
||||
mux3_req_resp1,
|
||||
mux3_req_resp2,
|
||||
mux4_req_resp1,
|
||||
mux4_req_resp2,
|
||||
prio_alu1_in_req_id,
|
||||
prio_alu1_out_req_id,
|
||||
prio_alu2_in_req_id,
|
||||
prio_alu2_out_req_id;
|
||||
|
||||
wire prio_alu1_out_vld,
|
||||
prio_alu2_out_vld,
|
||||
add_ovfl,
|
||||
shift_ovfl;
|
||||
|
||||
wire [0:3] error_found;
|
||||
assign error_found = 4'b0000;
|
||||
|
||||
exdbin_mac adder (
|
||||
.alu_cmd ( prio_alu1_in_cmd[0:3] ),
|
||||
.bin_ovfl ( add_ovfl ),
|
||||
.bin_sum ( add_sum[0:63] ),
|
||||
.fxu_areg_q ( fxu_areg_q[0:63] ),
|
||||
.fxu_breg_q ( fxu_breg_q[0:63] ),
|
||||
.local_error_found ( error_found[0] )
|
||||
);
|
||||
|
||||
|
||||
holdreg holdreg1(
|
||||
.c_clk ( c_clk ),
|
||||
.hold_data1 ( hold1_data1[0:31] ),
|
||||
.hold_data2 ( hold1_data2[0:31] ),
|
||||
.hold_prio_req ( hold1_prio_req[0:3] ),
|
||||
.req_cmd_in ( req1_cmd_in[0:3] ),
|
||||
.req_data_in ( req1_data_in[0:31] ),
|
||||
.reset ( reset [1: 7] )
|
||||
);
|
||||
|
||||
holdreg holdreg2(
|
||||
.c_clk ( c_clk ),
|
||||
.hold_data1 ( hold2_data1[0:31] ),
|
||||
.hold_data2 ( hold2_data2[0:31] ),
|
||||
.hold_prio_req ( hold2_prio_req[0:3] ),
|
||||
.req_cmd_in ( req2_cmd_in[0:3] ),
|
||||
.req_data_in ( req2_data_in[0:31] ),
|
||||
.reset ( reset [1: 7] )
|
||||
);
|
||||
|
||||
holdreg holdreg3(
|
||||
.c_clk ( c_clk ),
|
||||
.hold_data1 ( hold3_data1[0:31] ),
|
||||
.hold_data2 ( hold3_data2[0:31] ),
|
||||
.hold_prio_req ( hold3_prio_req[0:3] ),
|
||||
.req_cmd_in ( req3_cmd_in[0:3] ),
|
||||
.req_data_in ( req3_data_in[0:31] ),
|
||||
.reset ( reset [1: 7] )
|
||||
);
|
||||
|
||||
holdreg holdreg4(
|
||||
.c_clk ( c_clk ),
|
||||
.hold_data1 ( hold4_data1[0:31] ),
|
||||
.hold_data2 ( hold4_data2[0:31] ),
|
||||
.hold_prio_req ( hold4_prio_req[0:3] ),
|
||||
.req_cmd_in ( req4_cmd_in[0:3] ),
|
||||
.req_data_in ( req4_data_in[0:31] ),
|
||||
.reset ( reset [1: 7] )
|
||||
);
|
||||
|
||||
alu_input_stage in_stage1(
|
||||
.alu_data1 ( fxu_areg_q[0:63]),
|
||||
.alu_data2 ( fxu_breg_q[0:63]),
|
||||
.hold1_data1 ( hold1_data1[0:31]),
|
||||
.hold1_data2 ( hold1_data2[0:31]),
|
||||
.hold2_data1 ( hold2_data1[0:31]),
|
||||
.hold2_data2 ( hold2_data2[0:31]),
|
||||
.hold3_data1 ( hold3_data1[0:31]),
|
||||
.hold3_data2 ( hold3_data2[0:31]),
|
||||
.hold4_data1 ( hold4_data1[0:31]),
|
||||
.hold4_data2 ( hold4_data2[0:31]),
|
||||
.prio_alu_in_cmd ( prio_alu1_in_cmd[0:3]),
|
||||
.prio_alu_in_req_id ( prio_alu1_in_req_id[0:1])
|
||||
);
|
||||
|
||||
alu_input_stage in_stage2(
|
||||
.alu_data1 ( shift_val[0:63]),
|
||||
.alu_data2 ( shift_places[0:63]),
|
||||
.hold1_data1 ( hold1_data1[0:31]),
|
||||
.hold1_data2 ( hold1_data2[0:31]),
|
||||
.hold2_data1 ( hold2_data1[0:31]),
|
||||
.hold2_data2 ( hold2_data2[0:31]),
|
||||
.hold3_data1 ( hold3_data1[0:31]),
|
||||
.hold3_data2 ( hold3_data2[0:31]),
|
||||
.hold4_data1 ( hold4_data1[0:31]),
|
||||
.hold4_data2 ( hold4_data2[0:31]),
|
||||
.prio_alu_in_cmd ( prio_alu2_in_cmd[0:3]),
|
||||
.prio_alu_in_req_id ( prio_alu2_in_req_id[0:1])
|
||||
);
|
||||
|
||||
mux_out mux_out1(
|
||||
.req_data1 ( mux1_req_data1[0:31]),
|
||||
.req_data2 ( mux1_req_data2[0:31]),
|
||||
.req_data ( out_data1[0:31]),
|
||||
.req_resp1 ( mux1_req_resp1[0:1]),
|
||||
.req_resp2 ( mux1_req_resp2[0:1]),
|
||||
.req_resp ( out_resp1[0:1])
|
||||
);
|
||||
|
||||
mux_out mux_out2(
|
||||
.req_data1 ( mux2_req_data1[0:31]),
|
||||
.req_data2 ( mux2_req_data2[0:31]),
|
||||
.req_data ( out_data2[0:31]),
|
||||
.req_resp1 ( mux2_req_resp1[0:1]),
|
||||
.req_resp2 ( mux2_req_resp2[0:1]),
|
||||
.req_resp ( out_resp2[0:1])
|
||||
);
|
||||
|
||||
mux_out mux_out3(
|
||||
.req_data1 ( mux3_req_data1[0:31]),
|
||||
.req_data2 ( mux3_req_data2[0:31]),
|
||||
.req_data ( out_data3[0:31]),
|
||||
.req_resp1 ( mux3_req_resp1[0:1]),
|
||||
.req_resp2 ( mux3_req_resp2[0:1]),
|
||||
.req_resp ( out_resp3[0:1])
|
||||
);
|
||||
|
||||
mux_out mux_out4(
|
||||
.req_data1 ( mux4_req_data1[0:31]),
|
||||
.req_data2 ( mux4_req_data2[0:31]),
|
||||
.req_data ( out_data4[0:31]),
|
||||
.req_resp1 ( mux4_req_resp1[0:1]),
|
||||
.req_resp2 ( mux4_req_resp2[0:1]),
|
||||
.req_resp ( out_resp4[0:1])
|
||||
);
|
||||
|
||||
alu_output_stage out_stage1(
|
||||
.alu_overflow ( add_ovfl),
|
||||
.alu_result ( add_sum[0:63]),
|
||||
.c_clk ( c_clk),
|
||||
.local_error_found ( error_found[2]),
|
||||
.out_data1 ( mux1_req_data1[0:31]),
|
||||
.out_data2 ( mux2_req_data1[0:31]),
|
||||
.out_data3 ( mux3_req_data1[0:31]),
|
||||
.out_data4 ( mux4_req_data1[0:31]),
|
||||
.out_resp1 ( mux1_req_resp1[0:1]),
|
||||
.out_resp2 ( mux2_req_resp1[0:1]),
|
||||
.out_resp3 ( mux3_req_resp1[0:1]),
|
||||
.out_resp4 ( mux4_req_resp1[0:1]),
|
||||
.prio_alu_out_req_id ( prio_alu1_out_req_id[0:1]),
|
||||
.prio_alu_out_vld ( prio_alu1_out_vld ),
|
||||
.reset ( reset[1:7])
|
||||
);
|
||||
|
||||
alu_output_stage out_stage2(
|
||||
.alu_overflow ( shift_ovfl),
|
||||
.alu_result ( shift_out[0:63]),
|
||||
.c_clk ( c_clk),
|
||||
.local_error_found ( error_found[2]),
|
||||
.out_data1 ( mux1_req_data2[0:31]),
|
||||
.out_data2 ( mux2_req_data2[0:31]),
|
||||
.out_data3 ( mux3_req_data2[0:31]),
|
||||
.out_data4 ( mux4_req_data2[0:31]),
|
||||
.out_resp1 ( mux1_req_resp2[0:1]),
|
||||
.out_resp2 ( mux2_req_resp2[0:1]),
|
||||
.out_resp3 ( mux3_req_resp2[0:1]),
|
||||
.out_resp4 ( mux4_req_resp2[0:1]),
|
||||
.prio_alu_out_req_id ( prio_alu2_out_req_id[0:1]),
|
||||
.prio_alu_out_vld ( prio_alu2_out_vld ),
|
||||
.reset ( reset[1:7])
|
||||
);
|
||||
|
||||
priority1 priority_logic (
|
||||
.c_clk ( c_clk),
|
||||
.hold1_prio_req ( hold1_prio_req[0:3]),
|
||||
.hold2_prio_req ( hold2_prio_req[0:3]),
|
||||
.hold3_prio_req ( hold3_prio_req[0:3]),
|
||||
.hold4_prio_req ( hold4_prio_req[0:3]),
|
||||
.local_error_found ( error_found[3]),
|
||||
.prio_alu1_in_cmd ( prio_alu1_in_cmd[0:3]),
|
||||
.prio_alu1_in_req_id ( prio_alu1_in_req_id[0:1]),
|
||||
.prio_alu1_out_req_id ( prio_alu1_out_req_id[0:1]),
|
||||
.prio_alu1_out_vld ( prio_alu1_out_vld),
|
||||
.prio_alu2_in_cmd ( prio_alu2_in_cmd[0:3]),
|
||||
.prio_alu2_in_req_id ( prio_alu2_in_req_id[0:1]),
|
||||
.prio_alu2_out_req_id ( prio_alu2_out_req_id[0:1]),
|
||||
.prio_alu2_out_vld ( prio_alu2_out_vld),
|
||||
.reset ( reset[1:7])
|
||||
);
|
||||
|
||||
shifter shifter1(
|
||||
.bin_ovfl ( shift_ovfl),
|
||||
.local_error_found ( error_found[1]),
|
||||
.shift_cmd ( prio_alu2_in_cmd[0:3]),
|
||||
.shift_out ( shift_out[0:63]),
|
||||
.shift_places ( shift_places[0:63]),
|
||||
.shift_val ( shift_val[0:63])
|
||||
);
|
||||
|
||||
endmodule // calc1_top
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1279
code/vezba10/dut/exdbin_mac.v
Normal file
1279
code/vezba10/dut/exdbin_mac.v
Normal file
File diff suppressed because it is too large
Load Diff
56
code/vezba10/dut/holdreg.v
Normal file
56
code/vezba10/dut/holdreg.v
Normal file
@@ -0,0 +1,56 @@
|
||||
// Library: calc1
|
||||
// Module: Hold Register
|
||||
// Author: Naseer Siddique
|
||||
|
||||
module holdreg(hold_data1, hold_data2, hold_prio_req, c_clk, req_cmd_in, req_data_in, reset);
|
||||
|
||||
input c_clk;
|
||||
input [0:3] req_cmd_in;
|
||||
input [1:7] reset;
|
||||
input [0:31] req_data_in;
|
||||
|
||||
output [0:3] hold_prio_req;
|
||||
output [0:31] hold_data1, hold_data2;
|
||||
|
||||
|
||||
reg [0:3] cmd_hold, hold_prio_reg;
|
||||
wire [0:3] cmd_hold_q;
|
||||
reg [0:31] hold_data1_q, hold_data2_q;
|
||||
|
||||
always
|
||||
@ (posedge c_clk) begin
|
||||
fork
|
||||
|
||||
cmd_hold[0:3] <= (reset[1] == 1) ? 4'b0 : req_cmd_in[0:3];
|
||||
hold_prio_reg[0:3] <= cmd_hold[0:3];
|
||||
|
||||
join
|
||||
|
||||
end
|
||||
|
||||
|
||||
always
|
||||
@ (posedge c_clk) begin
|
||||
fork
|
||||
hold_data1_q[0:31] <=
|
||||
(reset[1]) ? 32'b0 :
|
||||
(req_cmd_in[0:3] != 4'b0) ? req_data_in[0:31] :
|
||||
hold_data1_q[0:31];
|
||||
|
||||
hold_data2_q[0:31] <=
|
||||
(reset[1]) ? 32'b0 : (cmd_hold[0:3] != 4'b0) ?
|
||||
req_data_in[0:31] : hold_data2_q[0:31];
|
||||
join
|
||||
|
||||
end
|
||||
|
||||
|
||||
assign hold_data1 = hold_data1_q;
|
||||
assign hold_data2 = hold_data2_q;
|
||||
assign hold_prio_req = hold_prio_reg;
|
||||
|
||||
endmodule // holdreg
|
||||
|
||||
|
||||
|
||||
|
||||
27
code/vezba10/dut/mux_out.v
Normal file
27
code/vezba10/dut/mux_out.v
Normal file
@@ -0,0 +1,27 @@
|
||||
// Library: calc1
|
||||
// Module: Output Mux
|
||||
// Author: Naseer Siddique
|
||||
|
||||
module mux_out(req_data, req_resp, req_data1, req_data2, req_resp1, req_resp2);
|
||||
|
||||
output [0:31] req_data;
|
||||
output [0:1] req_resp;
|
||||
|
||||
input [0:31] req_data1, req_data2;
|
||||
input [0:1] req_resp1, req_resp2;
|
||||
|
||||
assign req_resp[0:1] =
|
||||
(req_resp1[0:1] != 2'b00) ? req_resp1 :
|
||||
( req_resp2[0:1] != 2'b00 ) ? req_resp2 :
|
||||
2'b00;
|
||||
|
||||
assign req_data[0:31] =
|
||||
( req_resp1[0:1] != 2'b00 ) ? req_data1 :
|
||||
( req_resp2[0:1] != 2'b00 ) ? req_data2 :
|
||||
32'b0;
|
||||
|
||||
|
||||
|
||||
endmodule // mux_out
|
||||
|
||||
|
||||
155
code/vezba10/dut/priority.v
Normal file
155
code/vezba10/dut/priority.v
Normal file
@@ -0,0 +1,155 @@
|
||||
// Library: calc1
|
||||
// Priority Logic
|
||||
// Author: Naseer Siddique
|
||||
module priority1 ( prio_alu1_in_cmd, prio_alu1_in_req_id, prio_alu1_out_req_id, prio_alu1_out_vld, prio_alu2_in_cmd, prio_alu2_in_req_id, prio_alu2_out_req_id, prio_alu2_out_vld, c_clk, hold1_prio_req, hold2_prio_req, hold3_prio_req, hold4_prio_req, local_error_found, reset);
|
||||
|
||||
|
||||
output [0:3] prio_alu1_in_cmd, prio_alu2_in_cmd;
|
||||
output [0:1] prio_alu1_out_req_id, prio_alu1_in_req_id, prio_alu2_in_req_id, prio_alu2_out_req_id;
|
||||
output prio_alu1_out_vld, prio_alu2_out_vld;
|
||||
|
||||
input c_clk, local_error_found;
|
||||
input [0:3] hold1_prio_req, hold2_prio_req, hold3_prio_req, hold4_prio_req;
|
||||
input [1:7] reset;
|
||||
|
||||
reg [0:3] cmd1, cmd2, cmd3, cmd4;
|
||||
reg delay1, delay2;
|
||||
|
||||
wire cmd1_reset, cmd2_reset, cmd3_reset, cmd4_reset;
|
||||
|
||||
reg [0:1] prio_req1_id_q, prio_req2_id_q;
|
||||
|
||||
reg prio_alu1_out_vld_q, prio_alu2_out_vld_q;
|
||||
|
||||
always
|
||||
@ (posedge c_clk) begin
|
||||
if (reset[1]) begin
|
||||
cmd1 <= 0;
|
||||
cmd2 <= 0;
|
||||
cmd3 <= 0;
|
||||
cmd4 <= 0;
|
||||
end
|
||||
else begin
|
||||
fork
|
||||
delay1 <= prio_alu1_out_vld_q;
|
||||
delay2 <= prio_alu2_out_vld_q;
|
||||
|
||||
cmd1[0:3] <=
|
||||
(hold1_prio_req[0:3] != 4'b0) ? hold1_prio_req[0:3] :
|
||||
(cmd1_reset) ? 4'b0 :
|
||||
cmd1[0:3];
|
||||
|
||||
cmd2[0:3] <=
|
||||
(hold2_prio_req[0:3] != 4'b0) ? hold2_prio_req[0:3] :
|
||||
(cmd2_reset) ? 4'b0 :
|
||||
cmd2[0:3];
|
||||
|
||||
cmd3[0:3] <=
|
||||
(hold3_prio_req[0:3] != 4'b0) ? hold3_prio_req[0:3] :
|
||||
(cmd3_reset) ? 4'b0 :
|
||||
cmd3[0:3];
|
||||
|
||||
cmd4[0:3] <=
|
||||
(hold4_prio_req[0:3] != 4'b0) ? hold4_prio_req[0:3] :
|
||||
(cmd4_reset) ? 4'b0 :
|
||||
cmd4[0:3];
|
||||
join
|
||||
end
|
||||
|
||||
|
||||
end // always @ (posedge c_clk)
|
||||
|
||||
always
|
||||
@ (delay1 or delay2 or cmd1 or cmd2 or cmd3 or cmd4) begin
|
||||
|
||||
if (delay1)
|
||||
prio_alu1_out_vld_q <= 1'b0;
|
||||
else if ( (cmd1 != 4'b0000) && (cmd1 < 4'b0100) )
|
||||
prio_alu1_out_vld_q <= 1'b1;
|
||||
else if ( (cmd2 != 4'b0000) && (cmd2 < 4'b0100) )
|
||||
prio_alu1_out_vld_q <= 1'b1;
|
||||
else if ( (cmd3 != 4'b0000) && (cmd3 < 4'b0100) )
|
||||
prio_alu1_out_vld_q <= 1'b1;
|
||||
else if ( (cmd4 != 4'b0000) && (cmd4 < 4'b0100) && local_error_found )
|
||||
prio_alu1_out_vld_q <= 1'b1;
|
||||
else if ( (cmd4 != 4'b0000) && (cmd4 < 4'b0100) )
|
||||
prio_alu1_out_vld_q <= 1'b0;
|
||||
else prio_alu1_out_vld_q <= 1'b0;
|
||||
|
||||
if (delay2)
|
||||
prio_alu2_out_vld_q <= 1'b0;
|
||||
else if (cmd1 > 4'b0011)
|
||||
prio_alu2_out_vld_q <= 1'b1;
|
||||
else if (cmd2 > 4'b0011)
|
||||
prio_alu2_out_vld_q <= 1'b1;
|
||||
else if (cmd3 > 4'b0011)
|
||||
prio_alu2_out_vld_q <= 1'b1;
|
||||
else if (cmd4 > 4'b0011)
|
||||
prio_alu2_out_vld_q <= 1'b1;
|
||||
else prio_alu2_out_vld_q <= 1'b0;
|
||||
|
||||
if ( (cmd1 != 4'b0000) && (cmd1 < 4'b0100) )
|
||||
prio_req1_id_q[0:1] <= 2'b00;
|
||||
else if ( (cmd2 != 4'b0000) && (cmd2 < 4'b0100) )
|
||||
prio_req1_id_q[0:1] <= 2'b01;
|
||||
else if ( (cmd3 != 4'b0000) && (cmd3 < 4'b0100) )
|
||||
prio_req1_id_q[0:1] <= 2'b10;
|
||||
else if ( (cmd4 != 4'b0000) && (cmd4 < 4'b0100) )
|
||||
prio_req1_id_q[0:1] <= 2'b11;
|
||||
else prio_req1_id_q[0:1] <= 2'b00;
|
||||
|
||||
if ( cmd1 > 4'b0011 )
|
||||
prio_req2_id_q <= 2'b00;
|
||||
else if ( cmd2 > 4'b0011 )
|
||||
prio_req2_id_q <= 2'b01;
|
||||
else if ( cmd3 > 4'b0011 )
|
||||
prio_req2_id_q <= 2'b10;
|
||||
else if ( cmd4 > 4'b0011 )
|
||||
prio_req2_id_q <= 2'b11;
|
||||
else prio_req2_id_q <= 2'b00;
|
||||
|
||||
end // always @ (delay1 or or delay2 or cmd1 or cmd2 or cmd3 or cmd4)
|
||||
|
||||
assign prio_alu1_in_req_id[0:1] = prio_req1_id_q[0:1];
|
||||
assign prio_alu2_in_req_id[0:1] = prio_req2_id_q[0:1];
|
||||
assign prio_alu1_out_req_id[0:1] = prio_req1_id_q[0:1];
|
||||
assign prio_alu2_out_req_id[0:1] = prio_req2_id_q[0:1];
|
||||
assign prio_alu1_out_vld = prio_alu1_out_vld_q;
|
||||
assign prio_alu2_out_vld = prio_alu2_out_vld_q;
|
||||
|
||||
assign prio_alu1_in_cmd[0:3] =
|
||||
(prio_req1_id_q[0:1] == 2'b00) ? cmd1[0:3] :
|
||||
(prio_req1_id_q[0:1] == 2'b01) ? cmd2[0:3] :
|
||||
(prio_req1_id_q[0:1] == 2'b10) ? cmd3[0:3] :
|
||||
(prio_req1_id_q[0:1] == 2'b11) ? cmd4[0:3] :
|
||||
4'b0;
|
||||
|
||||
assign prio_alu2_in_cmd[0:3] =
|
||||
(prio_req2_id_q[0:1] == 2'b00) ? cmd1[0:3] :
|
||||
(prio_req2_id_q[0:1] == 2'b01) ? cmd2[0:3] :
|
||||
(prio_req2_id_q[0:1] == 2'b10) ? cmd3[0:3] :
|
||||
(prio_req2_id_q[0:1] == 2'b11) ? cmd4[0:3] :
|
||||
4'b0;
|
||||
|
||||
|
||||
assign cmd1_reset =
|
||||
(prio_alu1_out_vld_q && (prio_req1_id_q[0:1] == 2'b00) ) ? 1 :
|
||||
(prio_alu2_out_vld_q && (prio_req2_id_q[0:1] == 2'b00) ) ? 1 :
|
||||
0;
|
||||
|
||||
assign cmd2_reset =
|
||||
(prio_alu1_out_vld_q && (prio_req1_id_q[0:1] == 2'b01) ) ? 1 :
|
||||
(prio_alu2_out_vld_q && (prio_req2_id_q[0:1] == 2'b01) ) ? 1 :
|
||||
0;
|
||||
|
||||
assign cmd3_reset =
|
||||
(prio_alu1_out_vld_q && (prio_req1_id_q[0:1] == 2'b10) ) ? 1 :
|
||||
(prio_alu2_out_vld_q && (prio_req2_id_q[0:1] == 2'b10) ) ? 1 :
|
||||
0;
|
||||
|
||||
assign cmd4_reset =
|
||||
(prio_alu1_out_vld_q && (prio_req1_id_q[0:1] == 2'b11) ) ? 1 :
|
||||
(prio_alu2_out_vld_q && (prio_req2_id_q[0:1] == 2'b11) ) ? 1 :
|
||||
0;
|
||||
|
||||
endmodule // priority
|
||||
2310
code/vezba10/dut/shifter.v
Normal file
2310
code/vezba10/dut/shifter.v
Normal file
File diff suppressed because it is too large
Load Diff
44
code/vezba10/run.do
Normal file
44
code/vezba10/run.do
Normal file
@@ -0,0 +1,44 @@
|
||||
# ============================================================================
|
||||
# QuestaSim / ModelSim run script for the Calc1 UVM environment.
|
||||
# usage: vsim -do run.do
|
||||
# pick a test: vsim -do "set TEST test_corner; do run.do"
|
||||
# ============================================================================
|
||||
|
||||
if {![info exists TEST]} { set TEST test_sanity }
|
||||
|
||||
# fresh library
|
||||
if {[file exists work]} { vdel -all }
|
||||
vlib work
|
||||
|
||||
# --- compile the DUT (plain Verilog) ----------------------------------------
|
||||
vlog +incdir+./dut \
|
||||
./dut/alu_input_stage.v \
|
||||
./dut/alu_output_stage.v \
|
||||
./dut/exdbin_mac.v \
|
||||
./dut/holdreg.v \
|
||||
./dut/mux_out.v \
|
||||
./dut/shifter.v \
|
||||
./dut/priority.v \
|
||||
./dut/calc_top.v
|
||||
|
||||
# --- compile the UVM testbench ----------------------------------------------
|
||||
# (-L uvm or +incdir+$UVM_HOME depending on the tool installation)
|
||||
vlog -sv +acc \
|
||||
+incdir+./verif \
|
||||
+incdir+./verif/Agent \
|
||||
+incdir+./verif/Sequences \
|
||||
+incdir+./verif/Configurations \
|
||||
./verif/Configurations/configurations_pkg.sv \
|
||||
./verif/Agent/calc_agent_pkg.sv \
|
||||
./verif/Sequences/calc_seq_pkg.sv \
|
||||
./verif/calc_test_pkg.sv \
|
||||
./verif/calc_if.sv \
|
||||
./verif/calc_verif_top.sv
|
||||
|
||||
# --- elaborate + run --------------------------------------------------------
|
||||
vsim -coverage calc_verif_top +UVM_TESTNAME=$TEST +UVM_VERBOSITY=UVM_LOW -sv_seed random
|
||||
run -all
|
||||
|
||||
# functional coverage report (optional)
|
||||
coverage report -detail -cvg
|
||||
quit -f
|
||||
40
code/vezba10/run_vivado.sh
Executable file
40
code/vezba10/run_vivado.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
# ============================================================================
|
||||
# Terminal-only Vivado/xsim run for the Calc1 UVM environment (no Makefile).
|
||||
#
|
||||
# ./run_vivado.sh # default test_sanity
|
||||
# ./run_vivado.sh test_corner # pick a test
|
||||
# TEST=test_random VERB=UVM_HIGH ./run_vivado.sh
|
||||
#
|
||||
# Override the tool path with VIVADO=/path/to/Vivado/2022.2
|
||||
# ============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
VIVADO=${VIVADO:-/tools/Xilinx/Vivado/2022.2}
|
||||
TEST=${1:-${TEST:-test_sanity}}
|
||||
VERB=${VERB:-UVM_LOW}
|
||||
SEED=${SEED:-random}
|
||||
|
||||
source "$VIVADO/settings64.sh"
|
||||
|
||||
echo ">> compiling DUT"
|
||||
xvlog --nolog dut/*.v
|
||||
|
||||
echo ">> compiling UVM testbench"
|
||||
xvlog --nolog --sv -L uvm \
|
||||
-i ./verif -i ./verif/Agent -i ./verif/Sequences -i ./verif/Configurations \
|
||||
./verif/Configurations/configurations_pkg.sv \
|
||||
./verif/Agent/calc_agent_pkg.sv \
|
||||
./verif/Sequences/calc_seq_pkg.sv \
|
||||
./verif/calc_test_pkg.sv \
|
||||
./verif/calc_if.sv \
|
||||
./verif/calc_verif_top.sv
|
||||
|
||||
echo ">> elaborating"
|
||||
xelab --nolog -L uvm -timescale 1ns/10ps calc_verif_top -s calc_sim
|
||||
|
||||
echo ">> running $TEST"
|
||||
xsim --nolog calc_sim -R \
|
||||
-testplusarg "UVM_TESTNAME=$TEST" \
|
||||
-testplusarg "UVM_VERBOSITY=$VERB" \
|
||||
-sv_seed "$SEED"
|
||||
7
code/vezba10/tr_db.log
Normal file
7
code/vezba10/tr_db.log
Normal file
@@ -0,0 +1,7 @@
|
||||
CREATE_STREAM @0 {NAME:rnd T:Transactions SCOPE:uvm_test_top.env.agent.seqr STREAM:655}
|
||||
CREATE_STREAM @43750000 {NAME:alu T:Transactions SCOPE:uvm_test_top.env.agent.seqr STREAM:1297}
|
||||
CREATE_STREAM @59350000 {NAME:sh T:Transactions SCOPE:uvm_test_top.env.agent.seqr STREAM:1423}
|
||||
CREATE_STREAM @65350000 {NAME:dp T:Transactions SCOPE:uvm_test_top.env.agent.seqr STREAM:1643}
|
||||
CREATE_STREAM @82950000 {NAME:sp T:Transactions SCOPE:uvm_test_top.env.agent.seqr STREAM:1755}
|
||||
CREATE_STREAM @87650000 {NAME:sa T:Transactions SCOPE:uvm_test_top.env.agent.seqr STREAM:1851}
|
||||
CREATE_STREAM @94950000 {NAME:cor T:Transactions SCOPE:uvm_test_top.env.agent.seqr STREAM:2001}
|
||||
33
code/vezba10/v10_run.f
Normal file
33
code/vezba10/v10_run.f
Normal file
@@ -0,0 +1,33 @@
|
||||
-uvmhome "/eda/cadence/2019-20/RHELx86/XCELIUM_19.03.013/tools/methodology/UVM/CDNS-1.2/"
|
||||
-uvm +UVM_TESTNAME=test_sanity
|
||||
-sv +incdir+./verif
|
||||
-sv +incdir+./verif/Agent
|
||||
-sv +incdir+./verif/Sequences
|
||||
-sv +incdir+./verif/Configurations
|
||||
|
||||
./dut/alu_input_stage.v
|
||||
./dut/alu_output_stage.v
|
||||
./dut/exdbin_mac.v
|
||||
./dut/holdreg.v
|
||||
./dut/mux_out.v
|
||||
./dut/shifter.v
|
||||
./dut/priority.v
|
||||
./dut/calc_top.v
|
||||
|
||||
|
||||
-sv ./verif/Configurations/configurations_pkg.sv
|
||||
-sv ./verif/Agent/calc_agent_pkg.sv
|
||||
-sv ./verif/Sequences/calc_seq_pkg.sv
|
||||
-sv ./verif/calc_test_pkg.sv
|
||||
-sv ./verif/calc_if.sv
|
||||
|
||||
-sv ./verif/calc_verif_top.sv
|
||||
|
||||
|
||||
|
||||
|
||||
#-LINEDEBUG
|
||||
-access +rwc
|
||||
-disable_sem2009
|
||||
-nowarn "MEMODR"
|
||||
-timescale 1ns/10ps
|
||||
33
code/vezba10/v9_run.f~
Normal file
33
code/vezba10/v9_run.f~
Normal file
@@ -0,0 +1,33 @@
|
||||
-uvmhome "/eda/cadence/2019-20/RHELx86/XCELIUM_19.03.013/tools/methodology/UVM/CDNS-1.2/"
|
||||
-uvm +UVM_TESTNAME=test_simple
|
||||
-sv +incdir+./verif
|
||||
-sv +incdir+./verif/Agent
|
||||
-sv +incdir+./verif/Sequences
|
||||
-sv +incdir+./verif/Configurations
|
||||
|
||||
./dut/alu_input_stage.v
|
||||
./dut/alu_output_stage.v
|
||||
./dut/exdbin_mac.v
|
||||
./dut/holdreg.v
|
||||
./dut/mux_out.v
|
||||
./dut/shifter.v
|
||||
./dut/priority.v
|
||||
./dut/calc_top.v
|
||||
|
||||
|
||||
-sv ./verif/Configurations/configurations_pkg.sv
|
||||
-sv ./verif/Agent/v9_calc_agent_pkg.sv
|
||||
-sv ./verif/Sequences/v9_calc_seq_pkg.sv
|
||||
-sv ./verif/v9_calc_test_pkg.sv
|
||||
-sv ./verif/calc_if.sv
|
||||
|
||||
-sv ./verif/v9_calc_verif_top.sv
|
||||
|
||||
|
||||
|
||||
|
||||
#-LINEDEBUG
|
||||
-access +rwc
|
||||
-disable_sem2009
|
||||
-nowarn "MEMODR"
|
||||
-timescale 1ns/10ps
|
||||
47
code/vezba10/verif/Agent/calc_agent.sv
Normal file
47
code/vezba10/verif/Agent/calc_agent.sv
Normal file
@@ -0,0 +1,47 @@
|
||||
class calc_agent extends uvm_agent;
|
||||
|
||||
// components
|
||||
calc_driver drv;
|
||||
calc_sequencer seqr;
|
||||
calc_monitor mon;
|
||||
virtual interface calc_if vif;
|
||||
// configuration
|
||||
calc_config cfg;
|
||||
int value;
|
||||
`uvm_component_utils_begin (calc_agent)
|
||||
`uvm_field_object(cfg, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
function new(string name = "calc_agent", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction
|
||||
|
||||
function void build_phase(uvm_phase phase);
|
||||
super.build_phase(phase);
|
||||
/************Geting from configuration database*******************/
|
||||
if (!uvm_config_db#(virtual calc_if)::get(this, "", "calc_if", vif))
|
||||
`uvm_fatal("NOVIF",{"virtual interface must be set:",get_full_name(),".vif"})
|
||||
|
||||
if(!uvm_config_db#(calc_config)::get(this, "", "calc_config", cfg))
|
||||
`uvm_fatal("NOCONFIG",{"Config object must be set for: ",get_full_name(),".cfg"})
|
||||
/*****************************************************************/
|
||||
|
||||
/************Setting to configuration database********************/
|
||||
uvm_config_db#(virtual calc_if)::set(this, "*", "calc_if", vif);
|
||||
/*****************************************************************/
|
||||
|
||||
mon = calc_monitor::type_id::create("mon", this);
|
||||
if(cfg.is_active == UVM_ACTIVE) begin
|
||||
drv = calc_driver::type_id::create("drv", this);
|
||||
seqr = calc_sequencer::type_id::create("seqr", this);
|
||||
end
|
||||
endfunction : build_phase
|
||||
|
||||
function void connect_phase(uvm_phase phase);
|
||||
super.connect_phase(phase);
|
||||
if(cfg.is_active == UVM_ACTIVE) begin
|
||||
drv.seq_item_port.connect(seqr.seq_item_export);
|
||||
end
|
||||
endfunction : connect_phase
|
||||
|
||||
endclass : calc_agent
|
||||
25
code/vezba10/verif/Agent/calc_agent_pkg.sv
Normal file
25
code/vezba10/verif/Agent/calc_agent_pkg.sv
Normal file
@@ -0,0 +1,25 @@
|
||||
`ifndef CALC_AGENT_PKG
|
||||
`define CALC_AGENT_PKG
|
||||
|
||||
package calc_agent_pkg;
|
||||
|
||||
import uvm_pkg::*;
|
||||
`include "uvm_macros.svh"
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// include Agent components : driver,monitor,sequencer
|
||||
/////////////////////////////////////////////////////////
|
||||
import configurations_pkg::*;
|
||||
|
||||
`include "calc_seq_item.sv"
|
||||
`include "calc_sequencer.sv"
|
||||
`include "calc_driver.sv"
|
||||
`include "calc_monitor.sv"
|
||||
`include "calc_agent.sv"
|
||||
|
||||
endpackage
|
||||
|
||||
`endif
|
||||
|
||||
|
||||
|
||||
115
code/vezba10/verif/Agent/calc_driver.sv
Normal file
115
code/vezba10/verif/Agent/calc_driver.sv
Normal file
@@ -0,0 +1,115 @@
|
||||
`ifndef CALC_DRIVER_SV
|
||||
`define CALC_DRIVER_SV
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Calc1 driver.
|
||||
//
|
||||
// Protocol (Vezba 5):
|
||||
// * command + operand1 are driven in the same cycle,
|
||||
// * operand2 is driven in the next cycle (command line back to 0),
|
||||
// * a response appears on out_respX a few (>=3) cycles later.
|
||||
//
|
||||
// Only one request may be outstanding per port, so after issuing a request the
|
||||
// driver waits for that port's response before completing the item. This keeps
|
||||
// the very simple "bidirectional, non-pipelined" use model from Vezba 6.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_driver extends uvm_driver#(calc_seq_item);
|
||||
|
||||
`uvm_component_utils(calc_driver)
|
||||
|
||||
virtual interface calc_if vif;
|
||||
|
||||
function new(string name = "calc_driver", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction
|
||||
|
||||
function void connect_phase(uvm_phase phase);
|
||||
super.connect_phase(phase);
|
||||
if (!uvm_config_db#(virtual calc_if)::get(this, "", "calc_if", vif))
|
||||
`uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"})
|
||||
endfunction : connect_phase
|
||||
|
||||
task main_phase(uvm_phase phase);
|
||||
// start from a known idle state and wait until reset is released
|
||||
reset_inputs();
|
||||
wait_reset_done();
|
||||
|
||||
forever begin
|
||||
seq_item_port.get_next_item(req);
|
||||
`uvm_info(get_type_name(),
|
||||
$sformatf("Driving: %s", req.convert2string()), UVM_HIGH)
|
||||
drive_item(req);
|
||||
seq_item_port.item_done();
|
||||
end
|
||||
endtask : main_phase
|
||||
|
||||
// Drive a single transaction following the two-cycle request protocol and
|
||||
// wait for the corresponding response on the same port.
|
||||
task drive_item(calc_seq_item it);
|
||||
int unsigned wait_cnt;
|
||||
|
||||
// optional idle gap before the request
|
||||
repeat (it.delay) @(posedge vif.clk);
|
||||
|
||||
// cycle 1: command + operand1
|
||||
drive_req(it.port, it.cmd, it.op1);
|
||||
@(posedge vif.clk);
|
||||
|
||||
// cycle 2: operand2, command de-asserted
|
||||
drive_req(it.port, CMD_NOP, it.op2);
|
||||
@(posedge vif.clk);
|
||||
|
||||
// idle the port again while the pipeline produces the result
|
||||
drive_req(it.port, CMD_NOP, '0);
|
||||
|
||||
// wait for this port's response (resp != 0), bounded so a non-responding
|
||||
// DUT cannot deadlock the test
|
||||
wait_cnt = 0;
|
||||
do begin
|
||||
@(posedge vif.clk);
|
||||
wait_cnt++;
|
||||
end while (get_resp(it.port) === RESP_NONE && wait_cnt < RSP_TIMEOUT);
|
||||
|
||||
if (get_resp(it.port) === RESP_NONE)
|
||||
`uvm_warning(get_type_name(),
|
||||
$sformatf("No response on port %0d within %0d cycles (cmd=%s) - the scoreboard will flag this",
|
||||
it.port+1, RSP_TIMEOUT, it.cmd2string()))
|
||||
endtask : drive_item
|
||||
|
||||
// Drive command/data onto the selected port, leaving the others untouched.
|
||||
task drive_req(bit [1:0] port, bit [CMD_WIDTH-1:0] cmd, bit [DATA_WIDTH-1:0] data);
|
||||
case (port)
|
||||
2'd0 : begin vif.req1_cmd_in <= cmd; vif.req1_data_in <= data; end
|
||||
2'd1 : begin vif.req2_cmd_in <= cmd; vif.req2_data_in <= data; end
|
||||
2'd2 : begin vif.req3_cmd_in <= cmd; vif.req3_data_in <= data; end
|
||||
2'd3 : begin vif.req4_cmd_in <= cmd; vif.req4_data_in <= data; end
|
||||
endcase
|
||||
endtask : drive_req
|
||||
|
||||
// Combinational read of a port's response line.
|
||||
function bit [RESP_WIDTH-1:0] get_resp(bit [1:0] port);
|
||||
case (port)
|
||||
2'd0 : return vif.out_resp1;
|
||||
2'd1 : return vif.out_resp2;
|
||||
2'd2 : return vif.out_resp3;
|
||||
2'd3 : return vif.out_resp4;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
// Drive all request lines to their idle (zero) state.
|
||||
task reset_inputs();
|
||||
vif.req1_cmd_in <= '0; vif.req1_data_in <= '0;
|
||||
vif.req2_cmd_in <= '0; vif.req2_data_in <= '0;
|
||||
vif.req3_cmd_in <= '0; vif.req3_data_in <= '0;
|
||||
vif.req4_cmd_in <= '0; vif.req4_data_in <= '0;
|
||||
endtask : reset_inputs
|
||||
|
||||
task wait_reset_done();
|
||||
// reset is active-high (all ones); wait until it is fully released
|
||||
while (vif.rst !== '0) @(posedge vif.clk);
|
||||
`uvm_info(get_type_name(), "Reset released - starting to drive", UVM_LOW)
|
||||
endtask : wait_reset_done
|
||||
|
||||
endclass : calc_driver
|
||||
|
||||
`endif
|
||||
206
code/vezba10/verif/Agent/calc_monitor.sv
Normal file
206
code/vezba10/verif/Agent/calc_monitor.sv
Normal file
@@ -0,0 +1,206 @@
|
||||
`ifndef CALC_MONITOR_SV
|
||||
`define CALC_MONITOR_SV
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Calc1 monitor.
|
||||
//
|
||||
// Passive component. One collector thread per port reconstructs a transaction
|
||||
// from the pin activity:
|
||||
// * a request starts when reqX_cmd_in != 0 -> capture cmd and operand1,
|
||||
// * operand2 is the data line on the following cycle,
|
||||
// * the matching response is the first cycle in which out_respX != 0.
|
||||
//
|
||||
// The completed transaction (stimulus + observed response/result) is broadcast
|
||||
// over the analysis port to the scoreboard, and functional coverage is sampled.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_monitor extends uvm_monitor;
|
||||
|
||||
// control fields
|
||||
bit checks_enable = 1;
|
||||
bit coverage_enable = 1;
|
||||
|
||||
uvm_analysis_port #(calc_seq_item) item_collected_port;
|
||||
|
||||
`uvm_component_utils_begin(calc_monitor)
|
||||
`uvm_field_int(checks_enable, UVM_DEFAULT)
|
||||
`uvm_field_int(coverage_enable, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
// The virtual interface used to view HDL signals.
|
||||
virtual interface calc_if vif;
|
||||
|
||||
// number of transactions collected (per port and total)
|
||||
int unsigned num_collected;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Functional coverage model (Vezba 11).
|
||||
//--------------------------------------------------------------------------
|
||||
bit [CMD_WIDTH-1:0] cov_cmd;
|
||||
bit [1:0] cov_port;
|
||||
bit [RESP_WIDTH-1:0] cov_resp;
|
||||
bit [DATA_WIDTH-1:0] cov_op1;
|
||||
bit [DATA_WIDTH-1:0] cov_op2;
|
||||
|
||||
covergroup calc_cg;
|
||||
option.per_instance = 1;
|
||||
option.name = "calc_functional_coverage";
|
||||
|
||||
cp_cmd : coverpoint cov_cmd {
|
||||
bins add = {CMD_ADD};
|
||||
bins sub = {CMD_SUB};
|
||||
bins shl = {CMD_SHL};
|
||||
bins shr = {CMD_SHR};
|
||||
bins invalid = {[4'h3:4'h4], 4'h7, [4'h8:4'hF]};
|
||||
}
|
||||
cp_port : coverpoint cov_port {
|
||||
bins port1 = {2'd0};
|
||||
bins port2 = {2'd1};
|
||||
bins port3 = {2'd2};
|
||||
bins port4 = {2'd3};
|
||||
}
|
||||
// the monitor only emits an item once a real response is seen, so only
|
||||
// SUCCESS and ERROR are ever sampled here
|
||||
cp_resp : coverpoint cov_resp {
|
||||
bins success = {RESP_SUCCESS};
|
||||
bins error = {RESP_ERROR};
|
||||
}
|
||||
// interesting operand corners
|
||||
cp_op1 : coverpoint cov_op1 {
|
||||
bins zero = {32'h0000_0000};
|
||||
bins one = {32'h0000_0001};
|
||||
bins max = {32'hFFFF_FFFF};
|
||||
bins msb = {32'h8000_0000};
|
||||
bins others = default;
|
||||
}
|
||||
cp_op2 : coverpoint cov_op2 {
|
||||
bins zero = {32'h0000_0000};
|
||||
bins one = {32'h0000_0001};
|
||||
bins max = {32'hFFFF_FFFF};
|
||||
bins shamt = {[32'h2:32'h1F]}; // small shift amounts
|
||||
bins others = default;
|
||||
}
|
||||
// every legal command must be exercised on every port
|
||||
cx_cmd_port : cross cp_cmd, cp_port;
|
||||
// every command must be seen producing both success and error responses
|
||||
cx_cmd_resp : cross cp_cmd, cp_resp;
|
||||
endgroup
|
||||
|
||||
function new(string name = "calc_monitor", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
item_collected_port = new("item_collected_port", this);
|
||||
calc_cg = new();
|
||||
endfunction
|
||||
|
||||
function void connect_phase(uvm_phase phase);
|
||||
super.connect_phase(phase);
|
||||
if (!uvm_config_db#(virtual calc_if)::get(this, "", "calc_if", vif))
|
||||
`uvm_fatal("NOVIF",{"virtual interface must be set:",get_full_name(),".vif"})
|
||||
endfunction : connect_phase
|
||||
|
||||
task main_phase(uvm_phase phase);
|
||||
wait_reset_done();
|
||||
// launch one independent collector per port
|
||||
for (int p = 0; p < NUM_PORTS; p++) begin
|
||||
automatic int port = p;
|
||||
fork
|
||||
collect_port(port[1:0]);
|
||||
join_none
|
||||
end
|
||||
endtask : main_phase
|
||||
|
||||
// Collect every request/response pair seen on a single port.
|
||||
task collect_port(bit [1:0] port);
|
||||
calc_seq_item it;
|
||||
int unsigned wait_cnt;
|
||||
forever begin
|
||||
// wait for the start of a request on this port
|
||||
do @(posedge vif.clk); while (get_cmd(port) === CMD_NOP || vif.rst !== '0);
|
||||
|
||||
it = calc_seq_item::type_id::create($sformatf("it_p%0d", port));
|
||||
it.port = port;
|
||||
it.cmd = get_cmd(port);
|
||||
it.op1 = get_data(port);
|
||||
|
||||
// operand2 is presented on the next cycle
|
||||
@(posedge vif.clk);
|
||||
it.op2 = get_data(port);
|
||||
|
||||
// wait for the response on this port (bounded - a non-responding DUT
|
||||
// is reported, not waited on forever); resp stays NONE on timeout so
|
||||
// the scoreboard flags the missing response
|
||||
wait_cnt = 0;
|
||||
do begin
|
||||
@(posedge vif.clk);
|
||||
wait_cnt++;
|
||||
end while (get_resp(port) === RESP_NONE && wait_cnt < RSP_TIMEOUT);
|
||||
it.resp = get_resp(port);
|
||||
it.result = get_out_data(port);
|
||||
|
||||
num_collected++;
|
||||
`uvm_info(get_type_name(),
|
||||
$sformatf("Collected: %s", it.convert2string()), UVM_MEDIUM)
|
||||
|
||||
if (coverage_enable) sample_coverage(it);
|
||||
item_collected_port.write(it);
|
||||
end
|
||||
endtask : collect_port
|
||||
|
||||
function void sample_coverage(calc_seq_item it);
|
||||
cov_cmd = it.cmd;
|
||||
cov_port = it.port;
|
||||
cov_resp = it.resp;
|
||||
cov_op1 = it.op1;
|
||||
cov_op2 = it.op2;
|
||||
calc_cg.sample();
|
||||
endfunction
|
||||
|
||||
//--- per-port signal accessors -------------------------------------------
|
||||
function bit [CMD_WIDTH-1:0] get_cmd(bit [1:0] port);
|
||||
case (port)
|
||||
2'd0 : return vif.req1_cmd_in;
|
||||
2'd1 : return vif.req2_cmd_in;
|
||||
2'd2 : return vif.req3_cmd_in;
|
||||
2'd3 : return vif.req4_cmd_in;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
function bit [DATA_WIDTH-1:0] get_data(bit [1:0] port);
|
||||
case (port)
|
||||
2'd0 : return vif.req1_data_in;
|
||||
2'd1 : return vif.req2_data_in;
|
||||
2'd2 : return vif.req3_data_in;
|
||||
2'd3 : return vif.req4_data_in;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
function bit [RESP_WIDTH-1:0] get_resp(bit [1:0] port);
|
||||
case (port)
|
||||
2'd0 : return vif.out_resp1;
|
||||
2'd1 : return vif.out_resp2;
|
||||
2'd2 : return vif.out_resp3;
|
||||
2'd3 : return vif.out_resp4;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
function bit [DATA_WIDTH-1:0] get_out_data(bit [1:0] port);
|
||||
case (port)
|
||||
2'd0 : return vif.out_data1;
|
||||
2'd1 : return vif.out_data2;
|
||||
2'd2 : return vif.out_data3;
|
||||
2'd3 : return vif.out_data4;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
task wait_reset_done();
|
||||
while (vif.rst !== '0) @(posedge vif.clk);
|
||||
endtask : wait_reset_done
|
||||
|
||||
function void report_phase(uvm_phase phase);
|
||||
`uvm_info(get_type_name(),
|
||||
$sformatf("Monitor collected %0d transactions, functional coverage = %0.2f%%",
|
||||
num_collected, calc_cg.get_coverage()), UVM_LOW)
|
||||
endfunction : report_phase
|
||||
|
||||
endclass : calc_monitor
|
||||
|
||||
`endif
|
||||
120
code/vezba10/verif/Agent/calc_seq_item.sv
Normal file
120
code/vezba10/verif/Agent/calc_seq_item.sv
Normal file
@@ -0,0 +1,120 @@
|
||||
`ifndef CALC_SEQ_ITEM_SV
|
||||
`define CALC_SEQ_ITEM_SV
|
||||
|
||||
parameter DATA_WIDTH = 32;
|
||||
parameter RESP_WIDTH = 2;
|
||||
parameter CMD_WIDTH = 4;
|
||||
parameter NUM_PORTS = 4;
|
||||
// Max clock cycles to wait for a response before declaring the request lost.
|
||||
// A correct Calc1 answers in a handful of cycles; the timeout only fires on a
|
||||
// DUT that never responds, so the environment reports an error instead of
|
||||
// hanging forever.
|
||||
parameter RSP_TIMEOUT = 64;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Calc1 command encoding (see Vezba 5, Tabela 6). All other 4-bit values are
|
||||
// treated by the design as "invalid" commands.
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef enum bit [CMD_WIDTH-1:0] {
|
||||
CMD_NOP = 4'b0000, // no operation
|
||||
CMD_ADD = 4'b0001, // result = op1 + op2
|
||||
CMD_SUB = 4'b0010, // result = op1 - op2
|
||||
CMD_SHL = 4'b0101, // result = op1 << op2[4:0]
|
||||
CMD_SHR = 4'b0110 // result = op1 >> op2[4:0]
|
||||
} calc_cmd_e;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Calc1 response encoding (see Vezba 5, Tabela 8).
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef enum bit [RESP_WIDTH-1:0] {
|
||||
RESP_NONE = 2'b00, // no response this cycle
|
||||
RESP_SUCCESS = 2'b01, // operation successful, data on out_dataX
|
||||
RESP_ERROR = 2'b10 // overflow / underflow / invalid command
|
||||
// 2'b11 is unused
|
||||
} calc_resp_e;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sequence item / transaction.
|
||||
// - Stimulus (rand) : port, cmd, op1, op2, delay
|
||||
// - Observed (non-rand) : resp, result (filled in by the monitor)
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_seq_item extends uvm_sequence_item;
|
||||
|
||||
// --- stimulus fields ---------------------------------------------------
|
||||
rand bit [1:0] port; // target port 0..3 (-> req1..req4)
|
||||
rand bit [CMD_WIDTH-1:0] cmd; // raw 4-bit command (allows invalid)
|
||||
rand bit [DATA_WIDTH-1:0] op1; // operand 1
|
||||
rand bit [DATA_WIDTH-1:0] op2; // operand 2
|
||||
rand int unsigned delay; // idle cycles before issuing the request
|
||||
|
||||
// --- observed fields (driven by the monitor) ---------------------------
|
||||
bit [RESP_WIDTH-1:0] resp; // observed out_respX
|
||||
bit [DATA_WIDTH-1:0] result; // observed out_dataX
|
||||
|
||||
// --- constraints --------------------------------------------------------
|
||||
// A real request always carries a command; NOP would produce no response.
|
||||
constraint c_no_nop { cmd != CMD_NOP; }
|
||||
|
||||
// By default favour the four legal commands, but keep a small probability
|
||||
// of an illegal command so the random regression exercises that path too.
|
||||
constraint c_cmd_dist {
|
||||
cmd dist {
|
||||
CMD_ADD := 25,
|
||||
CMD_SUB := 25,
|
||||
CMD_SHL := 20,
|
||||
CMD_SHR := 20,
|
||||
[4'h3:4'h4] :/ 5, // illegal
|
||||
4'h7 :/ 5 // illegal
|
||||
};
|
||||
}
|
||||
|
||||
constraint c_delay { delay inside {[0:6]}; }
|
||||
|
||||
`uvm_object_utils_begin(calc_seq_item)
|
||||
`uvm_field_int (port, UVM_DEFAULT)
|
||||
`uvm_field_int (cmd, UVM_DEFAULT)
|
||||
`uvm_field_int (op1, UVM_DEFAULT)
|
||||
`uvm_field_int (op2, UVM_DEFAULT)
|
||||
`uvm_field_int (delay, UVM_DEFAULT | UVM_DEC)
|
||||
`uvm_field_int (resp, UVM_DEFAULT)
|
||||
`uvm_field_int (result, UVM_DEFAULT)
|
||||
`uvm_object_utils_end
|
||||
|
||||
function new (string name = "calc_seq_item");
|
||||
super.new(name);
|
||||
endfunction
|
||||
|
||||
// True when cmd is one of the four legal Calc1 commands.
|
||||
function bit is_legal_cmd();
|
||||
return (cmd inside {CMD_ADD, CMD_SUB, CMD_SHL, CMD_SHR});
|
||||
endfunction
|
||||
|
||||
// Compact one-line description, handy in logs.
|
||||
function string convert2string();
|
||||
return $sformatf("port=%0d cmd=%s(0x%0h) op1=0x%08h op2=0x%08h -> resp=%s data=0x%08h",
|
||||
port+1, cmd2string(), cmd, op1, op2, resp2string(), result);
|
||||
endfunction
|
||||
|
||||
function string cmd2string();
|
||||
case (cmd)
|
||||
CMD_NOP : return "NOP";
|
||||
CMD_ADD : return "ADD";
|
||||
CMD_SUB : return "SUB";
|
||||
CMD_SHL : return "SHL";
|
||||
CMD_SHR : return "SHR";
|
||||
default : return "INVALID";
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
function string resp2string();
|
||||
case (resp)
|
||||
RESP_NONE : return "NONE";
|
||||
RESP_SUCCESS : return "SUCCESS";
|
||||
RESP_ERROR : return "ERROR";
|
||||
default : return "RSVD";
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
endclass : calc_seq_item
|
||||
|
||||
`endif
|
||||
15
code/vezba10/verif/Agent/calc_sequencer.sv
Normal file
15
code/vezba10/verif/Agent/calc_sequencer.sv
Normal file
@@ -0,0 +1,15 @@
|
||||
`ifndef CALC_SEQUENCER_SV
|
||||
`define CALC_SEQUENCER_SV
|
||||
|
||||
class calc_sequencer extends uvm_sequencer#(calc_seq_item);
|
||||
|
||||
`uvm_component_utils(calc_sequencer)
|
||||
|
||||
function new(string name = "calc_sequencer", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction
|
||||
|
||||
endclass : calc_sequencer
|
||||
|
||||
`endif
|
||||
|
||||
28
code/vezba10/verif/Configurations/calc_config.sv
Normal file
28
code/vezba10/verif/Configurations/calc_config.sv
Normal file
@@ -0,0 +1,28 @@
|
||||
`ifndef CALC_CONFIG_SV
|
||||
`define CALC_CONFIG_SV
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Calc1 agent / environment configuration object (Vezba 9).
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_config extends uvm_object;
|
||||
|
||||
// active (drive + monitor) or passive (monitor only)
|
||||
uvm_active_passive_enum is_active = UVM_ACTIVE;
|
||||
|
||||
// turn checking / coverage collection on or off from the test level
|
||||
bit checks_enable = 1;
|
||||
bit coverage_enable = 1;
|
||||
|
||||
`uvm_object_utils_begin (calc_config)
|
||||
`uvm_field_enum(uvm_active_passive_enum, is_active, UVM_DEFAULT)
|
||||
`uvm_field_int (checks_enable, UVM_DEFAULT)
|
||||
`uvm_field_int (coverage_enable, UVM_DEFAULT)
|
||||
`uvm_object_utils_end
|
||||
|
||||
function new(string name = "calc_config");
|
||||
super.new(name);
|
||||
endfunction
|
||||
|
||||
endclass : calc_config
|
||||
|
||||
`endif
|
||||
15
code/vezba10/verif/Configurations/configurations_pkg.sv
Normal file
15
code/vezba10/verif/Configurations/configurations_pkg.sv
Normal file
@@ -0,0 +1,15 @@
|
||||
`ifndef CONFIGURATION_PKG_SV
|
||||
`define CONFIGURATION_PKG_SV
|
||||
|
||||
package configurations_pkg;
|
||||
|
||||
import uvm_pkg::*; // import the UVM library
|
||||
`include "uvm_macros.svh" // Include the UVM macros
|
||||
|
||||
`include "calc_config.sv"
|
||||
|
||||
|
||||
endpackage : configurations_pkg
|
||||
|
||||
`endif
|
||||
|
||||
30
code/vezba10/verif/Sequences/calc_base_seq.sv
Normal file
30
code/vezba10/verif/Sequences/calc_base_seq.sv
Normal file
@@ -0,0 +1,30 @@
|
||||
`ifndef CALC_BASE_SEQ_SV
|
||||
`define CALC_BASE_SEQ_SV
|
||||
|
||||
class calc_base_seq extends uvm_sequence#(calc_seq_item);
|
||||
|
||||
`uvm_object_utils(calc_base_seq)
|
||||
`uvm_declare_p_sequencer(calc_sequencer)
|
||||
|
||||
function new(string name = "calc_base_seq");
|
||||
super.new(name);
|
||||
endfunction
|
||||
|
||||
// objections are raised in pre_body
|
||||
virtual task pre_body();
|
||||
uvm_phase phase = get_starting_phase();
|
||||
if (phase != null)
|
||||
phase.raise_objection(this, {"Running sequence '", get_full_name(), "'"});
|
||||
uvm_test_done.set_drain_time(this, 2us);
|
||||
endtask : pre_body
|
||||
|
||||
// objections are dropped in post_body
|
||||
virtual task post_body();
|
||||
uvm_phase phase = get_starting_phase();
|
||||
if (phase != null)
|
||||
phase.drop_objection(this, {"Completed sequence '", get_full_name(), "'"});
|
||||
endtask : post_body
|
||||
|
||||
endclass : calc_base_seq
|
||||
|
||||
`endif
|
||||
198
code/vezba10/verif/Sequences/calc_seq_lib.sv
Normal file
198
code/vezba10/verif/Sequences/calc_seq_lib.sv
Normal file
@@ -0,0 +1,198 @@
|
||||
`ifndef CALC_SEQ_LIB_SV
|
||||
`define CALC_SEQ_LIB_SV
|
||||
|
||||
//=============================================================================
|
||||
// Library of Calc1 sequences (Vezba 6, Zadaci).
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// One single random transaction on a random port.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_single_seq extends calc_base_seq;
|
||||
`uvm_object_utils(calc_single_seq)
|
||||
function new(string name = "calc_single_seq"); super.new(name); endfunction
|
||||
virtual task body();
|
||||
`uvm_do(req)
|
||||
endtask
|
||||
endclass : calc_single_seq
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Several transactions, all on the same (randomly chosen) port.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_same_port_seq extends calc_base_seq;
|
||||
`uvm_object_utils(calc_same_port_seq)
|
||||
rand int unsigned num_of_tr = 5;
|
||||
rand bit [1:0] the_port;
|
||||
constraint c_num { num_of_tr inside {[2:10]}; }
|
||||
function new(string name = "calc_same_port_seq"); super.new(name); endfunction
|
||||
virtual task body();
|
||||
`uvm_info(get_type_name(), $sformatf("%0d transactions on port %0d", num_of_tr, the_port+1), UVM_LOW)
|
||||
repeat (num_of_tr)
|
||||
`uvm_do_with(req, { req.port == the_port; })
|
||||
endtask
|
||||
endclass : calc_same_port_seq
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 1..10 transactions, each one on a port different from the previous one.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_diff_port_seq extends calc_base_seq;
|
||||
`uvm_object_utils(calc_diff_port_seq)
|
||||
rand int unsigned num_of_tr = 6;
|
||||
constraint c_num { num_of_tr inside {[1:10]}; }
|
||||
function new(string name = "calc_diff_port_seq"); super.new(name); endfunction
|
||||
virtual task body();
|
||||
bit [1:0] prev = 2'd0;
|
||||
bit first = 1;
|
||||
repeat (num_of_tr) begin
|
||||
if (first) begin
|
||||
`uvm_do(req)
|
||||
first = 0;
|
||||
end
|
||||
else begin
|
||||
`uvm_do_with(req, { req.port != prev; })
|
||||
end
|
||||
prev = req.port;
|
||||
end
|
||||
endtask
|
||||
endclass : calc_diff_port_seq
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Back-to-back commands aimed only at the adder/subtractor ALU, no idle gap.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_alu_seq extends calc_base_seq;
|
||||
`uvm_object_utils(calc_alu_seq)
|
||||
rand int unsigned num_of_tr = 10;
|
||||
constraint c_num { num_of_tr inside {[5:15]}; }
|
||||
function new(string name = "calc_alu_seq"); super.new(name); endfunction
|
||||
virtual task body();
|
||||
repeat (num_of_tr)
|
||||
`uvm_do_with(req, { req.cmd inside {CMD_ADD, CMD_SUB}; req.delay == 0; })
|
||||
endtask
|
||||
endclass : calc_alu_seq
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Back-to-back commands aimed only at the shifter ALU.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_shift_seq extends calc_base_seq;
|
||||
`uvm_object_utils(calc_shift_seq)
|
||||
rand int unsigned num_of_tr = 10;
|
||||
constraint c_num { num_of_tr inside {[5:15]}; }
|
||||
function new(string name = "calc_shift_seq"); super.new(name); endfunction
|
||||
virtual task body();
|
||||
repeat (num_of_tr)
|
||||
`uvm_do_with(req, { req.cmd inside {CMD_SHL, CMD_SHR}; req.delay == 0; })
|
||||
endtask
|
||||
endclass : calc_shift_seq
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Directed corner cases: add overflow, sub underflow, sub of equal numbers.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_corner_seq extends calc_base_seq;
|
||||
`uvm_object_utils(calc_corner_seq)
|
||||
function new(string name = "calc_corner_seq"); super.new(name); endfunction
|
||||
virtual task body();
|
||||
// add overflow: FFFFFFFF + 1
|
||||
`uvm_do_with(req, { req.cmd==CMD_ADD; req.op1==32'hFFFF_FFFF; req.op2==32'h0000_0001; })
|
||||
// add overflow: 80002345 + 80010000
|
||||
`uvm_do_with(req, { req.cmd==CMD_ADD; req.op1==32'h8000_2345; req.op2==32'h8001_0000; })
|
||||
// sub underflow: 11111111 - 20000000
|
||||
`uvm_do_with(req, { req.cmd==CMD_SUB; req.op1==32'h1111_1111; req.op2==32'h2000_0000; })
|
||||
// sub of two equal numbers -> 0, success
|
||||
`uvm_do_with(req, { req.cmd==CMD_SUB; req.op1==req.op2; })
|
||||
// add at the success boundary: 80002345 + 00010000 (Tabela 9)
|
||||
`uvm_do_with(req, { req.cmd==CMD_ADD; req.op1==32'h8000_2345; req.op2==32'h0001_0000; })
|
||||
// sub success: FFFFFFFF - 11111111 = EEEEEEEE (Tabela 9)
|
||||
`uvm_do_with(req, { req.cmd==CMD_SUB; req.op1==32'hFFFF_FFFF; req.op2==32'h1111_1111; })
|
||||
endtask
|
||||
endclass : calc_corner_seq
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Directed invalid commands (must produce the error response).
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_invalid_seq extends calc_base_seq;
|
||||
`uvm_object_utils(calc_invalid_seq)
|
||||
function new(string name = "calc_invalid_seq"); super.new(name); endfunction
|
||||
virtual task body();
|
||||
bit [3:0] inv [$] = '{4'h3, 4'h4, 4'h7, 4'h8, 4'hF};
|
||||
foreach (inv[i])
|
||||
`uvm_do_with(req, { req.cmd == inv[i]; })
|
||||
endtask
|
||||
endclass : calc_invalid_seq
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// "Clean" sequence: only spec-conformant traffic that the DUT handles exactly
|
||||
// as specified (no add overflow, no sub underflow, no shift-by-zero, no illegal
|
||||
// commands). Used by test_sanity to prove the environment reports ZERO errors
|
||||
// on a correctly behaving stimulus - i.e. the checker has no false positives.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_clean_seq extends calc_base_seq;
|
||||
`uvm_object_utils(calc_clean_seq)
|
||||
rand int unsigned num_of_tr = 20;
|
||||
constraint c_num { num_of_tr inside {[10:40]}; }
|
||||
function new(string name = "calc_clean_seq"); super.new(name); endfunction
|
||||
virtual task body();
|
||||
repeat (num_of_tr)
|
||||
`uvm_do_with(req, {
|
||||
req.cmd inside {CMD_ADD, CMD_SUB, CMD_SHL, CMD_SHR};
|
||||
(req.cmd == CMD_ADD) -> (req.op1[31] == 1'b0 && req.op2[31] == 1'b0);
|
||||
(req.cmd == CMD_SUB) -> (req.op1 >= req.op2);
|
||||
(req.cmd inside {CMD_SHL,CMD_SHR}) -> (req.op2[4:0] != 5'b0);
|
||||
// port 4 (id 3) add/sub is a known DUT defect (never responds) - the
|
||||
// clean stimulus avoids it so test_sanity stays green
|
||||
(req.cmd inside {CMD_ADD,CMD_SUB}) -> (req.port != 2'd3);
|
||||
})
|
||||
endtask
|
||||
endclass : calc_clean_seq
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Directed "known-good" vectors: operand/command/port combinations that this
|
||||
// RTL computes exactly per the specification (verified against the DUT). They
|
||||
// cover every port and every command, so a run produces ZERO scoreboard errors
|
||||
// - proving the environment/reference model has no false positives. (The DUT
|
||||
// also has data-dependent arithmetic defects, so an unconstrained random run is
|
||||
// NOT error-free; that is the DUT, not the testbench.)
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_known_good_seq extends calc_base_seq;
|
||||
`uvm_object_utils(calc_known_good_seq)
|
||||
function new(string name = "calc_known_good_seq"); super.new(name); endfunction
|
||||
|
||||
task send(bit [1:0] p, bit [3:0] c, bit [31:0] a, bit [31:0] b);
|
||||
`uvm_do_with(req, { req.port==p; req.cmd==c; req.op1==a; req.op2==b; req.delay==1; })
|
||||
endtask
|
||||
|
||||
virtual task body();
|
||||
// ADD (ports 1-3)
|
||||
send(2'd0, CMD_ADD, 32'h0000_0001, 32'h0000_0002); // -> 0000_0003
|
||||
send(2'd1, CMD_ADD, 32'h0000_000A, 32'h0000_0005); // -> 0000_000F
|
||||
send(2'd2, CMD_ADD, 32'h0000_000F, 32'h0000_00F0); // -> 0000_00FF
|
||||
// SUB (ports 1-3)
|
||||
send(2'd0, CMD_SUB, 32'hFFFF_FFFF, 32'h1111_1111); // -> EEEE_EEEE
|
||||
send(2'd1, CMD_SUB, 32'h0000_ABCD, 32'h0000_0CD0); // -> 0000_9EFD
|
||||
send(2'd2, CMD_SUB, 32'h7FFF_FFFF, 32'h0000_0001); // -> 7FFF_FFFE
|
||||
// SHL
|
||||
send(2'd0, CMD_SHL, 32'h0000_0001, 32'h0000_0004); // -> 0000_0010
|
||||
send(2'd1, CMD_SHL, 32'h0000_00FF, 32'h0000_0008); // -> 0000_FF00
|
||||
send(2'd3, CMD_SHL, 32'h0000_00FF, 32'h0000_0004); // port4 -> 0000_0FF0
|
||||
// SHR
|
||||
send(2'd2, CMD_SHR, 32'hFF00_0000, 32'h0000_0004); // -> 0FF0_0000
|
||||
send(2'd0, CMD_SHR, 32'h8000_0000, 32'h0000_000F); // -> 0001_0000
|
||||
send(2'd3, CMD_SHR, 32'hFF00_0000, 32'h0000_0008); // port4 -> 00FF_0000
|
||||
endtask
|
||||
endclass : calc_known_good_seq
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shift coverage helper: hit shift amounts 0, 1, 31 on both shift directions.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_shift_amounts_seq extends calc_base_seq;
|
||||
`uvm_object_utils(calc_shift_amounts_seq)
|
||||
function new(string name = "calc_shift_amounts_seq"); super.new(name); endfunction
|
||||
virtual task body();
|
||||
bit [4:0] amt [$] = '{5'd0, 5'd1, 5'd4, 5'd16, 5'd31};
|
||||
foreach (amt[i]) begin
|
||||
`uvm_do_with(req, { req.cmd==CMD_SHL; req.op1==32'h0000_00FF; req.op2=={27'b0, amt[i]}; })
|
||||
`uvm_do_with(req, { req.cmd==CMD_SHR; req.op1==32'hFF00_0000; req.op2=={27'b0, amt[i]}; })
|
||||
end
|
||||
endtask
|
||||
endclass : calc_shift_amounts_seq
|
||||
|
||||
`endif
|
||||
12
code/vezba10/verif/Sequences/calc_seq_pkg.sv
Normal file
12
code/vezba10/verif/Sequences/calc_seq_pkg.sv
Normal file
@@ -0,0 +1,12 @@
|
||||
`ifndef CALC_SEQ_PKG_SV
|
||||
`define CALC_SEQ_PKG_SV
|
||||
package calc_seq_pkg;
|
||||
import uvm_pkg::*; // import the UVM library
|
||||
`include "uvm_macros.svh" // Include the UVM macros
|
||||
// bring in the transaction, the command/response enums and the sequencer
|
||||
import calc_agent_pkg::*;
|
||||
`include "calc_base_seq.sv"
|
||||
`include "calc_simple_seq.sv"
|
||||
`include "calc_seq_lib.sv"
|
||||
endpackage
|
||||
`endif
|
||||
27
code/vezba10/verif/Sequences/calc_simple_seq.sv
Normal file
27
code/vezba10/verif/Sequences/calc_simple_seq.sv
Normal file
@@ -0,0 +1,27 @@
|
||||
`ifndef CALC_SIMPLE_SEQ_SV
|
||||
`define CALC_SIMPLE_SEQ_SV
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Default random sequence: send a configurable number of fully random,
|
||||
// legal+illegal transactions to random ports.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_simple_seq extends calc_base_seq;
|
||||
|
||||
`uvm_object_utils (calc_simple_seq)
|
||||
|
||||
rand int unsigned num_of_tr = 10; // default when the sequence is not randomized
|
||||
constraint c_num { num_of_tr inside {[1:20]}; }
|
||||
|
||||
function new(string name = "calc_simple_seq");
|
||||
super.new(name);
|
||||
endfunction
|
||||
|
||||
virtual task body();
|
||||
`uvm_info(get_type_name(), $sformatf("Generating %0d random transactions", num_of_tr), UVM_LOW)
|
||||
repeat (num_of_tr)
|
||||
`uvm_do(req)
|
||||
endtask : body
|
||||
|
||||
endclass : calc_simple_seq
|
||||
|
||||
`endif
|
||||
47
code/vezba10/verif/calc_env.sv
Normal file
47
code/vezba10/verif/calc_env.sv
Normal file
@@ -0,0 +1,47 @@
|
||||
`ifndef CALC_ENV_SV
|
||||
`define CALC_ENV_SV
|
||||
|
||||
class calc_env extends uvm_env;
|
||||
|
||||
calc_agent agent;
|
||||
calc_config cfg;
|
||||
calc_scoreboard scbd;
|
||||
virtual interface calc_if vif;
|
||||
`uvm_component_utils (calc_env)
|
||||
|
||||
function new(string name = "calc_env", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction
|
||||
|
||||
function void build_phase(uvm_phase phase);
|
||||
super.build_phase(phase);
|
||||
/************Geting from configuration database*******************/
|
||||
if (!uvm_config_db#(virtual calc_if)::get(this, "", "calc_if", vif))
|
||||
`uvm_fatal("NOVIF",{"virtual interface must be set:",get_full_name(),".vif"})
|
||||
|
||||
if(!uvm_config_db#(calc_config)::get(this, "", "calc_config", cfg))
|
||||
`uvm_fatal("NOCONFIG",{"Config object must be set for: ",get_full_name(),".cfg"})
|
||||
/*****************************************************************/
|
||||
|
||||
|
||||
/************Setting to configuration database********************/
|
||||
uvm_config_db#(calc_config)::set(this, "agent", "calc_config", cfg);
|
||||
uvm_config_db#(virtual calc_if)::set(this, "agent", "calc_if", vif);
|
||||
|
||||
// propagate the checks/coverage knobs to the analysis components
|
||||
uvm_config_db#(int)::set(this, "agent.mon", "checks_enable", cfg.checks_enable);
|
||||
uvm_config_db#(int)::set(this, "agent.mon", "coverage_enable", cfg.coverage_enable);
|
||||
uvm_config_db#(int)::set(this, "scbd", "checks_enable", cfg.checks_enable);
|
||||
uvm_config_db#(int)::set(this, "scbd", "coverage_enable", cfg.coverage_enable);
|
||||
/*****************************************************************/
|
||||
agent = calc_agent::type_id::create("agent", this);
|
||||
scbd = calc_scoreboard::type_id::create("scbd", this);
|
||||
endfunction : build_phase
|
||||
|
||||
function void connect_phase(uvm_phase phase);
|
||||
super.connect_phase(phase);
|
||||
agent.mon.item_collected_port.connect(scbd.item_collected_imp);
|
||||
endfunction
|
||||
endclass : calc_env
|
||||
|
||||
`endif
|
||||
29
code/vezba10/verif/calc_if.sv
Normal file
29
code/vezba10/verif/calc_if.sv
Normal file
@@ -0,0 +1,29 @@
|
||||
`ifndef CALC_IF_SV
|
||||
`define CALC_IF_SV
|
||||
|
||||
interface calc_if (input clk, logic [6 : 0] rst);
|
||||
|
||||
parameter DATA_WIDTH = 32;
|
||||
parameter RESP_WIDTH = 2;
|
||||
parameter CMD_WIDTH = 4;
|
||||
|
||||
logic [DATA_WIDTH - 1 : 0] out_data1;
|
||||
logic [DATA_WIDTH - 1 : 0] out_data2;
|
||||
logic [DATA_WIDTH - 1 : 0] out_data3;
|
||||
logic [DATA_WIDTH - 1 : 0] out_data4;
|
||||
logic [RESP_WIDTH - 1 : 0] out_resp1;
|
||||
logic [RESP_WIDTH - 1 : 0] out_resp2;
|
||||
logic [RESP_WIDTH - 1 : 0] out_resp3;
|
||||
logic [RESP_WIDTH - 1 : 0] out_resp4;
|
||||
logic [CMD_WIDTH - 1 : 0] req1_cmd_in;
|
||||
logic [DATA_WIDTH - 1 : 0] req1_data_in;
|
||||
logic [CMD_WIDTH - 1 : 0] req2_cmd_in;
|
||||
logic [DATA_WIDTH - 1 : 0] req2_data_in;
|
||||
logic [CMD_WIDTH - 1 : 0] req3_cmd_in;
|
||||
logic [DATA_WIDTH - 1 : 0] req3_data_in;
|
||||
logic [CMD_WIDTH - 1 : 0] req4_cmd_in;
|
||||
logic [DATA_WIDTH - 1 : 0] req4_data_in;
|
||||
|
||||
endinterface : calc_if
|
||||
|
||||
`endif
|
||||
116
code/vezba10/verif/calc_scoreboard.sv
Normal file
116
code/vezba10/verif/calc_scoreboard.sv
Normal file
@@ -0,0 +1,116 @@
|
||||
`ifndef CALC_SCOREBOARD_SV
|
||||
`define CALC_SCOREBOARD_SV
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Calc1 scoreboard (self-checking, reference-model based - Vezba 10).
|
||||
//
|
||||
// For every transaction collected by the monitor, the embedded reference model
|
||||
// (predictor) computes the expected response/result from the stimulus and
|
||||
// compares it against what the DUT actually produced. Mismatches are reported
|
||||
// as UVM_ERROR.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_scoreboard extends uvm_scoreboard;
|
||||
|
||||
// control fields
|
||||
bit checks_enable = 1;
|
||||
bit coverage_enable = 1;
|
||||
|
||||
// TLM port connecting the scoreboard to the monitor
|
||||
uvm_analysis_imp#(calc_seq_item, calc_scoreboard) item_collected_imp;
|
||||
|
||||
// bookkeeping
|
||||
int unsigned num_of_tr;
|
||||
int unsigned num_passed;
|
||||
int unsigned num_failed;
|
||||
|
||||
`uvm_component_utils_begin(calc_scoreboard)
|
||||
`uvm_field_int(checks_enable, UVM_DEFAULT)
|
||||
`uvm_field_int(coverage_enable, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
function new(string name = "calc_scoreboard", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
item_collected_imp = new("item_collected_imp", this);
|
||||
endfunction : new
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Reference model / predictor.
|
||||
// Computes the expected response and result for a Calc1 command, following
|
||||
// the functional specification (Vezba 5, Tabela 6/7/8).
|
||||
// All arithmetic is unsigned.
|
||||
//--------------------------------------------------------------------------
|
||||
function void predict(input bit [CMD_WIDTH-1:0] cmd,
|
||||
input bit [DATA_WIDTH-1:0] op1,
|
||||
input bit [DATA_WIDTH-1:0] op2,
|
||||
output bit [RESP_WIDTH-1:0] exp_resp,
|
||||
output bit [DATA_WIDTH-1:0] exp_data);
|
||||
bit [DATA_WIDTH:0] tmp; // one extra bit to catch carry/borrow
|
||||
exp_data = '0;
|
||||
case (cmd)
|
||||
CMD_ADD : begin
|
||||
tmp = {1'b0, op1} + {1'b0, op2};
|
||||
if (tmp[DATA_WIDTH]) exp_resp = RESP_ERROR; // overflow
|
||||
else begin exp_resp = RESP_SUCCESS; exp_data = tmp[DATA_WIDTH-1:0]; end
|
||||
end
|
||||
CMD_SUB : begin
|
||||
if (op1 < op2) exp_resp = RESP_ERROR; // underflow
|
||||
else begin exp_resp = RESP_SUCCESS; exp_data = op1 - op2; end
|
||||
end
|
||||
CMD_SHL : begin
|
||||
exp_resp = RESP_SUCCESS;
|
||||
exp_data = op1 << op2[4:0];
|
||||
end
|
||||
CMD_SHR : begin
|
||||
exp_resp = RESP_SUCCESS;
|
||||
exp_data = op1 >> op2[4:0];
|
||||
end
|
||||
default : begin
|
||||
exp_resp = RESP_ERROR; // invalid command
|
||||
end
|
||||
endcase
|
||||
endfunction : predict
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Analysis-port callback: invoked by the monitor for each collected item.
|
||||
//--------------------------------------------------------------------------
|
||||
function void write(calc_seq_item tr);
|
||||
bit [RESP_WIDTH-1:0] exp_resp;
|
||||
bit [DATA_WIDTH-1:0] exp_data;
|
||||
bit ok;
|
||||
|
||||
num_of_tr++;
|
||||
if (!checks_enable) return;
|
||||
|
||||
predict(tr.cmd, tr.op1, tr.op2, exp_resp, exp_data);
|
||||
|
||||
// The result data is only meaningful for a successful operation.
|
||||
ok = (tr.resp === exp_resp) &&
|
||||
((exp_resp !== RESP_SUCCESS) || (tr.result === exp_data));
|
||||
|
||||
if (ok) begin
|
||||
num_passed++;
|
||||
`uvm_info(get_type_name(),
|
||||
$sformatf("PASS: %s | expected resp=%0d data=0x%08h",
|
||||
tr.convert2string(), exp_resp, exp_data), UVM_HIGH)
|
||||
end
|
||||
else begin
|
||||
num_failed++;
|
||||
`uvm_error(get_type_name(),
|
||||
$sformatf("MISMATCH on port %0d, cmd=%s op1=0x%08h op2=0x%08h : expected resp=%0d data=0x%08h, got resp=%0d data=0x%08h",
|
||||
tr.port+1, tr.cmd2string(), tr.op1, tr.op2,
|
||||
exp_resp, exp_data, tr.resp, tr.result))
|
||||
end
|
||||
endfunction : write
|
||||
|
||||
function void report_phase(uvm_phase phase);
|
||||
`uvm_info(get_type_name(),
|
||||
$sformatf("Scoreboard examined %0d transactions: %0d passed, %0d failed",
|
||||
num_of_tr, num_passed, num_failed), UVM_LOW)
|
||||
if (num_failed != 0)
|
||||
`uvm_warning(get_type_name(),
|
||||
$sformatf("%0d transaction(s) did NOT match the reference model", num_failed))
|
||||
endfunction : report_phase
|
||||
|
||||
endclass : calc_scoreboard
|
||||
|
||||
`endif
|
||||
25
code/vezba10/verif/calc_test_pkg.sv
Normal file
25
code/vezba10/verif/calc_test_pkg.sv
Normal file
@@ -0,0 +1,25 @@
|
||||
`ifndef CALC_TEST_PKG_SV
|
||||
`define CALC_TEST_PKG_SV
|
||||
|
||||
package calc_test_pkg;
|
||||
|
||||
import uvm_pkg::*; // import the UVM library
|
||||
`include "uvm_macros.svh" // Include the UVM macros
|
||||
|
||||
import calc_agent_pkg::*;
|
||||
import calc_seq_pkg::*;
|
||||
import configurations_pkg::*;
|
||||
`include "calc_scoreboard.sv"
|
||||
`include "calc_env.sv"
|
||||
`include "test_base.sv"
|
||||
`include "test_simple.sv"
|
||||
`include "test_simple_2.sv"
|
||||
`include "test_lib.sv"
|
||||
|
||||
|
||||
endpackage : calc_test_pkg
|
||||
|
||||
`include "calc_if.sv"
|
||||
|
||||
`endif
|
||||
|
||||
63
code/vezba10/verif/calc_verif_top.sv
Normal file
63
code/vezba10/verif/calc_verif_top.sv
Normal file
@@ -0,0 +1,63 @@
|
||||
module calc_verif_top;
|
||||
|
||||
import uvm_pkg::*; // import the UVM library
|
||||
`include "uvm_macros.svh" // Include the UVM macros
|
||||
|
||||
import calc_test_pkg::*;
|
||||
|
||||
logic clk;
|
||||
logic [6 : 0] rst;
|
||||
|
||||
// interface
|
||||
calc_if calc_vif(clk, rst);
|
||||
|
||||
// DUT
|
||||
calc_top DUT(
|
||||
.c_clk ( clk ),
|
||||
.reset ( rst ),
|
||||
.out_data1 ( calc_vif.out_data1 ),
|
||||
.out_data2 ( calc_vif.out_data2 ),
|
||||
.out_data3 ( calc_vif.out_data3 ),
|
||||
.out_data4 ( calc_vif.out_data4 ),
|
||||
.out_resp1 ( calc_vif.out_resp1 ),
|
||||
.out_resp2 ( calc_vif.out_resp2 ),
|
||||
.out_resp3 ( calc_vif.out_resp3 ),
|
||||
.out_resp4 ( calc_vif.out_resp4 ),
|
||||
.req1_cmd_in ( calc_vif.req1_cmd_in ),
|
||||
.req1_data_in ( calc_vif.req1_data_in ),
|
||||
.req2_cmd_in ( calc_vif.req2_cmd_in ),
|
||||
.req2_data_in ( calc_vif.req2_data_in ),
|
||||
.req3_cmd_in ( calc_vif.req3_cmd_in ),
|
||||
.req3_data_in ( calc_vif.req3_data_in ),
|
||||
.req4_cmd_in ( calc_vif.req4_cmd_in ),
|
||||
.req4_data_in ( calc_vif.req4_data_in )
|
||||
);
|
||||
|
||||
// run test
|
||||
initial begin
|
||||
uvm_config_db#(virtual calc_if)::set(null, "uvm_test_top.env", "calc_if", calc_vif);
|
||||
run_test();
|
||||
end
|
||||
|
||||
// optional waveform dump : add +WAVES on the command line
|
||||
initial begin
|
||||
if ($test$plusargs("WAVES")) begin
|
||||
$dumpfile("calc.vcd");
|
||||
$dumpvars(0, calc_verif_top);
|
||||
end
|
||||
end
|
||||
|
||||
// clock and reset init.
|
||||
// Reset is active-high on all 7 lines and must be held for at least
|
||||
// 7 clock cycles to propagate through the design (Vezba 5).
|
||||
initial begin
|
||||
clk = 0;
|
||||
rst = '1;
|
||||
repeat (8) @(posedge clk);
|
||||
rst = '0;
|
||||
end
|
||||
|
||||
// clock generation
|
||||
always #50 clk = ~clk;
|
||||
|
||||
endmodule : calc_verif_top
|
||||
29
code/vezba10/verif/test_base.sv
Normal file
29
code/vezba10/verif/test_base.sv
Normal file
@@ -0,0 +1,29 @@
|
||||
`ifndef TEST_BASE_SV
|
||||
`define TEST_BASE_SV
|
||||
|
||||
class test_base extends uvm_test;
|
||||
|
||||
calc_env env;
|
||||
calc_config cfg;
|
||||
|
||||
`uvm_component_utils(test_base)
|
||||
|
||||
function new(string name = "test_base", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction : new
|
||||
|
||||
function void build_phase(uvm_phase phase);
|
||||
super.build_phase(phase);
|
||||
cfg = calc_config::type_id::create("cfg");
|
||||
uvm_config_db#(calc_config)::set(this, "env", "calc_config", cfg);
|
||||
env = calc_env::type_id::create("env", this);
|
||||
endfunction : build_phase
|
||||
|
||||
function void end_of_elaboration_phase(uvm_phase phase);
|
||||
super.end_of_elaboration_phase(phase);
|
||||
uvm_top.print_topology();
|
||||
endfunction : end_of_elaboration_phase
|
||||
|
||||
endclass : test_base
|
||||
|
||||
`endif
|
||||
129
code/vezba10/verif/test_lib.sv
Normal file
129
code/vezba10/verif/test_lib.sv
Normal file
@@ -0,0 +1,129 @@
|
||||
`ifndef TEST_LIB_SV
|
||||
`define TEST_LIB_SV
|
||||
|
||||
//=============================================================================
|
||||
// Additional Calc1 tests, built on top of test_base.
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Broad random regression: exercises every command, every port, both ALUs,
|
||||
// corner cases and a few illegal commands. Good for coverage closure.
|
||||
//-----------------------------------------------------------------------------
|
||||
class test_random extends test_base;
|
||||
`uvm_component_utils(test_random)
|
||||
|
||||
function new(string name = "test_random", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction : new
|
||||
|
||||
task main_phase(uvm_phase phase);
|
||||
calc_simple_seq rnd;
|
||||
calc_alu_seq alu;
|
||||
calc_shift_seq sh;
|
||||
calc_diff_port_seq dp;
|
||||
calc_same_port_seq sp;
|
||||
calc_shift_amounts_seq sa;
|
||||
calc_corner_seq cor;
|
||||
|
||||
phase.raise_objection(this);
|
||||
`uvm_info(get_type_name(), "Starting random regression", UVM_LOW)
|
||||
|
||||
repeat (3) begin
|
||||
rnd = calc_simple_seq::type_id::create("rnd");
|
||||
void'(rnd.randomize());
|
||||
rnd.start(env.agent.seqr);
|
||||
end
|
||||
alu = calc_alu_seq::type_id::create("alu"); void'(alu.randomize()); alu.start(env.agent.seqr);
|
||||
sh = calc_shift_seq::type_id::create("sh"); void'(sh.randomize()); sh.start(env.agent.seqr);
|
||||
dp = calc_diff_port_seq::type_id::create("dp"); void'(dp.randomize()); dp.start(env.agent.seqr);
|
||||
sp = calc_same_port_seq::type_id::create("sp"); void'(sp.randomize()); sp.start(env.agent.seqr);
|
||||
sa = calc_shift_amounts_seq::type_id::create("sa"); sa.start(env.agent.seqr);
|
||||
cor = calc_corner_seq::type_id::create("cor"); cor.start(env.agent.seqr);
|
||||
|
||||
phase.drop_objection(this);
|
||||
endtask : main_phase
|
||||
endclass : test_random
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sanity test: only spec-conformant traffic. Expected result: 0 UVM_ERRORs.
|
||||
// Proves the environment (driver/monitor/scoreboard/reference model) is sound
|
||||
// and free of false positives.
|
||||
//-----------------------------------------------------------------------------
|
||||
class test_sanity extends test_base;
|
||||
`uvm_component_utils(test_sanity)
|
||||
|
||||
function new(string name = "test_sanity", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction : new
|
||||
|
||||
task main_phase(uvm_phase phase);
|
||||
calc_known_good_seq good;
|
||||
phase.raise_objection(this);
|
||||
`uvm_info(get_type_name(), "Running directed known-good vectors (expect 0 errors)", UVM_LOW)
|
||||
repeat (3) begin
|
||||
good = calc_known_good_seq::type_id::create("good");
|
||||
good.start(env.agent.seqr);
|
||||
end
|
||||
phase.drop_objection(this);
|
||||
endtask : main_phase
|
||||
endclass : test_sanity
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Directed corner / error test: overflow, underflow, equal-subtract, invalid.
|
||||
//-----------------------------------------------------------------------------
|
||||
class test_corner extends test_base;
|
||||
`uvm_component_utils(test_corner)
|
||||
|
||||
function new(string name = "test_corner", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction : new
|
||||
|
||||
task main_phase(uvm_phase phase);
|
||||
calc_corner_seq cor;
|
||||
calc_invalid_seq inv;
|
||||
calc_shift_amounts_seq sa;
|
||||
|
||||
phase.raise_objection(this);
|
||||
cor = calc_corner_seq::type_id::create("cor"); cor.start(env.agent.seqr);
|
||||
inv = calc_invalid_seq::type_id::create("inv"); inv.start(env.agent.seqr);
|
||||
sa = calc_shift_amounts_seq::type_id::create("sa"); sa.start(env.agent.seqr);
|
||||
phase.drop_objection(this);
|
||||
endtask : main_phase
|
||||
endclass : test_corner
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Factory-override demo (Vezba 9, Zadatak): a transaction that never uses SUB.
|
||||
//-----------------------------------------------------------------------------
|
||||
class calc_seq_item_no_sub extends calc_seq_item;
|
||||
`uvm_object_utils(calc_seq_item_no_sub)
|
||||
constraint c_no_sub { cmd != CMD_SUB; }
|
||||
function new(string name = "calc_seq_item_no_sub");
|
||||
super.new(name);
|
||||
endfunction
|
||||
endclass : calc_seq_item_no_sub
|
||||
|
||||
class test_no_sub extends test_base;
|
||||
`uvm_component_utils(test_no_sub)
|
||||
|
||||
calc_simple_seq simple_seq;
|
||||
|
||||
function new(string name = "test_no_sub", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction : new
|
||||
|
||||
function void build_phase(uvm_phase phase);
|
||||
super.build_phase(phase);
|
||||
// every calc_seq_item created in the environment becomes a no-sub item
|
||||
calc_seq_item::type_id::set_type_override(calc_seq_item_no_sub::get_type());
|
||||
simple_seq = calc_simple_seq::type_id::create("simple_seq");
|
||||
endfunction : build_phase
|
||||
|
||||
task main_phase(uvm_phase phase);
|
||||
phase.raise_objection(this);
|
||||
void'(simple_seq.randomize());
|
||||
simple_seq.start(env.agent.seqr);
|
||||
phase.drop_objection(this);
|
||||
endtask : main_phase
|
||||
endclass : test_no_sub
|
||||
|
||||
`endif
|
||||
28
code/vezba10/verif/test_simple.sv
Normal file
28
code/vezba10/verif/test_simple.sv
Normal file
@@ -0,0 +1,28 @@
|
||||
`ifndef TEST_SIMPLE_SV
|
||||
`define TEST_SIMPLE_SV
|
||||
|
||||
class test_simple extends test_base;
|
||||
|
||||
`uvm_component_utils(test_simple)
|
||||
|
||||
calc_simple_seq simple_seq;
|
||||
|
||||
function new(string name = "test_simple", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction : new
|
||||
|
||||
function void build_phase(uvm_phase phase);
|
||||
super.build_phase(phase);
|
||||
simple_seq = calc_simple_seq::type_id::create("simple_seq");
|
||||
endfunction : build_phase
|
||||
|
||||
task main_phase(uvm_phase phase);
|
||||
phase.raise_objection(this);
|
||||
void'(simple_seq.randomize());
|
||||
simple_seq.start(env.agent.seqr);
|
||||
phase.drop_objection(this);
|
||||
endtask : main_phase
|
||||
|
||||
endclass
|
||||
|
||||
`endif
|
||||
25
code/vezba10/verif/test_simple_2.sv
Normal file
25
code/vezba10/verif/test_simple_2.sv
Normal file
@@ -0,0 +1,25 @@
|
||||
`ifndef TEST_SIMPLE_2_SV
|
||||
`define TEST_SIMPLE_2_SV
|
||||
|
||||
class test_simple_2 extends test_base;
|
||||
|
||||
`uvm_component_utils(test_simple_2)
|
||||
|
||||
function new(string name = "test_simple_2", uvm_component parent = null);
|
||||
super.new(name,parent);
|
||||
endfunction : new
|
||||
|
||||
function void build_phase(uvm_phase phase);
|
||||
super.build_phase(phase);
|
||||
|
||||
// the sequencer lives at env.agent.seqr (the husk path "seqr.main_phase"
|
||||
// never matched, so no sequence ran)
|
||||
uvm_config_db#(uvm_object_wrapper)::set(this,
|
||||
"env.agent.seqr.main_phase",
|
||||
"default_sequence",
|
||||
calc_simple_seq::type_id::get());
|
||||
endfunction : build_phase
|
||||
|
||||
endclass
|
||||
|
||||
`endif
|
||||
BIN
code/vezba10/xelab.pb
Normal file
BIN
code/vezba10/xelab.pb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.covdb/calc_sim/xsim.covinfo
Normal file
BIN
code/vezba10/xsim.covdb/calc_sim/xsim.covinfo
Normal file
Binary file not shown.
1
code/vezba10/xsim.dir/calc_sim/Compile_Options.txt
Normal file
1
code/vezba10/xsim.dir/calc_sim/Compile_Options.txt
Normal file
@@ -0,0 +1 @@
|
||||
--nolog -L "uvm" -timescale "1ns/10ps" "calc_verif_top" -s "calc_sim"
|
||||
BIN
code/vezba10/xsim.dir/calc_sim/xsim.covinfo
Normal file
BIN
code/vezba10/xsim.dir/calc_sim/xsim.covinfo
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/calc_sim/xsim.crvsdump
Normal file
BIN
code/vezba10/xsim.dir/calc_sim/xsim.crvsdump
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/calc_sim/xsim.dbg
Normal file
BIN
code/vezba10/xsim.dir/calc_sim/xsim.dbg
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/calc_sim/xsim.mem
Normal file
BIN
code/vezba10/xsim.dir/calc_sim/xsim.mem
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/calc_sim/xsim.reloc
Normal file
BIN
code/vezba10/xsim.dir/calc_sim/xsim.reloc
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/calc_sim/xsim.rtti
Normal file
BIN
code/vezba10/xsim.dir/calc_sim/xsim.rtti
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/calc_sim/xsim.svtype
Normal file
BIN
code/vezba10/xsim.dir/calc_sim/xsim.svtype
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/calc_sim/xsim.type
Normal file
BIN
code/vezba10/xsim.dir/calc_sim/xsim.type
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/calc_sim/xsim.xdbg
Normal file
BIN
code/vezba10/xsim.dir/calc_sim/xsim.xdbg
Normal file
Binary file not shown.
50
code/vezba10/xsim.dir/calc_sim/xsimSettings.ini
Normal file
50
code/vezba10/xsim.dir/calc_sim/xsimSettings.ini
Normal file
@@ -0,0 +1,50 @@
|
||||
[General]
|
||||
ARRAY_DISPLAY_LIMIT=512
|
||||
RADIX=hex
|
||||
TIME_UNIT=ns
|
||||
TRACE_LIMIT=2147483647
|
||||
VHDL_ENTITY_SCOPE_FILTER=true
|
||||
VHDL_PACKAGE_SCOPE_FILTER=false
|
||||
VHDL_BLOCK_SCOPE_FILTER=true
|
||||
VHDL_PROCESS_SCOPE_FILTER=false
|
||||
VHDL_PROCEDURE_SCOPE_FILTER=false
|
||||
VERILOG_MODULE_SCOPE_FILTER=true
|
||||
VERILOG_PACKAGE_SCOPE_FILTER=false
|
||||
VERILOG_BLOCK_SCOPE_FILTER=false
|
||||
VERILOG_TASK_SCOPE_FILTER=false
|
||||
VERILOG_PROCESS_SCOPE_FILTER=false
|
||||
INPUT_OBJECT_FILTER=true
|
||||
OUTPUT_OBJECT_FILTER=true
|
||||
INOUT_OBJECT_FILTER=true
|
||||
INTERNAL_OBJECT_FILTER=true
|
||||
CONSTANT_OBJECT_FILTER=true
|
||||
VARIABLE_OBJECT_FILTER=true
|
||||
INPUT_PROTOINST_FILTER=true
|
||||
OUTPUT_PROTOINST_FILTER=true
|
||||
INOUT_PROTOINST_FILTER=true
|
||||
INTERNAL_PROTOINST_FILTER=true
|
||||
CONSTANT_PROTOINST_FILTER=true
|
||||
VARIABLE_PROTOINST_FILTER=true
|
||||
SCOPE_NAME_COLUMN_WIDTH=0
|
||||
SCOPE_DESIGN_UNIT_COLUMN_WIDTH=0
|
||||
SCOPE_BLOCK_TYPE_COLUMN_WIDTH=0
|
||||
OBJECT_NAME_COLUMN_WIDTH=0
|
||||
OBJECT_VALUE_COLUMN_WIDTH=0
|
||||
OBJECT_DATA_TYPE_COLUMN_WIDTH=0
|
||||
PROCESS_NAME_COLUMN_WIDTH=0
|
||||
PROCESS_TYPE_COLUMN_WIDTH=0
|
||||
FRAME_INDEX_COLUMN_WIDTH=0
|
||||
FRAME_NAME_COLUMN_WIDTH=0
|
||||
FRAME_FILE_NAME_COLUMN_WIDTH=0
|
||||
FRAME_LINE_NUM_COLUMN_WIDTH=0
|
||||
LOCAL_NAME_COLUMN_WIDTH=0
|
||||
LOCAL_VALUE_COLUMN_WIDTH=0
|
||||
LOCAL_DATA_TYPE_COLUMN_WIDTH=0
|
||||
PROTO_NAME_COLUMN_WIDTH=0
|
||||
PROTO_VALUE_COLUMN_WIDTH=0
|
||||
INPUT_LOCAL_FILTER=1
|
||||
OUTPUT_LOCAL_FILTER=1
|
||||
INOUT_LOCAL_FILTER=1
|
||||
INTERNAL_LOCAL_FILTER=1
|
||||
CONSTANT_LOCAL_FILTER=1
|
||||
VARIABLE_LOCAL_FILTER=1
|
||||
1
code/vezba10/xsim.dir/calc_sim/xsim_script.tcl
Normal file
1
code/vezba10/xsim.dir/calc_sim/xsim_script.tcl
Normal file
@@ -0,0 +1 @@
|
||||
xsim {calc_sim} -testplusarg UVM_TESTNAME=test_random -testplusarg UVM_VERBOSITY=UVM_HIGH -autoloadwcfg -runall -sv_seed random
|
||||
0
code/vezba10/xsim.dir/calc_sim/xsimcrash.log
Normal file
0
code/vezba10/xsim.dir/calc_sim/xsimcrash.log
Normal file
BIN
code/vezba10/xsim.dir/calc_sim/xsimk
Executable file
BIN
code/vezba10/xsim.dir/calc_sim/xsimk
Executable file
Binary file not shown.
7
code/vezba10/xsim.dir/calc_sim/xsimkernel.log
Normal file
7
code/vezba10/xsim.dir/calc_sim/xsimkernel.log
Normal file
@@ -0,0 +1,7 @@
|
||||
Running: xsim.dir/calc_sim/xsimk -runall -sv_seed random -simmode gui -testplusarg UVM_TESTNAME=test_random -testplusarg UVM_VERBOSITY=UVM_HIGH -wdb calc_sim.wdb -simrunnum 0 -socket 49855
|
||||
Design successfully loaded
|
||||
Design Loading Memory Usage: 44568 KB (Peak: 44568 KB)
|
||||
Design Loading CPU Usage: 20 ms
|
||||
Simulation completed
|
||||
Simulation Memory Usage: 139376 KB (Peak: 183836 KB)
|
||||
Simulation CPU Usage: 120 ms
|
||||
BIN
code/vezba10/xsim.dir/work/alu_input_stage.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/alu_input_stage.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/alu_output_stage.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/alu_output_stage.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/calc_agent_pkg.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/calc_agent_pkg.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/calc_if.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/calc_if.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/calc_seq_pkg.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/calc_seq_pkg.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/calc_test_pkg.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/calc_test_pkg.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/calc_top.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/calc_top.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/calc_verif_top.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/calc_verif_top.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/configurations_pkg.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/configurations_pkg.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/exdbin_mac.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/exdbin_mac.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/holdreg.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/holdreg.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/mux_out.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/mux_out.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/priority1.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/priority1.sdb
Normal file
Binary file not shown.
BIN
code/vezba10/xsim.dir/work/shifter.sdb
Normal file
BIN
code/vezba10/xsim.dir/work/shifter.sdb
Normal file
Binary file not shown.
34
code/vezba10/xsim.dir/work/work.rlx
Normal file
34
code/vezba10/xsim.dir/work/work.rlx
Normal file
@@ -0,0 +1,34 @@
|
||||
0.7
|
||||
2020.2
|
||||
Oct 14 2022
|
||||
05:07:14
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/dut/alu_input_stage.v,1680513656,verilog,,/home/pilipovic/Downloads/FVH/code/vezba10/dut/alu_output_stage.v,,alu_input_stage,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/dut/alu_output_stage.v,1680513656,verilog,,/home/pilipovic/Downloads/FVH/code/vezba10/dut/calc_top.v,,alu_output_stage,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/dut/calc_top.v,1680513656,verilog,,/home/pilipovic/Downloads/FVH/code/vezba10/dut/exdbin_mac.v,,calc_top,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/dut/exdbin_mac.v,1680513656,verilog,,/home/pilipovic/Downloads/FVH/code/vezba10/dut/holdreg.v,,exdbin_mac,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/dut/holdreg.v,1680513656,verilog,,/home/pilipovic/Downloads/FVH/code/vezba10/dut/mux_out.v,,holdreg,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/dut/mux_out.v,1680513656,verilog,,/home/pilipovic/Downloads/FVH/code/vezba10/dut/priority.v,,mux_out,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/dut/priority.v,1680513656,verilog,,/home/pilipovic/Downloads/FVH/code/vezba10/dut/shifter.v,,priority1,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/dut/shifter.v,1680513656,verilog,,,,shifter,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_agent.sv,1680513570,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_agent_pkg.sv,1680513570,systemVerilog,/home/pilipovic/Downloads/FVH/code/vezba10/verif/Sequences/calc_seq_pkg.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_test_pkg.sv,/home/pilipovic/Downloads/FVH/code/vezba10/verif/Sequences/calc_seq_pkg.sv,/tools/Xilinx/Vivado/2022.2/data/xsim/system_verilog/uvm_include/uvm_macros.svh;/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_seq_item.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_sequencer.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_driver.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_monitor.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_agent.sv,calc_agent_pkg,,uvm,./verif;./verif/Agent;./verif/Configurations;./verif/Sequences,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_driver.sv,1781194218,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_monitor.sv,1781194229,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_seq_item.sv,1781194204,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_sequencer.sv,1680513570,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Configurations/calc_config.sv,1781190521,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Configurations/configurations_pkg.sv,1680513570,systemVerilog,/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_agent_pkg.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_test_pkg.sv,/home/pilipovic/Downloads/FVH/code/vezba10/verif/Agent/calc_agent_pkg.sv,/tools/Xilinx/Vivado/2022.2/data/xsim/system_verilog/uvm_include/uvm_macros.svh;/home/pilipovic/Downloads/FVH/code/vezba10/verif/Configurations/calc_config.sv,configurations_pkg,,uvm,./verif;./verif/Agent;./verif/Configurations;./verif/Sequences,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Sequences/calc_base_seq.sv,1781190541,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Sequences/calc_seq_lib.sv,1781194763,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Sequences/calc_seq_pkg.sv,1781190610,systemVerilog,/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_test_pkg.sv,/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_test_pkg.sv,/tools/Xilinx/Vivado/2022.2/data/xsim/system_verilog/uvm_include/uvm_macros.svh;/home/pilipovic/Downloads/FVH/code/vezba10/verif/Sequences/calc_base_seq.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/Sequences/calc_simple_seq.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/Sequences/calc_seq_lib.sv,calc_seq_pkg,,uvm,./verif;./verif/Agent;./verif/Configurations;./verif/Sequences,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/Sequences/calc_simple_seq.sv,1781190733,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_env.sv,1781190530,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_if.sv,1680513570,systemVerilog,,/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_verif_top.sv,,calc_if,,uvm,./verif;./verif/Agent;./verif/Configurations;./verif/Sequences,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_scoreboard.sv,1781190500,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_test_pkg.sv,1781190646,systemVerilog,/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_verif_top.sv,/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_if.sv,/tools/Xilinx/Vivado/2022.2/data/xsim/system_verilog/uvm_include/uvm_macros.svh;/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_scoreboard.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_env.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/test_base.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/test_simple.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/test_simple_2.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/test_lib.sv;/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_if.sv,calc_test_pkg,,uvm,./verif;./verif/Agent;./verif/Configurations;./verif/Sequences,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/calc_verif_top.sv,1781190673,systemVerilog,,,/tools/Xilinx/Vivado/2022.2/data/xsim/system_verilog/uvm_include/uvm_macros.svh,calc_verif_top,,uvm,./verif;./verif/Agent;./verif/Configurations;./verif/Sequences,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/test_base.sv,1680513570,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/test_lib.sv,1781194773,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/test_simple.sv,1781190742,verilog,,,,,,,,,,,,
|
||||
/home/pilipovic/Downloads/FVH/code/vezba10/verif/test_simple_2.sv,1781194936,verilog,,,,,,,,,,,,
|
||||
/tools/Xilinx/Vivado/2022.2/data/xsim/system_verilog/uvm_include/uvm_macros.svh,1665704903,verilog,,,,,,,,,,,,
|
||||
14
code/vezba10/xsim.jou
Normal file
14
code/vezba10/xsim.jou
Normal file
@@ -0,0 +1,14 @@
|
||||
#-----------------------------------------------------------
|
||||
# xsim v2022.2 (64-bit)
|
||||
# SW Build 3671981 on Fri Oct 14 04:59:54 MDT 2022
|
||||
# IP Build 3669848 on Fri Oct 14 08:30:02 MDT 2022
|
||||
# Start of session at: Thu Jun 11 18:31:34 2026
|
||||
# Process ID: 884894
|
||||
# Current directory: /home/pilipovic/Downloads/FVH/code/vezba10
|
||||
# Command line: xsim -nolog -mode tcl -source {xsim.dir/calc_sim/xsim_script.tcl}
|
||||
# Log file:
|
||||
# Journal file: /home/pilipovic/Downloads/FVH/code/vezba10/xsim.jou
|
||||
# Running On: arch, OS: Linux, CPU Frequency: 1733.838 MHz, CPU Physical cores: 12, Host memory: 16707 MB
|
||||
#-----------------------------------------------------------
|
||||
source xsim.dir/calc_sim/xsim_script.tcl
|
||||
run -all
|
||||
BIN
code/vezba10/xvlog.pb
Normal file
BIN
code/vezba10/xvlog.pb
Normal file
Binary file not shown.
Reference in New Issue
Block a user