EmbDev.net

Forum: FPGA, VHDL & Verilog Need help with Simon(game) VHDL code


Author: Xabier Gandiaga (doctormckay)
Posted on:
Attached files:

Rate this post
0 useful
not useful
I'm kinda new to programming in VHDL so I need help with this.  I've 
gotta write a code that simulates an implementation for the Simon game 
for a Basys3 board(I'm using Vivado).  I've attached/uploaded what I've 
got so far(the code is written in Spanish but I've commented it in 
English so that you can understand what I'm trying to do in each part).

I am suppossed to only use one .vhd, so I've tried to use many "process" 
statements, although I'm not sure if I implemented them correctly.

The program goes like this:

We have 3 clocks, the main one that runs at 100MHz, and two others that 
I've created, slower than the main one of course.  These two clocks are 
used to set the values for a sequence that consists of four 2 bit buses, 
kinda giving the simon game a pseudo-random sequence to work with each 
time you turn the board on.

Once the sequence is set, "with select" statements at the bottom of the 
code read those buses and create arrays of bits that are used to turn 
the respective Leds on when I need it.

The game starts after a delay that gives time for the above mentioned 
processes "to complete"(I've made it so that the values of the buses can 
only be set once).
It should work as a normal Simon game:
1- A led turns on, the user presses the corresponding button, if he gets 
it right he continues to the next level.
2- The same led turns on, another led turns on, user interaction, user 
interaction...
3- If the user gets the whole sequence right he wins and the segmented 
display shows something.
4- If the user misses he loses and the displays shows something.
* You cannot restart the program while running, you have restart the 
board.

I would like you to check if the program does what I say it does, cuz 
I've been programming it onto the hardware but it does not work, you 
instantly lose, no delays, no nothing.
I've tried simulating it and it asigns the values of the buses correctly 
and enters the first state of the game(where the first Led should turn 
on) after the corresponding delay.
The only warnings Vivado gives me talk about the sensitivity lists of 
the processes("something like, "X is read in the process but is not in 
the sensitivity list"), but I do not see why it should affect my game at 
all.  It should work with "clock" as the only sensitivity.
Synth, Implementation and Bitstream give no errors.
PLS HELP

Author: Xabier Gandiaga (doctormckay)
Posted on:

Rate this post
0 useful
not useful
I forgot to mention it, I live in GMT+1.  I'm posting this at 3:00am. 
I'll try to answer ASAP but I'll be AFK for about 8 hours.

Author: EverTrueGate (Guest)
Posted on:

Rate this post
1 useful
not useful
First add all inputs, for which Vivado warns you, about not being in the 
sensitivity list, to the sensitivity list.

You say, you dont see why this should affect the result, but it is 
affecting the result.

The explanation for that sounds a bit weird, if you regard your design 
as already being synthesized as the resulting device, can't act in 
another way as getting input and doing something with it.

But the logic of the synthesizer-software differs somewhat from that 
view. It simply does not synthesize a process or a part of it, which 
does not depend of an input and takes the sensitivity list as the only 
authoritative means to state such dependancy.
From a "common sense" point of view, that is "weird" because the 
software could collect info of the process about inputs, which occur as 
"input" from the signal description or appears on the right side of 
"transport" expressions (<=).
But the software does not. And there is a fact which makes that more 
understandable: The synthesizer software does not check that, because 
the factual dependencies depend largely on the actual code, not on an 
input being an input alone.

As an example take the idiom:
if rising_edge(clk) then ...
   ... <= a;

where the process depends on inputs clk and a.

But the appropriate view (from the view of the synthesizer) is, that the 
process will only take effect, if clk changes - regardless whether input 
a changes or not. In case of the example the software could determine 
that by itself, but the expressions and statements possible within 
processes are potentially so complicated, that writing an analyzer doing 
that fully automically is overwhelmingly ineffective (if possible at all 
- can't say that with any authority).

You could check, if what I said is true, for the inputs, about which the 
synthesizer warned you.

Hope the solution helps, and the explanation get you a but further in 
understanding.

A more general remark about that issue: It is a good rule of thumb in 
imperative programming (like C aso.) to never ignore any warning (not 
only errors). This is not to the full extent, but mostly, true for the 
hardware description in VHDL too.

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
1 useful
not useful
Xabier G. wrote:
> The program
Is NOT a program, it is a description, as VHDL is a Hardware 
Description Language and not a VHPL Hardware Programming Language.

After having that cleared there is one question: du you have a picture 
or a sketch of the desired hardware on paper or at least in mind?
No?
So, how can you describe something you don't know how it look like?

Now to your code:
SUBTYPE STATE_TYPE IS STD_LOGIC_VECTOR(4 downto 0);
SIGNAL STATE: STATE_TYPE;

CONSTANT s0: STATE_TYPE:="00000";
CONSTANT s1: STATE_TYPE:="00001";
CONSTANT s2: STATE_TYPE:="00010";
CONSTANT s3: STATE_TYPE:="00011";
:
:
:
:
Why so much code for something VHDL gives you for free?
I would have defined my own States_Type:
TYPE STATE_TYPE IS (s0,s1,s2,....);
SIGNAL STATE: STATE_TYPE;

That is not a way to generate clocks inside an FPGA:
crear_clock_2: process (clock)  --This creates a second clock, clock2, slower than the main clock

begin

  if(rising_edge(clock)) then 
  
    if (clock_desfasado1="0000000000000") then  
      clock2 <= '1';
    else
      clock2<= '0';
    end if;
For generating or deriving clocks use the clock managers (DCM, DLL, 
PLL...).
For a beginners design let me say: one clock is enough. Print this 
sentence on paper an pin it to the wall. All the things you are doing by 
derived clocks can better be done by clock enables.

But the major problem are those processes:
asignar_valores_sig1: process (clock2)   --This four processes asign values for sig1, sig2, sig3 and sig4.  Those values are pseudo randomized
                     --as they are set according to clock2 and clock3's values.
                     --They serve as the sequence in which the simon game has to switch on the Leds.

begin
  if (contador_espera_valores > "10000") then 
     ...
  end if;
Here it can easily seen, that (at least up to now) you did not get the 
idea of "describing hardware". Very much it is like using the "unknown 
tricks of VHDL". And one of the "best unknown tricks" is called "the 
incomplete senstitvity list". You can do beasty tricks with that in a 
test bench, oh yeah. But for pity: the synthesizer does not need (and 
not even use) this list.

EverTrueGate wrote:
> But the logic of the synthesizer-software differs somewhat from that
> view. It simply does not synthesize a process or a part of it, which
> does not depend of an input and takes the sensitivity list as the only
> authoritative means to state such dependancy.
To keep things short: the sensitivity list is only used for 
simulation, it is ignored by the synthesizer.

Then this here:
  --Those values are pseudo randomized
  --as they are set according to clock2 and clock3's values.
Do you only expect that or did you check it out? There is no random 
behaviour, because clock2 and clock3 are derived out of clock straight 
forward by counters. Where do you expect randomity here?
If you want pseudo random values, then take a counter and a user 
interaction (a user will not be able to press a button in equal steps 
according to a clock of lets say 50MHz). Or take a pseudo random 
generator with a LFSR:
http://www.lothar-miller.de/s9y/categories/38-LFSR


And at last a word to the asynchronous external signals: the buttons 
must be synchronized to the systems clock prior to being used inside 
your logic. Otherwise you will enclounter some curious behaviour and get 
a design, that runs "mostly perfect", but now and then it must be reset.
Try that with Google translate, its German:
http://www.lothar-miller.de/s9y/archives/64-State-...

My hints:
1. Why do you try even the most simple thing on your own? Why don't you 
use books on VHDL? Try one from Peter Ashenden.

2. As the glad man you are, you are not the first doing such a thing. 
Have a look on the way others do a similar job (clock enables, state 
machines, synchronizing external signals...).

3. Start with a blinking LED then do a chasing light. Have a look for 
the generated RTL schematics generated by the synthesizer: does the 
synthesizer generate that schematic you wanted to describe?

4. Use integers for counters. It will make the code readable for humans.

: Edited by Moderator
Author: EverTrueGate (Guest)
Posted on:

Rate this post
0 useful
not useful
Lothar is right. The sensitivity list is only important for the 
simulation.
Sorry.

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Xabier G. wrote:
> The only warnings Vivado gives me talk about the sensitivity lists of
> the processes("something like, "X is read in the process but is not in
> the sensitivity list"), but I do not see why it should affect my game at
> all.  It should work with "clock" as the only sensitivity.
You must interpret that warnnings as "the most severe error that ever 
can happen". It simply says: the generated hardware implementation does 
not match the behavioural simulation.

> Synth, Implementation and Bitstream give no errors.
If you try a "post-routing" hardware simulation you will see that this 
simulation will match your hardware. But it will not match your 
requirements.

Author: Xabier Gandiaga (doctormckay)
Posted on:

Rate this post
0 useful
not useful
EverTrueGate wrote in:
> First add all inputs, for which Vivado warns you, about not being
> in the
> sensitivity list, to the sensitivity list.
>
> You say, you dont see why this should affect the result, but it is
> affecting the result.

I'll get to it right now.

> But the appropriate view (from the view of the synthesizer) is, that the
> process will only take effect, if clk changes - regardless whether input
> a changes or not.

I'll add this to my notes.

> A more general remark about that issue: It is a good rule of thumb in
> imperative programming (like C aso.) to never ignore any warning (not
> only errors). This is not to the full extent, but mostly, true for the
> hardware description in VHDL too.

I guess I've had too much Java 8 since it's release.  Right now my mind 
works via functional statements.

Author: Xabier Gandiaga (doctormckay)
Posted on:

Rate this post
0 useful
not useful
> Lothar M. wrote:

> Now to your code:SUBTYPE STATE_TYPE IS STD_LOGIC_VECTOR(4 downto 0);
> SIGNAL STATE: STATE_TYPE;
>
> CONSTANT s0: STATE_TYPE:="00000";
> CONSTANT s1: STATE_TYPE:="00001";
> CONSTANT s2: STATE_TYPE:="00010";
> CONSTANT s3: STATE_TYPE:="00011";
> :
> :
> :
> :
> Why so much code for something VHDL gives you for free?
> I would have defined my own States_Type:TYPE STATE_TYPE IS
> (s0,s1,s2,....);
> SIGNAL STATE: STATE_TYPE;

I have that statement in another version of the code.  I'll just go back 
to it.

> That is not a way to generate clocks inside an FPGA:crear_clock_2:
> process (clock)  --This creates a second clock, clock2, slower than the
> main clock
>
> begin
>
>   if(rising_edge(clock)) then
>
>     if (clock_desfasado1="0000000000000") then
>       clock2 <= '1';
>     else
>       clock2<= '0';
>     end if;
> For generating or deriving clocks use the clock managers (DCM, DLL,
> PLL...).
> For a beginners design let me say: one clock is enough. Print this
> sentence on paper an pin it to the wall. All the things you are doing by
> derived clocks can better be done by clock enables.

Ok, I'll look up how to use clock enables.

> To keep things short: the sensitivity list is only used for
> simulation, it is ignored by the synthesizer.
>
> Then this here:  --Those values are pseudo randomized
>   --as they are set according to clock2 and clock3's values.
> Do you only expect that or did you check it out? There is no random
> behaviour, because clock2 and clock3 are derived out of clock straight
> forward by counters. Where do you expect randomity here?
>
> If you want pseudo random values, then take a counter and a user
> interaction (a user will not be able to press a button in equal steps
> according to a clock of lets say 50MHz). Or take a pseudo random
> generator with a LFSR:
> http://www.lothar-miller.de/s9y/categories/38-LFSR

My train of thought was the following:
Basys3 board's clock should work similarly to a motherboards RTC, so, 
the crystal oscillator can give me a 0 to 1 or a 1 to 0 change at the 
start.  If this is true my sig(s) should take one of two values because 
of the derived clock's values when the time arrives.  I'll try the LFSR.


> My hints:
> 1. Why do you try even the most simple thing on your own? Why don't you
> use books on VHDL? Try one from Peter Ashenden.

Peter Ashenden.  Annotated.

> 4. Use integers for counters. It will make the code readable for humans.

Maybe my calculations are wrong, but, I think I won't be able to use an 
Integer counter for a 6 second wait as I'll reach the limit of what an 
Integer can hold.

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Xabier G. wrote:
> Basys3 board's clock should work similarly to a motherboards RTC
You are thinking far far away from the real hardware you want do 
describe. The clock on the Basys is a crytal oscillator. And you derived 
clocks are in a predictable way directly connected to that clock. That 
has absolutely nothing to do with with an abstract RTC on a PC.

> but, I think I won't be able to use an Integer counter for a 6 second
> wait as I'll reach the limit of what an Integer can hold.
You could calculate it depending on the clock frequency (e.g. 50MHz), 
the necessary value to count those clock cycles for 6 minutes (= 50 000 
000 * 6 = 300 000 000) and the signed 32 bit integers range from −2 147 
483 648 to 2 147 483 647.

But far more easy is to have a look ab the vectors length:
CONSTANT MAX : STD_LOGIC_VECTOR (28 downto 0) ...
And for sure, a 29 bit vector fits perfectly in a 32 bit integer.

Author: Xabier Gandiaga (doctormckay)
Posted on:

Rate this post
0 useful
not useful
Just to wrap things up, I have one last question to ask.  Would there be 
any problem with me using "after" statements as replacements for the 
counters that act as delays?

Like in:
Led <= sig1;
Led <= "0000" after 1000ms;


This should turn on a Led and then turn it off after a second.

Author: Svenska (Guest)
Posted on:

Rate this post
0 useful
not useful
As far as I understand, "after" statements are not synthesizable. They 
are made for simulation only.

How should the hardware know when a second has passed?

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Xabier G. wrote:
> Would there be any problem with me using "after" statements as
> replacements for the counters that act as delays?
Of course not. At least in simulation. But what part of hardware inside 
a FPGA could achieve a adjustable delay in the range of milliseconds to 
seconds?

And did I already mention the synthesizers user guide? In it is written 
what the synthesizer is able to handle and how it must be written.

To keep things short: every delay in your design is based on counters.

See that "after-trick" there (with Google translato)r:
http://www.lothar-miller.de/s9y/archives/80-Hello-...

Keep in mind: out of the 100% VHDL offers you no more than 5% may be 
synthesizeable...

: Edited by Moderator

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig