cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
asai9493
Explorer
Explorer
631 Views
Registered: ‎12-10-2020

Problem of metastability in memory simulation VHDL

Hello!

i simulate Dual Port Ram Register in VHDL and have some doubts about the metastability problem.

Dual Port Ram has 2 clock signal, one for Port A , the second for Port B. In my simulation I create two processes with 2 differentes clocks.

 

type memory_type is array(0 to adress_width) of std_logic_vector(data_width-1 downto 0); --> memory array
signal memory_sgnl : memory_type := (others => (others => '0'));;

begin

-- Port A
process(clk_a)
begin
if(rising_edge(clk_a)) then
if(we_a = '1') then
memory_sgnl (addr_a) := data_in;
end if;
data_out<= memory_sgnl (addr_a);
end if;
end process;

-- Port B
process(clk_b)
begin
if(rising_edge(clk_b)) then
if(we_b = '1') then
memory_sgnl (addr_b) := data_in;
end if;
data_out<= memory_sgnl (addr_b);
end if;
end process;

 



I have found a post here [1]. Mr Jim Lewis made a suggestion how DP Ram with 2 clocks can be simulated. He did the same implementation. So i can conclude I did correctly.

BUT I have read We need to solve a problem metastability, because there 2 clock signal : clock time crossing.

 

clk_crossing: process(clk, rst)
begin
if rst ='1' then
--
a_clk_b <= '1';
a_clk_bb <= '1';

b_clk_b <= '1';
b_clk_bb <= '1';

elsif rising_edge(clk) then
a_clk_b <= a_clk;
a_clk_bb <= a_clk_b;

b_clk_b <= b_clk;
b_clk_bb <= b_clk_b;

end if; -- if rst ='1' then
end process clk_crossing;

 

 

and then the processes should be `process(a_clk_bb )` and `process(b_clk_bb )`

Will be it correct? Did I understand correctly how to solve metastability question?

 

 

[1]: memory - Creating large dual-port RAM in VHDL - Stack Overflow

0 Kudos
12 Replies
richardhead
Scholar
Scholar
609 Views
Registered: ‎08-01-2012

With a dual port ram, there is no metastability problem as the data is being transferred between the clock domains via the ram. 

Also, I dont know what you're trying to do with all those clocks from a single source clock, but it certainly isnt metastability protection. You should never sample a clock with another clock. 

If you are transfering signals between clock domains, then at a minimum, you should use two registers in the destination domain as this will minimise the risk of meta stable conditions. But you also need to think about the relative clock speeds. For example, transferring from a fast clock to a slow clock will mean short pulses will be missed. If possible, you should transfer between domains using a dual port ram or a FIFO.

asai9493
Explorer
Explorer
604 Views
Registered: ‎12-10-2020

@richardhead 

I have two asynchronous clocks, it means metastability  is appeared, right ? With the process "clk_crossing" (pipelined latches) I would like to resolve it. 

0 Kudos
dpaul24
Scholar
Scholar
595 Views
Registered: ‎08-07-2014

@asai9493 ,

Just as a check for you (I did not go through your code)....

i simulate Dual Port Ram Register in VHDL and have some doubts about the metastability problem.

Are you following the Vivado guidelines for inferring Dual Port Ram? If not, I STRONGLY advice you to refer to the code snippet recommended by Xilinx.

https://www.xilinx.com/support/documentation/sw_manuals/xilinx2019_2/ug901-vivado-synthesis.pdf

See Chapter4, RAM HDL Coding guidelines.

------------FPGA enthusiast------------
Consider giving "Kudos" if you like my answer. Please mark my post "Accept as solution" if my answer has solved your problem
Asking for solutions to problems via PM will be ignored.

richardhead
Scholar
Scholar
567 Views
Registered: ‎08-01-2012

@asai9493 

Your post is confusing as you have lots of signals called a_clk, b_clk, and clk_a and clk_b. Maybe you should be more clear what you are trying to do? are you trying to get a single bit across a clock domain? or an actual clock?

