Перейти к содержанию
    

а какая-то разница в SV между $cast (который task) и "статическим" type'( ) существует?

ну то есть в каком-нибудь C++ есть всякие static_cast reinterpret_cast 
а в SV, который как бы интерпретатор, то есть type'(), это отнюдь не С-шный (type) var.

какая-то разница между type'() и $cast есть?

------------

для извращенной красоты можно всегда писать $cast,

для каких-то тестов в которых не просто по ошибке вывалиться, можно делать if($cast()) то есть фунцию звать

но можно ли что-то делать с type' кастованием для замены $cast?

как-то обнаружил, что не знаю, проверил - да, весь этот полиморфизьм с type'() работает... 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

$cast - это типа dynamic_cast (в С++).

Особенность: это одновременно и task, и function, зависит от контекста использования. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

56 minutes ago, yes said:

а в SV, который как бы интерпретатор, то есть type'(), это отнюдь не С-шный (type) var

Почему же  нет?  SV-шый  type'()  это как раз эквивалент  С-ишного явного приведения типов (type) var 
Как вы и заметили  type'() это статический каст который "работает"  в время компиляции. Он  не проверяет корректность результата. 
В отличии от динамического $cast() который в рантайме проверяет возможность каста и корректность результата  приведения типов.  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вопрос только один: зачем вы туда полезли?

UVM не хватило, или наоборот, делаете все "в рукопашную". чтобы не влезать в UVM?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

46 minutes ago, krux said:

UVM не хватило, или наоборот, делаете все "в рукопашную". чтобы не влезать в UVM?

Вопрос вот зачем вы сюда лезете, если вообще ничего  не понимаете?

On 7/7/2023 at 7:07 PM, yes said:

а в SV, который как бы интерпретатор, то есть type'(), это отнюдь не С-шный (type) var.
 

SV - это уже давно не интерпретатор, ну, может в icarus он ещё интерпретатором сделан, но у большой тройки он давным давно компилируемый язык. Со своими стадиями компиляции, элаборации и исполнения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/9/2023 at 10:30 AM, one_eight_seven said:

Вопрос вот зачем вы сюда лезете, если вообще ничего  не понимаете?

ну прогнулись "поддержатели" SV и прописали синтаксис в стандарт. Дальше то что? Если его больше реально кроме одной ситуации не применить ни как?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 hours ago, krux said:

ну прогнулись "поддержатели" SV и прописали синтаксис в стандарт. Дальше то что? Если его больше реально кроме одной ситуации не применить ни как?

А. Просто словесный понос. Тогда понятно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вопрос в том, что квеста отрабатывает одинаково - 

то есть если базовый класс указывает на хендл на производный/дочерний класс, то преобразование к переменной этого дочернего выполняется как $cast, так и derived_class' с одинаковыми сообщениями об ошибках и возможностями. то есть не какая-то отложенная ошибка после использования объекта, а сама операция приведения.

мне (чисто из любопытства) стало интересно это поведение type' , которое очевидно динамическое, а не статическое, так как в зависимости от объекта дает разные сообщения об ошибках, а не ошибку во время компиляции
это как-то описано в стандарте или принято в симуляторах и т.п.?

естественно, что на практике я не выпендриваюсь, а использую $cast

-------------------

зачем мне понадобилось - ну в С++ есть такой грязный хак как reinterpret_cast, которым можно (иногда) наоборот к производному классу приравнять объект базового. а конкретно нужно было достать поля protected библиотечного класса

опять же - да в uvm есть фактори оверрайд, поэтому можно не объяснять мне как это делается "правильно"

вот я и подумал, а вдруг... и в sv так 🙂

 

 

 

15 hours ago, one_eight_seven said:

SV - это уже давно не интерпретатор, ну, может в icarus он ещё интерпретатором сделан, но у большой тройки он давным давно компилируемый язык. Со своими стадиями компиляции, элаборации и исполнения.

ну я некоректно написал, имелось в виду, что хэндл это не указатель, и статическое преобразование в sv, это не просто команда компилятора "теперь это у нас указатель на другой тип", а вызов какого-то кода, который обрабатывает операцию

ну и сильно похоже, что для квесты $cast и type' вызывает один и тот же код.

