Перейти к содержанию
    

QuestaSim не отрабатывает выражение.

Здравствуйте все.

Почему то в выражение wire PB_idle = (PB_state == PB_sync_1);  PB_idle всегда находится в неопределенном состоянии. Оператор PB_state всегда 0, а PB_sync_1 меандр. PB_idle по идеи тоже меандр должен быть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте,

На сколько я понимаю, Вы пытаетесь осуществить "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 и пояснения к нему.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

wire PB_idle = (PB_state == с);

Здесь PB_idle  присваивается начальное значение. При этом начальное значение PB_sync_1 не определено.

Поэтому и PB_idle не определено.

Непрерывное присваивание делается через оператор assign.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Понятно. Спасибо. Взял из примера. assign да, так и делаю.

25 минут назад, kirill70674 сказал:

 

 

Осуществлять присвоение при объявлени сигнала - дурной стиль.

Согласен. В коде можно легко проглядеть, запутаться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/9/2024 at 6:15 PM, khlenar said:

PB_idle всегда находится в неопределенном состоянии.

Похоже, значение переменной PB_idle присваивается в нескольких разных местах.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

image.thumb.png.df24979786d2a2043251be8779e2bb22.png

В одном месте присваивание.

Сделал с assign, но почему то всегда в нуле.(

 

image.thumb.png.ccf3a367f84736d31ab89a45a626a205.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

PB_state выход. Он как бы не определен в выражении. Когда его убираю из assign PB_idle = (PB_state == PB_sync_1)? 1'b1 : 1'b0; то выражение выполняется. Но в wave он равен 0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можете пояснить словами, как должен вести себя PB_idle

P.S. 

57 минут назад, khlenar сказал:

почему то всегда в нуле.(

 

Потому что у Вас сигнал имеет тип bit у которого всего 2 состояния: 0 и 1. Использование типов int, byte, bit в синтезируемом коде крайне не желательно. Используйте logic, у него 4 состояния...

2 минуты назад, khlenar сказал:

Надо было инициализировать его (PB_state).

Если код далее идёт в синтез - забудте про блоки initial. Инициализация осуществляется только по сигналу reset

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 минуты назад, kirill70674 сказал:

Можете пояснить словами, как должен вести себя PB_idle

P.S. 

Потому что у Вас сигнал имеет тип bit у которого всего 2 состояния: 0 и 1. Использование типов int, byte, bit в синтезируемом коде крайне не желательно. Используйте logic, у него 4 состояния...

Если код далее идёт в синтез - забудте про блоки initial. Инициализация осуществляется только по сигналу reset

initial синтезироваться не будет. Это я только пример проверяю. Разбираюсь с алгоритмом. 

В questa

Скажите, почему bit применять не желательно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 минут назад, khlenar сказал:

Скажите, почему bit применять не желательно?

Потому что данный тип не отражает в полной мере поведение реального "железа". Первая и главная причина: после сброса все не инициализированные переменные в симуляторе Вы будете видеть в 0'ях, когда в реальном устройстве их начальное сотояние определено не будет (X).

21 минуту назад, khlenar сказал:

bit применять не желательно

Типы с 2 состояниями введены больше для верификации, где время от времени приходится иметь дело с пересылкой данных в C++ и обратно.

Настоятельно рекомендую к прочтению данную статью: https://sutherland-hdl.com/papers/2013-SNUG-SV_Synthesizable-SystemVerilog_paper.pdf Там подробно рассказано что синтезируемое, а что нет. А что синтезируемо, но в синтезе личше не использовать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/9/2024 at 7:56 PM, khlenar said:

В одном месте присваивание.

Тогда вопрос: почему на графике во временной диаграмме сигнал PD_idle выбран из модуля /Test/Debounce/, а сигнал PB_state выбран из модуля /Test/ ???

В коде же, эти сигналы, похоже, описаны в одном и том же модуле..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

image.thumb.png.ad32655bf42a2b192e656c94ba197371.png

В данном случае 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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...