latches in vhdl

X

Xin Xiao

Guest
I'm designing a cache memory using a Finite State Machine (in vhdl). This is
the template code:

process (Clk, Reset)
begin
if (Reset = '1') then
STATE <= RESET_STATE;
elsif (rising_edge(Clk)) then
STATE <= NEXT_STATE;
end if;

process (STATE)
variable cache : cache_type;
begin
case STATE is
...
...
end case;
end if;

The problem is that I'm getting millions of warnings from my synthesis tool
because it is inferring latches for variable cache, I suppose this is
because the second process (where I put/get data from the memory) is not
clocked and I'm not assigning values for cache variable in every state (of
course, a memory should keep previous data intact!). Simulation works well
but I'm afraid I will get sim/synth mismatches. What do you think? I don't
think a latch would be a good idea to model a cache memory...
 
<quote>
If you insist on using two
processes, then you must provide a value for 'cache' for every
possible way through the process (typically this is done by assigning
a default value at the start of the process and then getting into the
rest of the logic). This guarantees that it will be assigned to no
matter what.
</quote>

Yep, the problem is that if I assign default values each time the process is
woken up (ie every state transition) then i'm losing all the information i
stored in the memory, or am I missing something?

OK, if I assign values to my memory in a clocked process I suppose that the
synthesis tool would infer register(s) to store the information. Right?



"KJ" <kkjennings@sbcglobal.net> wrote in message
news:490dd218-2568-4b87-83ab-309428047a17@e4g2000hsg.googlegroups.com...
On Jan 3, 9:33 am, "Xin Xiao" <x...@x.com> wrote:
I'm designing a cache memory using a Finite State Machine (in vhdl). This
is
the template code:

process (Clk, Reset)
begin
if (Reset = '1') then
STATE <= RESET_STATE;
elsif (rising_edge(Clk)) then
STATE <= NEXT_STATE;
end if;

process (STATE)
variable cache : cache_type;
begin
case STATE is
...
...
end case;
end if;

The problem is that I'm getting millions of warnings from my synthesis
tool
because it is inferring latches for variable cache, I suppose this is
because the second process (where I put/get data from the memory) is not
clocked and I'm not assigning values for cache variable in every state
That's the reason....and also why the two process model that you're
using is not recommended by many folks. Use one clocked process
(probably just means moving your case statement up into your clocked
process) and make life easier on yourself. If you insist on using two
processes, then you must provide a value for 'cache' for every
possible way through the process (typically this is done by assigning
a default value at the start of the process and then getting into the
rest of the logic). This guarantees that it will be assigned to no
matter what. But like I said, one synchronous process is the
generally cleaner approach.

(of
course, a memory should keep previous data intact!). Simulation works well
but I'm afraid I will get sim/synth mismatches. What do you think? I don't
think a latch would be a good idea to model a cache memory...
It's not a good thing. Fix it before it bites you harder down the
road.

Kevin Jennings
 
I see that the synthesis tool now is using registers to model my cache
memory...

It detected the FSM too...

Wow, but the report says there are 16,968 registers in the design ! this is
cache_type:

subtype cache_range is natural range 1 downto 0;

type entry is record
tag: natural;
valid : boolean;
dirty : boolean;
data : std_logic_vector(15 downto 0);
end record;

type cache_type is array (cache_range) of entry;

Indeed, the synthesis tool is taking a long time to finish and with such
number of registers, delay paths will be huge! maybe I will burn the fpga!


"KJ" <kkjennings@sbcglobal.net> wrote in message
news:490dd218-2568-4b87-83ab-309428047a17@e4g2000hsg.googlegroups.com...
On Jan 3, 9:33 am, "Xin Xiao" <x...@x.com> wrote:
I'm designing a cache memory using a Finite State Machine (in vhdl). This
is
the template code:

process (Clk, Reset)
begin
if (Reset = '1') then
STATE <= RESET_STATE;
elsif (rising_edge(Clk)) then
STATE <= NEXT_STATE;
end if;

process (STATE)
variable cache : cache_type;
begin
case STATE is
...
...
end case;
end if;

