Constraint solver error using the config object of subsequence in the nested sequence and subsequence that inherited the base sequence

In reply to YMNKY:

Note: Some non-recommended way of writing code however, the purpose is to display the results. Please don’t take this as reference code. concept here is, the my_cfg should be set and get before the constraint solver.

As I suspected earlier, you need to get the my_cfg instance before constraint solver starts.

function new(string name = "base_seq");
    super.new(name);
    //cfg = my_config::type_id::create("cfg", null);

if(!uvm_config_db #(my_config)::get(get_sequencer(), get_sequence_path(), “cfg”, cfg))
`uvm_fatal(get_type_name(), “Failed to get configuration”)

endfunction : new

I put these lines into constructor from the pre_start in base_seq and it works for me.

In the build_phase of the test, I changed the sim_line = 20 different value from the default declared in my_config and I can get that value in base_seq.

virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    cfg = my_config::type_id::create("cfg", null);
    cfg.sim_line = 20;
    uvm_config_db#(my_config)::set(null, "*", "cfg", cfg);
endfunction : build_phase

Complete code:

import uvm_pkg::*;
`include “uvm_macros.svh”
typedef class my_config;
class my_item extends uvm_sequence_item;
rand bit [31:0] dummy;
endclass : my_item

class base_seq extends uvm_sequence#(my_item);
// control knobs
rand bit [11:0] line_addr;

// configuration handle
my_config cfg;


`uvm_object_utils_begin(base_seq)
    `uvm_field_int(line_addr, UVM_DEFAULT)
    `uvm_field_object(cfg, UVM_DEFAULT)
`uvm_object_utils_end
// constraints
constraint line_addr_c {line_addr >=0; line_addr < cfg.sim_line;}

function new(string name = "base_seq");
    super.new(name);
    //cfg = my_config::type_id::create("cfg", null);
    if(!uvm_config_db #(my_config)::get(get_sequencer(), get_sequence_path(), "cfg", cfg))
        `uvm_fatal(get_type_name(), "Failed to get configuration")
endfunction : new

virtual task pre_body();
    super.pre_body();
    `uvm_info(get_type_name(), $sformatf("Executing pre_body"), UVM_MEDIUM)
endtask : pre_body

endclass : base_seq
class my_config extends uvm_object;
int sim_line = 16;
uvm_object_utils_begin(my_config) uvm_field_int(sim_line, UVM_DEFAULT)
`uvm_object_utils_end

function new(string name = "my_config");
    super.new(name);
endfunction : new

endclass : my_config

class my_test extends uvm_test;
base_seq m_base;
my_config cfg;
`uvm_component_utils(my_test)

function new(string name = "my_test", uvm_component parent);
    super.new(name, parent);
endfunction : new

virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    cfg = my_config::type_id::create("cfg", null);
    cfg.sim_line = 20;
    uvm_config_db#(my_config)::set(null, "*", "cfg", cfg);
endfunction : build_phase

task run_phase(uvm_phase phase);
    m_base = base_seq::type_id::create("m_base", null);
    for (int i = 0 ; i < 10 ; i++) begin
        void'(m_base.randomize());
        `uvm_info(get_type_name(), $sformatf("m_base transactions: %0s",m_base.sprint()), UVM_MEDIUM)
    end
endtask : run_phase

endclass : my_test
module tb();
import uvm_pkg::*;
`include “uvm_macros.svh”

initial begin
    //uvm_config_db #(my_config)::set(null, "*", "cfg", cfg);
    run_test("my_test");
end

endmodule : tb

1 Like