【问题标题】:VHDL - if < statement not workingVHDL - if < 语句不起作用
【发布时间】:2017-01-22 22:59:09
【问题描述】:

我正在尝试开发自动驾驶汽车。我有一个传感器,可以计算我们汽车车轮的圈数。当圈数达到特定输入数时,它应该改变状态,但 if 语句似乎不起作用。它不比较两个数字,而是进入 else 语句,直到输入的 vueltas 全部为“1”。如果我更改代码并编写 if (vueltas

注意:vueltas = 西班牙语中的圈数

            library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    --use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    entity Circuito is Port (
        clk : in STD_LOGIC;
        ir1 : in STD_LOGIC;
        ir2 : in STD_LOGIC;
        moverCoche : in STD_LOGIC;
        angulo : in STD_LOGIC_VECTOR(4 downto 0);
        vMaxCurva : in STD_LOGIC_VECTOR(4 downto 0);
        posInicial : in STD_LOGIC_VECTOR(9 downto 0);
        vueltasCurva : in STD_LOGIC_VECTOR(9 downto 0);
        vueltasRecta : in STD_LOGIC_VECTOR(9 downto 0);
        obst : in STD_LOGIC;
        servoOut : out STD_LOGIC;
        motorOut : out STD_LOGIC;
        vueltasLed : out STD_LOGIC_VECTOR(9 downto 0);
        vueltasDentroDeCircuito : out STD_LOGIC_VECTOR(11 downto 0);
        revolucionesPorSeg : out STD_LOGIC_VECTOR(11 downto 0));
    end Circuito;

    architecture Behavioral of Circuito is

        component motor_pwm_clk32kHz is Port (
            clk     : in  STD_LOGIC;
            entrada : in  STD_LOGIC_VECTOR(4 downto 0);
            salida  : out STD_LOGIC);
        end component;

        component servo_pwm_clk32kHz is Port (
            clk   : in  STD_LOGIC;
            pos   : in  STD_LOGIC_VECTOR(4 downto 0);
            servo : out STD_LOGIC);
        end component;

        component Contador_Vueltas is Port ( 
            out1 : in STD_LOGIC; --Negro: 1  Blanco: 0
            out2 : in STD_LOGIC; --Negro: 1  Blanco: 0
            vueltas : out STD_LOGIC_VECTOR (9 downto 0);
            rst : in STD_LOGIC;
            clk : in STD_LOGIC);
        end component;

        component revoluciones is Port (
            clk : in STD_LOGIC;
            vueltasDentroDeCircuito : in STD_LOGIC_VECTOR(11 downto 0);
            revoluciones : out STD_LOGIC_VECTOR(11 downto 0));
        end component;

        signal posServo, posMotor: STD_LOGIC_VECTOR(4 downto 0);

        signal vueltas : STD_LOGIC_VECTOR(9 downto 0);
        signal primeraVuelta : STD_LOGIC := '1';
        signal sigReiniciarVueltas : STD_LOGIC;
        signal sigVueltasDentroDeCircuito : STD_LOGIC_VECTOR(11 downto 0);
        signal sigVueltasInicioEstado : STD_LOGIC_VECTOR(11 downto 0);
        --signal sigVueltasRecta : unsigned := to_integer(unsigned(vueltasRecta));
        --constant sigVueltasRecta : STD_LOGIC_VECTOR(9 downto 0) := "0000011110";
        --constant sigVueltasCurva : STD_LOGIC_VECTOR(9 downto 0) := "0000011110";
        signal flag : STD_LOGIC := '0';

        signal Qt: STD_LOGIC_VECTOR(3 downto 0);
        SUBTYPE STATE_TYPE IS STD_LOGIC_VECTOR(3 downto 0);
        SIGNAL STATE: STATE_TYPE;
        CONSTANT s0 : STATE_TYPE := "0000";
        CONSTANT s1 : STATE_TYPE := "0001";
        CONSTANT s2 : STATE_TYPE := "0010";
        CONSTANT s3 : STATE_TYPE := "0011";
        CONSTANT s4 : STATE_TYPE := "0100";
        CONSTANT s5 : STATE_TYPE := "0101";
        CONSTANT s6 : STATE_TYPE := "0110";
        CONSTANT s7 : STATE_TYPE := "0111";
        CONSTANT s8 : STATE_TYPE := "1000";

    begin

        UUT_Motor: motor_pwm_clk32kHz Port Map (
           clk => clk,
           entrada => posMotor,
           salida => motorOut);

        UUT_Servo: servo_pwm_clk32kHz Port Map (
           clk => clk,
           pos => posServo,
           servo => servoOut);

        UUT_ContadorVueltas: Contador_Vueltas Port Map (
           clk => clk,
           rst => sigReiniciarVueltas,
           vueltas => vueltas,
           out1 => ir1,
           out2 => ir2);

        UUT_Revoluciones: revoluciones Port Map(
           clk => clk,
           vueltasDentroDeCircuito => sigVueltasDentroDeCircuito,
           revoluciones => revolucionesPorSeg
        );

        process(clk, moverCoche)
        begin
            if (moverCoche = '0') then 
                Qt <= s0;
                sigReiniciarVueltas <= '1';
                sigVueltasDentroDeCircuito <= (others => '0');
                posServo <= "10000";
                posMotor <= "10000";
            elsif (clk'event and clk = '1') then 
                case Qt is
                --Quieto
                when s0 =>
                    posServo <= "10000";
                    posMotor <= "10000";
                    sigReiniciarVueltas <= '0';
                    Qt <= s1;
                --Recta1
                when s1 =>
                    sigReiniciarVueltas <= '0';
                    posServo <= "10000";
                    posMotor <= vMaxCurva;    --Min: 10011
                    sigVueltasDentroDeCircuito <= ("00" & vueltas);
                    if (unsigned(vueltas) >= unsigned(vueltasRecta)) then
                        Qt <= s2;
                        sigReiniciarVueltas <= '1';
                    elsif (obst = '1') then
                        Qt <= s8;
                    else
    --                  sigVueltasRecta <= vueltasRecta;          
                        Qt <= s1;                 
                    end if;
                -- Curva1
                when s2 =>
                    sigReiniciarVueltas <= '0';
                    posServo <= angulo;
                    posMotor <= vMaxCurva;
                    sigVueltasDentroDeCircuito <= posInicial + ("00" & vueltas);
                    if (unsigned(vueltas) >= unsigned(vueltasCurva)) then
                        sigReiniciarVueltas <= '1';
                        Qt <= s3;
                    elsif (obst = '1') then
                        Qt <= s8;
                    else 
                        Qt <= s2;
                    end if;
                --Recta2
                when s3 =>
                    sigReiniciarVueltas <= '0';
                    posServo <= "10000";
                    posMotor <= vMaxCurva;    --Min: 10011
                    sigVueltasDentroDeCircuito <= posInicial + vueltasCurva + ("00" & vueltas);
                    if (unsigned(vueltas) >= unsigned(vueltasRecta)) then
                        sigReiniciarVueltas <= '1';
                        Qt <= s4;
                    elsif (obst = '1') then
                        Qt <= s8;
                    else 
                        Qt <= s3;
                    end if;
                --Curva2
                when s4 =>
                    sigReiniciarVueltas <= '0';
                    posServo <= angulo;
                    posMotor <= vMaxCurva;
                    sigVueltasDentroDeCircuito <= posInicial + vueltasCurva + vueltasRecta + ("00" & vueltas);
                    if (unsigned(vueltas) >= unsigned(vueltasCurva)) then
                        sigVueltasDentroDeCircuito <= (others => '0');
                        sigReiniciarVueltas <= '1';
                        Qt <= s4;
                    elsif (obst = '1') then
                        Qt <= s8;
                    else
                        Qt <= s1;
                    end if;

                --Mantener Quieto
                when s5 =>
                    posMotor <= "10000";
                    Qt <= s5;

                when others =>
                    if(obst = '1') then
                        posMotor <= "00000";
                        --sigReiniciarVueltas <= '0';
                        Qt <= s8;
                    else
                        Qt <= s1;
                    end if;
                end case;
                vueltasDentroDeCircuito <= sigVueltasDentroDeCircuito;
                vueltasLed <= vueltasRecta;
            end if;
        end process;
    end Behavioral;

【问题讨论】:

标签: if-statement integer signals vhdl


【解决方案1】:

虽然可以对std_logic_vector 执行算术比较(在本例中为&lt;),但这可能不是最佳做法,因为不知道基础值是有符号还是无符号。如果您需要进行任何算术或比较,请使用 numeric_std 包中的 unsignedsigned 类型。

发现一个很好的讨论here

【讨论】:

  • 还是不行。它仍然做同样的事情。我已经更改了代码,我还能做其他更改吗?
  • @ainhoarru 这不是真的。虽然您通常无法使用 std_logic_vector 进行算术运算,但您可以将 std_logic_vector&lt; 和类似的运算符进行比较。但是,如果向量的长度不同,您应该小心 - 您会得到奇怪的结果。
  • @MatthewTaylor 我编辑了我的答案以反映您的评论。虽然您说可以对 SLV 进行算术比较是正确的,但我认为这不是一个好的设计实践
  • @ainhoarru 正如 user1155120 指出的那样,如果没有 MCVE,就很难重现您遇到的问题 - 我现在只是在猜测
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-16
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多