VHDL可能在组合代码中产生信号误解

时间:2014-02-24 11:23:38

标签: vhdl fpga

我的代码旨在纯粹是组合。只有一个元素为模拟提供了一些同步。它是一个4 * 4的led矩阵,只有3 * 3(从右上角开始)有效。喜欢:

--        LED matrix
-- rows\cols | A    | B | C | D |
---------------------------------
--  1        | 3    | 2 | 1 | 0 |
--  2        | 7    | 6 | 5 | 4 |
--  3        | 11   | 10| 9 | 8 |

--  4        | 15   | 14| 13| 12|   <- row not used

--             ^
--             |
--      column not used
---------------------------------

以下代码在FPGA上编译和模拟但不具有所需的行为。如果检测到一个输入,则想要的行为是照亮红色LED,如果是2则是2,如果3在矩阵中同时连续而不是3个红色LED则应显示3个蓝色。没有记忆。观察到的行为被解释为代码中的内容。

entity mt is
    PORT ( 
    cD, cC, cB, cA : in std_logic;  -- comparators for each column. cA is not necessary / not used.
    row : inout std_logic_vector (3 downto 0) := (others => '0'); -- detection of each row.
    led_R, led_G, led_B : out std_logic_vector (15 downto 0) := (others => '1')  -- '1' indicates they are OFF. 12 to 15 will not be used (as well as 3, 7, 11 positions)
    );
end mt;

我有4个并发进程,这取决于所解释的信号:

architecture arc1 of mt is

signal led_R_in : std_logic_vector (15 downto 0) := (others => '1');
signal led_G_in : std_logic_vector (15 downto 0) := (others => '1'); -- don't think they are necessary
signal led_B_in : std_logic_vector (15 downto 0) := (others => '1'); -- don't think they are necessary
signal counter : std_logic_vector (1 downto 0) := "00";

begin

PROCESS (row, cD, cC, cB, cA)  -- execute if any of these change
BEGIN
    CASE row IS 
    WHEN "1000" => -- row 1 --
        -- (LEDs are active at logic level 0)
        CASE cD IS
            WHEN '1' => led_R_in(0) <= '0'; led_G_in(0) <= '1'; led_B_in(0) <= '1';
            WHEN OTHERS => led_R_in(0) <= '1'; led_G_in(0) <= '1'; led_B_in(0) <= '1';
        END CASE;
        CASE cC IS
            WHEN '1' => led_R_in(1) <= '0'; led_G_in(1) <= '1'; led_B_in(1) <= '1';
            WHEN OTHERS => led_R_in(1) <= '1'; led_G_in(1) <= '1'; led_B_in(1) <= '1';
        END CASE;
        CASE cB IS
            WHEN '1' => led_R_in(2) <= '0'; led_G_in(2) <= '1'; led_B_in(2) <= '1';
            WHEN OTHERS => led_R_in(2) <= '1'; led_G_in(2) <= '1'; led_B_in(2) <= '1';
        END CASE;
        CASE cA IS  -- not necessary
            WHEN '1' => led_R_in(3) <= '0'; led_G_in(3) <= '1'; led_B_in(3) <= '1';
            WHEN OTHERS => led_R_in(3) <= '1'; led_G_in(3) <= '1'; led_B_in(3) <= '1';
        END CASE;

    WHEN "0100" => -- row 2 --
        -- (LEDs are active at logic level 0)
        CASE cD IS
            WHEN '1' => led_R_in(4) <= '0'; led_G_in(4) <= '1'; led_B_in(4) <= '1';
            WHEN OTHERS => led_R_in(4) <= '1'; led_G_in(4) <= '1'; led_B_in(4) <= '1';
        END CASE;
        CASE cC IS
            WHEN '1' => led_R_in(5) <= '0'; led_G_in(5) <= '1'; led_B_in(5) <= '1';
            WHEN OTHERS => led_R_in(5) <= '1'; led_G_in(5) <= '1'; led_B_in(5) <= '1';
        END CASE;
        CASE cB IS
            WHEN '1' => led_R_in(6) <= '0'; led_G_in(6) <= '1'; led_B_in(6) <= '1';
            WHEN OTHERS => led_R_in(6) <= '1'; led_G_in(6) <= '1'; led_B_in(6) <= '1';
        END CASE;
        CASE cA IS  -- not necessary
            WHEN '1' => led_R_in(7) <= '0'; led_G_in(7) <= '1'; led_B_in(7) <= '1';
            WHEN OTHERS => led_R_in(7) <= '1'; led_G_in(7) <= '1'; led_B_in(7) <= '1';
        END CASE;

    WHEN "0010" => -- row 3 --
        -- (LEDs are active at logic level 0)
        CASE cD IS
            WHEN '1' => led_R_in(8) <= '0'; led_G_in(8) <= '1'; led_B_in(8) <= '1';
            WHEN OTHERS => led_R_in(8) <= '1'; led_G_in(8) <= '1'; led_B_in(8) <= '1';
        END CASE;
        CASE cC IS
            WHEN '1' => led_R_in(9) <= '0'; led_G_in(9) <= '1'; led_B_in(9) <= '1';
            WHEN OTHERS => led_R_in(9) <= '1'; led_G_in(9) <= '1'; led_B_in(9) <= '1';
        END CASE;
        CASE cB IS
            WHEN '1' => led_R_in(10) <= '0'; led_G_in(10) <= '1'; led_B_in(10) <= '1';
            WHEN OTHERS => led_R_in(10) <= '1'; led_G_in(10) <= '1'; led_B_in(10) <= '1';
        END CASE;
        CASE cA IS  -- not necessary
            WHEN '1' => led_R_in(11) <= '0'; led_G_in(11) <= '1'; led_B_in(11) <= '1';
            WHEN OTHERS => led_R_in(11) <= '1'; led_G_in(11) <= '1'; led_B_in(11) <= '1';
        END CASE;
    WHEN OTHERS => Null; -- not necessary, although for avoiding latches creation I will have to assign them.
    END CASE;
END PROCESS;

PROCESS (led_R_in)  -- executes when led_R_in changes
BEGIN
    -- leds are ON at '0' value
    -- the problem is that, when initialising, the first row of leds will be blue, which means that
    -- led_R_in 0, 1, 2 are 0, but they should be 1 as stated in their default values
    -- the second and third row initialises correctly to green values, although the response to changes in the inputs are not only affecting them but also their neighbours, which I think it could be a problem of the FPGA pin assignment.
    if (led_R_in(0)='0' AND ((led_R_in(1)='0' AND led_R_in(2)='0') OR (led_R_in(4)='0' AND led_R_in(8)='0') OR (led_R_in(5)='0' AND led_R_in(10)='0'))) then
        led_B(0) <= '0';
        led_R(0) <= '1';
        led_G(0) <= '1';
    else
        led_R(0) <= led_R_in(0);
        led_G(0) <= '0';
        led_B(0) <= '1';
    end if;
    if (led_R_in(1)='0' AND ((led_R_in(0)='0' AND led_R_in(2)='0') OR (led_R_in(5)='0' AND led_R_in(9)='0'))) then
        led_B(1) <= '0';
        led_R(1) <= '1';
        led_G(1) <= '1';
    else
        led_R(1) <= led_R_in(1);
        led_G(1) <= '0';
        led_B(1) <= '1';
    end if;
    if (led_R_in(2)='0' AND ((led_R_in(0)='0' AND led_R_in(1)='0') OR (led_R_in(10)='0' AND led_R_in(6)='0') OR (led_R_in(5)='0' AND led_R_in(8)='0'))) then
        led_B(2) <= '0';
        led_R(2) <= '1';
        led_G(2) <= '1';
    else
        led_R(2) <= led_R_in(2);
        led_G(2) <= '0';
        led_B(2) <= '1';
    end if;
    if (led_R_in(4)='0' AND ((led_R_in(0)='0' AND led_R_in(8)='0') OR (led_R_in(5)='0' AND led_R_in(6)='0'))) then
        led_B(4) <= '0';
        led_R(4) <= '1';
        led_G(4) <= '1';
    else
        led_R(4) <= led_R_in(4);
        led_G(4) <= '0';
        led_B(4) <= '1';
    end if;
    if (led_R_in(5)='0' AND ((led_R_in(2)='0' AND led_R_in(8)='0') OR (led_R_in(1)='0' AND led_R_in(9)='0') OR (led_R_in(0)='0' AND led_R_in(10)='0') OR (led_R_in(6)='0' AND led_R_in(4)='0'))) then
        led_B(5) <= '0';
        led_R(5) <= '1';
        led_G(5) <= '1';
    else
        led_R(5) <= led_R_in(5);
        led_G(5) <= '0';
        led_B(5) <= '1';
    end if;
    if (led_R_in(6)='0' AND ((led_R_in(2)='0' AND led_R_in(10)='0') OR (led_R_in(5)='0' AND led_R_in(4)='0'))) then
        led_B(6) <= '0';
        led_R(6) <= '1';
        led_G(6) <= '1';
    else
        led_R(6) <= led_R_in(6);
        led_G(6) <= '0';
        led_B(6) <= '1';
    end if;
    if (led_R_in(8)='0' AND ((led_R_in(2)='0' AND led_R_in(5)='0') OR (led_R_in(4)='0' AND led_R_in(0)='0') OR (led_R_in(9)='0' AND led_R_in(10)='0'))) then
        led_B(8) <= '0';
        led_R(8) <= '1';
        led_G(8) <= '1';
    else
        led_R(8) <= led_R_in(8);
        led_G(8) <= '0';
        led_B(8) <= '1';
    end if;
    if (led_R_in(9)='0' AND ((led_R_in(1)='0' AND led_R_in(5)='0') OR (led_R_in(10)='0' AND led_R_in(8)='0'))) then
        led_B(9) <= '0';
        led_R(9) <= '1';
        led_G(9) <= '1';
    else
        led_R(9) <= led_R_in(9);
        led_G(9) <= '0';
        led_B(9) <= '1';
    end if;
    if (led_R_in(10)='0' AND ((led_R_in(9)='0' AND led_R_in(8)='0') OR (led_R_in(5)='0' AND led_R_in(0)='0') OR (led_R_in(6)='0' AND led_R_in(2)='0'))) then
        led_B(10) <= '0';
        led_R(10) <= '1';
        led_G(10) <= '1';
    else
        led_R(10) <= led_R_in(10);
        led_G(10) <= '0';
        led_B(10) <= '1';
    end if;
END PROCESS;

PROCESS  -- executes at the beginning (when is equal to "00") and changes its value every 10 ms
BEGIN
    counter <= counter + "01";  -- there is an intended combinational loop here, so that it does this forever changing the row.
    WAIT for 10 ms;  
END PROCESS;

PROCESS (counter) -- executes at the beginning (when is equal to "00") and when counter changes (every 10 ms)
BEGIN
    CASE counter IS
        WHEN "00" => row <= "1000";
        WHEN "01" => row <= "0100";
        WHEN "10" => row <= "0010";
        WHEN OTHERS => Null;  -- for avoiding the automatic generation of latches due to non existing assignments. although it could also be row <= "0001"
    END CASE;
END PROCESS;

END arc1;

为什么不能处理我想要的行为?

0 个答案:

没有答案