Код VHDL для конечного автомата

Я пытаюсь написать регистр последовательного приближения в VHDL для АЦП. Я делаю это государственной машиной. Я просто немного не уверен в своем коде в последнем блоке состояния (current_state = S_LSB). Этот код действителен? Есть ли лучший способ сбросить DigitalOutTemp и OutTemp перед возвратом в исходное состояние?

ПРИМЕЧАНИЕ Значение компаратора зависит от выхода DigitalOutTemp после прохождения через цифро-аналоговый преобразователь.

LIBRARY ieee;
USE     ieee.std_logic_1164.all;

ENTITY SARegister IS
PORT (
    Comparator, Clock                     : IN std_logic;
    DigitalOutFinal, DigitalOutTemp   : OUT std_logic_vector (13 downto 0)
);
END;

ARCHITECTURE Behavioural OF SARegister IS

CONSTANT S_MSB      : STD_LOGIC_VECTOR(3 downto 0) := "0000";
CONSTANT S_TWELVE   : STD_LOGIC_VECTOR(3 downto 0) := "0001";
CONSTANT S_ELEVEN   : STD_LOGIC_VECTOR(3 downto 0) := "0010";
CONSTANT S_TEN      : STD_LOGIC_VECTOR(3 downto 0) := "0011";
CONSTANT S_NINE     : STD_LOGIC_VECTOR(3 downto 0) := "0100";
CONSTANT S_EIGHT    : STD_LOGIC_VECTOR(3 downto 0) := "0101";
CONSTANT S_SEVEN    : STD_LOGIC_VECTOR(3 downto 0) := "0110";
CONSTANT S_SIX      : STD_LOGIC_VECTOR(3 downto 0) := "0111";
CONSTANT S_FIVE     : STD_LOGIC_VECTOR(3 downto 0) := "1000";
CONSTANT S_FOUR     : STD_LOGIC_VECTOR(3 downto 0) := "1001";
CONSTANT S_THREE    : STD_LOGIC_VECTOR(3 downto 0) := "1010";
CONSTANT S_TWO      : STD_LOGIC_VECTOR(3 downto 0) := "1011";
CONSTANT S_ONE      : STD_LOGIC_VECTOR(3 downto 0) := "1100";
CONSTANT S_LSB      : STD_LOGIC_VECTOR(3 downto 0) := "1101";

SIGNAL Next_state       : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL Current_state    : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL OutTemp          : STD_LOGIC_VECTOR(13 DOWNTO 0);    

BEGIN

PROCESS (Clock)
BEGIN

    IF (rising_edge (Clock)) THEN       
        Current_state <= Next_state;
    END IF;

END PROCESS;

