Jump to content
    

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

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

wire PB_idle = (PB_state == с);

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

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

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

Share this post


Link to post
Share on other sites

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

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

 

 

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

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

image.thumb.png.df24979786d2a2043251be8779e2bb22.png

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

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

 

image.thumb.png.ccf3a367f84736d31ab89a45a626a205.png

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

image.thumb.png.b1a46538fefe608de030fd4880235236.png

Share this post


Link to post
Share on other sites

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

P.S. 

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

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

 

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

P.S. 

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

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

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

В questa

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

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

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...