init
This commit is contained in:
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
|
||||
Reference in New Issue
Block a user