Есть ли лучший способ переписать BCD_counter в коде VHDL с меньшим количеством «if-Statement»? - PullRequest
0 голосов
/ 27 марта 2012

Я только начинаю изучать VHDL в modelsim, поэтому заранее прошу прощения, если то, что я делаю, кажется действительно нубистским.

По сути, я пытаюсь создать синтезируемый код VHDL для одноразрядного счетчика BCD вверх / вниз. Счетчик будет считать, когда «Включить» равен «1», или же он останется прежним. При инициализации входа «Инициализация» счетчик устанавливается на 0 или 9 в зависимости от значения входа «Направление». (Когда «Направление» равно «1», это счетчик увеличения).

Мне просто интересно, есть ли лучшие инструменты, которые можно использовать для этой работы, кроме использования 100, если и еще подряд.

Вот мой код, я пишу тестовый стенд для него прямо сейчас, так что я пока не уверен, сработает ли он вообще. Поэтому, если вы случайно заметили какую-то ошибку, пожалуйста, укажите мне.

Заранее большое спасибо, и вот мой код

entity BCD_counter is
  port(clk, direction, init, enable: in bit;
    q_out: out integer);
end entity BCD_counter;

architecture behaviour of BCD_counter is
  signal q: integer;
begin
  process(clk)
  begin
    if(Clk'event and Clk = '1') then
      if(direction = '1') then -- counting up
        if(init = '1')then --initialize
          q<=0; -- reset to 0
        else
         if(enable = '1')then -- counting          
            if (q<9) then
              q<=q+1;
            else
              q<=0;
            end if;          
         else
          q<=q;
          end if;
        end if;
      elsif(direction = '0') then --counting down
        if(init = '1') then --initialize
          q<=9; --reset to 9
        else
          if(enable = '1') then --counting        
            if (q>0) then
              q<=q-1;
            else
              q<=9;
            end if;       
          else
            q<=q;
          end if;
        end if;
      end if;
    end if;

  end process;  
      q_out <= q;  
end architecture behaviour;

Ответы [ 3 ]

2 голосов
/ 27 марта 2012

Немного другой стиль, но я бы так написал

architecture behaviour of BCD_counter is
  signal next_q : integer;
  signal q      : integer;
begin

  pReg : process
  begin  -- process pReg
    wait until clk'event and clk = '1';
    if init = '1' then
      q <= 0;
    else
      q <= next_q;
    end if;
  end process pReg;

  pCount : process (direction, enable, q)
  begin  -- process pCount
    next_q <= q;

    if enable = '1' then
      if direction = '1' then
        next_q <= q + 1;

        if q = 9 then
          next_q <= 0;
        end if;

      else
        next_q <= q - 1;

        if q = 0 then
          next_q <= 9;
        end if;

      end if;
    end if;
  end process pCount;

  q_out <= q;
end architecture behaviour;

Примечания:

  • Поведение регистра находится в отдельном процессе от логики. Я считаю, что этот стиль чистый. Другие имеют разные мнения, которые обычно сводятся к тому, что им не нравится иметь next_blah сигналы.
  • init - ваш сигнал сброса, поэтому он отменяет все остальное, и я помещаю сигналы сброса в процесс регистрации.
  • Первая строка процесса счетчика - это то, что я хочу выполнить по умолчанию. В этом случае говорится, что следующим состоянием q будет текущее состояние.
  • У меня есть внешний if чек на enable. Если мы не включены, мы ничего не делаем, так зачем сначала проверять direction
  • Внутри каждой половины условия направления структура кода одинакова. Установите желаемое значение в обычном случае, а затем проверьте исключение из правила. Например: если мы идем вверх, я устанавливаю следующее состояние q + 1, но если q равно 9, я переопределяю его с помощью q <= 0. </li>
  • Я не использую >, < ни в каких сравнениях. Это дороже, чем =, а = просто отлично.

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

  pReg : process
  begin  -- process pReg
    wait until clk'event and clk = '1';
    if init = '1' then
      q <= 0;
    else
      if enable = '1' then
        q <= next_q;
      end if;
    end if;
  end process pReg;

  pCount : process (direction, q)
  begin  -- process pCount
    if direction = '1' then
      next_q <= q + 1;

      if q = 9 then
        next_q <= 0;
      end if;
    else
      next_q <= q - 1;

      if q = 0 then
        next_q <= 9;
      end if;
    end if;
  end process pCount;
1 голос
/ 27 марта 2012

Единственное, что приходит мне в голову, это то, что вы могли бы пропустить два

else
   q<=q;

заявления, потому что это делается неявно, если не выполняется ни одно из других условий.

0 голосов
/ 27 марта 2012

Я делаю многое из этого - я создал функцию с именем modulo_increment, которая принимает целочисленное значение ввода и целочисленное значение "модуль" и возвращает обернутое значение.

так что вы можете сделать

q <= modulo_increment(q, 10);
...