а так - кому и питон компилятор 🙂

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, yes сказал:

то есть если базовый класс указывает на хендл на производный/дочерний класс, то преобразование к переменной этого дочернего выполняется как $cast, так и derived_class' с одинаковыми сообщениями об ошибках и возможностями. то есть не какая-то отложенная ошибка после использования объекта, а сама операция приведения.

 

Нет, не одинаково. type' -- это статический каст, он просто говорит компилятору: "трактуй это как такой-то тип", конечно, в рамках допустимого. Например, можно привести пакованный массив к пакованной структуре, но хендл объекта класса это не пропустит. Т.е. если в терминах С++, то это аналог static_cast<>(). И выполняется это именно на этапе компиляции.

$cast же -- это аналог dynamic_cast<>(), он выполняется на рантайме. Используя принципы RTTI. У него другое назначение. Он полезен, например, когда ситуация требует разбора контекста во время выполнения. Например, вот есть у нас сетевые пакеты: ethernet, IP, UDP, TCP и т.д.,  они описаны как иерархия классов -- базовый ethernet, его наследник -- IP,  его наследники UDP и TCP. И у нас код принимает, например, IP пакеты, и нам надо отфильтровать TCP пакеты с флагом SYN -- т.е. начало соединения. Для этого мы входящий пакет (IP) динамически кастуем к TCP, если кастуется, то полученный объект уже проверяем на флаги TCP -- они в нём точно есть, т.к. проверка типов это гарантирует. Т.е. это полезно для парсинга, когда на этапе компиляции недостаточно информации, полная картина есть только на рантайме.

4 часа назад, yes сказал:

зачем мне понадобилось - ну в С++ есть такой грязный хак как reinterpret_cast, которым можно (иногда) наоборот к производному классу приравнять объект базового. а конкретно нужно было достать поля protected библиотечного класса

 

В плюсах, чтобы привести указатель базового класса на указатель производного, достаточно static_cast<>(). И  делается это на этапе компиляции. При этом ответственность за правильность возлагается на программиста. А reinterpret_cast<>() -- это никакой не грязный хак, это необходимое средство в ряде случаев. Просто пользоваться этим надо с пониманием. Например, если нужно, как в примере выше, указатель базового класса привести к указателю на производный, то нужно использовать static_cast<>(), а не reinterpret_cast<>(), использование которого может привести к неожиданным  ошибкам (например, можно привести указатель на тип вообще другой иерархии классов, что, очевидно, не является целью -- такой класс ошибок отлавливается static_cast<>()).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, dxp said:

Нет, не одинаково. type' -- это статический каст, он просто говорит компилятору: "трактуй это как такой-то тип", конечно, в рамках допустимого. Например, можно привести пакованный массив к пакованной структуре, но хендл объекта класса это не пропустит. Т.е. если в терминах С++, то это аналог static_cast<>(). И выполняется это именно на этапе компиляции.

 

ну я же выше написал - на практике нет (по крайней мере для квесты).

и речь о полиморфизме - то есть объект от/к которому приводится тип это класс с виртуальными и невиртуальными функциями (другие варианты неинтересны в данном случае)

во время компиляции неизвестно какой объект будет привязан к указателю на базовый класс

и поведение преобразования зависит в ран-тайм от этого объекта (абсолютно так же как и для $cast) - то есть если к этому указателю привязан объект того типа, к переменной которого присвоение/преобразование, то ОК, если что-то другое то ошибка

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот код, чтобы проиллюстрировать
ну я то как раз и хотел посмотреть, получится ли мне как-то путем статического кастанья - преобразовать объект chilg к указателю на grand_child (прошу не смеяться, но вдруг бы вышло, как в С++)

`include "uvm_macros.svh"

import uvm_pkg::*;


class base_obj extends uvm_object;
  `uvm_object_utils(base_obj)
 
  function new(string name = "base_obj");
    super.new(name);
  endfunction

  virtual function void display();
    `uvm_info(get_type_name(), $sformatf("inside base_obj"), UVM_LOW);
  endfunction

 function void display_nv();
    `uvm_info(get_type_name(), "inside base_obj", UVM_LOW);
  endfunction

