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
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:
1
ifrising_edge(clk)then...
2
...<=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.
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:
1
SUBTYPESTATE_TYPEISSTD_LOGIC_VECTOR(4downto0);
2
SIGNALSTATE:STATE_TYPE;
3
4
CONSTANTs0:STATE_TYPE:="00000";
5
CONSTANTs1:STATE_TYPE:="00001";
6
CONSTANTs2:STATE_TYPE:="00010";
7
CONSTANTs3:STATE_TYPE:="00011";
8
:
9
:
10
:
11
:
Why so much code for something VHDL gives you for free?
I would have defined my own States_Type:
1
TYPESTATE_TYPEIS(s0,s1,s2,....);
2
SIGNALSTATE:STATE_TYPE;
That is not a way to generate clocks inside an FPGA:
1
crear_clock_2:process(clock)--This creates a second clock, clock2, slower than the main clock
2
3
begin
4
5
if(rising_edge(clock))then
6
7
if(clock_desfasado1="0000000000000")then
8
clock2<='1';
9
else
10
clock2<='0';
11
endif;
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:
1
asignar_valores_sig1:process(clock2)--This four processes asign values for sig1, sig2, sig3 and sig4. Those values are pseudo randomized
2
--as they are set according to clock2 and clock3's values.
3
--They serve as the sequence in which the simon game has to switch on the Leds.
4
5
begin
6
if(contador_espera_valores>"10000")then
7
...
8
endif;
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:
1
--Those values are pseudo randomized
2
--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-Machine-mit-asynchronem-Eingang.html
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.
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.
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.
> 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.
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.
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:
1
Led<=sig1;
2
Led<="0000"after1000ms;
This should turn on a Led and then turn it off after a second.
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?
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-World!.html
Keep in mind: out of the 100% VHDL offers you no more than 5% may be
synthesizeable...