EmbDev.net

Forum: FPGA, VHDL & Verilog Problem of Rom & sensitivity list


Author: Ed Hut (hachhac)
Posted on:
Attached files:

Rate this post
0 useful
not useful
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&note_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 :
------------------------------MAIN_FSM.vhd----------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
--library work;
--use work.midi_package.all;

entity MAIN_FSM is
  port(Clk                      : in  std_logic;
       Reset                    : in  std_logic;
       Rom_out                  : in std_logic_vector(7 downto 0);
       note_rom_out             : in std_logic_vector(31 downto 0);
  freq_value              : out std_logic_vector(31 downto 0);
  wr_note      : out std_logic;
  wr_volume    : out std_logic;
        volume_value            : out std_logic_vector(7 downto 0);
       note_value               : out std_logic_vector(7 downto 0);
       event_value              : out std_logic_vector(7 downto 0);
  note_rom_Address        : out std_logic_vector(7 downto 0);
       Rom_Address              : out std_logic_vector(5 downto 0));
    

end MAIN_FSM;
-- Machine à états la lecture des fichiers qui incluera fsm_header_chunk et fsm_track_chunk.

architecture A of MAIN_FSM is
  type STATE is (Start,Mthd,Calculation_length,Track_Chunk,Sub_track_time,Sub_track_event,Sub_track_note,Sub_track_volume,Erreur,Wait_delay,Final);-- differents états
signal curr_state, next_state : state;
  
signal Rom_counter : UNSIGNED (5 downto 0) ;--compteur d'adresse de rom
signal next_Rom_counter : UNSIGNED (5 downto 0):="000000"; --compteur d'adresse de rom

signal nbre_note: UNSIGNED ( 2 downto 0):="110"; --nbre de note dans la track
  
signal flag_note: UNSIGNED ( 2 downto 0); --compteur de note
signal next_flag_note: UNSIGNED ( 2 downto 0):="000"; --compteur de note    
  
signal reg_tempo : unsigned  (15 downto 0);  --registre
                                                                   --16 bit pour stocker le tempo du header
signal reg_header : unsigned (31 downto 0);  --pour
                                                                                     --verifier
                                                                                     --les header
signal next_reg_tempo : UNSIGNED (15 downto 0) :="0000000000000000" ; --tempo_header en cas de maj+store

signal next_reg_header : unsigned (31 downto 0) := "00000000000000000000000000000000";  --pour
                                                                                     --verifier
                                                                                     --les header

--signal compteur_time : unsigned (31 downto 0) :="00000000000000000000000000000000";
--signal next_compteur_time : unsigned (31 downto 0) :="00000000000000000000000000000000";

signal time_value : unsigned (7 downto 0); 
signal next_time_value : unsigned (7 downto 0):="00000000"; 

signal compteur_time : unsigned (7 downto 0); 
signal next_compteur_time : unsigned (7 downto 0):="00000000"; 

signal test : std_logic_vector (7 downto 0); 






begin
  P_STATE: process(Clk, Reset)
  begin
    if(Reset='1') then
        curr_state<=Start;
  Rom_counter<="000000";
  flag_note<="000";
  time_value<=(others=>'0');
  compteur_time<=(others=>'0');
  reg_tempo<=(others=>'0');
  reg_header<=(others=>'0');


  
  
    elsif (Clk='1' and Clk'event) then -- sur front montant d'horloge

        Rom_counter <= next_Rom_counter;
  curr_state <= next_state;
  flag_note <= next_flag_note;
  compteur_time<=next_compteur_time;
  reg_tempo<=next_reg_tempo;
  reg_header<=next_reg_header;
  time_value<=next_time_value;

    
    end if;
  end process;
  


  P_FSM: process(curr_state, Rom_counter, compteur_time, flag_note,reg_header,Rom_out,note_rom_out,time_value )
  begin

--Problème de latch solutionné :
--next_data_wanted <= data_wanted;

next_reg_tempo<=reg_tempo;
next_Rom_counter<=Rom_counter;
next_reg_header<=reg_header;
next_flag_note<=flag_note;
next_time_value<=time_value;
next_compteur_time<=compteur_time;
    
    -- INITIALISATION --
  nbre_note<="110";
  
  --next_time_value<="00000000";
  wr_note<='0';
  wr_volume<='0';
  note_value<="00000000";
  event_value<="00000000";
  volume_value<="00000000";
  freq_value<=(others=>'0');


  
  -------------------------------


    case curr_state is


      -- ETAT  START -- 
      when Start =>
  
        next_state<=Mthd;

        
        -- ETAT  Mthd -- Reading 4 bytes
        -- -- On vérifie qu'on a bien mis un fichier midi
      when Mthd =>
        next_Rom_counter<=Rom_counter+"000001";
        Rom_Address <= STD_logic_vector (Rom_counter);

        --if Rom_counter = 0 then 
         -- next_state<=Mthd;

        if Rom_counter = 0 then 
          next_reg_header(31 downto 24)<= unsigned (Rom_out);
          next_state<=Mthd;


        elsif Rom_counter= 1 then
            next_reg_header(23 downto 16)<=unsigned (Rom_out);
            next_state<=Mthd;

                                      
        elsif Rom_counter= 2 then
            next_reg_header(15 downto 8)<=unsigned (Rom_out);
            next_state<=Mthd;


        elsif Rom_counter= 3 then
            next_reg_header(7 downto 0)<=unsigned (Rom_out);
            next_state<=Mthd;



        elsif (Rom_counter= 4 and reg_header=1297377380) then
            next_Rom_counter<=Rom_counter+7;
            next_state<=Calculation_length;
        else
          next_state<=Erreur;
                                        
        end if;

        

        -- ETAT  Calculation time --
        ----------------------------------------------------------
      when Calculation_length =>
        
        next_Rom_counter<=Rom_counter+"000001";
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);

        if Rom_counter = 12 then
          next_reg_tempo(15 downto 8)<=unsigned (Rom_out);
    next_state<=Calculation_length;

        elsif Rom_counter=13 then
            next_reg_tempo(7 downto 0)<=unsigned (Rom_out);
      next_state<=Calculation_length;
            
        elsif Rom_counter=14 then
    next_state<=Track_Chunk; --passe direct au track chunk
          next_Rom_counter<=Rom_counter+7;  --comme dit dans l'état suivant
        end if;
        
                                                

        -- ETAT  Header Chunk -- 
        ------------------------------------------------------
      --when Header_Chunk =>
        ----Etat à rajouter si on lit plusieurs track
  
        --next_state<=Track_Chunk;
        
        -------------------------------------------------------



        -- ETAT  Track Chunk -- et ses sous etats
        -------------------------------------------------------
      when Track_Chunk =>
        next_Rom_counter<=Rom_counter+1;
        
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
        next_state<=Sub_track_time;

      when Sub_track_time =>
  next_compteur_time<=(others=>'0');
        next_Rom_counter<=Rom_counter+1;
        next_flag_note<=flag_note+1;--on incrémente le compteur d'un, début de note
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
        next_time_value<=unsigned(Rom_out); --pas encore fait le calcul
  next_state<=Wait_delay;

  when Wait_delay =>
  --Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
  --next_time_value<=unsigned(Rom_out);
  --next_compteur_time<=compteur_time+1;
  
  if compteur_time<time_value then 
    next_compteur_time<=compteur_time+1;
    next_state<=Wait_delay;
  else 
    next_state<=Sub_track_event;
  end if;


      when Sub_track_event =>
        next_Rom_counter<=Rom_counter+1;
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
        event_value<=Rom_out;
        next_state<=Sub_track_note;

      when Sub_track_note =>
        next_Rom_counter<=Rom_counter+1;
  wr_note<='1';
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
  --note_rom_Address<=Rom_out;     -------> PROBLEM HERE
  test<=Rom_out;
        note_value<=Rom_out;
        next_state<=Sub_track_Volume;

      when Sub_track_volume =>
        next_Rom_counter<=Rom_counter+1;
  wr_volume<='1';
  --freq_value<="00000000000000000000000000001010";
  freq_value<=note_rom_out;
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
        volume_value<=Rom_out;

  if flag_note<nbre_note then
     next_state<=Sub_track_time;
  else 
    next_state<=Final;
  end if;
  

  

        
  -------------------------------------------------------
        


        -- ETAT  Choice END or another Track Chunk --
        -----------------------------------------------------
      --when Choice_End_Another =>
        -- pour le moment on a qu'une seul track 
        -----------------------------------------------------------

        -- ETAT  Final --
                --------------------------------------------------
      when Final => 
  next_state<=Final ;  
                   ---------------------------------------------------
                   
         -- ETAT Error
      when Erreur => 
  next_state<=Erreur ;

  when others => NULL;


                     
    end case;

  end process;

