7-сегментный дисплей с несколькими состояниями verilog

Я знаю, что вопрос звучит странно и расплывчато, но у меня возникла проблема с обходом Verilog. У меня есть FSM, который должен использовать 4 7-сегментных дисплея, в одном состоянии он должен отображать только одно число на одном дисплее, в другом он должен использовать все 4 дисплея для отображения строки. Мой вопрос в том, как я могу обойти блоки always@ с такой проблемой. Я пытался установить в одном блоке Always@ два разных случая в блоке If else, но это не сработало. Пробовал также сделать два модуля один для числа, а другой для строки, назначив разные выходные порты, но дело в том, что он должен указывать на одни и те же аппаратные порты, и он не работает на битовом потоке.

Может ли кто-нибудь из вас дать мне несколько советов?

Хорошо, я выложу немного кода, но основная картина такова, что у меня есть главный конечный автомат, а затем я получил еще один конечный автомат. В зависимости от состояния другого FSM я вывожу номер состояния на дисплей. Но в другом состоянии главного конечного автомата я должен отображать сообщение на 4-сегментных дисплеях. Что я получил сейчас: здесь я использовал CLK, чтобы сделать сообщение

always@(BIN_IN or CLK) begin
if(FAIL==1) begin
     case(state)
           left:
           begin
               HEX_OUT [6:0] <= F;
               SEG_SELECT_OUT <= 4'b0111;
               state <= midleft;
           end
           midleft:
           begin
               HEX_OUT [6:0] <= A;
               SEG_SELECT_OUT <= 4'b1011;
               state <= midright;
           end
//same for the rest
end
else begin  
case (BIN_IN)
4'h0 : begin
    HEX_OUT [6:0] <= 7'b1000000;
    SEG_SELECT_OUT <= 4'b0111;
end
//same logic for the other cases

Используемая плата Xilinx Basys 3 с использованием инструмента синтеза vivado

Спасибо


person Nick    schedule 12.11.2015    source источник
comment
все четыре 7-сегментных сегмента используют одну и ту же линию данных? Если нет, простой оператор if else решит проблему.   -  person vipin    schedule 12.11.2015
comment
Было бы полезно либо увидеть код, который вы используете, либо плату, для которой вы синтезируете, поскольку возможные решения различаются в зависимости от некоторых факторов, зависящих от них.   -  person Unn    schedule 12.11.2015
comment
Вы выводите комбинационную логику с always@(BIN_IN or CLK), и поведение RTL не будет соответствовать синтезированным вентилям. Как минимум, вам нужно изменить его на always@(posedge CLK), чтобы сделать его синхронным.   -  person Greg    schedule 12.11.2015


Ответы (1)


Как сказал Грег:

always@(BIN_IN or CLK)

Выводит комбинационную логику. FSM не может быть создан только с помощью комбинационной логики. Как вы знаете, FSM должен иметь возможность сохранять состояние между каждым тактом.

always@(posedge CLK)

Вводит шлепанцы в ваш дизайн. То есть операции, которые вы выполняете внутри этого цикла always, будут храниться до следующего положительного фронта. Если вы поместите весь дизайн в этот всегда блок, вы получите типичную машину Мура, где ваши выходные данные будут обновляться только при каждом положительном фронте тактового сигнала.

Немного сложно понять, что вы пытаетесь создать из своего фрагмента кода. Вы говорите о двух FSM, но мне кажется, что вы пытаетесь выполнить одну комбинационную операцию и одну тактовую операцию. Если вы хотите, чтобы ваш проект обновлял некоторые выходные данные, например BIN_IN, комбинационно (то есть немедленно), вы должны выполнять эти назначения за пределами блока always@(posedge CLK). Используйте блок always@(posedge CLK), чтобы обновить ваши значения FSM, а затем используйте комбинационный блок always@(BIN_IN or FAIL), чтобы вывести мультиплексор, который будет выбирать между вашим FSM-выводом и другими выходами. Что-то вроде этого может сработать:

always@(posedge CLK)
  begin
    case(state)
    left:
    begin
      FAIL_HEX_OUT <= "A";
      FAIL_SEG_OUT <= 4'b1011;
      state <= midleft;
    end
    //Rest of statements
    endcase
  end

always@(FAIL or BIN_IN or FAIL_SEG_OUT or FAIL_HEX_OUT)
  begin
    if(FAIL == 1) begin
      HEX_OUT <= FAIL_HEX_OUT;
      SEG_SELECT_OUT <= FAIL_SEG_OUT;
    end else begin
      case(BIN_IN)
        //your statements
      endcase
   end
 end

Кроме того, это не сработает:

HEX_OUT [6:0] = A;

сделайте это, чтобы назначить ascii регистру

HEX_OUT [6:0] = "A";

Я также предполагаю, что вы используете endcase для закрытия своих case-операторов. Я скомпилировал ваш фрагмент кода здесь: http://www.edaplayground.com/x/P_v

Редактировать: я изменил список чувствительности в комбинационной логике. Приведенный выше код не работал бы раньше.

Поскольку вы опубликовали так мало своего кода, трудно понять, в чем ваша проблема. Я предполагаю, что у вас есть только один выходной порт для управления всеми 7-сегментными дисплеями. В этом случае вам нужно перебрать все SEG_SELECT_OUT и установить HEX_OUT для каждого дисплея, когда вы хотите вывести FAIL. Это, в свою очередь, подразумевает, что каждый дисплей также имеет возможность хранить полученный им сигнал HEX_OUT, а ваши выходы (вероятно, SEG_SELECT_OUT) должны включать функцию записи этих регистров дисплея. Убедитесь, что это так. Я также предполагаю, что ваш счетчик реального времени, который считает 30 секунд, устанавливает флаг FAIL по завершении и сбрасывается каждый раз, когда лабиринт (я понятия не имею, что вы имеете в виду, когда говорите лабиринт) завершенный. Вы говорите, что вам нужно изменить число, и я предполагаю, что вы говорите о выводе числа в BIN_IN на свой дисплей и что BIN_IN изменен в другом месте. Все это должно работать в приведенном выше коде.

Без дополнительной информации трудно помочь дальше.

person Hida    schedule 12.11.2015
comment
Спасибо за ответ. Весь проект состоит из верхнего модуля и 6 подмодулей к нему. Итак, все вложено, и теперь это выглядит сложно. Итак, у меня есть главная машина состояний и машина-лабиринт. Когда я вхожу, скажем, в состояние 3 мастера, я иду к машине лабиринта, а затем я должен закончить ее и передать готовый результат мастеру. Также я должен отсчитать 30 секунд, за которые я должен пройти лабиринт. Если я не могу, я должен отобразить сообщение. - person Nick; 13.11.2015
comment
Я действительно не знаю, как это может работать в модуле 7segment, поскольку в одном случае он должен изменить числа, а в другом - использовать все сегменты для отображения сообщения. - person Nick; 13.11.2015
comment
Вы решили проблему? Если нет, я настоятельно рекомендую вам предоставить еще немного кода. - person Hida; 18.11.2015
comment
Ну, моя цель здесь состоит в том, чтобы получить подсказку, как заставить это работать, я имею в виду некоторые способы, которые обычно делают люди, когда у них возникает та же проблема. Во всяком случае, мне удалось это исправить. Проблема была с флагом FAIL. Это было потому, что я использовал тот же блок if-else для его установки и сброса. Когда я меняю только, чтобы установить его в одном месте и сбрасывать в совершенно независимом месте, все работает хорошо. Спасибо, в любом случае! - person Nick; 18.11.2015