我的代码旨在纯粹是组合。只有一个元素为模拟提供了一些同步。它是一个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;
为什么不能处理我想要的行为?