This commit is contained in:
2026-06-12 07:53:32 +02:00
commit 59e71f3297
259 changed files with 29010 additions and 0 deletions

70
code/vezba10/Makefile Normal file
View 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
View 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 511). 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

Binary file not shown.

View 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

View 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
View 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

File diff suppressed because it is too large Load Diff

View 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

View 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
View 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

File diff suppressed because it is too large Load Diff

44
code/vezba10/run.do Normal file
View 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
View 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
View 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
View 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
View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
--nolog -L "uvm" -timescale "1ns/10ps" "calc_verif_top" -s "calc_sim"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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

View File

@@ -0,0 +1 @@
xsim {calc_sim} -testplusarg UVM_TESTNAME=test_random -testplusarg UVM_VERBOSITY=UVM_HIGH -autoloadwcfg -runall -sv_seed random

Binary file not shown.

View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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
View 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

Binary file not shown.