【问题标题】:VHDL - how to detect and output correct priorityVHDL - 如何检测和输出正确的优先级
【发布时间】:2018-05-04 07:50:59
【问题描述】:

目前,我正在使用 VHDL 开发停车场系统。

目标很简单。停车时,它会查看所有可用位置并输出下一个空闲位置。看起来很简单,但我在让它正常工作时遇到了一些问题。

我正在使用板上的开关并检测开关何时打开。这表示天气是否有车停在那里。

目标是我可以点击例如开关 1、开关 2 和开关 4,直到输出 3 作为可用位置。然后,如果我打开 3,它会重新计算并说 5 是下一个可用位置。

为了实现这一点,我使用了一堆 if else 语句,但发生的情况是,例如,如果我按下 #4 开关,它会正确显示 5,但是一旦我按下 #5 开关,它将继续显示 5 作为下一个可用位置,而不是 6。

我认为我的问题是我没有足够的条件来涵盖所有场景。有没有办法让我用更短的方式写这个?

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

entity Priority is
port(
    SWITCH: in std_logic_vector (8 downto 0);
    H1: out std_logic_vector (3 downto 0);
    H2: out std_logic_vector (3 downto 0);
    H3: out std_logic_vector (3 downto 0);
    H4: out std_logic_vector (3 downto 0)
);
end Priority;

architecture Behavioral of Priority is

begin 
process (SWITCH)
begin

if (SWITCH(0) = '1' AND SWITCH(1) = '1' AND SWITCH(2) = '1' AND SWITCH(3) = '1' AND SWITCH(4) = '1' AND SWITCH(5) = '1' AND SWITCH(6) = '1' AND SWITCH(7) = '1')   then  --if all switches are on, display "FULL"


H1 <= "1100";
H2 <= "1100";
H3 <= "1011";
H4 <= "1010";


elsif SWITCH(0) = '1' then  --if switch 0 is turned on, show "PS-1"

H1 <= "1101";
H2 <= "1110";
H3 <= "1111";
H4 <= "0010";



elsif SWITCH(1) = '1' then  --if switch 1 is turned on, show "PS-2"

H1 <= "1101";
H2 <= "1110";
H3 <= "1111";
H4 <= "0011";



elsif SWITCH(2) = '1' then  

H1 <= "1101";
H2 <= "1110";
H3 <= "1111";
H4 <= "0100";



elsif SWITCH(3) = '1' then  

H1 <= "1101";
H2 <= "1110";
H3 <= "1111";
H4 <= "0101";



elsif SWITCH(4) = '1' then  

H1 <= "1101";
H2 <= "1110";
H3 <= "1111";
H4 <= "0110";



elsif SWITCH(5) = '1' then  

H1 <= "1101";
H2 <= "1110";
H3 <= "1111";
H4 <= "0111";


elsif SWITCH(6) = '1' then  

H1 <= "1101";
H2 <= "1110";
H3 <= "1111";
H4 <= "1000";



elsif SWITCH(7) = '1' then  

H1 <= "1101";
H2 <= "1110";
H3 <= "1111";
H4 <= "0001";


end if;
--end if;

end process;

end Behavioral;

【问题讨论】:

  • 您的代码中没有算术运算,那么为什么要包含非标准化包STD_LOGIC_ARITH 和STD_LOGIC_UNSIGNED?你应该删除它们。如果您决定添加算术,请使用标准化包numeric_std。
  • 我还有其他使用这些软件包的 vhdl 代码,所以为了安全起见,我将它们包括在内。我不需要这样做吗?即使我将它们与顶级文件连接起来,每个 vhdl 文件是否都是单独的?
  • 您的读者如何理解 ...显示 5 作为下一个可用位置,而不是 6 就您的代码而言? H1 - H4 是什么意思?你模拟过吗?
  • H1 - H4 是我板上的四个七段显示器。我正在做的是,例如,如果 #one spot ,板将显示 PS-1 如果它已满,板将在板上的七段显示器中显示 FULL。

标签: vhdl encoder


【解决方案1】:

好的,所以如果以后有人和我有同样的问题,我就是这样解决的。