The problem is that I'm getting millions of warnings from my synthesis
tool
because it is inferring latches for variable cache, I suppose this is
because the second process (where I put/get data from the memory) is not
clocked and I'm not assigning values for cache variable in every state
That's the reason....and also why the two process model that you're
using is not recommended by many folks. Use one clocked process
(probably just means moving your case statement up into your clocked
process) and make life easier on yourself. If you insist on using two
processes, then you must provide a value for 'cache' for every
possible way through the process (typically this is done by assigning
a default value at the start of the process and then getting into the
rest of the logic). This guarantees that it will be assigned to no
matter what. But like I said, one synchronous process is the
generally cleaner approach.

(of
course, a memory should keep previous data intact!). Simulation works well
but I'm afraid I will get sim/synth mismatches. What do you think? I don't
think a latch would be a good idea to model a cache memory...
It's not a good thing. Fix it before it bites you harder down the
road.

Kevin Jennings
 
On Jan 3, 9:33 am, "Xin Xiao" <x...@x.com> wrote:
I'm designing a cache memory using a Finite State Machine (in vhdl). This is
the template code:

process (Clk, Reset)
begin
  if (Reset = '1') then
   STATE <= RESET_STATE;
  elsif (rising_edge(Clk)) then
   STATE <= NEXT_STATE;
end if;

process (STATE)
    variable cache : cache_type;
begin
    case STATE   is
        ...
        ...
    end case;
end if;

The problem is that I'm getting millions of warnings from my synthesis tool
because it is inferring latches for variable cache, I suppose this is
because the second process (where I put/get data from the memory) is not
clocked and I'm not assigning values for cache variable in every state
That's the reason....and also why the two process model that you're
using is not recommended by many folks. Use one clocked process
(probably just means moving your case statement up into your clocked
process) and make life easier on yourself. If you insist on using two
processes, then you must provide a value for 'cache' for every
possible way through the process (typically this is done by assigning
a default value at the start of the process and then getting into the
rest of the logic). This guarantees that it will be assigned to no
matter what. But like I said, one synchronous process is the
generally cleaner approach.

(of
course, a memory should keep previous data intact!). Simulation works well
but I'm afraid I will get sim/synth mismatches. What do you think? I don't
think a latch would be a good idea to model a cache memory...
It's not a good thing. Fix it before it bites you harder down the
road.

Kevin Jennings
 
On Jan 3, 10:15 am, "Xin Xiao" <x...@x.com> wrote:
quote
If you insist on using two
processes, then you must provide a value for 'cache' for every
possible way through the process (typically this is done by assigning
a default value at the start of the process and then getting into the
rest of the logic).  This guarantees that it will be assigned to no
matter what.
/quote

Yep, the problem is that if I assign default values each time the process is
woken up (ie every state transition) then i'm losing all the information i
stored in the memory, or am I missing something?

No you're not missing anything...and you're catching on now to one of
the drawbacks to the 'two process style' where you have a purely
combinatorial process with all the logic and a second clocked process
simply for generating the registers. There is nothing really to
recommend this style of design, it is more error prone, more prone to
generating unintended latches, and takes more lines of code.

That style is often taught, you're not alone it recurs in these groups
somewhat frequently but there are no actual advantages to it, only
drawbacks.

OK, if I assign values to my memory in a clocked process I suppose that the
synthesis tool would infer register(s) to store the information. Right?

Most likely. Depending on the size of the memory it might also
synthesize to an embedded memory that is likely available in the
device itself. In either case though, using a single clocked process
is the way to get to what you are trying to accomplish.

Kevin Jennings
 
On Jan 3, 9:37 am, "Xin Xiao" <x...@x.com> wrote:
I see that the synthesis tool now is using registers to model my cache
memory...

It detected the FSM too...

Wow, but the report says there are 16,968 registers in the design ! this is
cache_type:

subtype cache_range is natural range 1 downto 0;

type entry is record
tag: natural;
valid : boolean;
dirty : boolean;
data : std_logic_vector(15 downto 0);
end record;

type cache_type is array (cache_range) of entry;

Indeed, the synthesis tool is taking a long time to finish and with such
number of registers, delay paths will be huge! maybe I will burn the fpga!

"KJ" <kkjenni...@sbcglobal.net> wrote in message

news:490dd218-2568-4b87-83ab-309428047a17@e4g2000hsg.googlegroups.com...
On Jan 3, 9:33 am, "Xin Xiao" <x...@x.com> wrote:



I'm designing a cache memory using a Finite State Machine (in vhdl). This
is
the template code:

process (Clk, Reset)
begin
if (Reset = '1') then
STATE <= RESET_STATE;
elsif (rising_edge(Clk)) then
STATE <= NEXT_STATE;
end if;