0 Kudos
asai9493
Explorer
Explorer
539 Views
Registered: ‎12-10-2020

@richardhead 

clk_a and clk_b are input clk

a_clk_b ,b_clk_b,a_clk_bb ,b_clk_bb are std_logic.

a_clk_b ,b_clk_b are one clk delay

a_clk_bb ,b_clk_bb are 2 clk delay

0 Kudos
drjohnsmith
Teacher
Teacher
532 Views
Registered: ‎07-09-2009

taking step back,

dual port rams, have two independent clocks,

    you read and write to the clock of the port you are using

 

Could it be that in your code, you are using a signal and a variable ?

memory_sgnl (addr_a) := data_in;

 

Why not just signals ?

has feeling as if you have assumed there is an asynchronous problem, and tried to fix it when there is no problem,

    If so, Weve all done that many a time I cab assure you, 

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
bruce_karaffa
Scholar
Scholar
520 Views
Registered: ‎06-21-2017

If you are doing a behavioral simulation, the simulation cannot show metastability.  This is something that happens in hardware, not simulators.  @richardhead , @dpaul24  and @drjohnsmith are correct.  A Xilinx dual ported RAM uses independent clock domains and does not exhibit metastability.  Either use the dual port RAM template, or explicitly instantiate a dual port RAM.  I also looked at the post you referenced and did not see Jim Lewis's name.

dpaul24
Scholar
Scholar
505 Views
Registered: ‎08-07-2014

@bruce_karaffa , If the OP, @asai9493  just can answer my question as to whether he is using Xilinx recommended template or not, our speculations will be over. But he seems to ignore my advice.

------------FPGA enthusiast------------
Consider giving "Kudos" if you like my answer. Please mark my post "Accept as solution" if my answer has solved your problem
Asking for solutions to problems via PM will be ignored.

0 Kudos
asai9493
Explorer
Explorer
465 Views
Registered: ‎12-10-2020

@drjohnsmith 

 

type memory_type is array(0 to (2*adress_width-1)) of std_logic_vector(data_width-1 downto 0); --> memory array
signal memory_sgnl : memory_type := (others => (others => '0'));

 

memory_sgnl is a signal.

 

I create two different clk signal: for port A and for port B. 

 

 

 

0 Kudos
asai9493
Explorer
Explorer
462 Views
Registered: ‎12-10-2020

0 Kudos
asai9493
Explorer
Explorer
462 Views
Registered: ‎12-10-2020

@dpaul24 

I have has a look at the pdf you suggested and found templates.

Currently I am trying to rewrite the code and fixed mistakes.

thank you for your suggestion

 

avrumw
Expert
Expert
417 Views
Registered: ‎01-23-2009

A Xilinx dual ported RAM uses independent clock domains and does not exhibit metastability. 

I just want to clarify this statement...

Any time there are asynchronous events that occur around a memory cell there is a possibility of metastability. And this must be true of the the block RAM (or any other memory technology). If you write and read to the same memory location at almost the same time on two different clocks, then there is the possibility of metastability. The metastability will not be in the memory cell itself (the writing port is purely synchronous to the write clock), but somewhere in the read path - in the latched outputs and/or in the registered outputs of the RAM. This is "documented" in the rules associated with reading and writing to the same address; they don't call it metastability, but describe it as producing unpredictable read results.

Now, in most systems we avoid this metastability by ensuring that we never read and write to the same address "near" the same time. This is either done by some user mechanism, or, more commonly, through a "FIFO" paradigm; one of the principle characteristics of the pointer manipulation (and synchronization) in an asynchronous FIFO is to ensure (via the empty and full flags) that the FIFO never attempts to read from a memory location that has recently been written to - the clock crossings of the pointers and the generation of full/empty ensure that there is always at least a couple of clocks between when a location is written and when it is read (and vice versa). It is this mechanism that avoids the potential for metastability in the read path.

Avrum

0 Kudos