-
Постов
190 -
Зарегистрирован
-
Посещение
Сообщения, опубликованные embddr
-
-
думал что сначала выполнится инверсия, а уж потом будет приведение типа.
Похоже, что сначала все переменные приводятся к типу результата, а потом производятся вычисления.
Надо стандарт еще раз почитать, наверняка там есть информация про это.
-
Действительно странно.
Это как-то связано с неявным приведением типов, потому что если сделать
wire inv_one_bit = ~one_bit; assign mask = inv_one_bit << select;
то работает как задумывалось.
Однако, в стандарте я ничего не нашел на этот счет. Может плохо искал, потому что все симуляторы показывают одинаковый результат.
-
Тема когда-то поднималась, но с тех пор ничего не изменилось.
Планируется ли добавление подсветки синтаксиса для языков программиновани и HDL? Было бы неплохо для начала сделать код моноширным шрифтом.
Не жизненно важно, но было бы приятно изменять тему оформления форума и размеры шрифтов.
-
Порядок менять нельзя, но можно использовать разные конструкции SV, котороые сэплируют ассерты в разные временные слоты.
Вот тут об этом хорошо написано
http://www.doulos.com/knowhow/sysverilog/D...ncSVA_paper.pdf
Но боюсь ModelSim не потянет, нужна будет Questa
Спасибо! Теперь понятно, откуда гонки.
Согласно документу, ассерты вычисляются в самом начале цикла, потом приходит асинхронный сигнал, и следом защелкивается триггер по неблокирующему присваиванию (NBA). Получается, что триггер захватил сигнал, а ассерт нет.
Чтобы это исправить, нужно сделать так, чтобы асинхронный сигнал пришел после NBA.
В SystemVerilog есть несколько конструкций, вычисления в которых происходят после NBA, и в общем использрование любой из них для этих целей - это чит. По этому я взял самую короткую:
logic async_pre = 0; logic async = 0; // Вот здесь присваивание переносится за NBA always expect (@(async_pre) 1) async = async_pre; syncher #(SYNC_LEN) DUT (clock, reset, async, sync); sync1: assert property (async |-> ##(SYNC_LEN) sync); sync0: assert property (~async |-> ##(SYNC_LEN) ~sync); initial begin ... #(10us) async_pre = 1; #(1us) async_pre = 0; ... end
PS: Оказывается этот документ я скачал на просторах интернета еще месяц назад, но почитать его руки не доходили.
-
Опубликовано · Изменено пользователем embddr · Пожаловаться
с чего это он у вас детерменированный то ? поставили асинхронный сигнал, как он лег на тактовую так и лег. синхронизируйте сигналы и будет вам счастье.Он был бы у вас детерменированный вот в таком случае
@(posedge clock) async <= 1; @(posedge clock) async <= 0;
а вас случай, это как фишка (читай шедулер симулятора) ляжет.
Шедулер симулятора тоже не черный ящик, он вполне поддается настройке (например #0). И был бы он недетерминированным, результаты симуляции менялись бы от запуска к запуску.
Я хочу узнать, можно ли как-то принудительно (тем-же #0) изменить порядок вычисления, чтобы заставить одинаково работать RTL и assert-ы.
Хотя, вы (ты? не привычно мне в интернете на Вы общаться) наверное прав.
Нужно синхронизировать async. Это уберет гонки и в общем не изменит смысл тестбенча.
Спасибо!
-
Запрета то нет, но вы посмотрите что вы пишете. Четко после сигнала, через 2 такта что-то должно быть. А в CDC этого быть не может. Пишите доверительный интервал.
В физической реализации возможен недетерминизм в виде метастабильности, по этому две одинаковых схемы (RTL синхронизатора и описание в форме ассертов) могли бы давать разные результаты.
Но здесь детерминированный (если не считать искусственного недетерминизма) программный симулятор, в котором всё должно быть однозначно. По этому я и задал вопрос, как заставить симулятор обрабатывать такие случаи однозначно.
Доверительный интервал - это не выход, потому что тогда описание не соответствует реализации.
-
Опубликовано · Изменено пользователем embddr · Пожаловаться
вас не напрягает что на каждый дельтацикл симулятора у вас порождается программный тред ассерта по сигналу async ?Наверное нет, т.к. в коде объявлен default clocking. Ну и без клока ModelSim симулировать не будет.
Потому что не для этого придуманыВ стандарте я не нашел запрета на использование синхронных ассертов для асинхронных сигналов.
-
Опубликовано · Изменено пользователем embddr · Пожаловаться
не использовать синхронные ассерты в проверке асинхронных схем. между прочим то что вы видите это штатное поведение синхронизатора.Да, я понимаю, что синхронизатор работает как и должен.
Но почему нельзя использовать синхронные ассерты для асинхронных сигналов?
Есть же мультиклоковые последовательности, в которых тоже возможны гонки.
-
-
Опубликовано · Изменено пользователем embddr · Пожаловаться
Здравствуйте!
Подскажите, как избавиться от гонок при симуляции с использованием синхронных ассертов в SystemVerilog (симулятор - ModelSim)?
Ниже приведен простой пример с симуляцией синхронизатора, в котором я оставил только существенную часть.
Синхронизатор:
`timescale 1ns/100ps module syncher #(parameter LENGTH = 2) (input clock, input reset, input async, output sync); logic [LENGTH-1:0] register; always_ff @(posedge clock, posedge reset) if (reset) register <= 0; else register <= {async, register[1 +: LENGTH-1]}; assign sync = register[0]; endmodule
Тестбенч:
`timescale 1ns/100ps module syncher_tb; logic clock = 0; logic reset = 1; logic async = 0; logic sync; localparam CLOCK_HALF_PERIOD = 0.5us; localparam SYNC_LEN = 2; syncher #(SYNC_LEN) DUT (clock, reset, async, sync); always #(CLOCK_HALF_PERIOD) clock <= ~clock; default clocking @(posedge clock); endclocking default disable iff (reset); sync1: assert property (async |-> ##(SYNC_LEN) sync); sync0: assert property (~async |-> ##(SYNC_LEN) ~sync); initial begin #(3us) ##1 reset = 0; // ** Здесь гонок нет ##10 async = 1; ##10 async = 0; // ** Здесь гонки есть #(10us) async = 1; #(10us) async = 0; #(10us); $finish; end initial begin $dumpfile("syncher_tb.vcd"); $dumpvars; end endmodule
Временная диаграмма:
Как можно видеть, во время симуляции возникают гонки (во второй части тестбенча), которые выливаются в защелкивании невалидного сигнала async. Однако, в ассертах sync0 и sync1 этих гонок нет, и они выдают ошибку:
# ** Error: Assertion error. # Time: 35500 ns Started: 33500 ns Scope: syncher_tb.sync0 File: syncher_tb.sv Line: 20 # ** Error: Assertion error. # Time: 45500 ns Started: 43500 ns Scope: syncher_tb.sync1 File: syncher_tb.sv Line: 19
Как можно избавиться от таких гонок?
-
Скачал сегодня триал SlickEdit и не впечатлился. Неплохой редактор, но 300 баксов я бы не стал за него отдавать. Бесплатные/свободные альтернативы не хуже, а где-то даже лучше.
А еще он у меня два раза повис.
-
Я использую emacs для verilog. Раньше был vim, но из-за его дурацкого встроенного языка перешёл на emacs (lisp мне нравится).
В emacs можно довольно просто все настроить под себя и при желании добавить новый функционал, это его главное достоинство.
-
Зато это мировой сайт чисто по hardware IP, а проект на гитхабе "потеряется" через 2-3 месяца и будет интересен только вам.
Ок, попробую поэкспериментировать с зеркалом на svn.
-
Можно полюбопытствовать, что за IP core Вы хотите выложить?
Да я не профессионал в этом деле, по этому не ждите от меня чего-то серьезного :)
Для начала выложу корку I2C, а там посморю.
Если все как положено, то лучше на opencores.org :)Только если как дополнительное место. Там SVN, корорый я последний раз использовал лет десять назад и возвращаться не хочу. Если только через git svn.
-
2 embddr
есть тут у меня один товарищ, который через MS ASE всё SV-шное моделировал (не сложное / правда потом ему
мочаVHDL в голову ударил и он стал везьде его использовать .. эх.. нигде нет порядка..). Советую и вам попробовать MS ASE - возможно это и будет вам "совместимость с открытыми средствами моделирования" :laughingЯ тоже использую MoselSim ASE, но он не умеет делать анализ тестового покрытия. Есть открытый code coverage tool - Covered, но он не умеет SV.
-
Можете на форуме выложить - вложением.
Я лучше ссылкой на гитхаб. Вот только надо оформить всё как положено, чтоб не стыдно было людям в
глазааватарки смотреть. :) -
Здравствуйте!
Есть некоторое количество кода RTL на SV, которое хотелось бы открыть в open source.
Стоит ли переписать это для обеспечения совместимости с открытыми средствами моделирования (Icarus Verilog, Verilator), или оставить как есть, тем самым ограничив возможность моделирования коммерческими программами?
На сколько важна возможность моделирования открытыми средствами?
И вообще, стоит ли использовать все возможности SV для RTL? Cтоит ли вообще использовать SV для RTL? Может быть ограничиться V2001? Я слышал мнение, что некоторые синтезаторы не всегда корректно синтезируют из SV (сам, правда, не сталкивался).
-
а синтезатор потом по своему не пределает7
потому что
localparam IDLE = 0; localparam STATE1 = 1; localparam STATE1 = 2; reg [3:0] MainState = IDLE; case(MainState) IDLE: .... STATE1: ... endcase
синтезатор берет и все константы по своему усмотрению переназначает... мне кажется для енума он значения тоже переиначит... нет?
Такое переназначит, а one-hot не распознает. Может быть из-за того, что я обращаюсь к битам слова состояния. Т.е. для меня это не атомарная сущность, по этому ее нельзя переделывать.
ЗЫ. сброс автомата нужен всегда. Исключение самосинхронизированные автоматы в системах не требующих детерминированного поведения после начала работы.Забыл ответить. В моем случае сброс не нужен, потому что по включению питания все регистры устанавливаются в 0 (CPLD MAX II).
-
Опубликовано · Изменено пользователем embddr · Пожаловаться
А что значит закодировано вручную? Ведь изначально автомат описан тоже какими-то состояниями, заданными, а синтезатор берет их и перекодирует...Имеется в виду вот такой способ кодирования:
enum int unsigned { IDLE, STATE0, STATE1, STATE2, STATE3 } state, next;
и такой:
enum logic [4:0] { IDLE = 5'b00001, STATE0 = 5'b00010, STATE1 = 5'b00100, STATE2 = 5'b01000, STATE3 = 5'b10000 } state, next;
Ну и разница в выходной логике.
Вот это:
out = (state == STATE0) & in;
против этого:
out = state[STATE0_BIT] & in;
-
-
Большей частью разрешаю софту делать как считает нужным, но задаю требования к синтезу (тип кодирования). Руками кодирую только когда нужно выжать максимум из тактовой. Часто делаю полные автоматы, т.е. задаю последовательный тип кодирования и все 2^N состояний
ЗЫ. сброс автомата нужен всегда. Исключение самосинхронизированные автоматы в системах не требующих детерминированного поведения после начала работы.
Я вот смотрю проекты на OpenCores, и еще не встретил описания автомата для автоматического синтеза. Везде состояния кодируются вручную (в т.ч. в вашем проекте), и чаще всего one-hot. По этому мне стало интересно, может это какой-то тайнный орден ручного кодирования? :)
-
В Xilinx синтезатор автоматически делает схему кодирования состояний FSM типа one-hot, где по умолчанию нет состояния кодирующегося всеми нулями.
У меня квартус кодирует модифицированным one-hot, где начальное (по его мнению) состояние кодируется всеми нулями, а остальные one-hot с дополнительным установленным битом:
00000 - IDLE 00011 - STATE0 00101 - STATE1 01001 - STATE2 10001 - STATE3
Причем он это делает и для автомата с тремя состояниями и для автомата с 10-ю состояниями.
-
Еще ни разу не приходилось указывать вручную.
А можно как-то управлять этим процессом? Например, я хочу, чтобы состояние, которое кодируется всеми нулями, было не то, которое выбрал компилятор.
Это можно сделать добавлением асинхронного сброса, который выведен за пределы модуля, но он мне не нужен.
-
Опубликовано · Изменено пользователем embddr · Пожаловаться
Здравствуйте!
Скажите, как по вашему мнению лучше описывать состояния конечного автомата - вручную, выбирая тип кодирования (binary, Gray, one-hot), или автоматически, с помощью компилятора?
Я вот поэкспериментировал, и получилось, что с компилятором результат получается меньше и быстрее. Однако, я помню, что когда-то я имел проблемы с автоматической оптимизацией, но забыл какие.
Что вы думаете на этот счет?
Причины неправильного вычисления маски
в Языки проектирования на ПЛИС (FPGA)
Опубликовано · Изменено пользователем embddr · Пожаловаться
Не, там написано, что результат операции "~" имеет длину аргумента.
По идее, сначала дожно вычисляться (~one_bit) с длиной результата 1 бит, а потом расширение до 16 бит. Но в нашем случае почему-то сначала расширяется one_bit до 16 бит, а потом происходит инверсия.
Кстати, можно и без сдвига. Если оставить одну инверсию, получится 0xfff.