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