Verilog: изменение нескольких состояний в одном операторе case

В основном я пытаюсь отобразить сумму или произведение двух чисел (введенных с помощью переключателей на FPGA) на 7-сегментном дисплее. Я знаю, что мои биты сложения и умножения работают нормально, так как я тестировал их по отдельности.

У меня проблемы с LSB, хотя. Независимо от того, что он просто по умолчанию F и никогда не меняется. Я думаю, что Verilog не позволяет мне изменять Cout1 и Cout0 в одном и том же операторе case. Есть ли обходной путь для этого? Смотрите мой код ниже.

always@*
    if (key1press)
    casex(PrintSum)

        // Hex 1 (MSB)
        // Works!
        5'b0xxxx : Cout1 = 7'b1000000;  //0 if S[4] = 0
        5'b1xxxx : Cout1 = 7'b1111001;  //1 if S[4] = 1

        // Hex 0 (LSB)
        // Doesn't work :(
        5'bx0000 : Cout0 = 7'b1000000;  //0
        ...
        5'bx1111 : Cout0 = 7'b0001110;  //F
        //default  : begin
        //            Cout1 = 7'b1000000;   //0 by default
        //            Cout0 = 7'b1000000;   //0 by default
        //end
    endcase

Заранее всем спасибо :)


person Walby    schedule 10.12.2017    source источник


Ответы (2)


В симуляциях операторы case будут выполнять первое совпадение. Все будет соответствовать первым двум условиям (5'b0xxxx, 5'b1xxxx). Если вы переместите эти условия в конец, они никогда не будут достигнуты, поскольку будет совпадение в диапазоне от 5'bx0000 до 5'bx1111.

Между битами ухода нет перекрытия. Поэтому самое простое решение — разделить Cout1 и Cout0 на отдельные конституционные операторы:

begin
  if (PrintSum[4]) begin
    Cout1 = 7'b1111001;  //1 if S[4] = 1
  end
  else begin
    Cout1 = 7'b1000000;  //0 if S[4] = 0
  end

  case(PrintSum[3:0])
    4'b0000 : Cout0 = 7'b1000000;  //0
    // ...
    4'b1111 : Cout0 = 7'b0001110;  //F
  endcase
end

Другие вещи, о которых следует знать:

person Greg    schedule 11.12.2017
comment
Спасибо, все это было действительно полезно, и спасибо за дополнительные ресурсы. Я принял решение заменить casex на casez. - person Walby; 12.12.2017
comment
Вы должны отобразить значок принятия ответа, если это соответствует вашему вопросу. Это поможет другим с подобными вопросами. - person Greg; 14.12.2017

следующие 2 термина из вашего оператора case охватывают все возможные значения селектора PrintSum. Поскольку они являются первыми в списке, никакие другие значения никогда не попадут туда.

    5'b0xxxx : Cout1 = 7'b1000000;  //0 if S[4] = 0
    5'b1xxxx : Cout1 = 7'b1111001;  //1 if S[4] = 1

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

вы также можете изменить порядок элементов, как это.

    // Hex 0 (LSB)
    // Doesn't work :(
    5'bx0000 : Cout0 = 7'b1000000;  //0
    ...
    5'bx1111 : Cout0 = 7'b0001110;  //F


   // Hex 1 (MSB)
    // Works!
    5'b0xxxx : Cout1 = 7'b1000000;  //0 if S[4] = 0
    5'b1xxxx : Cout1 = 7'b1111001;  //1 if S[4] = 1
person Serge    schedule 10.12.2017
comment
Разве оба сценария не приведут к попаданию одного значения и завершению дела? (Также я пробовал переключать два элемента, к сожалению, не повезло) - person Walby; 11.12.2017
comment
он сначала попадет в первое совпадение. Итак, если PrintSum имеет 4 младших бита, установленных на «0000», он попадет в первый член. Однако для «00001» он будет соответствовать термину «0xxxx», а для «10001» — «1xxxx». - person Serge; 11.12.2017