- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello everyone,
I am trying to make a marble line. I have red marbles and blue marbles and I basically want to fill in order an integer vector with the value 2 for blue marbles, 1 for red marbles and 0 for when there are no marbles. The way I want this to work is that I want to start with an empty line and, every time I press a button called redMarble, a red marble will go to the first empty space of this line and every time I press the blueMarble button, a blue marble will go to the first empty space available of the line. The vector that represent the line is called marbleLine, and I made it in a way that I can change its size if I want. Unfortunately though, I have not been able to get this right. I have gone through it over and over again but I can't find what I am doing wrong or another way to do what I want. The code I have so far is:
library IEEE;
use IEEE.std_logic_1164.all;
Entity Central is
generic (N: integer := 9);
port(
redMarble, blueMarble: in std_logic;
-- outLine is here just for tests
outLine: out std_logic_vector(N downto 0)
);
end Central;
architecture archC of Central is
type Vector is array (N downto 0) of integer range 0 to 2;
signal marbleLine : Vector;
begin
process(redMarble, blueMarble) is
variable alreadyFoundFirstZero: std_logic;
begin
alreadyFoundFirstZero := '0';
if(rising_edge(redMarble)) then
-- Here I will look for the first empty space, or 0, in the marbleLine
for i in 0 to N loop
if(alreadyFoundFirstZero = '0') then
if(marbleLine(i) = 0) then
marbleLine(i) <= 1;
alreadyFoundFirstZero := '1';
end if;
end if;
end loop;
end if;
alreadyFoundFirstZero := '0';
if(rising_edge(blueMarble)) then
for i in 0 to N loop
if(alreadyFoundFirstZero = '0') then
if(marbleLine(i) = 0) then
marbleLine(i) <= 2;
alreadyFoundFirstZero := '1';
end if;
end if;
end loop;
end if;
end process;
-- Testing Output
process(marbleLine) is
begin
for i in 0 to N loop
if (marbleLine(i)= 1) then
outLine(i) <= '1';
end if;
if (marbleLine(i)= 2) then
outLine(i) <= '0';
end if;
end loop;
end process;
end archC;
With this code I am getting multiple erros of the kind: Error (10821): HDL error at Central.vhd(34): can't infer register for "marbleLine[0][0]" because its behavior does not match any supported register model and Error (10820): Netlist error at Central.vhd(34): can't infer register for marbleLine[1][0] because its behavior depends on the edges of multiple distinct clocks Does anyone know how to fix these problems, or even, how to make this possible in a different way? Thank you all in advance, Stomp
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An FPGA register cannot be clocked from multiple sources. I suggest you have a system clock running and then use redMarble and blueMarble as clock enables.
Did you write a testbench for your code?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I will try that!
I didn't write one, I am trying to make it work first. But basically I plan to press redMarble and blueMarble a few times and see if marbleLine is filled in the correct order. I will come back here once I am done. Thanks a lot!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Okay, now I could compile it!
I didn't get the output I was expecting though. Here is the code:
library IEEE;
use IEEE.std_logic_1164.all;
Entity Central is
generic (N: integer := 9);
port(
clock, redMarble, blueMarble: in std_logic;
outLine: out std_logic_vector(N downto 0)
);
end Central;
architecture archC of Central is
type Vector is array (N downto 0) of integer;
signal marbleLine : Vector;
begin
process(redMarble, blueMarble) is
variable alreadyFoundFirstZero: std_logic;
begin
alreadyFoundFirstZero := '0';
if(rising_edge(clock)) then
if(redMarble = '1' and blueMarble = '0') then
-- Here I will look for the first empty space, or 0, in the marbleLine
for i in 0 to N loop
if(alreadyFoundFirstZero = '0') then
if(marbleLine(i) = 0) then
marbleLine(i) <= 1;
alreadyFoundFirstZero := '1';
end if;
end if;
end loop;
elsif(redMarble = '0' and blueMarble = '1')then
for i in 0 to N loop
if(alreadyFoundFirstZero = '0') then
if(marbleLine(i) = 0) then
marbleLine(i) <= 2;
alreadyFoundFirstZero := '1';
end if;
end if;
end loop;
end if;
end if;
end process;
-- Testing Output
process(marbleLine) is
begin
for i in 0 to N loop
if (marbleLine(i)= 1) then
outLine(i) <= '1';
end if;
if (marbleLine(i)= 2) then
outLine(i) <= '0';
end if;
end loop;
end process;
end archC;
I don't know if it is possible to use an integer vector as an output so I decided to make a std_logic_vector and use 1 for redMarble (marbleLine = 1) and 0 for blueMarble (marbleLine = 2) and empty spaces (marbleLine = 0). I am so sorry for this super clumsy test but this was as much as I had time to do right now. Here is what I got: https://www.alteraforum.com/forum/attachment.php?attachmentid=8129 Am I doing anything stupidly wrong and not noticing? Thanks again!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You should write a testbench - the testbench will help you debug it without having to go to hardware (it is much harder to debug on hardware).
You need to make your process sensitive to clock, not red/blueMarble. Be aware that for loops will unroll into the worst case hardware. So for your code, it is a long chain of 2:1 muxes. Other points to note: Using integers makes the values 32 bit. You probably want to limit the range to limit the bit-width (the synthesisor may trim this for you). You can use an integer array as an output, but I wouldnt do it for the top level, as you would need to map all the bits to pins on the chip. In VHDL you have no direct access to the bits in an integer (they dont exist in VHDL, the synthesisor maps them for you) so its best to go with some std_logic array type (usually std_logic_vector or signed or unsigned).- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok,
I will try to do all that, hopefully things become more clear. I appreciate your help and patience, thank you.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page