end A;


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

: Edited by User
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
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...

: Edited by Moderator
Author: Ed Hut (hachhac)
Posted on:

Rate this post
0 useful
not useful
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
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.

: Edited by User
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
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...

: Edited by Moderator
Author: Ed Hut (hachhac)
Posted on:

Rate this post
0 useful
not useful
> 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.
entity MAIN_FSM is
  port(Clk                      : in  std_logic;
       Reset                    : in  std_logic;
       Rom_out                  : in std_logic_vector(7 downto 0);
       note_rom_out             : in std_logic_vector(31 downto 0);
       freq_value               : out std_logic_vector(31 downto 0);
       wr_note                  : out std_logic;
       wr_volume                : out std_logic;
       volume_value             : out std_logic_vector(7 downto 0);
       note_value               : out std_logic_vector(7 downto 0);
       event_value              : out std_logic_vector(7 downto 0);
       note_rom_Address         : out std_logic_vector(7 downto 0); -----HERE
       Rom_Address              : out std_logic_vector(5 downto 0));
    

end MAIN_FSM;


>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.

: Edited by User
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
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...

Author: Ed Hut (hachhac)
Posted on:
Attached files:

Rate this post
0 useful
not useful
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 :
 when Sub_track_note =>
        next_Rom_counter<=Rom_counter+1;
        wr_note<='1';
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);

        note_rom_Address<=Rom_out;     -------> PROBLEM HERE
        
        note_value<=Rom_out;
        next_state<=Sub_track_Volume;

      when Sub_track_volume =>
        next_Rom_counter<=Rom_counter+1;
        wr_volume<='1';
  
        freq_value<=note_rom_out;

        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
        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.
 when Sub_track_note =>
        next_Rom_counter<=Rom_counter+1;
        wr_note<='1';
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);

        --note_rom_Address<=Rom_out;     -------> PROBLEM HERE commented
        test<=Rom_out; ------> test value

        note_value<=Rom_out;
        next_state<=Sub_track_Volume;

      when Sub_track_volume =>
        next_Rom_counter<=Rom_counter+1;
        wr_volume<='1';

        freq_value<="00000000000000000000000000001010"; --->constant
        -- freq_value<=note_rom_out;

        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
        volume_value<=Rom_out;


> 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 ....)

: Edited by User
Author: Achim S. (Guest)
Posted on:

Rate this post
0 useful
not useful
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 .....)

Author: Ed Hut (hachhac)
Posted on:

Rate this post
0 useful
not useful
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 !

Author: Achim S. (Guest)
Posted on:

Rate this post
0 useful
not useful
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.

Author: Ed Hut (hachhac)
Posted on:

Rate this post
0 useful
not useful
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.

Author: Achim S. (Guest)
Posted on:

Rate this post
0 useful
not useful
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.

Author: Ed Hut (hachhac)
Posted on:

Rate this post
0 useful
not useful
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 !

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

Rate this post
0 useful
not useful
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:
      when Sub_track_note =>
        next_Rom_counter<=Rom_counter+1;
        wr_note<='1';
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
        note_rom_Address<=Rom_out;
        test<=Rom_out;
        note_value<=Rom_out;
        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*:
      when Sub_track_note =>
        note_value<=Rom_out;
        wr_note<='1';
        note_rom_Address<=Rom_out;
        next_Rom_counter<=Rom_counter+1;
        next_state<=Sub_track_Volume;
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter);
        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...

: Edited by Moderator
Author: Ed Hut (hachhac)
Posted on:
Attached files:

Rate this post
0 useful
not useful
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 ...

: Edited by User
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Ok, one step back: what do you want here?
      when Sub_track_note =>
        next_Rom_counter<=Rom_counter+1;
        wr_note<='1';

        -- update HERE the new ROM adress
        Rom_Address <= STD_LOGIC_VECTOR(Rom_counter); 

        -- and HERE fetch the data from the ROM adress assigned one line above above
        note_rom_Address<=Rom_out;                    

        test<=Rom_out;
        note_value<=Rom_out;
        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?

: 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
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.