【问题标题】:VHDL Changing and holding the signal in if statementVHDL 在 if 语句中更改和保持信号
【发布时间】:2019-11-23 08:21:54
【问题描述】:

我对 VHDL 非常陌生,我有一个指定的项目要做。基本上我的目标是显示2个数字并在开关的帮助下减去和添加它们。 (在 FPGA 板上)

例如: 假设我有一个位值为 9 和 B 为 2 的信号 A,每当我打开开关时,它都会操作 AB 并显示 7。问题是,当我关闭开关时,我得到的是 9 而不是 7。(它没有t 保持值)我想要的是通过打开和关闭同一个开关来显示所有减法结果:9,7,5,3,1

到目前为止我做了什么:

  1. 我为七段显示器编写了一个解码器
  2. 我有一个 5 位位片加法器减法器实现
  3. 在我的主模块中,我将它们作为组件和实例化
  4. 在主模块中,我有我声明的两个数字的信号 作为我的位片实例的输入值
  5. 在此过程中,我为信号(9 和 2)分配了默认值
  6. 在 if 语句中,我将信号 A 分配给结果 信号(逐位分配给加减法器实例)并将七段的信号分配给结果。

当我打开开关时它可以工作,但是当我关闭开关时默认值保持不变。如何每次都用结果更新 A 的值?

我的代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity main is

    Port ( 
              S : in  STD_LOGIC_VECTOR (1 downto 0);
           Cin : in  STD_LOGIC;
              Cout: out STD_LOGIC;
              StartGameSwitch : IN std_logic;
              SevenSegControl : OUT std_logic_vector(7 downto 0):=x"ff";
              SevenSegBus : OUT std_logic_vector(7 downto 0);
              clk : IN std_logic);
end main;


architecture Behavioral of main is

--COMPONENTS-------------------------------------------------------------------------------------------------------

COMPONENT sevenSegment
    PORT(
        A : IN std_logic_vector(4 downto 0);
        B : IN std_logic_vector(4 downto 0);
        C : IN std_logic_vector(4 downto 0);
        D : IN std_logic_vector(4 downto 0);
        E : IN std_logic_vector(4 downto 0);
        F : IN std_logic_vector(4 downto 0);
        G : IN std_logic_vector(4 downto 0);
        H : IN std_logic_vector(4 downto 0);
        SevenSegControl : OUT std_logic_vector(7 downto 0);
        SevenSegBus : OUT std_logic_vector(7 downto 0);
        clk : IN std_logic          
        );
END COMPONENT;

COMPONENT logic
    PORT(
        A : IN std_logic;
        B : IN std_logic;
        COld : IN std_logic;
        S : IN std_logic_vector(1 downto 0);
        AG : IN std_logic;
        BG : IN std_logic;          
        CNew : OUT std_logic;
        NumberBit : OUT std_logic;
        negativeSign : OUT std_logic
        );
END COMPONENT;

COMPONENT comparator
    PORT(
        A : IN std_logic_vector(4 downto 0);
        B : IN std_logic_vector(4 downto 0);          
        AG : OUT std_logic;
        BG : OUT std_logic
        );
END COMPONENT;

--SIGNALS-------------------------------------------------------------------------------------------------------

signal sA,sB,sC,sD,sE,sF,sG,sH: std_logic_vector (4 downto 0) ;
signal logicLed,result,negativeSign,sevenSegmentResult,sevenSegmentNegativeSign: std_logic_vector (4 downto 0);
signal c0,c1,c2,c3,c4: std_logic;
signal AG,BG: std_logic;
signal HP1,HP2,ATK1,ATK2: std_logic_vector (4 downto 0);

--CONSTANTS-------------------------------------------------------------------------------------------------------

