cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Explorer
Explorer
392 Views
Registered: ‎02-04-2013

True dual port bram simulation : X value

Jump to solution

Hello everybody,

I am experimenting with true dual port bram instantiated in VHDL code. After i write some value to BRAM memory, i read X instead of the value i stored. Any idea why is that?

 

memory_side_A_cpu : process(clk_i)
begin
if rising_edge(clk_i) then

if (memA_acc_en = '1') then -- reduce switching activity when not accessed
if (memA_wren(1) = '1') then
mem_ram_H(to_integer(unsigned(memA_addr))) <= memA_wdata(15 downto 8);
end if;
if (memA_wren(0) = '1') then
mem_ram_L(to_integer(unsigned(memA_addr))) <= memA_wdata(07 downto 0);
end if;
end if;

memA_rdata(15 downto <= mem_ram_H(to_integer(unsigned(memA_addr)));
memA_rdata(07 downto 0) <= mem_ram_L(to_integer(unsigned(memA_addr)));

end if;
end process;


memory_side_B_rxmac : process(clk_mac_i)
begin
if rising_edge(clk_mac_i) then

if (memB_acc_en = '1') then
if (memB_wren(1) = '1') then
mem_ram_H(to_integer(unsigned(memB_addr))) <= memB_wdata(15 downto 8);
end if;
if (memB_wren(0) = '1') then
mem_ram_L(to_integer(unsigned(memB_addr))) <= memB_wdata(07 downto 0);
end if;
end if;

memB_rdata(15 downto <= mem_ram_H(to_integer(unsigned(memB_addr)));
memB_rdata(07 downto 0) <= mem_ram_L(to_integer(unsigned(memB_addr)));

end if;
end process;

 

Block RAM: Preliminary Mapping Report (see note below)

mem_ram_H_reg | 1 K x 8(READ_FIRST) | W | R | 1 K x 8(READ_FIRST) | W | R | Port A and B | 1 mem_ram_L_reg | 1 K x 8(READ_FIRST) | W | R | 1 K x 8(READ_FIRST) | W | R | Port A and B | 1 |

 

 

 

bram.png
0 Kudos
1 Solution

Accepted Solutions
Highlighted
Scholar
Scholar
336 Views
Registered: ‎08-01-2012

Your ram has multiple drivers:

mem_ram_H and mem_ram_L are driven from two processes. You can only drive a signal from one proces.

You'll either need to use a shared variable (with VHDL 93 code) or merge the two processes.

View solution in original post

7 Replies
Highlighted
Scholar
Scholar
337 Views
Registered: ‎08-01-2012

Your ram has multiple drivers:

mem_ram_H and mem_ram_L are driven from two processes. You can only drive a signal from one proces.

You'll either need to use a shared variable (with VHDL 93 code) or merge the two processes.

View solution in original post

Highlighted
Explorer
Explorer
322 Views
Registered: ‎02-04-2013

This is typical for BRAM with true dual port. You can see how to infer a BRAM in UG901 page 121 and on.

I think this you can write to BRAM from two separate processes. Actually til now i was using BRAM macro the same way without any problem. I decided to infer a BRAM in VHDL to make the code portable, but now i have this problem with X, and i cannot simulate my design.

 

Regards

0 Kudos
Highlighted
Voyager
Voyager
317 Views
Registered: ‎06-20-2012

@fogl 

As @richardhead  says the example page 121 is with shared variable not signals.

 

== If this was helpful, please feel free to give Kudos, and close if it answers your question ==
0 Kudos
Highlighted
Adventurer
Adventurer
291 Views
Registered: ‎05-09-2018

Assuming that this is a behavioural sim the ram inferencing guidelines shouldn't really matter. (Until you actually want to infer the RAM)

Also, you can in fact drive a signal from more than one process (Providing that it is a resolved type).

I would trace out the memory arrays. This way you can check that the write process is working.

0 Kudos
Highlighted
Scholar
Scholar
281 Views
Registered: ‎08-01-2012

@fogl @stfarley 

Any signal that is driven from more than one process has multiple drivers. And yes, while only resolved types are allowed multiple drivers, it means that if one process drove a '0' and the other drove a '1', you'll get 'X' as a result. If if you used std_ulogic_vector instead of std_logic_vector for the memory array you would have had an error when you compiled because of multiple drivers.

The only answer here is to use a shared variable or stick to a single process. This is VHDL issue, not a BRAM issue - this is what happens with signals in multiple processes.

@fogl 

Previously a macro is just that - a macro - so internally you dont know how it was coded (its basically a netlist)

@stfarley 

Here this is true dual port - so both A and B sides can both read and write. The ram inferencing guidelines recommend using a shared variable for this (but then you cant use 2008 code).

0 Kudos
Highlighted
Voyager
Voyager
280 Views
Registered: ‎06-20-2012

@stfarley 

"Also, you can in fact drive a signal from more than one process (Providing that it is a resolved type)."

Sure, but you're doing a short circuit.
In simulation the result of the resolution function is an 'X'.

Fortunately it cannot be synthesized.

== If this was helpful, please feel free to give Kudos, and close if it answers your question ==
0 Kudos
Highlighted
Explorer
Explorer
237 Views
Registered: ‎02-04-2013

Thank you all for your reply, i was not careful enough and i didn't notice in the it was actually a shared variable.

Now everything works as expected

0 Kudos