Hello !
This question is a kind of sequel of
https://embdev.net/topic/394811#new, but because it's another problem, i
made another topic ... i hope it's not bad.
Context : I have a Rom (Rom_out&Rom_address), in each state of my FSM i
need to read some data of the Rom before moving to the next state.
In my state Sub_track_note i read the data from the Rom and i need to
use this data as an address for my second rom (it's a correspondence
between data) (note_rom_address¬e_rom_out).
So, i had my main_fsm with all my other files ... everything was working
perfectly, but my synthesis tool complained about missing signals in the
sensitivity list, like Rom_out, note_rom_out ... but my opinion is that
it was not necessary. But after synthesis the simulation was a disaster
because everything was offbeat and coul pass the first states of
vérification (you will undersatnd reading the code i hope).
So, i added those signal in the sensitivity list, make the adjustment of
all the "shift" about rom_counter and i am now facing a new problem. In
my state sub_track_note, the is a fatal error during the simulation
about note_rom_address.
So, here is my code for the fsm, i'm sorry of my non-professional
writing code :
So, i think that there is a link between my modification of the
sensitivity list and this new error ... but i worked several hours on
the problem ... i found no solution. (
http://img15.hostingpics.net/pics/369469error1.png , not_rom_Adress is
the UUUUUUUU signal)
so,I have created a signal "test", and it tooks exactly the values i
want (http://img15.hostingpics.net/pics/848283error2.png and a zoom
http://img15.hostingpics.net/pics/635965erro3.png) that means it's not a
problem of a false value of Rom_out involving the problem.
After all those test, i though, that adding all those signal to the
sensitivity list (the four last one) was a mistake, so i just make a
constant to replace the rom. I made the synthesis and re-simulate.
Everything worked perfectly. So ading those signals was not a mistake.
I hope my explanation is clear enought (because of my bad english) and i
hope to have include all the information you need to try to help me.
I just don't understand why it's not working.
Thank you very much for your help !
Ed
Ed H. wrote:> I just don't understand why it's not working.
I didn't have a close look at the code, but one thing to think about:
the sensitivity list is used for simulation only. The synthesizer just
throws a warning like "list incomplete, synthesis result will differ
from simulation"...
> i have a Rom (Rom_out&Rom_address)
Is this ROM working properly? Is it an external ROM?
What timing constraints did you specify? What's the crystals clock
frequency?
Ed H. wrote:> not_rom_Adress is the UUUUUUUU signal
So the problem here must be somewhere else, cause I cannot find this
signal in your description. Where does it come from?
(I cannot find note_rom_Adress, too...)
BTW: its really horrible to read this "next_..." code.
I'll bet you anything that I'm able to reduce this description to less
than a third with the 1-process style... ;-)
BTW2: you should attach pictures here in the forum (you can attach
multiple files) instead of linking to a website storing the pictures
only for a few months...
Lothar M. wrote:>> I just don't understand why it's not working.> I didn't have a close look at the code, but one thing to think about:> the sensitivity list is used for simulation only. The synthesizer just> throws a warning like "lust incomplete, synthesis result will differ> from simulation"...>
Ok, but the fact is that correcting the list make the simulation working
after the synthesis ( besides the major problem of course , replacing
the second rom by a constant). Si i think my code was working
miraculously before, but now, it's corrected and the only problem is the
1
note_rom_address<=Rom_out;
But what is strange is that if I use an internal signal to validate the
value of rom_out , I have the right result. And when I assign this value
to note_rom_address , it seems that this value exceeds the size of the
Rom , or this is not the case !
> Is this ROM working properly? Is it an external ROM?
Yes and yes.
> What timing constraints did you specify? What's the crystals clock> frequency?
You mean in the bench ? the period is 20ns.
> BTW: you should attach pictures here in the forum (you can attach> multiple files) instead of linking to a dubious website...
Okay, i'll do it next time.
A hint: in VHDL the std_logic value 'U' means "uninitialized". So you
should have a closer look for the assignment to and and the
initialisation of note_rom_address.
That will bring the simulation running. But it will not bring much for
reality, as in reality there is no 'U' value. Every uninitialized signal
will become '0' instead...
Ed H. wrote:>> Is this ROM working properly?> Yes
How did you ensure that?
>> Is it an external ROM?> yes
An external ROM connected to FPGA IO-Ports?
An asynchronous ROM?
What ROM ist that?
Does your testbench model properly describe the beahaviour of that ROM?
> You mean in the bench ? the period is 20ns.
No I mean reqality (besides: the testbench should reflect reality...).
Is your real ROM really that fast?
BTW: its a little bit tiring to worm every little bit of information out
of you. When you post something then read it, as if you would know
absolutely nothing about your specific problem. Thats the way how we
others must look at it...
> BTW: its a little bit tiring to worm every little bit of information out> of you. When you post something then read it, as if you would know> absolutely nothing about your specific problem. Thats the way how we> others must look at it...
I understand. I'm sorry, but the fact is i'm really beginning vhdl, so,
when I see a problem I really do not know how to resolve , and I do not
know from where it comes, I do not know what information are useful or
not in order to solve/understand the problem. I try to do my best, but I
will do even more attention in the future.
I just hope not appear to haven't search any solution and ask for help.
> Ed H. wrote:>>> Is this ROM working properly?>> Yes> How did you ensure that?
Before modifying the sensitivity list, i had absolutely no problem with
my code and this rom, and I got exactly what I wanted. So i think it's
working.
>>> Is it an external ROM?>> yes> An external ROM connected to FPGA IO-Ports?> An asynchronous ROM?> What ROM ist that?> Does your testbench model properly describe the beahaviour of that ROM?
I must admit that these questions go beyond my skills. When I said
"external" I mean , yes it is an external file , one more "component".
So, i can't really answer the question.
>> You mean in the bench ? the period is 20ns.> No I mean reqality (besides: the testbench should reflect reality...).> Is your real ROM really that fast?
And i don't really know the speed, but for now, for the simulation
before syntesis, this should not influence ?
>> not_rom_Adress is the UUUUUUUU signal>So the problem here must be somewhere else, cause I cannot find this>signal in your description. Where does it come from?>(I cannot find note_rom_Adress, too...)
It's an out signal ! note_rom_address is sent by my FSM to the note_rom
, who return me note_rom_out.
>BTW: its really horrible to read this "next_..." code.>I'll bet you anything that I'm able to reduce this description to less>than a third with the 1-process style... ;-)
I'm have absolutely no doubt and i really want to try to do it with
1-process style, but as i already said in the previous topic, i'm a
little scared
with respect to the teaching of my teachers.
But if I can run my project, it is certain that I'll intend to improve
my FSM with your advice and website.
I'm certainly a hassle to say that, but I had no problem until I added
reg_header,Rom_out,note_rom_out,time_value to the sensitivity list.
Although I do not see any connection , the problem certainly comes from
here ( or maybe that again miraculously my code work before, by
correcting this list , this brings up a big issue ).
Maybe you need my entire work ? i can upload it if you need.
Thank you very much for the time you give me and i really apologize of
not being enough clear both in my code and in my way of describing my
problem.
Ed.
Ed H. wrote:> the only problem is the note_rom_address<=Rom_out;
And for the code above its clear, why there are only 'U' in
note_rom_address: the assignment to note_rom_address ist commented out,
so there can never get any other value than 'U'...
One thing more: note_rom_address is a latch again, because in a
combinatorial process the value to note_rom_adress is assigned only
once...
Ed H. wrote:> Before modifying the sensitivity list, i had absolutely no problem with> my code
"No problem" means also "it was running ok in hardware"?
Or does it only mean that your simulation showed anything looking
halfway ok?
>>>> Is it an external ROM?>>> yes>> An external ROM connected to FPGA IO-Ports?>> it is an external file , one more "component".
OK, it is not a "real" Rom, but instead (presumably) a distributed
asynchronous ROM made out ot LUTs and Flipflops...
>> it is an external file , one more "component".
So MAIN_FSM is not the top level of your design. Theres (at least) one
more level above it?
Ed H. wrote:> Maybe you need my entire work ?
Maybe thats the best way to look at the things.
> i can upload it if you need.
Do that. Don't zip the files, instead attach each single VHDL file on
its own...
Lothar M. wrote:>> the only problem is the note_rom_address<=Rom_out;> And for the code above its clear, why there are only 'U' in> note_rom_address: the assignment to note_rom_address ist commented out,> so there can never get any other value than 'U'...
Here is what i want to do :
1
whenSub_track_note=>
2
next_Rom_counter<=Rom_counter+1;
3
wr_note<='1';
4
Rom_Address<=STD_LOGIC_VECTOR(Rom_counter);
5
6
note_rom_Address<=Rom_out;-------> PROBLEM HERE
7
8
note_value<=Rom_out;
9
next_state<=Sub_track_Volume;
10
11
whenSub_track_volume=>
12
next_Rom_counter<=Rom_counter+1;
13
wr_volume<='1';
14
15
freq_value<=note_rom_out;
16
17
Rom_Address<=STD_LOGIC_VECTOR(Rom_counter);
18
volume_value<=Rom_out;
and here is the code, when i wanted to be sure the value from Rom_out
(from the Rom) was not a wrong value for the note_rom.
That's why i commented the problem and created a "test" signal and a
constant for the freq_value.
1
whenSub_track_note=>
2
next_Rom_counter<=Rom_counter+1;
3
wr_note<='1';
4
Rom_Address<=STD_LOGIC_VECTOR(Rom_counter);
5
6
--note_rom_Address<=Rom_out; -------> PROBLEM HERE commented
> One thing more: note_rom_address is a latch again, because in a> combinatorial process the value to note_rom_adress is assigned only> once...
I did not realize it , so, it is the same problem for Rom_adress I guess
... I 'll fix that!
> Ed H. wrote:>> Before modifying the sensitivity list, i had absolutely no problem with>> my code> "No problem" means also "it was running ok in hardware"?> Or does it only mean that your simulation showed anything looking> halfway ok?
It was only working for the simulation ! (And then i made a synthesis
and nothing was working)
>>> it is an external file , one more "component".> So MAIN_FSM is not the top level of your design. Theres (at least) one> more level above it?
Exactly, my top level design is my "midi.vhd" file !
To help you understand here i made a quick drawing of my architecture
(attached file).
I read data form my rom in my fsm, at a point, i need the data of my rom
to be used as an adress for my note_rom, which sends me back another
data (freq_value). Then i send all this data to what i called MULTIPLEX,
which, depending on the case, send those data to different synthetiser.
(I tried to make a very simple synthesizer midi, taht i'll try to
implant of FPGA).
I have also attached my code.
Thank you very much for your help ! (I hope that my code will not be so
catastrophic it to decipher ....)
in your code you check if the reg_header (i.e. the combined content of
the first 4 ROM reads) is 1297377380. If it's not, you go to state
erreur and note_address_ram will remain unassigned and stuck at "U".
Did you check in your simulation, if you receive the correct reg_header?
(you can monitor internal signals of your fsm in simulation too).
Once it works in simulation: any slightest problem in the real hardware
can lead into state erreur, and you get no notice of it. The ROM data
access could be to slow for your 20ns CLK. Or the Byte endianess in the
ROM may be different to your expectation. You should at least get some
indicator for the error-state (e.g. light an LED when you are in
erreur).
If you are really stuck in erreur, you could try to find out, which
value of reg_header brought you there. Send the actual value of
reg_header to IOs of your FPGA (just re-use your rom address lines for
debugging). Then you could check how the actual value of reg_header
differs from the one you expected (some bits wrong or wrong byte
sequence or .....)
Achim S. wrote:> Did you check in your simulation, if you receive the correct reg_header?> (you can monitor internal signals of your fsm in simulation too).
Yes i got the correct reg_header !
>You should at least get some>indicator for the error-state (e.g. light an LED when you are in>erreur).
It is true that it would be worth it , but given the fact that it is me
who write the data into the Rom for now, I know exactly what they are,
so, for the moment, I should not be in the state error !
according to the things you know (e.g. the content of the ROM) your
design should work. Unfortunatelly it does not. So something you believe
to know must be wrong ;-)
If I were in your case, I would light an LED when I'm stuck in error. Or
I would send the actual state to some output pins (that would even allow
you to follow the progress you your fsm.
The problem is i'm still stuck during my simulation and i know where !
It's when
"note_rom_address<=Rom_out" in the "Sub_track_note" state.
My simulation tool just wrote me a fatal error, but i don't know why,
because, before adding some signal to the sensitivity list i had no
problem . Currently, it's like if note_rom_address get a wrong value,
but it's not the case because i try it with a signal ("test") and it's
the right value.
Ed H. wrote:> My simulation tool just wrote me a fatal error, but i don't know why,> because, before adding some signal to the sensitivity list i had no> problem .
I saw such fatal error messages in the past as a reaction of
combinatorial loops.
What signals did you add to the sensitivity that brought the problem up?
You may set a breakpoint in the code and step through the simulation
linewise. Maybe that brings some new insight, and you may check the
values you assign.
Achim S. wrote:> What signals did you add to the sensitivity that brought the problem up?
I added reg_header,Rom_out,note_rom_out and time_value !
But I tried to remove note_rom_out and it changes nothing !
Achim S. wrote:> I saw such fatal error messages in the past as a reaction of> combinatorial loops.
You think it's because note_rom_address is a latch ? But why i had no
problem before ... it's still a mystery for me !
Ed H. wrote:> I have also attached my code.
The testbench is missing...
However, i simply set one up. And then I uncommented the line in
question and the simulation ran to the point, where a value greater than
80 is assigned to note_rom_adress.
And here it gets kind of tricky:
because a signal changes its value at the end of the process. But
because immediately "after" the assignment of a new adress the "output"
value of the ROM is used for an assignment to the note_rom_adress:
1
whenSub_track_note=>
2
next_Rom_counter<=Rom_counter+1;
3
wr_note<='1';
4
Rom_Address<=STD_LOGIC_VECTOR(Rom_counter);
5
note_rom_Address<=Rom_out;
6
test<=Rom_out;
7
note_value<=Rom_out;
8
next_state<=Sub_track_Volume;
Then of course the "Rom_out" is NOT changing here, it kepps its old
value until the end of the process! Inside a process all signal values
are stable and only new signal values are calculated, but not updated.
Because signals don't change their values until the end of the process
(or the next wait statement) I could change the order of the above
snippet to this here *without any change in behaviour*:
1
whenSub_track_note=>
2
note_value<=Rom_out;
3
wr_note<='1';
4
note_rom_Address<=Rom_out;
5
next_Rom_counter<=Rom_counter+1;
6
next_state<=Sub_track_Volume;
7
Rom_Address<=STD_LOGIC_VECTOR(Rom_counter);
8
test<=Rom_out;
Remarkably note_value and test will be exactly the same with both code
snippets!
And here again you have the 2-process problem: you should wait for the
next clock before reading the Rom_out, but you mix it up.
Lets say it that way: in the state Sub_track_event you should set up the
rom adress for the value read in the state Sub_track_note.
Ed H. wrote:> But why i had no problem before
You always had problems. Never ever your design ran on hardware...
First of all : thank you very much for your help and your detailed
answer !
Lothar M. wrote:> And here again you have the 2-process problem: you should wait for the> next clock before reading the Rom_out, but you mix it up.> Lets say it that way: in the state Sub_track_event you should set up the> rom adress for the value read in the state Sub_track_note.
Yes, I am aware of that , and I have "anticipated " the thing ( the
problem of the 2 -process ... ) because I want note_value and
note_rom_address to take the same value : 3C.
In my word, i say to my self : "the value you want for your Rom, is
available, on clock after you ask it". Am I right ?
That's why i'm writing :
freq_value<=note_rom_out
one state after, because i want te result of a 3C address. But maybe my
mistake is here.
Wich leads me to your simulation : why note_value is taking 90 and not
3C since i anticipated (maybe not as well as i though) the problem of
"the next wait statement" with the 2-process style ! Because if
note_value/test was taking 90 in my simulation I would immediately
understood where the problem comes from !
During the Sub_track_event, Rom_out is taking 90 as value, and during
the sub_track_note state, 3C ! So, how, in the sub_track_note,
note_value could take 90 and note 3C ? Why in my simulation test an
note_value are taking 3C and not you ?
But, as you can see in my simulation (attached screen), "test" (which is
the same value as note_value), is 3C and not 90.(3C being the data just
after 90).
In summary, with your simulation I know how to solve the problem, but
with mine I do not understood .... Or, I have absolutely not understood
the message you were trying to make me understand ...
-- and HERE fetch the data from the ROM adress assigned one line above above
9
note_rom_Address<=Rom_out;
10
11
test<=Rom_out;
12
note_value<=Rom_out;
13
next_state<=Sub_track_Volume;
Is it that?
If so, then its a little bit stumbling here:
The Rom_adress is udated at the end of the process, so Rom_out does not
change here at all...
Ed H. wrote:> In my word, i say to my self : "the value you want for your Rom, is> available, on clock after you ask it". Am I right ?
No, not exactly. In a synchronous design there is a clock. After that
clock the FPGA is busy until all logic found its final state, then comes
the next clock, the FPGA gets busy until al logic ran through and so on.
So the only thing one mus ensure is, that the logic ist stable well
before the next clock (thats the well known "setup time").
And usually the adress for the ROM is stored in some flipflops. Then
with this stored adress the ROM has time to fetch the value, which must
be finished well before the next clock edge.
But in your code I assume you assign the adress and you want the data in
the very same cycle...
In your code that whole filter_rom is combinatorial and so the different
result in those two simulators is due to different handling of delta
cycles.
What happens here (at the very same time!) is:
0. P_FSM: process(....curr_state, ... )
Current state has changed, process must be calculated.
1. Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
Assign a new adress.
2. note_rom_Address<=Rom_out;
Assign the old value of Rom_out to note_rom_Adress.
3. end process;
Update signal values for "outside world", here focus on Rom_Address.
4. Rom_Address : out std_logic_vector(7 downto 0);
Rom_Address => Rom_Address
Hand the adress over to the ROM.
5. Rom_out <= filter_rom(to_integer(unsigned(Rom_Address)));
Read ROM value.
6. Rom_out => Rom_out,
Hand ROM value over to the main_fsm.
7. P_FSM: process(.... Rom_out,... )
Sensitivity list has changed! Process must be calculated a second time!
8. note_rom_Address<=Rom_out;
Now the correct value is assigned to note_rom_Adress.
In simulation time did not change, but because the process had to be
calculated 2 times one dela cycle more was involved...
In real life that means a glitch on the signal. A glitch on its own
is not bad (after a clock the whole FPGA is "glitching"), but here it is
a warning sign: this ROM adress is not registered.
You already register the Rom_Adress (because Rom_counter are
flipflops):
Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
Why not doing the same with the note_rom_Address?