Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

Marble line

Altera_Forum
Honored Contributor II
1,752 Views

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
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
792 Views

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?
0 Kudos
Altera_Forum
Honored Contributor II
792 Views

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!
0 Kudos
Altera_Forum
Honored Contributor II
792 Views

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!
0 Kudos
Altera_Forum
Honored Contributor II
792 Views

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).
0 Kudos
Altera_Forum
Honored Contributor II
792 Views

Ok, 

I will try to do all that, hopefully things become more clear. 

I appreciate your help and patience, thank you.
0 Kudos
Reply