yes 6 7 июля, 2023 Опубликовано 7 июля, 2023 · Жалоба ну то есть в каком-нибудь C++ есть всякие static_cast reinterpret_cast а в SV, который как бы интерпретатор, то есть type'(), это отнюдь не С-шный (type) var. какая-то разница между type'() и $cast есть? ------------ для извращенной красоты можно всегда писать $cast, для каких-то тестов в которых не просто по ошибке вывалиться, можно делать if($cast()) то есть фунцию звать но можно ли что-то делать с type' кастованием для замены $cast? как-то обнаружил, что не знаю, проверил - да, весь этот полиморфизьм с type'() работает... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 56 7 июля, 2023 Опубликовано 7 июля, 2023 · Жалоба $cast - это типа dynamic_cast (в С++). Особенность: это одновременно и task, и function, зависит от контекста использования. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 30 7 июля, 2023 Опубликовано 7 июля, 2023 · Жалоба 56 minutes ago, yes said: а в SV, который как бы интерпретатор, то есть type'(), это отнюдь не С-шный (type) var Почему же нет? SV-шый type'() это как раз эквивалент С-ишного явного приведения типов (type) var Как вы и заметили type'() это статический каст который "работает" в время компиляции. Он не проверяет корректность результата. В отличии от динамического $cast() который в рантайме проверяет возможность каста и корректность результата приведения типов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
krux 8 9 июля, 2023 Опубликовано 9 июля, 2023 · Жалоба вопрос только один: зачем вы туда полезли? UVM не хватило, или наоборот, делаете все "в рукопашную". чтобы не влезать в UVM? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 9 июля, 2023 Опубликовано 9 июля, 2023 · Жалоба 46 minutes ago, krux said: UVM не хватило, или наоборот, делаете все "в рукопашную". чтобы не влезать в UVM? Вопрос вот зачем вы сюда лезете, если вообще ничего не понимаете? On 7/7/2023 at 7:07 PM, yes said: а в SV, который как бы интерпретатор, то есть type'(), это отнюдь не С-шный (type) var. SV - это уже давно не интерпретатор, ну, может в icarus он ещё интерпретатором сделан, но у большой тройки он давным давно компилируемый язык. Со своими стадиями компиляции, элаборации и исполнения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
krux 8 9 июля, 2023 Опубликовано 9 июля, 2023 · Жалоба On 7/9/2023 at 10:30 AM, one_eight_seven said: Вопрос вот зачем вы сюда лезете, если вообще ничего не понимаете? ну прогнулись "поддержатели" SV и прописали синтаксис в стандарт. Дальше то что? Если его больше реально кроме одной ситуации не применить ни как? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 9 июля, 2023 Опубликовано 9 июля, 2023 · Жалоба 4 hours ago, krux said: ну прогнулись "поддержатели" SV и прописали синтаксис в стандарт. Дальше то что? Если его больше реально кроме одной ситуации не применить ни как? А. Просто словесный понос. Тогда понятно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 6 9 июля, 2023 Опубликовано 9 июля, 2023 · Жалоба вопрос в том, что квеста отрабатывает одинаково - то есть если базовый класс указывает на хендл на производный/дочерний класс, то преобразование к переменной этого дочернего выполняется как $cast, так и derived_class' с одинаковыми сообщениями об ошибках и возможностями. то есть не какая-то отложенная ошибка после использования объекта, а сама операция приведения. мне (чисто из любопытства) стало интересно это поведение type' , которое очевидно динамическое, а не статическое, так как в зависимости от объекта дает разные сообщения об ошибках, а не ошибку во время компиляции это как-то описано в стандарте или принято в симуляторах и т.п.? естественно, что на практике я не выпендриваюсь, а использую $cast ------------------- зачем мне понадобилось - ну в С++ есть такой грязный хак как reinterpret_cast, которым можно (иногда) наоборот к производному классу приравнять объект базового. а конкретно нужно было достать поля protected библиотечного класса опять же - да в uvm есть фактори оверрайд, поэтому можно не объяснять мне как это делается "правильно" вот я и подумал, а вдруг... и в sv так 🙂 15 hours ago, one_eight_seven said: SV - это уже давно не интерпретатор, ну, может в icarus он ещё интерпретатором сделан, но у большой тройки он давным давно компилируемый язык. Со своими стадиями компиляции, элаборации и исполнения. ну я некоректно написал, имелось в виду, что хэндл это не указатель, и статическое преобразование в sv, это не просто команда компилятора "теперь это у нас указатель на другой тип", а вызов какого-то кода, который обрабатывает операцию ну и сильно похоже, что для квесты $cast и type' вызывает один и тот же код. а так - кому и питон компилятор 🙂 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 56 10 июля, 2023 Опубликовано 10 июля, 2023 · Жалоба 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<>()). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 6 10 июля, 2023 Опубликовано 10 июля, 2023 · Жалоба 3 hours ago, dxp said: Нет, не одинаково. type' -- это статический каст, он просто говорит компилятору: "трактуй это как такой-то тип", конечно, в рамках допустимого. Например, можно привести пакованный массив к пакованной структуре, но хендл объекта класса это не пропустит. Т.е. если в терминах С++, то это аналог static_cast<>(). И выполняется это именно на этапе компиляции. ну я же выше написал - на практике нет (по крайней мере для квесты). и речь о полиморфизме - то есть объект от/к которому приводится тип это класс с виртуальными и невиртуальными функциями (другие варианты неинтересны в данном случае) во время компиляции неизвестно какой объект будет привязан к указателю на базовый класс и поведение преобразования зависит в ран-тайм от этого объекта (абсолютно так же как и для $cast) - то есть если к этому указателю привязан объект того типа, к переменной которого присвоение/преобразование, то ОК, если что-то другое то ошибка Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 6 10 июля, 2023 Опубликовано 10 июля, 2023 · Жалоба вот код, чтобы проиллюстрировать ну я то как раз и хотел посмотреть, получится ли мне как-то путем статического кастанья - преобразовать объект 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 - то есть виртуальные функции останутся именно те, которые были в оъекте, а для невиртуальных указатели перескачут на производный клас (ну то есть компилятор будет знать, что вот эти, от производного класса, а не от базового надо вызывать) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 6 10 июля, 2023 Опубликовано 10 июля, 2023 · Жалоба добавлю, что все-таки не совсем одно и то же, а разное, но похожее поведение (что-то я просмотрел). но мне кажется, что вывода о "динамичности" преобразования 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 56 10 июля, 2023 Опубликовано 10 июля, 2023 · Жалоба 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 - то есть виртуальные функции останутся именно те, которые были в оъекте, а для невиртуальных указатели перескачут на производный клас (ну то есть компилятор будет знать, что вот эти, от производного класса, а не от базового надо вызывать) В С++ ничего никуда не перескакивает. Касты просто велят компилятору трактовать выражение как указанный тип. Если при дальнейшем использовании программа упадёт, это вина программиста, а не компилятора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 6 10 июля, 2023 Опубликовано 10 июля, 2023 · Жалоба 3 hours ago, dxp said: type'() -- это просто говорит компилятору трактовать да. вобщем предлагаю закрыть тему, практического смысла она не имеет (хотя лучше получить fatal и разбираться, что не так с тестом, чем проскочить с error-ом и пару суток непонятно что будет тест делать - но это решается вызовом функции $cast и по ее результатам фатала). я не призываю использовать type'() для полиморфизма. просто показалось забавным, что он работает. ну и так как он виртуальные фукции приводит к объекту, а невиртуальные к указателю, то есть ну вот совсем разницы с $cast не вижу. то есть во время компиляции где брать адреса этих виртуальных функций неизвестно, а они как-то оказываются верными. извиняюсь за C++ терминологию, "перескакивает" это про reinterpret_cast, что компилер дальше считает объект другим типом, ну а статик_каст может (при том, что тип объекта тоже будет заменен) например, выравнивание проверять и вылетать с ошибкой и т.п., я обычно применяю простое правило - юзай reinterpret для указателей, а статик для объектов (но опять же - с осторожностью) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 10 июля, 2023 Опубликовано 10 июля, 2023 · Жалоба 1 hour ago, yes said: я обычно применяю простое правило - юзай reinterpret для указателей, Неправильное правило - reinterpret вообще применять нельзя. Это очень опасное средство - оно полностью отключает всяческий контроль за тем что и куда преобразовывается. reinterpret в программе это признак некоректного использования базовых типов языка (т.е. хакерство в чистом виде). 2 hours ago, yes said: а статик для объектов Для всего Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться