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
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.
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 | if rising_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 | SUBTYPE STATE_TYPE IS STD_LOGIC_VECTOR(4 downto 0); |
2 | SIGNAL STATE: STATE_TYPE; |
3 | |
4 | CONSTANT s0: STATE_TYPE:="00000"; |
5 | CONSTANT s1: STATE_TYPE:="00001"; |
6 | CONSTANT s2: STATE_TYPE:="00010"; |
7 | CONSTANT s3: 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 | TYPE STATE_TYPE IS (s0,s1,s2,....); |
2 | SIGNAL STATE: 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 | 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:
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 | 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:
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.
:
Edited by Moderator
Lothar is right. The sensitivity list is only important for the simulation. Sorry.
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" after 1000ms; |
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...
:
Edited by Moderator
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.