PROCESS (Current_state, Comparator)
BEGIN
    Next_state <= Current_state;
    DigitalOutTemp <= "10000000000000";
    OutTemp <= "10000000000000";
    DigitalOutFinal <= "00000000000000";

    IF (Current_state = S_MSB) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(13) <= '0';
            OutTemp(13) <= '0';
        END IF;
        DigitalOutTemp(12) <='1';
        OutTemp(12) <= '1';
        Next_state <= S_TWELVE;

    ELSIF (Current_state = S_TWELVE) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(12) <= '0';
            OutTemp(12) <= '0';
        END IF;
        DigitalOutTemp(11) <='1';
        OutTemp(11) <= '1';
        Next_state <= S_ELEVEN;

    ELSIF (Current_state = S_ELEVEN) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(11) <= '0';
            OutTemp(11) <= '0';
        END IF;
        DigitalOutTemp(10) <='1';
        OutTemp(10) <= '1';         
        Next_state <= S_TEN;

    ELSIF (Current_state = S_TEN) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(10) <= '0';
            OutTemp(10) <= '0';
        END IF;
        DigitalOutTemp(9) <='1';
        OutTemp(9) <= '1';          
        Next_state <= S_NINE;

    ELSIF (Current_state = S_NINE) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(9) <= '0';
            OutTemp(9) <= '0';
        END IF;
        DigitalOutTemp(8) <='1';
        OutTemp(8) <= '1';          
        Next_state <= S_EIGHT;

    ELSIF (Current_state = S_EIGHT) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(8) <= '0';
            OutTemp(8) <= '0';
        END IF;
        DigitalOutTemp(7) <='1';
        OutTemp(7) <= '1';          
        Next_state <= S_SEVEN;

    ELSIF (Current_state = S_SEVEN) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(7) <= '0';
            OutTemp(7) <= '0';
        END IF;
        DigitalOutTemp(6) <='1';
        OutTemp(6) <= '1';          
        Next_state <= S_SIX;

    ELSIF (Current_state = S_SIX) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(6) <= '0';
            OutTemp(6) <= '0';
        END IF;
        DigitalOutTemp(5) <='1';
        OutTemp(5) <= '1';          
        Next_state <= S_FIVE;

    ELSIF (Current_state = S_FIVE) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(5) <= '0';
            OutTemp(5) <= '0';
        END IF;
        DigitalOutTemp(4) <='1';
        OutTemp(4) <= '1';          
        Next_state <= S_FOUR;

    ELSIF (Current_state = S_FOUR) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(4) <= '0';
            OutTemp(4) <= '0';
        END IF;
        DigitalOutTemp(3) <='1';
        OutTemp(3) <= '1';          
        Next_state <= S_THREE;

    ELSIF (Current_state = S_THREE) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(3) <= '0';
            OutTemp(3) <= '0';
        END IF;
        DigitalOutTemp(2) <='1';
        OutTemp(2) <= '1';          
        Next_state <= S_TWO;

    ELSIF (Current_state = S_TWO) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(2) <= '0';
            OutTemp(2) <= '0';
        END IF;
        DigitalOutTemp(1) <='1';    
        OutTemp(1) <= '1';      
        Next_state <= S_ONE;

    ELSIF (Current_state = S_ONE) THEN
        IF (Comparator = '0') THEN 
            DigitalOutTemp(1) <= '0';
            OutTemp(1) <= '0';
        END IF;
        DigitalOutTemp(0) <='1';
        OutTemp(0) <= '1';          
        Next_state <= S_LSB;

    ELSIF (Current_state = S_LSB) THEN
        IF (Comparator = '0') THEN
            DigitalOutTemp(0) <= '0';
            OutTemp(0) <= '0';
        END IF;

        DigitalOutFinal <= OutTemp;

        DigitalOutTemp <= "10000000000000";
        OutTemp <= "10000000000000";

        Next_state <= S_MSB;

    END IF;
END PROCESS;
END;

person atbauman    schedule 26.10.2012    source источник


Ответы (1)


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

В вашем коде много ненужных повторений, которые вы можете исправить, используя счетчик для индексации ваших битов, а не жестко закодированный индекс в каждом состоянии, например, используя счетчик idx, который считает от вашего MSB до LSB, вы можете сделать:

...

elsif (current_state = COMPARE) then

  OutTemp(idx)     <= comparator;

  if idx > 0 then
    OutTemp(idx-1) <= '1';
    idx            <= idx - 1;
    next_state     <= current_state;
  else
    idx            <= MSB;
    next_state     <= idle;
  end if;
end if;

Это предполагает, что вы хотите установить OutTemp(idx-1) в предыдущее состояние, что кажется мне немного бессмысленным, но, возможно, это требуется для вашего внешнего оборудования...

Вы также продублировали свой OutTemp, назначив как сигнал, так и порт, я бы удалил все ваши назначения на порт DigitalOutTemp и вместо этого добавил следующее к вашему синхронизированному процессу:

process (clock)
begin

  if rising_edge(clock) then      
    Current_state <= Next_state;
    DigitalOutTemp <= OutTemp;
  end if;
end process;

Это установит DigitalOutTemp синхронно, если вы этого не хотите, вы можете вместо этого установить его вне тактового процесса, но я бы посоветовал вам установить его синхронно, чтобы избежать сбоев.

Чтобы ответить на ваш вопрос, окончательное состояние:

    ELSIF (Current_state = S_LSB) THEN
      IF (Comparator = '0') THEN
          DigitalOutTemp(0) <= '0';
          OutTemp(0) <= '0';
      END IF;

      DigitalOutFinal <= OutTemp;

      DigitalOutTemp <= "10000000000000";
      OutTemp <= "10000000000000";

      Next_state <= S_MSB;

    END IF;

.. просто установит DigitalOutTemp на "10000000000000" и DigitalOutFinal на то, что было в OutTemp в предыдущем состоянии. Похоже, вы ожидаете, что OutTemp будет обновлено присваиванием OutTemp(0) выше, но это не так. Присвоение OutTemp(0) запланировано на конец процесса и не отображается сразу.

Присвоения OutTemp(0) и DigitalOutTemp(0) в операторе IF ничего не сделают, так как их запланированные операции записи будут отменены вашими присваиваниями им ниже.

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

Надеюсь это поможет.

person Peter Bennett    schedule 29.10.2012