process (STATE)
variable cache : cache_type;
begin
case STATE is
...
...
end case;
end if;

The problem is that I'm getting millions of warnings from my synthesis
tool
because it is inferring latches for variable cache, I suppose this is
because the second process (where I put/get data from the memory) is not
clocked and I'm not assigning values for cache variable in every state

That's the reason....and also why the two process model that you're
using is not recommended by many folks. Use one clocked process
(probably just means moving your case statement up into your clocked
process) and make life easier on yourself. If you insist on using two
processes, then you must provide a value for 'cache' for every
possible way through the process (typically this is done by assigning
a default value at the start of the process and then getting into the
rest of the logic). This guarantees that it will be assigned to no
matter what. But like I said, one synchronous process is the
generally cleaner approach.

(of
course, a memory should keep previous data intact!). Simulation works well
but I'm afraid I will get sim/synth mismatches. What do you think? I don't
think a latch would be a good idea to model a cache memory...

It's not a good thing. Fix it before it bites you harder down the
road.

Kevin Jennings
In order to infer memory from your array (besides memory being
available in your target device), the synthesis tool has to be able to
tell from your code that only one element of that array (one address
in the ram) is accessed in the same clock cycle (two elements/
addresses for a dual port ram). Making that clear to the synthesis
tool is where the fun starts...

Andy
 
Xin Xiao schrieb:

I'm designing a cache memory using a Finite State Machine (in vhdl).
Hi Xin,
you should describe the memory part separate from the FSM. The way you
did it the synthesis tool is not able to infer a block of memeory.
Instead it creates a single flip flop for each bit to store.

Just imagine your synthesis tool istn't able to infer memory blocks at
all and you have to work with an instantiated memory block.
Now you can design your FSM for controlling this memory block to behave
like a cache.

Afterwards write some code to infer that memory block. ;-)
(separate from your FSM)

have a nice synthesis
Eilert
 
Hi backhus, could you explain a bit more? how can i work with an
instantiated memory block?

Afterwards write some code to infer that memory block. ;-)
(separate from your FSM)
if you could write a brief example or give me some webpage i'll apreciate
it.

"backhus" <nix@nirgends.xyz> wrote in message
news:flkofi$ov9$1@news.hs-bremen.de...
Xin Xiao schrieb:

I'm designing a cache memory using a Finite State Machine (in vhdl).

Hi Xin,
you should describe the memory part separate from the FSM. The way you did
it the synthesis tool is not able to infer a block of memeory. Instead it
creates a single flip flop for each bit to store.

Just imagine your synthesis tool istn't able to infer memory blocks at all
and you have to work with an instantiated memory block.
Now you can design your FSM for controlling this memory block to behave
like a cache.

Afterwards write some code to infer that memory block. ;-)
(separate from your FSM)

have a nice synthesis
Eilert
 
Xin Xiao wrote:

if you could write a brief example or give me some webpage i'll
apreciate it.
http://home.comcast.net/~mike_treseler/block_ram.vhd
 
It's more of less what I have in my code, but all the write/read is done
inside my FSM code (to model the cache behaviour). So my synthesis tool
creates a single flip flop to each bit to store (as backhus said), not a ram
block.


"Mike Treseler" <mike_treseler@comcast.net> wrote in message
news:5u71tpF1dtqm7U1@mid.individual.net...
Xin Xiao wrote:

if you could write a brief example or give me some webpage i'll apreciate
it.

http://home.comcast.net/~mike_treseler/block_ram.vhd
 
On Thu, 3 Jan 2008 16:37:49 +0100, "Xin Xiao" <x@x.com> wrote:

I see that the synthesis tool now is using registers to model my cache
memory...

It detected the FSM too...

Wow, but the report says there are 16,968 registers in the design ! this is
cache_type:

subtype cache_range is natural range 1 downto 0;

type entry is record
tag: natural;
valid : boolean;
dirty : boolean;
data : std_logic_vector(15 downto 0);
end record;

type cache_type is array (cache_range) of entry;
Inferring memory is preferable, but if you are trying to compare against all
tags in a cycle to detect matches, it will not be possible.

Why is the tag a natural? You probably want to restrict its range; that would
certainly reduce register usage...

- Brian
 

Welcome to EDABoard.com

Sponsor

Back
Top