Search code examples
castingsystem-verilog

Does SystemVerilog support downcasting?


Does SystemVerilog support downcasting (casting a base object to a derived object)? If so, how?

The following downcast example does not work:

class base;
  int a = 5;
endclass

class extend extends base;
  int b = 1;
endclass

module test;

  initial begin
    base m_base;
    extend m_extend;

    m_base = new();
    m_extend = new();
    $cast(m_extend, m_base);
    $display(m_extend.a);
  end
endmodule

Modify and rerun the example on EDA Playground: http://www.edaplayground.com/s/4/581


Solution

  • Yes, you can downcast. Your example is the correct syntax, and it actually does compile. However you are getting a runtime error because the cast fails.

    The cast in you example is failing because you can only successfully downcast if the handle to the base object is actual referencing an object of the derived type. You can call $cast as a function and it will return a boolean indicating whether the cast was successful or not.

    Here is an example:

    class animal;
      function void eat();
      endfunction
    endclass
    
    class dog extends animal;
      function void bark();
        $display("woof");
      endfunction
    endclass
    
    class cat extends animal;
      function void meow();
        $display("meow");
      endfunction
    endclass
    
    module test;
    
      initial begin
        dog a_dog = new();
        cat a_cat = new();
    
        animal animals[$];
        animals.push_back(a_dog);
        animals.push_back(a_cat);
    
        foreach (animals[i]) begin
          dog another_dog;
          animals[i].eat();
          if ($cast(another_dog, animals[i])) begin
            $display("Found a dog!");
            another_dog.bark();
          end
        end
    
      end
    endmodule
    

    Outputs:

    # Found a dog!
    # woof
    

    See http://www.edaplayground.com/s/474/586