cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
dcwhitehead
Adventurer
Adventurer
6,107 Views
Registered: ‎03-28-2014

Vivado 2016.2 won't generate a WRITE_FIRST Simple Dual Port BRAM

Jump to solution

For some reason I am unable to generate a Simple Dual Port BRAM in WRITE_FIRST mode. I have the BRAM configured for a common clock, Port A Operating Mode=Write First, and no output registers. The BRAM is behaving the way I would expect a READ_FIRST BRAM to behave, and sure enough when I checked the primitive in the synthesized design WRITE_MODE_A  has been changed to READ_FIRST.

 

Settings.pngRD_FIRST.png

Tags (4)
0 Kudos
1 Solution

Accepted Solutions
balkris
Xilinx Employee
Xilinx Employee
10,664 Views
Registered: ‎08-01-2008

This is expected behavior check the PG058 page 55

http://www.xilinx.com/support/documentation/ip_documentation/blk_mem_gen/v8_0/pg058-blk-mem-gen.pdf

Thanks and Regards
Balkrishan
--------------------------------------------------------------------------------------------
Please mark the post as an answer "Accept as solution" in case it helped resolve your query.
Give kudos in case a post in case it guided to the solution.

View solution in original post

tt.png
0 Kudos
5 Replies
balkris
Xilinx Employee
Xilinx Employee
6,085 Views
Registered: ‎08-01-2008
The HDL code has the WRITE_FIRST definition at the top but this can be overwriten by Vivado Synthesis if the generic paramater WRITE_FIRST is false.
Thanks and Regards
Balkrishan
--------------------------------------------------------------------------------------------
Please mark the post as an answer "Accept as solution" in case it helped resolve your query.
Give kudos in case a post in case it guided to the solution.
0 Kudos
dcwhitehead
Adventurer
Adventurer
6,082 Views
Registered: ‎03-28-2014

@balkris

 

There is nothing in my design/constraints that should be overwriting the WRITE_FIRST parameter and yet it still shows up as READ_FIRST after performing synthesis. I checked the HDL code and C_WRITE_MODE_A is set to "WRITE_FIRST," so this value should propagate through since it isn't being modified anywhere else.

 

Thanks,

Dan

0 Kudos
balkris
Xilinx Employee
Xilinx Employee
10,665 Views
Registered: ‎08-01-2008

This is expected behavior check the PG058 page 55

http://www.xilinx.com/support/documentation/ip_documentation/blk_mem_gen/v8_0/pg058-blk-mem-gen.pdf

Thanks and Regards
Balkrishan
--------------------------------------------------------------------------------------------
Please mark the post as an answer "Accept as solution" in case it helped resolve your query.
Give kudos in case a post in case it guided to the solution.

View solution in original post

tt.png
0 Kudos
dcwhitehead
Adventurer
Adventurer
6,054 Views
Registered: ‎03-28-2014

@balkris 

 

In the latest version of PG058 it specifically states that WRITE_FIRST is available. Later on it does recommend against using WRITE_FIRST but it is no longer "hard-coded" to READ_FIRST.

wr_first.png

 

I just find it surprising that UG901's example of inferring a Simple Dual Port BRAM is coded as a WRITE_FIRST RAM when it is not supported by the tools. It seems like the example should infer a READ_FIRST if that's the recommended behavior.

 

architecture syn of simple_dual_one_clock is
  type ram_type is array (RAM_DEPTH-1 downto 0) of std_logic_vector(WORD_DEPTH-1 downto 0);
  shared variable RAM : ram_type; -- WRITE_FIRST (UG901)
  --signal RAM : ram_type; -- READ_FIRST (Actual behavior)
begin
  process(clk)
  begin
    if clk'event and clk = '1' then
if ena = '1' then if wea = '1' then RAM(conv_integer(addra)) := dia; -- WRITE_FIRST (UG901) --RAM(conv_integer(addra)) <= dia; -- READ_FIRST (Acutal behavior) end if; end if; end if; end process;
process(clk) begin if clk'event and clk = '1' then if enb = '1' then dob <= RAM(conv_integer(addrb)); end if; end if; end process; end syn;

 

 

 

0 Kudos
ross@bitbybitsp.com
Contributor
Contributor
2,594 Views
Registered: ‎02-22-2018

PG058 page 55 seems to directly contradict UG573, page 17, "Simple Dual-Port Block RAM", which says that READ_FIRST, WRITE_FIRST, and NO_CHANGE are all available for Simple Dual Port BRAMs.  So is UG573 wrong then?

 

I've encountered this thread because I'm trying to infer block ram from verilog code.  I can infer READ_FIRST fine, but it's very difficult to infer WRITE_FIRST.  It keeps getting changed to READ_FIRST -- even when I can infer WRITE_FIRST in the initial synthesis.  Also, the standard template for WRITE_FIRST requires that the Verilog code be written with a race condition affecting simulation, which is pretty shabby.

 

The reason I want to infer WRITE_FIRST is that it seems to have a more relaxed PULSE_WIDTH requirement.  NO_CHANGE would also be fine, since it also has a smaller required PULSE_WIDTH.  In my application, read and write addresses can't ever be identical (I'm using the BRAM as a double-buffer), so it really doesn't matter which mode I'm in -- I just want the fastest one.

0 Kudos