我说我有一个有 8 个停车位的停车场,我需要知道什么时候有停车位。我做错的是我正在检测汽车何时来并试图找到下一个可用的位置。馊主意。发生的情况是每个停车位有很多组合的可能性(8 X 8 所以总共 64 个组合),除非你把它们写出来,否则完全不值得。

执行此操作的更好方法是检测何时没有汽车。这样,最高优先级将始终处于活动状态,因此无论他们停在哪里,只要他们没有停在优先级,它将继续是优先级。如果他们确实停在优先位置,那么它会寻找下一个没有车的位置,而不是有车的位置并试图找到合适的优先位置。我在这里有意义吗?我希望我是。

这就是我在代码形式中的意思。

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;

ENTITY Priority IS     PORT
(  switch:     IN    STD_LOGIC_VECTOR(8 DOWNTO 0);
   H1:     out std_logic_vector (3 downto 0);
   H2:     out std_logic_vector (3 downto 0);
   H3:     out std_logic_vector (3 downto 0);
   H4:     out std_logic_vector (3 downto 0)
    );
END Priority;

ARCHITECTURE behavioral OF Priority IS
BEGIN
--SIGNAL Sel : STD_LOGIC;    
Process(switch)

BEGIN


    if switch(7 downto 0) = "11111111" then

     H4<= "1010";
     H3<= "1011";    
     H2<= "1100";    
     H1<= "1100";    

    elsif switch(0) = '0' then
     H4<= "0001";
     H3<= "1111";    
     H2<= "1110";    
     H1<= "1101";

    elsif switch(1) = '0' then
     H4<= "0010" ;
     H3<= "1111";    
     H2<= "1110";    
     H1<= "1101";

    elsif switch(2) = '0' then
     H4<= "0011" ;
     H3<= "1111";    
     H2<= "1110";    
     H1<= "1101";

    elsif switch(3) = '0' then
     H4<= "0100" ;
     H3<= "1111";    
     H2<= "1110";    
     H1<= "1101";

    elsif switch(4) = '0' then
     H4<= "0101";
     H3<= "1111";    
     H2<= "1110";    
     H1<= "1101";

    elsif switch(5) = '0' then
     H4<= "0110";
     H3<= "1111";    
     H2<= "1110";    
     H1<= "1101";

    elsif switch(6) = '0' then
     H4<= "0111";
     H3<= "1111";    
     H2<= "1110";    
     H1<= "1101";

    elsif switch(7) = '0' then
     H4<= "1000";
     H3<= "1111";    
         H2<= "1110";    
     H1<= "1101";

    else
     H4<= "0000";     
     H3<= "1111";    
     H2<= "1110";    
     H1<= "1101";
    end if;

    end process;

END Behavioral;

如果二进制文件对您没有意义,请不要担心。只需看一下 h4 的二进制文件。当所有开关都为 1 时,则显示 FULL。如果开关 1 处于关闭状态,它会显示 1。因此,只要开关 1 处于关闭状态,它就会继续显示 1。如果它上升,它会移动到下一个并检查它是否可用。就是这样。

【讨论】:

    【解决方案2】:

    我建议使用循环遍历 SWITCH 输入并检测第一个空点。这使您的代码也更加通用,即使用循环结构而不是 if-else 语句来支持数百个停车位更容易。

    process(switch)
        variable v_empty_slot : integer;
    begin
        v_empty_slot := -1; --default value
    
        for i in SWITCH'low to SWITCH'high loop
            if SWITCH(i)='0' then
                v_empty_slot := i;
                exit;
            end if;
        end loop;
    
        --add code here to map v_empty_slot to H1,H2,H3,H4
    
    end process;
    

    注意:我还没有验证代码 sn-p。

    【讨论】:

    • 映射 v_empty_slot?对不起,但我是 VHDL 世界的新手。我正在改变的输出将是 H4,那么我将如何去做呢?如果我有那个例子(如果你不介意的话),我可以手动完成剩下的工作
    • @TheRealPdGaming 您必须添加将 v_empty_slot 中的整数值转换为 std_logic_vector(3 downto 0) 的代码,因为 H4 需要它。从您的示例中,我无法理解您对 H4 值的编码,因此找到合适的转换/映射取决于您:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    • 2011-10-27
    相关资源
    最近更新 更多