constant charO:std_logic_vector(4 downto 0):= "01010"; --10
constant charP:std_logic_vector(4 downto 0):= "01011"; --11
constant charE:std_logic_vector(4 downto 0):= "01100"; --12
constant charN:std_logic_vector(4 downto 0):= "01101"; --13
constant charF:std_logic_vector(4 downto 0):= "01110"; --14
constant charI:std_logic_vector(4 downto 0):= "01111"; --15
constant charG:std_logic_vector(4 downto 0):= "10000"; --16
constant charH:std_logic_vector(4 downto 0):= "10001"; --17
constant charT:std_logic_vector(4 downto 0):= "10010"; --18
constant charA: std_logic_vector(4 downto 0):= "10011";--19
constant char0:std_logic_vector(4 downto 0):= "00000";
constant char1:std_logic_vector(4 downto 0):= "00001";
constant char2:std_logic_vector(4 downto 0):= "00010";
constant char3:std_logic_vector(4 downto 0):= "00011";
constant char4:std_logic_vector(4 downto 0):= "00100";
constant char5:std_logic_vector(4 downto 0):= "00101";
constant char6:std_logic_vector(4 downto 0):= "00110";
constant char7:std_logic_vector(4 downto 0):= "00111";
constant char8:std_logic_vector(4 downto 0):= "01000";
constant char9:std_logic_vector(4 downto 0):= "01001";
constant charEmpty:std_logic_vector(4 downto 0):= "11111";

begin


--INSTANTIATIONS-------------------------------------------------------------------------------------------------------

    Inst_logic1: logic PORT MAP(
        A =>HP2(0) ,
        B =>ATK1(0) ,
        COld =>c0 ,
        CNew =>c1,
        NumberBit =>result(0) ,
        S =>S, 
        AG => AG,
        BG => BG,
        negativeSign => negativeSign(0)
    );

        Inst_logic2: logic PORT MAP(
        A =>HP2(1) ,
        B =>ATK1(1) ,
        COld =>c1 ,
        CNew =>c2,
        NumberBit =>result(1) ,
        S =>S, 
        AG => AG,
        BG => BG,
        negativeSign => negativeSign(1)
    );

        Inst_logic3: logic PORT MAP(
        A =>HP2(2) ,
        B =>ATK1(2) ,
        COld =>c2 ,
        CNew =>c3,
        NumberBit =>result(2) ,
        S =>S, 
        AG => AG,
        BG => BG,
        negativeSign => negativeSign(2)
    );

        Inst_logic4: logic PORT MAP(
        A =>HP2(3) ,
        B =>ATK1(3) ,
        COld =>c3 ,
        CNew =>c4,
        NumberBit =>result(3) ,
        S =>S, 
        AG => AG,
        BG => BG,
        negativeSign => negativeSign(3)
    );

        Inst_logic5: logic PORT MAP(
        A =>HP2(4) ,
        B =>ATK1(4) ,
        COld =>c4 ,
        CNew =>Cout,
        NumberBit =>result(4) ,
        S =>S, 
        AG => AG,
        BG => BG,
        negativeSign => negativeSign(4)
    );  

        Inst_comparator: comparator PORT MAP(
        A => HP2,
        B => ATK1,
        AG => AG,
        BG => BG
    );

--GAME LOGIC-------------------------------------------------------------------------------------------------------



process(StartGameSwitch)
begin


--DEFAULT VALUES FOR HP1,HP2,ATK1,ATK2--
-- I WANT HP1 AND HP2 TO CHANGE ACCORDING TO SWITCHES --
    HP2 <= char9;
    ATK1 <= char2;   
   HP1 <= char9;
    ATK2 <= char3;

    if(StartGameSwitch = '0') then -- OPEN P35 ON FPGA

            sA <= charO; -- s_ are the signals for the seven segment 
            sB <= charP;
            sC <= charE;
            sD <= charN;
            sE <= charEmpty;
            sF <= charP;
            sG <= char7;
            sH <= char8;

    else -- WHEN P35 IS OPENED ( WHEN THE GAME STARTS) 


            sA <= HP1; --HP POINT FOR P1
            sB <= charEmpty; 
            sC <= ATK1; --Attack POINT FOR P1
            sD <= charEmpty; 

            sE <= charEmpty; 
            sF <= ATK2; --Attack POINT FOR P2
            sG <= charEmpty; 
            sH <= HP2; --HP POINT FOR P2

            if(S = "01") then -- WHEN PLAYER 1 ATTACKS PLAYER 2 ( HP2 - ATK1 = RESULT (i.e 9-2 = 7))
                HP2 <= result; 
                sH <= HP2; -- When SWITCH IS OPEN, IT SHOWS 7 WITHOUT ANY PROBLEM
            end if;
    -- HOWEVER, WHEN THE SWITCH IS AGAIN BACK TO 00, sH displays 9 instead of 7, HOW CAN I SAVE THE VALUE OF HP2?

    end if;
end process;

-- SIGNALS ASSIGNED TO DISPLAY 
Inst_sevenSegment: sevenSegment PORT MAP(
        A =>sA, --1ST PLAYER HEALTH 
        B =>sB, -- 1ST PLAYER DMG
        C =>sC ,
        D =>sD ,
        E =>sE ,
        F =>sF ,
        G =>sG , -- 2ND PLAYER DMG
        H =>sH , --2ND PLAYER HEALTH
        SevenSegControl =>SevenSegControl ,
        clk => clk,
        SevenSegBus => SevenSegBus
    );

end Behavioral;

谢谢

【问题讨论】:

    标签: vhdl fpga


    【解决方案1】:

    问题出在你的游戏逻辑过程中。由于您的 HP 和 ATK 信号处于流程的最高级别,因此它们基本上一直连续分配给默认值。这种变化的唯一一次是当您打开开关并看到显示的预期结果时。当您再次关闭开关时,这些值将再次被分配其默认值,而不是保留之前的算术结果。

    如果您仅在触发StartGameSwitch(见下文)时将这些信号指定为默认值,那么您应该在使用开关时看到正确的显示。

    附带说明,您的过程敏感度列表不完整。您的过程中的逻辑取决于开关信号S,因此这应该包含在灵敏度列表中(如下所示)。合成并不重要,仅用于正确模拟您的代码。

    process(StartGameSwitch,S)
    begin
    
    
    --DEFAULT VALUES FOR HP1,HP2,ATK1,ATK2--
    -- I WANT HP1 AND HP2 TO CHANGE ACCORDING TO SWITCHES --
        --HP2 <= char9;
        --ATK1 <= char2;   
        --HP1 <= char9;
        --ATK2 <= char3;
    
        if(StartGameSwitch = '0') then -- OPEN P35 ON FPGA
    
                HP2 <= char9;  --Assign default values here instead
                ATK1 <= char2;   
                HP1 <= char9;
                ATK2 <= char3;
    
                sA <= charO; -- s_ are the signals for the seven segment 
                sB <= charP;
                sC <= charE;
                sD <= charN;
                sE <= charEmpty;
                sF <= charP;
                sG <= char7;
                sH <= char8;
    
        else -- WHEN P35 IS OPENED ( WHEN THE GAME STARTS) 
    

    【讨论】:

    • 非常感谢您的快速回复,现在价值保持不变。现在我应该继续下一个问题,即:我将 HP2 的值设置为新的值,这就是结果,并且我希望 HP2 的新值在我打开和关闭开关时一次又一次地减小,所以我需要的是 9-2 = 7 和 7-2= 5 等等。我该如何实现?即有没有办法用新值重复这个过程?
    • 您当前的逻辑应该已经允许这样做。下次切换开关时,应显示下一个较低的结果。
    • 是的,如果我仅将结果分配给 sH(即显示信号)时切换开关,它就会起作用。如果我将结果分配给 HP2,那么我猜它会不断计算新结果并显示无意义的值。如何阻止 HP2 连续变化,但只有在我切换开关时才会改变?
    • 您可以创建一个只允许更新一次的标志信号(即标志最初设置(允许更新)/开关移动到所需位置/标志信号状态检查/如果标志设置 HP2更新值并清除标志信号(不再允许更新),如果未设置标志,则不执行任何操作/当开关移回原始位置时重置标志以允许在开关移回正确位置时更新)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多