cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
573 Views
Registered: ‎05-09-2019

How to avoid ISE optimize ROM from BRAM to logic

Ise tool for Virtex 6 (so far we are stuck with old HW)
We do want to use inferred BRAM instead of core generator, so code can be changed using generic an is more portable when HW is upgraded.

We need to implement ROMs some as block RAM, some as destributed, so I leave synthesis HDL otpions ROM_STYLE to AUTO.
We need to do it in source code (or perhaps by constrains).
Unfortunately translate or MAP optimize the ROM in BRAM to logic, how do I avoid that?
In general we code in VHDL, as VHDL do not support specify the ROM contence as a file, we have a verilog rom_async with a vhdl dp_rom.vhd file above it.

In synthesis report it seems okay:

Synthesizing Unit <DP_ROM>.
Related source file is "C:\Users\psoerensen\Desktop\SPM_BUILD\RNilsson_BF\src\Common\ram\DP_ROM.vhd".
BRAM_DATA_W = 36
ADDR_W = 12
DATA_W = 36
FILE_NAME = "..\src\Beamformer\BfEbgineSinCos_36w_12d_ROM_init.hex"
CLK_DELAY = 1
Found 36-bit register for signal <b_rom_dout_q>.
Found 36-bit register for signal <a_rom_dout_q>.
Summary:
inferred 72 D-type flip-flop(s).
Unit <DP_ROM> synthesized.

Synthesizing Unit <DP_ROM_async>.
Related source file is "C:\Users\psoerensen\Desktop\SPM_BUILD\RNilsson_BF\src\Common\ram\DP_ROM_async.v".
ADDR_W = 12
DATA_W = 36
FILE_NAME = "..\src\Beamformer\BfEbgineSinCos_36w_12d_ROM_init.hex"
Set property "rom_style = block" for signal <a_dout>.
Set property "rom_Style = block" for signal <b_dout>.
Set property "ROM_STYLE = block" for signal <mem>.
WARNING:Xst:2999 - Signal 'mem', unconnected in block 'DP_ROM_async', is tied to its initial value.
Found 4096x36-bit dual-port Read Only RAM <Mram_mem> for signal <mem>.
Summary:
inferred 1 RAM(s).
Unit <DP_ROM_async> synthesized.

However in the final Module Utilization it has been changed to logic, the logic is far to big and too slow to close timing, it must be BRAM for 1024*36 bits.
The basic verilog source code is:

`timescale 1ns/1ns
module DP_ROM_async (a_addr, b_addr, a_dout, b_dout);
parameter ADDR_W = 12;
parameter DATA_W = 36;
parameter FILE_NAME = "SP_ROM_init.hex";
input [ADDR_W-1:0] a_addr;
input [ADDR_W-1:0] b_addr;
(* rom_style="block" *) output [DATA_W-1:0] a_dout;
(* rom_Style="block" *) output [DATA_W-1:0] b_dout;

(* ROM_STYLE="block" *) reg [DATA_W-1:0] mem [0:2**ADDR_W-1];
wire [DATA_W-1:0] a_dout;
wire [DATA_W-1:0] b_dout;

initial begin
#100 // Wait for units of timescale (to allow tb to write init file)
$readmemh (FILE_NAME, mem, 0, 2**ADDR_W-1);
end

assign a_dout = mem[a_addr];
assign b_dout = mem[b_addr];

endmodule

 

0 Kudos
12 Replies
drjohnsmith
Teacher
Teacher
554 Views
Registered: ‎07-09-2009

to reliably convince ISE to use a BRAM,

you need to follow exactly the provided templates in ISE,

 

The normal problem I see, is people trying to use BRAM in a mode it can not support,

   

so double check what you are wanting

 

BTW: 

VHDL inference of a ROM is very normal, 

 can't see why your using verilog .

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
544 Views
Registered: ‎05-09-2019

The problem is that provided template do not support what we want, and yes I know we this is tricky I have done FPGA for 30 years.
I use verilog because VHDL do NOT support describing the ROM contence in a text file, for VHDL you must make a script that write the contence into vhdl code, very inconvenient. Or am I wrong?

I believe my code is okay for the following reasons:

1. The synthesis report states it has inferred the ROM in BRAM.
2. (New info, sorry should have been there in the first place) I have a test file DP_ROM_top.vhd with only one DP_ROM.vhd inside with registers on inputs and outputs, it goes all the way and implement in BRAM as final result, this proves the library file we have maded works.
However when we use multiple of these SP_ROM in a generate statement in our full design, translate or MAP change it into logic. I have checked the input pins of DP_ROM is driven by registers in the code (unless ISE move these registers). I have also checked that we have enough BRAM blocks in the device. So I simply don't understand why translate/Map change the BRAM to logic, the report filles do not state anythink about the change?
Any help is very appreciated

0 Kudos
avrumw
Expert
Expert
521 Views
Registered: ‎01-23-2009

You are coding for a ROM with combinatorial read (0 latency). The block RAM has a minimum latency of one clock cycle - the data output is available on the clock cycle after the address is presented to the RAM/ROM. 

So what you are coding cannot be implemented in a block RAM. The tools have no choice but to implement it either as distributed RAM used as ROM or as a LUT network - the two are actually the same thing. This has nothing to do with language (Verilog vs. VHDL), but matching your RTL code to the capabilities of the cells you are targeting.

If you change your code (and the design around it, since this changes the functionality) to

always @(posedge clk) begin
  a_dout <= mem[a_addr];
  b_dout <= mem[b_addr];
end

Then this should be able to be implemented as a dual port block ROM. 

Avrum
  

drjohnsmith
Teacher
Teacher
521 Views
Registered: ‎07-09-2009

many many ways to fill a BRAM / array in VHDL from a file

   basicaly using textio, and a fiel in the folder,

e.g.

https://vhdlwhiz.com/initialize-ram-from-file/

or in the good old XST templates, page 225,

https://studfile.net/preview/4643996/page:29/

yes , it goes back that far,

   VHDL 2008 makes the type conversions easier, 

   

 

What do the templates not support that you want ?

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
409 Views
Registered: ‎05-09-2019

Expert pointed out the problem Kudo to him, Eventhough ISE synthesize said ROM found and a single ROM test design worked, translate or MAP did not accept it when included in a real design, I moved the non optional register from the VHDL above down to the verilog file and now it works. 
To Drjohn I still don't se how vhdl can read the ROM contence from a text file so it works in synthesis, simulation yes, but ISE synthesis no, using verilogs $readmemh is the only one way I have found that works in synthesis.
Yes there are work arounds like the making a program that reads the file and writes out a vhdl file having constants for the contence, but the $readmemh is a lot more straitforward and efficient.
Eventhough we never write code in verilog because we prefer the strict syntax check in VHDL ( the compiler catch a lot of coding errors), in this particulary case verilog has the needed feature and vhdl don't.

drjohnsmith
Teacher
Teacher
396 Views
Registered: ‎07-09-2009

The VHDL load a rom from a file at synthesis works just fine,

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
343 Views
Registered: ‎05-09-2019

Do have an example of the VHDL reading ROm contence from file that works in ISE, because I failed to find a way?

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

did you look in the links I posted above ?

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
257 Views
Registered: ‎05-09-2019

Yes I did, I tried some think very close to the first link and I could not get it to work in ISE synthesis.
Second example do not read from a file, it use constants directly in code.

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

 Something "similar" is not the example

    Try the example, then modify once it works,

 

Th esecodn link , you say uses embeded constants,

   NO

Yes, the first page shows you the easy , constants, 

BUT

read down a few pages and there are the file input examples, 

Works wonderfully, been using them for years 

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
219 Views
Registered: ‎05-09-2019

The examples are RAM not ROM so I would have to modify them, If you say it works I believe you, I must have done some think wrong then, for unfortunately we are behind schedule and I got my verilog version to work, so I won't have time to investigate the vhdl version.
Thanks for helping out but I must close the case here.

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

For others,

  can I highlight that the links ARE for ROM, 

       ROM is by definition a RAM that you do not write to after FPGA i configured.

 

Sorry you have not been able to follow the examples, may be next time,.

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos