3
\$\begingroup\$

I am storing a 16k constant sine table of 14 bit signed vectors in a package.

I use this package in my module to read out the array in a clocked process

But I get this warning during synthesis and my synthesis is taking a long time -

The RAM will be implemented on LUTs either because you have described an asynchronous read or because of currently unsupported block RAM features. If you have described an asynchronous read, making it synchronous would allow you to take advantage of available block RAM resources, for optimized device usage and improved timings. Please refer to your documentation for coding guidelines."

code in package -

TYPE signed_array IS ARRAY (integer RANGE <>) OF signed (DATAWIDTH-1 DOWNTO 0); 
CONSTANT SINE_TABLE_SIZE : integer := QUARTER_LENGTH+1; -- 16384+1
----sine pi/2 = 1 <=> "0111111....1" MSB is 0 because of the signed representation
CONSTANT SINE_TABLE : signed_array(0 TO SINE_TABLE_SIZE-1):= (
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.0), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*9.5873799096e-05), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000191747597311), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000287621393763), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000383495187571), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000479368977855), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000575242763732), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000671116544322), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000766990318743), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000862864086114), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.000958737845553), DATAWIDTH) ,
 to_signed(integer((2.0**(DATAWIDTH-1)-1.0)*0.00105461159618), DATAWIDTH) ,
process(clk)
 if rising_edge(clk) then
 ctd <= ctr + 1;
 end if;
end process;
cos <= SINE_TABLE(to_integer(unsigned(ctr)));

Any suggestions on how to write a vhdl code in infer a block RAM instead of LUTs?

The SINE TABLE is in a package, and the process is in the main module

Martin Thompson
8,6491 gold badge26 silver badges45 bronze badges
asked Apr 29, 2015 at 7:05
\$\endgroup\$
4
  • \$\begingroup\$ Can you present some code? You can set a RAM_STYLE attribute to force BlockRAM usage. I assume XST misses a read clock because BlockRAM does not support synchronous read. \$\endgroup\$ Commented Apr 29, 2015 at 7:24
  • \$\begingroup\$ I will modify the question to add code.. \$\endgroup\$ Commented Apr 29, 2015 at 7:46
  • \$\begingroup\$ What you have in here is giant combinatorial block you need to synchronize your access by putting the read operation in the clocked process. \$\endgroup\$ Commented Apr 30, 2015 at 6:36
  • \$\begingroup\$ @FarhadA yes...have done it \$\endgroup\$ Commented May 4, 2015 at 6:43

2 Answers 2

3
\$\begingroup\$

Move the take lookup right next to the increment so the output is registered.

That is a gigantic lookup table, though. You may want to consider using a compressed lookup table to save on the block RAM. The trade-off is you may need a couple of multipliers.

Here is an example of a pipelined, compressed sine lookup table: https://github.com/alexforencich/verilog-dsp/blob/master/rtl/sine_dds_lut.v . By default, this one has an 18 bit phase input (2^18 = 262k equivalent entries) with a 16 bit output width. It consumes 3 block RAMs (two are 512x16 and one is 256x8) and two DSP slices.

answered Apr 29, 2015 at 8:01
\$\endgroup\$
7
  • 1
    \$\begingroup\$ u mean i should register cos assignment as well? \$\endgroup\$ Commented Apr 29, 2015 at 8:04
  • 2
    \$\begingroup\$ Yeah. Xilinx block RAMs want a register on the output data. If you don't provide one, this is the error you get. Yes, I have made this mistake many times before. \$\endgroup\$ Commented Apr 29, 2015 at 8:07
  • \$\begingroup\$ i registered the output. It still doesnt work. \$\endgroup\$ Commented Apr 29, 2015 at 8:49
  • \$\begingroup\$ i want the output to be registered based on the 2 MSBs of the counter. So I have a case statement inside the process where the output is being registered. this is a clocked process \$\endgroup\$ Commented Apr 29, 2015 at 8:50
  • \$\begingroup\$ i however saw that if i register the output inside a simple clocked process, the tool infers a block ram \$\endgroup\$ Commented Apr 29, 2015 at 8:51
2
\$\begingroup\$

The memory read needs to be registered to be recognised as a block RAM:

process(clk)
 if rising_edge(clk) then
 ctr <= ctr + 1;
 cos <= SINE_TABLE(to_integer(unsigned(ctr)));
 end if;
end process;

I would also make ctr of an integer type - then you don't need to faff around with the conversions.

answered Apr 29, 2015 at 14:22
\$\endgroup\$
4
  • \$\begingroup\$ this works...but what i actually want is not a direct assignment of "cos" but an assignment based on the 2 MSBs of the ctr to decide which quadrant of the sine signal is used. So I gave a case structure inside this clocked process, but this causes somehow the synthesis tool again not to infer the block ram \$\endgroup\$ Commented May 4, 2015 at 6:46
  • \$\begingroup\$ Are you trying to read both the sin and cos in the same clock cycle? If so you need to be careful to use a VHDL construct which the synthesis tool recognises as a dual-read BRAM. Also, keep the memory-reading logic separate from the address calculating logic (in separate processes) if you are using XST - it sometimes struggles to identify RAM constructs when things are mixed together in the same process. \$\endgroup\$ Commented May 4, 2015 at 19:07
  • \$\begingroup\$ Thank you...that makes sense why the tool was not inferring the block RAM \$\endgroup\$ Commented May 6, 2015 at 7:01
  • \$\begingroup\$ I had mixed a mux inside the same clocked process as the output registration of the block RAM \$\endgroup\$ Commented May 7, 2015 at 7:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.