0

我正在尝试用 VHDL 为 ADC 编写一个逐次逼近寄存器。我正在把它变成一个状态机。我只是有点不确定我在最终状态块(current_state = S_LSB)中的代码。此代码有效吗?在返回状态一之前,有没有更好的方法来重置 DigitalOutTemp 和 OutTemp?

注意Comparator 的值取决于通过数模转换器后的 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;
4

1 回答 1

0

很难说出你的代码试图完成什么,所以我想我会做一些一般性的观察,可能会对你有所帮助。

您的代码中有很多不必要的重复,您可以通过使用计数器来索引您的位而不是在每个状态中使用硬编码索引来修复,例如使用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)IF 语句和IF 语句中的分配DigitalOutTemp(0)将不会执行任何操作,因为它们的预定写入会被您对它们的分配进一步取消。

因此,要回答您的问题,它看起来像是有效的代码,因为它可能会编译和合成,但它不会表现出您似乎期望的行为。

希望这可以帮助。

于 2012-10-29T10:30:41.927 回答