khlenar 5 9 марта Опубликовано 9 марта · Жалоба Здравствуйте все. Почему то в выражение wire PB_idle = (PB_state == PB_sync_1); PB_idle всегда находится в неопределенном состоянии. Оператор PB_state всегда 0, а PB_sync_1 меандр. PB_idle по идеи тоже меандр должен быть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khlenar 5 9 марта Опубликовано 9 марта · Жалоба Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kirill70674 5 9 марта Опубликовано 9 марта · Жалоба Здравствуйте, На сколько я понимаю, Вы пытаетесь осуществить "gating" сигнала PB_sync_1 с помощью управляющего сигнала PB_state. Это делается через оператор assign. Поробуйте переписать выражение так: wire PB_idle; assign PB_idle = PB_state ? PB_sync_1 : '0; Осуществлять присвоение при объявлени сигнала - дурной стиль. 1 час назад, khlenar сказал: PB_idle по идеи тоже меандр должен быть. См. пункт "10.3.2 The continuous assignment statement" LRM. Пример 3 и пояснения к нему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
honinbo 1 9 марта Опубликовано 9 марта · Жалоба wire PB_idle = (PB_state == с); Здесь PB_idle присваивается начальное значение. При этом начальное значение PB_sync_1 не определено. Поэтому и PB_idle не определено. Непрерывное присваивание делается через оператор assign. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khlenar 5 9 марта Опубликовано 9 марта · Жалоба Понятно. Спасибо. Взял из примера. assign да, так и делаю. 25 минут назад, kirill70674 сказал: Осуществлять присвоение при объявлени сигнала - дурной стиль. Согласен. В коде можно легко проглядеть, запутаться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 16 9 марта Опубликовано 9 марта · Жалоба On 3/9/2024 at 6:15 PM, khlenar said: PB_idle всегда находится в неопределенном состоянии. Похоже, значение переменной PB_idle присваивается в нескольких разных местах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khlenar 5 9 марта Опубликовано 9 марта · Жалоба В одном месте присваивание. Сделал с assign, но почему то всегда в нуле.( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khlenar 5 9 марта Опубликовано 9 марта · Жалоба PB_state выход. Он как бы не определен в выражении. Когда его убираю из assign PB_idle = (PB_state == PB_sync_1)? 1'b1 : 1'b0; то выражение выполняется. Но в wave он равен 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khlenar 5 9 марта Опубликовано 9 марта · Жалоба Надо было инициализировать его (PB_state). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kirill70674 5 9 марта Опубликовано 9 марта · Жалоба Можете пояснить словами, как должен вести себя PB_idle? P.S. 57 минут назад, khlenar сказал: почему то всегда в нуле.( Потому что у Вас сигнал имеет тип bit у которого всего 2 состояния: 0 и 1. Использование типов int, byte, bit в синтезируемом коде крайне не желательно. Используйте logic, у него 4 состояния... 2 минуты назад, khlenar сказал: Надо было инициализировать его (PB_state). Если код далее идёт в синтез - забудте про блоки initial. Инициализация осуществляется только по сигналу reset. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khlenar 5 9 марта Опубликовано 9 марта · Жалоба 4 минуты назад, kirill70674 сказал: Можете пояснить словами, как должен вести себя PB_idle? P.S. Потому что у Вас сигнал имеет тип bit у которого всего 2 состояния: 0 и 1. Использование типов int, byte, bit в синтезируемом коде крайне не желательно. Используйте logic, у него 4 состояния... Если код далее идёт в синтез - забудте про блоки initial. Инициализация осуществляется только по сигналу reset. initial синтезироваться не будет. Это я только пример проверяю. Разбираюсь с алгоритмом. В questa Скажите, почему bit применять не желательно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kirill70674 5 9 марта Опубликовано 9 марта · Жалоба 17 минут назад, khlenar сказал: Скажите, почему bit применять не желательно? Потому что данный тип не отражает в полной мере поведение реального "железа". Первая и главная причина: после сброса все не инициализированные переменные в симуляторе Вы будете видеть в 0'ях, когда в реальном устройстве их начальное сотояние определено не будет (X). 21 минуту назад, khlenar сказал: bit применять не желательно Типы с 2 состояниями введены больше для верификации, где время от времени приходится иметь дело с пересылкой данных в C++ и обратно. Настоятельно рекомендую к прочтению данную статью: https://sutherland-hdl.com/papers/2013-SNUG-SV_Synthesizable-SystemVerilog_paper.pdf Там подробно рассказано что синтезируемое, а что нет. А что синтезируемо, но в синтезе личше не использовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khlenar 5 9 марта Опубликовано 9 марта · Жалоба Ясно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 16 9 марта Опубликовано 9 марта · Жалоба On 3/9/2024 at 7:56 PM, khlenar said: В одном месте присваивание. Тогда вопрос: почему на графике во временной диаграмме сигнал PD_idle выбран из модуля /Test/Debounce/, а сигнал PB_state выбран из модуля /Test/ ??? В коде же, эти сигналы, похоже, описаны в одном и том же модуле.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khlenar 5 9 марта Опубликовано 9 марта · Жалоба В данном случае PB_state присваивается после условия сам на себя. Поэтому он был не определен. PB_state это output logic. В данном случае надо еще один вход RESET заводить. 6 минут назад, blackfin сказал: Тогда вопрос: почему на графике во временной диаграмме сигнал PD_idle выбран из модуля /Test/Debounce/, а сигнал PB_state выбран из модуля /Test/ ??? В коде же, эти сигналы, похоже, описаны в одном и том же модуле.. Сейчас работает нормально. Это вариант антидребезга. `timescale 1ns / 100ps module PushButton_Debouncer ( input wire clk, input wire PB, // "PB" is the glitchy, asynchronous to clk, active low push-button signal // from which we make three outputs, all synchronous to the clock output logic PB_state, // 1 as long as the push-button is active (i.e. pushed down) output logic PB_down, // 1 for one clock cycle when the push-button goes down (i.e. just pushed) output logic PB_up // 1 for one clock cycle when the push-button goes up (i.e. just released) ); initial begin PB_state = 1'b0; end // First use two flip-flops to synchronize the PB signal the "clk" clock domain logic PB_sync_0; always @(posedge clk) PB_sync_0 <= ~PB; // invert PB to make PB_sync_0 active high logic PB_sync_1; always @(posedge clk) PB_sync_1 <= PB_sync_0; // счетчик logic [3:0] PB_cnt; // When the push-button is pushed or released, we increment the counter // The counter has to be maxed out before we decide that the push-button state has changed wire PB_idle = (PB_state == PB_sync_1); wire PB_cnt_max = &PB_cnt; // true when all bits of PB_cnt are 1's always @(posedge clk) if(PB_idle) PB_cnt <= 0; // nothing's going on else begin PB_cnt <= PB_cnt + 1'b1; // something's going on, increment the counter if(PB_cnt_max) PB_state <= ~PB_state; // if the counter is maxed out, PB changed! end assign PB_down = ~PB_idle & PB_cnt_max & ~PB_state; assign PB_up = ~PB_idle & PB_cnt_max & PB_state; endmodule // Тестовый модуль module Test; bit clk; bit PB; bit PB_state; bit PB_down; bit PB_up; shortint i; PushButton_Debouncer Debounce ( .clk(clk), .PB(PB), .PB_state(PB_state), .PB_down(PB_down), .PB_up(PB_up) ); initial begin clk = 1'b0; PB = 1'b1; for(i = 0; i < 8; i++) begin #150 PB = 1'b0; #150 PB = 1'b1; end #150 PB = 1'b0; #2500 PB = 1'b1; #2500 $stop; end always #50 clk = ~clk; endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться