I know what the error means and why it's bad, but can't figure out how to do it in other way.
Can't resolve multiple constant drivers for net "snake[17]" at snake_driver.
(and others the same)
The assignment is that we have a "moving snake" in a std_logic_vector, which goes end-to-end, and when you press a button (toggle signal), the snake changes it's length (2, 3, 4, 5, 6, 2, ...)
Obviously, the snake vector must therefore be changed by both a process listening for toggle, and the one listening for clock. When I put both in the same process, I got an error that two edge detects can't be in the same process.
/\____ +--------------------+
toggle ----> change length |
| v |
| [snake register] =====> snake 17 downto 0
\/\/\/ | ^ |
clock ----> move one step |
+--------------------+
Any ideas welcome.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity snake_driver is
generic
(
LEN : integer := 18;
MAX_SNAKE_LEN : integer := 6
);
port
(
clk : in std_logic;
change : in std_logic;
output : out std_logic_vector(LEN-1 downto 0)
);
end snake_driver;
architecture Anaconda of snake_driver is
signal snake : std_logic_vector(LEN-1 downto 0) := (0 => '1', 1 => '1', others => '0'); -- two snake pieces
signal dir_right : boolean := FALSE; -- start left
begin
process(change)
variable data : std_logic_vector(LEN-1 downto 0); -- two snake pieces
variable snake_len : integer := 2; -- snake 2 long
begin
if rising_edge(change) then -- change snake length
-- add snake piece based on direction
data := snake; -- <-- here I tried to avoid the problem
-- by caching snake data. To no avail.
if snake_len = MAX_SNAKE_LEN then
snake_len := 2;
-- shorten to 2 len
if dir_right then
-- moving right, remove from left
data := std_logic_vector(unsigned(data) and shift_right(unsigned(data), MAX_SNAKE_LEN-2));
else
-- moving left, remove from right
data := std_logic_vector(unsigned(data) and shift_left(unsigned(data), MAX_SNAKE_LEN-2));
end if;
else
-- add one at the end
if dir_right then
-- moving right, add on left
data := std_logic_vector(unsigned(data) or shift_left(unsigned(data), 1));
else
-- moving left, add on right
data := std_logic_vector(unsigned(data) or shift_right(unsigned(data), 1));
end if;
end if;
snake <= data;
end if;
end process;
-- move snake on clock
process(clk)
-- variables in the process
variable data : std_logic_vector(LEN-1 downto 0);
begin
-- shift the snake
if rising_edge(clk) then
data := snake;
if dir_right then
-- right move
data(LEN-2 downto 0) := data(LEN-1 downto 1);
if data(0) = '1' then
dir_right <= FALSE; -- change direction
end if;
else
-- left move
data(LEN-1 downto 1) := data(LEN-2 downto 0);
if data(LEN-1) = '1' then
dir_right <= TRUE; -- change direction
end if;
end if;
snake <= data;
end if;
end process;
-- send changed data to output
output <= snake;
end Anaconda;
rising_edge()onclk. And on the other asynchronous signal, we simply usedchange = '1'. I know that's simple but maybe that could work? - Lucas Godoy