-
Постов
4 593 -
Зарегистрирован
-
Посещение
-
Победитель дней
15
Весь контент dxp
-
Сделано немало приборов изрядно посложнее мигалки светодидом. Все вопросы выявлены в ходе тестов и испытаний в железе. С успешной последующей эксплуатацией. Что касается отладки тормозов автомобиля, согласен, что на ходу это делать несколько не с руки. Но в этом конкретном случае всё равно необходимо строить стенд, на котором проверять, тестировать, ибо цена вопроса. Программные тесты могут просто снизить стоимость в целом, т.к. помогут выявить ряд ошибок и сократить время использования дорогостоящего сложного стенда. Но предфинальные проверки-тесты всё равно нужно делать на реальном железе.
-
Мне понятно, о чём вы (оба) говорите. Приходится работать с FPGA, и уже тут подходы иные: отдельные модули целесообразно гонять на верификации, т.к. потом на железе ловить глюки очень затратно, а создать даже не все возможные, но какие-нибудь редкие кейсы для полного проекта на симе зачастую не получается. На МК сам процесс отладки в железе несравнимо проще - тут тебе и отладочная печать, и доступ к потрохам через JTAG/SWD, а рабочие кейсы создаются достаточным количеством испытаний, что обычно намного быстрее организовать (хотя случаи, конечно, бывают разные - иной раз для этого необходимо городить немаленькие и недешёвые стенды).
-
МКшные проекты очень тесно завязаны на железо и прочий аппаратный контекст. Симуляциями и программными тестами сложновато будет создавать те реальные кейсы, которые возникают в реальности. При этом запуск ПО как раз и происходит в этой самой реальности, поэтому и отладка идёт на достоверных кейсах. Юнит-тестирование хорошо себя проявляет на сугубо программных вещах - например, реализация алгоритмов. Такие вещи действительно удобно проверять отдельно, и это можно и нужно использовать в проектах на МК. Но по объёму это не доминирует. Целевую же прошивку зачастую проще и эффективнее запускать на реальном железе, тем более, что оно всегда под рукой. Думается, в этом основная причина "перекоса".
-
С интересом посмотрел бы на юнит тест для таймера или UART'а.
-
Резюме тезисно: Квеста не выдаёт ненулевой код ошибки при вызове $error(), $fatal() т.к. не считает это основанием для аварийного (т.е. когда надо возвращать код ошибки) завершения работы. Если пользователю нужно такое поведение, он должен об этом позаботиться сам - для этого предусмотрена команда Tcl API exit с опцией -code <n>. При вызове $fatal() поток управления не возвращается в скрипт, запустивший run [-all], что осложняет анализ результата симуляции. Для исправления этого поведения необходимо использовать команду onfinish с опцией final перед вызовом run. Анализ результатов симуляции может осуществляться несколькими способами: проверкой состояния симулятора с помощью команды runStatus. К сожалению, все остановы, кроме $finish() не различаются, т.е. нет возможности определить, остановка случилась по $stop() или $fatal(). созданием в HDL коде переменной состояния, которая будет отражать результат симуляции. Значение этой переменной по окончании прогона можно проинспектировать с помощью команды examine. К сожалению, и тут существует недостаток: эту переменную состояния симулятор может оптимизировать, т.ч. может оказаться, что инспектировать будет нечего. запись состояния во внешний файл - например, записывать туда код завершения. В запускающем скрипте на старте проверять наличие этого файла и удалять. После останова снова проверять: если файла нет, то значит завершение без ошибок, если появился, то считывать из него код и, например, возвращать его при завершении работы симулятора. Пример реализации с помощью внешнего файла (фрагменты): // HDL function automatic void __sim_fatal_error(int code); int fd = $fopen("sim_error_status_code", "w"); $fwrite(fd, code); $fclose(fd); $fatal(); endfunction # Tcl ... set errcode sim_error_status_code if { [file exists $errcode] } { file delete $errcode } onfinish final run -all if { [file exists $errcode] } { set fd [open $errcode r] set exit_code [read $fd] close $fd } else { set exit_code 0 } exit -code $exit_code В итоге на этом способе и остановился.
-
У меня по коду остановки везде сделаны через $stop(2) (чтобы можно было продолжить, если что). Не хотелось бы их менять на дурацкий $finish(), который вдобавок по умолчанию в GUI предлагает выйти из сима. Т.ч. как-то так себе решение. Вам большущее спасибо за участие и ценные подсказки! Поведение программы всё равно странное. При ошибках всё-таки должна возвращать код ошибки сама, а не вынуждать пользователя костылить это поведение. Ну, если хотелось гибкости - например, иметь возможность при ошибках не останавливать сборку, - это можно решить просто аргументом тех же $error/$fatal.
-
Так я там выше с -full и использую. А с $finish() у меня выдаёт: break step_builtin
-
Да, ваш пример работает. Добавил к себе в код onfinish final, и таки да - это он управляет тем, будет ли исполняться код после run в случае ошибки. Но вот дальше, к сожалению, что-то не поехало: runStatus у меня всегда выдаёт break. onfinish final puts "################ before ##############" run -all puts "################ after ##############" puts [runStatus -full] exit -code [expr {[runStatus] eq "ready" ? 0 : 1}] по $stop(): ################ before ############## # ** Note: $stop : top_tb.sv(130) # Time: 0 ps Iteration: 0 Instance: /top__tb # Break at top__tb.sv line 130 # Stopped at top__tb.sv line 130 ################ after ############## break simulation_stop unknown # End time: 17:02:06 on May 19,2022, Elapsed time: 0:00:01 # Errors: 0, Warnings: 2 scons: *** Error 1 ######### rcode: 1 по $fatal(): ################ before ############## # ** Fatal: Assertion error. # Time: 0 ps Scope: top_tb File: top_tb.sv Line: 129 # ** Note: Data structure takes 115995132 bytes of memory # Process time 0.06 seconds # $finish : top_tb.sv(129) # Time: 0 ps Iteration: 0 Instance: /top_tb # Break at top_tb.sv line 129 # Stopped at top_tb.sv line 129 ################ after ############## break simulation_stop unknown # End time: 17:32:05 on May 19,2022, Elapsed time: 0:00:01 # Errors: 1, Warnings: 2 scons: *** Error 1 ######### rcode: 1 Т.е. runStatus всегда выдаёт break, что не совпадает с ready. Пытаюсь понять, в чём значимое отличие от вашего варианта.
-
Ну, для разного рода автоматизаций почему бы и да.
-
Ну, может в интерактивном режиме это и работает. А тут-то он просто вываливается шелл и всё, там уже нечего ловить.
-
Эту пробовал. В пакетном режиме не понял, как её пользоваться (вызов ничего не делает и на консоль не выводит), в GUI режиме вызывал руками, там она печатает текстовый статус. В пакетном режиме опять же не ясно, как ей пользоваться, если в случае ошибок управление в скрипт из 'run -all' не возвращается. К сожалению, тоже без изменений.
-
Без изменений.
-
proc run_sim {} { sim_begin; onerror { puts "<<<<<<<<<<<<<<<<<<<<<<<<<<<< onerror" } onbreak { puts "<<<<<<<<<<<<<<<<<<<<<<<<<<<< onbreak" } puts "################ before ##############" run -all puts "################ after ##############" exit натыкал принтов отладочных, чтобы в логе было легче искать. Выхлоп: ################ before ############## # ** Fatal: Assertion error. # Time: 0 ps Scope: top_tb File: top_tb.sv Line: 129 # ** Note: $finish : top_tb.sv(129) # Time: 0 ps Iteration: 0 Instance: /top_tb # End time: 11:42:57 on May 19,2022, Elapsed time: 0:00:01 # Errors: 1, Warnings: 2 $ echo $? 0 Т.е. до run -all доходит, дальше нет (вываливается внутри по ошибке). Реакции ни на onerror, ни на onbreak нет.
-
Насколько понимаю, там ситуация такая: $error - ошибка, но сим не останавливается и едет до конца, сколько может. $fatal - ошибка и немедленный останов. В любом из этих случаев сим должен вернуть в ОС код ошибки, а не 0.
-
Пробовал onerror: Это не работает. По ходу, эта команда ловит ошибки в скриптах (тикле), а не в HDL. onbreak - это, судя по документации, обработка события breakpoint, что к моему случаю отношения не имеет.
-
В упомянутой таблице, например, есть: И если, скажем, удаляю рабочую библиотеку, то запуск получается такой: # sim_begin # vsim -lib wlib -wlf func.wlf -quiet opt_top_tb # Start time: 11:24:57 on May 19,2022 # ** Error (suppressible): (vsim-19) Failed to access library 'wlib'. # No such file or directory. (errno = ENOENT) # Error loading design Error loading design # End time: 11:24:57 on May 19,2022, Elapsed time: 0:00:00 # Errors: 1, Warnings: 0 и $ echo $? 12 Т.е. всё чётко тут работает.
-
Да, это сразу нагуглилось. Там вопрошающий делал выход по $finish, и удивлялся, что код ошибки не "ошибочный", ведь он же по асерту выходит. $fatal там, судя по всему, ведёт себя как надо. У меня исходно запуск осуществлялся так: vsim -c -do prj.tcl -do sim_begin -do sim_run где sim_run sim_begin run -all exit Так вот, если в коде есть $fatal или $error, то до exit дело не доходит - симулятор выходит неким иным путём. И по идее он должен сам вернуть код ошибки (там у него есть в доках таблица с кодами ошибки), что и происходит в обсуждении по ссылке. У меня же как раз этого не случается почему-то - возвращает 0.
-
Questa(Model)Sim. Exit code always 0.
dxp опубликовал тема в Среды разработки - обсуждаем САПРы
Всем привет! Обнаружилась непонятка в, казалось бы, совершенно безобидном месте. По непонятной причине симулятор после прогона возвращает код 0 там, где должна быть ошибка. Конкретно, вот есть код: initial begin $fatal(); $stop(2); end Запуск: vsim -c -do prj.tcl -do sim_begin -do "run -all; exit" prj.tcl содержит всё необходимое окружение - имена файлов, ключи, процедуры - например, указанная выше 'sim_begin' определена там же: proc sim_begin { } { global vsim_cmd vsim_flags; quit -sim; set cmd [concat ${vsim_cmd} ${vsim_flags}]; eval ${cmd} radix -hex log -r /* } При запуске выхлоп: # run -all # ** Fatal: Assertion error. # Time: 0 ps Scope: top_tb File: top_tb.sv Line: 129 # ** Note: $finish : top_tb.sv(129) # Time: 0 ps Iteration: 0 Instance: /katun_tb # End time: 10:39:56 on May 19,2022, Elapsed time: 0:00:01 # Errors: 1, Warnings: 2 Вроде норм. Но проверка кода возврата говорит: $ echo $? 0 Из-за этого не удаётся использовать прогон симулятора в пакетном режиме, когда в случае неуспеха вся сборка должна остановиться. Если принудительно выходить с кодом ошибки, например, по команде exit -code 1 то код возврата правильный. Была идея закостылить - проверять наличие ошибки и выход делать вручную, как показано выше, но это не работает, т.к. в случае ошибки сим выходит сам, не достигая проверки, которая может быть запущена только после останова по $stop() или $finish(). Ну и вообще, хочется разобраться, и чтобы работало правильно, а не на костылях. Буду благодарен за любые идеи. -
В смысле, Xilinx поставляет Versal в РФ? Или для кого эта новость?
-
Адекватный и удобный симулятор схем
dxp ответил Arlleex тема в Схемотехника
Из всего, чем пользовался, больше всего нравился PSpice (потом OrCAD PSpice, сейчас входит в Allegro). Схематик там, собственно, OrCAD. Является стандартом де-факто в отрасли, подавляющее большинство моделей вендоров делаются для него и совместимым с ним. К сожалению, начиная с какого-то момента Linear Technology (RIP) перестала делать пригодные для него модели (начали вводить какие-то проприетарные элементы в них), которые стали годиться только для LTspice. Мегаудобная фича у OrCAD PSpice - он умеет показывать прямо на схеме режимы по постоянному току (напряжения в узлах, токи через элементы), включается это одной кнопкой. В том же LTspice чтобы вывести напряжение на узле, нужно для каждого узла это делать отдельно и итоговый вид далёк от желаемого. Главный недостаток PSpice: он сильно коммерческий. И установка с лечением там местами нетривиальные. И да, при выборе движка симулятора надо выбирать не PSpice, а другой движок (на букву A начинается, точнее не помню, но там их всего два), т.к. PSpice тут скорее как бренд, а сам движок там старый и давно не развивается (неверное держать для какой-нить совместимости), на относительно современных моделях ОУ были проблемы со сходимостью. А новый работает чётко. -
На VMK180 (Versal Prime) для DDR4 (аппаратный, via NoC) мне не удалось найди example project. Пришлось самостоятельно ковырять.
-
Офтопный вопрос. Вот тут report_property возвращает некие объекты с кучей параметров. А можно где-то посмотреть код, где описаны эти property? Насколько мне известно, Tcl язык незамысловатый и в нём не то, что сложных объектов, и типов-то почти нет (есть базовый тип "строка", значения которого кастуются по месту в зависимости от контекста). А тут такие навороченные объекты, представление которых подозрительно сильно похоже на С++'ные типы. Интересно посмотреть, как они это на Tcl реализовали.
-
Плавный переход C -> C++ под МК
dxp ответил Arlleex тема в Программирование
И сразу отлично видно потенциально проблемное место, на которое компилятор промолчит, и сразу видно, что к чему кастуется. Вот это: if(br >= 0 && !can->setBitRate((cCAN::eBitRate)(br + 1))) выглядит ничем не лучше, даже наоборот - нужно прилагать усилия, чтобы понять, что тут ручное преобразование типов, а не просто скобки для выделения приоритетов операций. И вдобавок тут может скрываться злобный reinterpret_cast, если, скажем, тип, к которому делается преобразование, например, указатель. static_cast это с ходу отловит. -
Плавный переход C -> C++ под МК
dxp ответил Arlleex тема в Программирование
Про различие static_cast и reinterpret_cast сказали выше - это очень разные "по силе" касты (и последствия от преобразований тоже разные), но С не различает их в своём синтаксисе. А смысл их такого громоздкого синтаксиса именно в том, чтобы они своим безобразным видом прямо-таки подсвечивали место потенциальной ошибки (там где компилятору велели "умыть руки" и не контролировать работы с типами). Каст на С в коде зачастую нетрудно пропустить, т.к. это обычное выражение с круглыми скобками, коими С/C++ злоупотребляют. А *_cast<...>() кроме того ещё и подсвечивается в программерских редакторах, т.к. являются ключевыми словоми языка.