Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

- Community Forums
- :
- Forums
- :
- Vivado RTL Development
- :
- Synthesis
- :
- Can you populate a ROM with a behavioral function ...

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

silverace99work

Adventurer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

01-16-2020 07:13 AM

1,340 Views

Registered:
03-04-2018

Hi,

I'm building a quarter wave lookup table for sin/cos.

I know in VHDL, that it is possible in design rtl to write a behavioral function and then reference that function to set the values of a ROM, like below, and it will synthesize in Vivado:

-------------------------------------------------------------------------------- -- sin function -------------------------------------------------------------------------------- function generate_sin_rom ( addr_width : natural; data_width : natural; scale_factor: real ) return rom_t is variable sin_rom_v : rom_t; begin for i in 0 to ((2**addr_width) - 1) loop sin_rom_v(i) := to_unsigned(integer(((2.0**data_width)-1.0) * scale_factor * sin((math_pi/2.0) * (real(i) / real(2**addr_width)))), data_width); end loop; return sin_rom_v; end function generate_sin_rom; -------------------------------------------------------------------------------- constant SIN_ROM : rom_t := generate_sin_rom(ADDR_WIDTH, DATA_WIDTH, SCALE_FACTOR); -- Sine quantized generated look-up table begin -------------------------------------------------------------------------------- -- Describes the behavior of a trigonometric sine ROM. -------------------------------------------------------------------------------- Sine_ROM: process(CLOCK) begin if rising_edge(CLOCK) then SINE_Z <= SIN_ROM(to_integer(SIN_ADDR)); end if; end process Sine_ROM;

Is that possible in verilog? If so, how might I go about doing it, and will the vivado synthesis tool handle it?

If it's not possible, are there any alternative ways I could initialize my lookup table without pre-building with .hex files or scripts?

The idea is to make the whole thing a parameterizable IP.

Thanks,

Stephen

1 Solution

Accepted Solutions

avrumw

Expert

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

01-16-2020 01:53 PM

1,289 Views

Registered:
01-23-2009

I am pretty sure (but not 100%) that you can do it in an initial block; put the same kind of for loop in the initial block that sets a value for each value in the lookup function. This will result in an initialized array (at time 0), which can then be dereferenced using sin_rom[sin_addr].

The sysnthesis tool should accept this as initialization of the block memory based ROM...

(But I haven't tried something like this since the XST days, so I don't know for sure that it will work in Vivado).

Avrum

6 Replies

avrumw

Expert

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

01-16-2020 01:53 PM

1,290 Views

Registered:
01-23-2009

I am pretty sure (but not 100%) that you can do it in an initial block; put the same kind of for loop in the initial block that sets a value for each value in the lookup function. This will result in an initialized array (at time 0), which can then be dereferenced using sin_rom[sin_addr].

The sysnthesis tool should accept this as initialization of the block memory based ROM...

(But I haven't tried something like this since the XST days, so I don't know for sure that it will work in Vivado).

Avrum

silverace99work

Adventurer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

01-20-2020 10:13 AM - edited 01-20-2020 10:21 AM

1,212 Views

Registered:
03-04-2018

@avrumw thanks for the idea.

I put together some verilog code along those lines, and realized that I have another problem: If I want to use a math library to calculate sin/cos, I would have to call the library with something like this:

//////////////////////////////////////////////////////////////// //Behavioral math function package setup //NOTE: Relies on the libmath.so library built into linux //////////////////////////////////////////////////////////////// import "DPI-C" pure function real sin (input real rTheta); import "DPI-C" pure function real cos (input real rTheta); const real pi = 3.141592653589793; //IEEE double precision

I got a synthesis error: [Synth 8-27] DPI function not supported

From what I gather, it generally isn't possible to synthesize DPI calls. But in this special case where I'm only using it to generate initial ROM values, is there any chance that Vivado can handle it, and I'm just missing something?

I suppose in the worst case I can write my lookup table in VHDL (I know that vivado supports the vhdl IEEE math library), but I was hoping to avoid mixed-language simulation.

Thanks,

Stephen

avrumw

Expert

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

01-20-2020 08:10 PM

1,177 Views

Registered:
01-23-2009

I'm not sure why you are trying to work with a DPI function. Verilog and SystemVerilog have trig functions built in - just use $sin(x) and $cos(x) - these accept an angle (x) as a real operand and return a real value. The LRM for both Verilog and SystemVerilog say they are the equivalents of the C functions sin(x) and cos(x) - (I would have to go look at a C manual to remember if these functions take degrees or radians)...

However, I haven't tried these to know if they are synthesizable (as elaboration constants).

Avrum

silverace99work

Adventurer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

01-21-2020 06:36 AM

1,153 Views

Registered:
03-04-2018

Also, I couldn't locate anything about $sin/$cos in the SystemVerilog LRM...however when I tried it, it passed Vivado synthesis. For my reference could you kindly tell me what page of the LRM that was on? Just cannot seem to find it.

Will go and build a testbench on this just to make sure it works...

avrumw

Expert

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

01-21-2020 03:08 PM - edited 01-21-2020 03:09 PM

1,118 Views

Registered:
01-23-2009

For my reference could you kindly tell me what page of the LRM that was on?

In the last few versions of the SystemVerilog LRM (IEEE 1800-2012 and 1800-2017) these functions are described in section 20.8.2 "Real math functions".

In the last Verilog LRM (IEEE 1364-2005) they are in section 17.11.2 "Real math functions".

Avrum

silverace99work

Adventurer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

01-22-2020 03:47 PM

1,085 Views

Registered:
03-04-2018