endclass

class child_obj extends base_obj;
  `uvm_object_utils(child_obj)

  function new(string name = "child_obj");
    super.new(name);
  endfunction // new

  function void display();
    `uvm_info(get_type_name(), "inside child_obj", UVM_LOW);
  endfunction // display

  function void display_nv();
    `uvm_info(get_type_name(), "inside child_obj", UVM_LOW);
  endfunction // display_nv

endclass


class gch_obj extends child_obj;
   `uvm_object_utils(gch_obj)

   function new(string name = "gch_obj");
      super.new(name);
   endfunction // new

 function void display();
    `uvm_info(get_type_name(), "virtual GCH_obj", UVM_LOW);
  endfunction // display

   function void display_nv();
      `uvm_info(get_type_name(), $sformatf("GCH_obj"), UVM_LOW);
   endfunction // display_v

endclass // gch_obj



class my_test extends uvm_test;

   `uvm_component_utils(my_test)

   base_obj  obj_b;
   child_obj ch_b,ch_b1;
   gch_obj gch_b;

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

   function void build_phase(uvm_phase phase);
      uvm_factory factory = uvm_factory::get();
      super.build_phase(phase);

      //    base_obj::type_id::set_type_override(child_obj::get_type());

      //ch_b = child_obj::type_id::create("child_obj");
      //$cast(ch_b,obj_b);

      //gch_b=new();
      //ch_b=new();

      base_obj::type_id::set_type_override(gch_obj::get_type());
      obj_b = base_obj::type_id::create("obj_b");

//      $cast(ch_b,obj_b);
      ch_b=child_obj'(obj_b);

//      $cast(gch_b,obj_b);
      gch_b=gch_obj'(obj_b);

      factory.print();

   endfunction // build_phase
   
   task run_phase(uvm_phase phase);

      super.run_phase(phase);

      obj_b.display();
      obj_b.display_nv();

      ch_b.display();
      ch_b.display_nv();

      gch_b.display();
      gch_b.display_nv();

   endtask // run_phase


  function void end_of_elaboration_phase(uvm_phase phase);

    super.end_of_elaboration_phase(phase);

    uvm_top.print_topology();

  endfunction

endclass

module ex2;

   initial begin

      run_test("my_test");

   end

endmodule


type'

# UVM_INFO ex2.sv(49) @ 0: reporter [gch_obj] virtual GCH_obj
# UVM_INFO ex2.sv(18) @ 0: reporter [gch_obj] inside base_obj
# UVM_INFO ex2.sv(49) @ 0: reporter [gch_obj] virtual GCH_obj
# UVM_INFO ex2.sv(35) @ 0: reporter [gch_obj] inside child_obj
# UVM_INFO ex2.sv(49) @ 0: reporter [gch_obj] virtual GCH_obj
# UVM_INFO ex2.sv(53) @ 0: reporter [gch_obj] GCH_obj

$cast
# UVM_INFO ex2.sv(49) @ 0: reporter [gch_obj] virtual GCH_obj
# UVM_INFO ex2.sv(18) @ 0: reporter [gch_obj] inside base_obj
# UVM_INFO ex2.sv(49) @ 0: reporter [gch_obj] virtual GCH_obj
# UVM_INFO ex2.sv(35) @ 0: reporter [gch_obj] inside child_obj
# UVM_INFO ex2.sv(49) @ 0: reporter [gch_obj] virtual GCH_obj
# UVM_INFO ex2.sv(53) @ 0: reporter [gch_obj] GCH_obj

 

4 hours ago, dxp said:

В плюсах, чтобы привести указатель базового класса на указатель производного, достаточно static_cast<>(). И  делается это на этапе компиляции. При этом ответственность за правильность возлагается на программиста. А reinterpret_cast<>() -- это никакой не грязный хак, это необходимое средство в ряде случаев. Просто пользоваться этим надо с пониманием. Например, если нужно, как в примере выше, указатель базового класса привести к указателю на производный, то нужно использовать static_cast<>(), а не reinterpret_cast<>(), использование которого может привести к неожиданным  ошибкам (например, можно привести указатель на тип вообще другой иерархии классов, что, очевидно, не является целью -- такой класс ошибок отлавливается static_cast<>()).

тут не буду проверять и [сильно] спорить, но по-моему с static_cast так не сработает или сделает чего-то лишнего, для этого как раз reinterpret_cast - то есть виртуальные функции останутся именно те, которые были в оъекте, а для невиртуальных указатели перескачут на производный клас (ну то есть компилятор будет знать, что вот эти, от производного класса, а не от базового надо вызывать)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

добавлю, что все-таки не совсем одно и то же, а разное, но похожее поведение (что-то я просмотрел). но мне кажется, что вывода о "динамичности" преобразования type' это не отменяет
 

     ch_b=new();
     gch_b=gch_obj'(ch_b);
# ** Fatal: (vsim-12051) Illegal assignment in cast to class work.ex2_sv_unit::gch_obj from class work.ex2_sv_unit::child_obj

      ch_b=new();
      $cast(gch_b,ch_b);
** Error: (vsim-3971) $cast to type 'class work.ex2_sv_unit::gch_obj' from 'class work.ex2_sv_unit::child_obj' failed in file ex2.sv at line 84.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

type'() -- это просто говорит компилятору трактовать выражение в скобках как указанный тип. От ошибок оно не защищает. Если хендл предка присвоить типу хендла потомка, то будет рантайм ошибка. В С++ это не обязательно ошибка, если после такого приведения не лезть в "зону" объекта, определённую в потомке. В SV он чекает тип хендла и прогон падает с фатальной ошибкой (которая типа сегфолта). Хотя type'() вполне закрывает вопрос на этапе компиляции. type'() -- это годная тема для "мапинга" пакованных объектов друг на друга, для классов в SV не годится.

$cast() тоже вызывает ошибку при таком приведении, но она не фатальная, а обычная, т.е. это не рантайм ошибка -- прогон после неё не останавливается, это ошибка только лишь приведения типов, которая сообщает, что преобразование некорректно. Она служит для последующего анализа.

Вот внятное объяснение разницы между динамическим и статическим кастами от гуру SV: https://verificationacademy.com/forums/systemverilog/difference-between-static-casting-and-dynamic-casting-sv

5 часов назад, yes сказал:

тут не буду проверять и [сильно] спорить, но по-моему с static_cast так не сработает или сделает чего-то лишнего, для этого как раз reinterpret_cast - то есть виртуальные функции останутся именно те, которые были в оъекте, а для невиртуальных указатели перескачут на производный клас (ну то есть компилятор будет знать, что вот эти, от производного класса, а не от базового надо вызывать)

В С++ ничего никуда не перескакивает. Касты просто велят компилятору трактовать выражение как указанный тип. Если при дальнейшем использовании программа упадёт, это вина программиста, а не компилятора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, dxp said:

type'() -- это просто говорит компилятору трактовать

да. вобщем предлагаю закрыть тему, практического смысла она не имеет (хотя лучше получить fatal и разбираться, что не так с тестом, чем проскочить с error-ом и пару суток непонятно что будет тест делать - но это решается вызовом функции $cast и по ее результатам фатала). я не призываю использовать type'() для полиморфизма. просто показалось забавным, что он работает.
ну и так как он виртуальные фукции приводит к объекту, а невиртуальные к указателю, то есть ну вот совсем разницы с $cast не вижу. то есть во время компиляции где брать адреса этих виртуальных функций неизвестно, а они как-то оказываются верными.

извиняюсь за C++ терминологию, "перескакивает" это про reinterpret_cast, что компилер дальше считает объект другим типом, ну а статик_каст может (при том, что тип объекта тоже будет заменен) например, выравнивание проверять и вылетать с ошибкой и т.п., я обычно применяю простое правило - юзай reinterpret для указателей, а статик для объектов (но опять же - с осторожностью)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, yes said:

я обычно применяю простое правило - юзай reinterpret для указателей,

Неправильное правило - reinterpret вообще применять нельзя. Это очень опасное средство - оно полностью отключает всяческий контроль за тем что и куда преобразовывается. reinterpret в программе это признак некоректного использования базовых типов языка (т.е. хакерство в чистом виде).

2 hours ago, yes said:

а статик для объектов

Для всего

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...