=AK= 12 30 марта, 2006 Опубликовано 30 марта, 2006 · Жалоба Пытаюсь делать тривиальный фильтрик на входе UART-а, чтобы короткие выбросы не вызывали ложного срабатывания. Фильтр делаю на сдвиговом регистре flt, первые два каскада используются для подавления метастабильности, последние 3 каскада сравниваю на все 0 или все 1 и, соответственно, взвожу или сбрасываю бит результата shr(0), который затем вдвигаю в другой сдвиговый регистр shr process(clk16x,Rxd) variable flt :unsigned(4 downto 0); variable shr :unsigned(3 downto 0)l begin if rising_edge(clk16x) then flt(0) := Rxd; flt := flt sll 1; if flt(4 downto 2) = "000" then shr(0) := '0'; elsif flt(4 downto 2) = "111" then shr(0) := '1'; end if; shr := shr sll 1; end if; end process; Проверяю на симуляторе - полные дрова, не работает, не фильтрует ни фига. Почему? Переделал подубовее, ввел внешний сигнал filtered, и во второй регистр вдвигаю уже его process(clk16x,Rxd, filtered) variable flt :unsigned(4 downto 0); variable shr :unsigned(3 downto 0)l begin if rising_edge(clk16x) then flt(0) := Rxd; flt := flt sll 1; if flt(4 downto 2) = "000" then filtered <= '0'; elsif flt(4 downto 2) = "111" then filtered <= '1'; end if; shr(0) := filtered; shr := shr sll 1; end if; end process; Проверил на симуляторе - все ОК, работает. Это я чего-то не понимаю, или симулятор глючит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CaPpuCcino 0 30 марта, 2006 Опубликовано 30 марта, 2006 · Жалоба я чего-то не вижу или у вас там правда состояние неопределённости получается когда регистр не равен 111 или 000. где мажеритарное голосование-то? ну вот отсюда и глюк, кажись и на..зачем вам в списке чувствительности что-либо ещё кроме тактового сигнала? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Very_hard 0 30 марта, 2006 Опубликовано 30 марта, 2006 · Жалоба Разница, как я понял, заключается в использовании сигнала вместо переменной. В отличие от сигнала, переменная немедленно меняет свое значение после выполнения операции присваивания, и это новое значение становится сразу видным для последующих операторов в теле процесса. Поэтому в первом случае у Вас запись единицы во второй сдвиговый регистр shr происходит по тому же фронту клока, по которому получается 111 на выходе первого сдвигового регистра flt. При использовании сигнала это происходит по следующему фронту клока... Такие вот особенности VHDL-моделирования... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
o-henry 0 30 марта, 2006 Опубликовано 30 марта, 2006 (изменено) · Жалоба Не уверен, но по-моему в первый код надо добавить ELSE SHR(0) :=SHR(0) ; т.е. так: process(clk16x,Rxd) variable flt :unsigned(4 downto 0); variable shr :unsigned(3 downto 0)l begin if rising_edge(clk16x) then flt(0) := Rxd; flt := flt sll 1; if flt(4 downto 2) = "000" then shr(0) := '0'; elsif flt(4 downto 2) = "111" then shr(0) := '1'; ELSE SHR(0) :=SHR(0); end if; shr := shr sll 1; end if; end process; Изменено 30 марта, 2006 пользователем o-henry Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CaPpuCcino 0 30 марта, 2006 Опубликовано 30 марта, 2006 · Жалоба Разница, как я понял, заключается в использовании сигнала вместо переменной. В отличие от сигнала, переменная немедленно меняет свое значение после выполнения операции присваивания, и это новое значение становится сразу видным для последующих операторов в теле процесса. Поэтому в первом случае у Вас запись единицы во второй сдвиговый регистр shr происходит по тому же фронту клока, по которому получается 111 на выходе первого сдвигового регистра flt. При использовании сигнала это происходит по следующему фронту клока... Такие вот особенности VHDL-моделирования... да в этом-то как раз на мой ИМХО ничего страшного нет - коряво конечно переменные испольуются но огрех то только в том что: в одном (едином) дельта-цикле переменной flt содержащей на предыдущем цикле ААААА (где А=1V0) присваивается: flt[0]=R; <=> flt :=AAAAR; затем flt[4:1]=flt[3:0], flt[0]=0 <=> flt:=AAAR0; то есть всё равно что записывать на каждом клоке flt[4:2]=flt[3:1], flt[1:0]=R0; т.е нулевой бит веkтора можно вообще выбросить потом проиcxодит проверка нового значения и то же самое вытваряется с shr: если в shr было BBBB то стало BBBL (L выход с логики if-a ) а затем сразу BBF0 то есть нулевой бит опять в ауте получается что код эквивалентен 2 регистрам в первый входной битовый сигнал записывается со сдвинутым предыдущим зна4ением в бит номер один,с трeх битов которого flt (3 downto 1)через логику (определённую if-aми) идёт сигнал на бит номер один второго сдвиг. регистра (так как присваивание блокирующее - то фактически блок комбинаторной логики присоединён к flt[3:1]) неплохо бы весь код посмотреть - а то не исключено что нет какой-нибудь инициализации или например сигналу filtered может быть присвоено значение вне какого-либо процесса - компилятор это хавает и устраняет проблему неопределённости и вообще - где виновник торжества??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Very_hard 0 30 марта, 2006 Опубликовано 30 марта, 2006 · Жалоба CaPpuCcino :a14: Да уж кривовато... сдвиговые регистры оказались не такими длинными, как их представлял автор :) . Но судя по тому, что второй пример работает(как считает автор), то дело скорее всего именно в использовании сигнала вместо переменной... все таки лишний клок (при укороченном регистре) может и помогать в некоторых случаях. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 12 30 марта, 2006 Опубликовано 30 марта, 2006 · Жалоба я чего-то не вижу или у вас там правда состояние неопределённости получается когда регистр не равен 111 или 000. где мажеритарное голосование-то? Нет мажоритарного голосования, я хотел получить триггер, который взводится по трем 1 и сбрасывается по трем 0. и на..зачем вам в списке чувствительности что-либо ещё кроме тактового сигнала? В списке должны быть все сигналы, изменение которых сказывается на процессе. Детское объяснение: иначе Квартус ругается :) огрех то только в том что: в одном (едином) дельта-цикле переменной flt содержащей на предыдущем цикле ААААА (где А=1V0) Что такое 1V0? присваивается: flt[0]=R; <=> flt :=AAAAR; затем flt[4:1]=flt[3:0], flt[0]=0 <=> flt:=AAAR0; Почему присваивается flt[0]=0 ? то есть всё равно что записывать на каждом клоке flt[4:2]=flt[3:1], flt[1:0]=R0; Я не понял, почему это должно происходить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Very_hard 0 31 марта, 2006 Опубликовано 31 марта, 2006 · Жалоба Что такое 1V0? Единица или нуль. Почему присваивается flt[0]=0 ? Потому что flt - переменная(а не сигнал!). И изменяясь в ходе процесса она сразу становится доступной дальнейшим операциям процесса. Поэтому последовательное присвоение flt[0]:=Rxd и дальнейший сдвиг целого flt на один разряд приводят к записи в flt[0] нуля(должно же там чтото появиться :) ), а в flt[1] тут же попадает принятое значение Rxd. Если вместо переменной используется сигнал, то новое значение, полученное сигналом в ходе выполнения процесса, становится доступным дальнейшим операторам в теле процесса только при следующем запуске процесса. А до этого следующего запуска в дальнейшем в процессе будет использоваться старое значение сигнала. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 12 31 марта, 2006 Опубликовано 31 марта, 2006 (изменено) · Жалоба Что такое 1V0? Единица или нуль. Вот и я подумал, нафиг там 1.0 вольт? :) То есть, в более общепринятой нотации, подразумевалось 1|0 Почему присваивается flt[0]=0 ? Потому что flt - переменная(а не сигнал!). И изменяясь в ходе процесса она сразу становится доступной дальнейшим операциям процесса. Поэтому последовательное присвоение flt[0]:=Rxd и дальнейший сдвиг целого flt на один разряд приводят к записи в flt[0] нуля(должно же там чтото появиться :) ), Почему 0, а не 1? :) В конечном счете все свелось к тому, как на самом деле работает оператор сдвига sll. По моему, совершенно не очевидно, что он вообще должен хоть что-то присваивать младшему разряду, будь то сигнал или переменная. Тем не менее, мне лучше было бы сдвиговый регистр прописывать одной командой, типа flt := flt(3 downto 0) & Rxd; Здесь нет возможностей для множественного толкования, как в случае с sll Что ж касается filtered, то, получается, вполне можно сделать его не сигналом, а локальной переменной. От этого ничего не должно измениться, только сдвиговый регистр shr надо делать так же, как flt Изменено 31 марта, 2006 пользователем =AK= Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CaPpuCcino 0 1 апреля, 2006 Опубликовано 1 апреля, 2006 · Жалоба 1)дело не в том что должно хоть что-то записываться - а в том что в ВХДЛ есть сдвиги типа: логический - расширяется нулём арифметический - расширяется знаком циклический - расширяется значением младшего или старшего бита в зависимости от направления сдвига см. спецификацию sll- логический 2) всё верно, V - обозначение логического ИЛИ знак | применять не стал потому как верилоговский а в ВХДЛ на сколько помню только OR (хотя я давно с ВХДЛ не имел дела) 3) в списке чувствительности процесса перечисляются сигналы при изменении которых прoцесс "запускается" (в случае симуляционной модели) на исполнение. при компияции в модели создаётся список объектов-событий, которые отслеживаются симулятором и при возникновении события запускается связанный с ним процесс - то что вы заводите в список дополнительное событие ухудшает производительность модели потому что событие звязанное с Rxd запускает процесс на исполнение всякий раз когда происходит изменение сигнала Rxd и гоняет его в холостую (потому что ни один оператор в теле процесса не выполняется при условии срабатывания только триггера Rxd[1] все они отсеиваются первым же if-ом), если бы существовала задача построить схему чувствительную к асинхронному относительно тактирующего сигналу - как например происходит при асинхронном сбросе\установке - то такой сигнал действительно заводился бы в список чувствительности; либо при описании комбинаторной логики процесс действительно чувствителен ко всем сигналам с правой стороны от оператора присваивания 4) с неопределённостью я действительно погорячился -извините- но реально милее было бы сделать явное указание на то что значение остаётся неизменным как посоветовал товарищ Very_hard, чтобы у таких как я не возникало вопросов о мажеритарном голосование 5) так вот ошибка происходит (и труднообнаруживаема она именно из-за отсутствия явного присваивания переменной самой себя на наборах отличных от 000 и 111) из- за вползания во второй сдвиговый регистр НУЛЯ в то время как вы думаете что регистр должен сохранять все единицы при стабильном уровне - введение сигнала же спасает вас от этого вползания так как пердыдущее значение (истинное) содержится в этом сигнале и на каждом клоке в сдвиговый регистр задвигается истинное значение а не ложный ноль от операции сдвига: для удобоваримости пример: дотустим ваша логика устанавливает единицу и во второй сдвиговый регистр вы задвигаете единицу (была комбинация 111) на следующем же такте логика не даёт установку в единицу но и не даёт установку в ноль (допустим комбинация 110) вы полагаете что значение истинного значения вашего сигнала должно оставаться 1, но на самом деле происходит простой сдвиг и задвижка нуля. когда же вы пришли ко второму варианту изменилось то что сигнал filtered сохраняет предыдущее значение и его значение присваивается биту второго сдвиг регистра на каждом такте - то есть не происходит вдвижки ложного нуля (подумайте хорошенько над этим) вообще говоря я советовал бы вам поработать над стилем программирования - чтобы не ломать глаза о собственный код и иметь представление о том что же вы реально получаете. также иметь чёткое представление о разнице между переменными и сигналами и о разнице в присвоение им новых значений относительно дельта-цикла и хорошо иметь чёткое представление о событиях и чувствительности процесса (хоть я тут кое-чего и написал, но боюсь что не очень высокохудожественно) к стати спасибо за "Детское объяснение" [1]-здесь триггер = событие запускающее все процессы асоциированные с сигналом Rxd, как в ОСРВ, а не схемотехн. понятие Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 12 1 апреля, 2006 Опубликовано 1 апреля, 2006 · Жалоба 1)дело не в том что должно хоть что-то записываться - а в том что в ВХДЛ есть сдвиги типа: логический - расширяется нулём арифметический - расширяется знаком циклический - расширяется значением младшего или старшего бита в зависимости от направления сдвига см. спецификацию sll- логический Логично :) 2) всё верно, V - обозначение логического ИЛИ знак | применять не стал потому как верилоговский а в ВХДЛ на сколько помню только OR (хотя я давно с ВХДЛ не имел дела) | есть общеупотребительный знак для ИЛИ для всех, кто печатает на обычной ПК клаве, и это не связано ни с Верилогом, ни с Це. Бо более адекватного знака для И чем & на этой клаве нет. Иначе знаку V нет подходящего комплемента, ведь ни Л не подходит в качестве И, ни ^. Так что V в качестве ИЛИ только сбивает с толку :) и хорошо иметь чёткое представление о событиях и чувствительности процесса Дело практики, имхо. На то и форум, чтоб спрашивать и получать разумные объяснения, чем долбаться в одиночку. Спасибо. :cheers: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 3 1 апреля, 2006 Опубликовано 1 апреля, 2006 · Жалоба А на результаты можно посмотреть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 12 4 апреля, 2006 Опубликовано 4 апреля, 2006 · Жалоба Нет, все-таки что-то не так... :( Пишу код типа process(Reset, CSn,SCLKin,CLK48,bit_cnt,cmd_gate) variable pulse5 :std_logic; variable shr : unsigned(2 downto 0); begin if (Reset='1') or (CSn='1') then bit_cnt <= "000"; elsif rising_edge(SCLKin) then bit_cnt <= bit_cnt + "001"; -- count SCLK pulses if (bit_cnt = "101") then pulse5 := '1'; else pulse5 := '0'; end if; end if; if rising_edge(CLK48) then shr := shr(1 downto 0) & pulse5; RdWr_done <= shr(2) and (not cmd_gate); end if; end process; Проверяю модуль на симуляторе, все чудно работает, диаграмки соответствуют ожидаемым. Компилирую весь проект - полные дрова, не пашет. Начинаю разбираться и вижу, что сигнала RdWr_done на выходе модуля на самом деле нет (он всегда 0), а симулятор, стало быть, врет. Убираю переменную shr, делаю ее сигналом - вуаля, все работает. :blink: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Very_hard 0 4 апреля, 2006 Опубликовано 4 апреля, 2006 · Жалоба Убираю переменную shr, делаю ее сигналом - вуаля, все работает. И снова сдвиговый регистр при использовании переменной оказывается короче, чем хотелось бы... :) Каким боком это влияет на функционирование не знаю, но факт налицо. Я бы посоветовал иногда заглядывать в сгенеренную по коду схематику... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vetal 0 4 апреля, 2006 Опубликовано 4 апреля, 2006 · Жалоба Я бы посоветовал иногда заглядывать в сгенеренную по коду схематику... Это надо делать всегда. Желательно перед симуляцией. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться