PDA

View Full Version : Port sin LUT from VHDL to Verilog


09-20-2008, 07:36 AM
Hi all,

I am trying to port some VHDL code that generates a sin LUT (0 to pi/
2) at compile time that is configurable based on desired LUT depth and
resolution to Verilog. This is pretty straightforward in VHDL since
the synthesis tools support using real values to calculate the sin as
shown below, but I have been unable to find a way to do this in
Verilog without hardcoding in the entire LUT. I am using Synplify Pro
for synthesis, and as far as I can tell it doesnt support the sin
function or even Verilog reals at all. If anyone has any ideas on how
to do this, I'd really appreciate it.

constant c_pi_2 : real := 1.5707963;
constant c_lut_size : integer := 2048;
constant c_sin_width : integer := 16;

type sin_lut_type is array(natural range <>) of
unsigned(c_sin_width-1 downto 0);

function gen_sin_lut_func(table_size : positive; sin_width:
positive) return sin_lut_type is
variable ret_sin_lut_v : sin_lut_type(0 to table_size-1);
begin
ret_sin_lut_v := (others => (others => '0'));
for i in ret_sin_lut_v'range loop
ret_sin_lut_v(i) := to_unsigned(integer(round(
sin(real(i)/real(table_size) * c_pi_2) *
real((2**(sin_width) - 1)))), sin_width);
end loop;
return ret_sin_lut_v;
end function gen_sin_lut_func;

constant c_sin_lut : sin_lut_type(0 to c_lut_size-1) :=
gen_sin_lut_func(c_lut_size);


Thanks,
Roy

ABC
09-21-2008, 12:26 PM
On Sep 20, 2:36*pm, [email protected] wrote:
> Hi all,
>
> I am trying to port some VHDL code that generates a sin LUT (0 to pi/
> 2) at compile time that is configurable based on desired LUT depth and
> resolution to Verilog. *This is pretty straightforward in VHDL since
> the synthesis tools support using real values to calculate the sin as
> shown below, but I have been unable to find a way to do this in
> Verilog without hardcoding in the entire LUT. *I am using Synplify Pro
> for synthesis, and as far as I can tell it doesnt support the sin
> function or even Verilog reals at all. *If anyone has any ideas on how
> to do this, I'd really appreciate it.
>
> * constant c_pi_2 : real := 1.5707963;
> * constant c_lut_size : integer := 2048;
> * constant c_sin_width : integer := 16;
>
> * type sin_lut_type is array(natural range <>) of
> * * unsigned(c_sin_width-1 downto 0);
>
> * function gen_sin_lut_func(table_size : positive; sin_width:
> positive) return sin_lut_type is
> * * variable ret_sin_lut_v : sin_lut_type(0 to table_size-1);
> * begin
> * * ret_sin_lut_v := (others => (others => '0'));
> * * for i in ret_sin_lut_v'range loop
> * * * ret_sin_lut_v(i) := to_unsigned(integer(round(
> * * * * sin(real(i)/real(table_size) * *c_pi_2) *
> * * * * real((2**(sin_width) - 1)))), sin_width);
> * * end loop;
> * * return ret_sin_lut_v;
> * end function gen_sin_lut_func;
>
> * constant c_sin_lut : sin_lut_type(0 to c_lut_size-1) :=
> * * gen_sin_lut_func(c_lut_size);
>
> Thanks,
> Roy

Use Maclaurin theorem to translation the sin.

Best regards,
ABC

09-21-2008, 09:41 PM
On Sep 21, 7:26*am, ABC <[email protected]> wrote:
> On Sep 20, 2:36*pm, [email protected] wrote:
>
>
>
> > Hi all,
>
> > I am trying to port some VHDL code that generates a sin LUT (0 to pi/
> > 2) at compile time that is configurable based on desired LUT depth and
> > resolution to Verilog. *This is pretty straightforward in VHDL since
> > the synthesis tools support using real values to calculate the sin as
> > shown below, but I have been unable to find a way to do this in
> > Verilog without hardcoding in the entire LUT. *I am using Synplify Pro
> > for synthesis, and as far as I can tell it doesnt support the sin
> > function or even Verilog reals at all. *If anyone has any ideas on how
> > to do this, I'd really appreciate it.
>
> > * constant c_pi_2 : real := 1.5707963;
> > * constant c_lut_size : integer := 2048;
> > * constant c_sin_width : integer := 16;
>
> > * type sin_lut_type is array(natural range <>) of
> > * * unsigned(c_sin_width-1 downto 0);
>
> > * function gen_sin_lut_func(table_size : positive; sin_width:
> > positive) return sin_lut_type is
> > * * variable ret_sin_lut_v : sin_lut_type(0 to table_size-1);
> > * begin
> > * * ret_sin_lut_v := (others => (others => '0'));
> > * * for i in ret_sin_lut_v'range loop
> > * * * ret_sin_lut_v(i) := to_unsigned(integer(round(
> > * * * * sin(real(i)/real(table_size) * *c_pi_2) *
> > * * * * real((2**(sin_width) - 1)))), sin_width);
> > * * end loop;
> > * * return ret_sin_lut_v;
> > * end function gen_sin_lut_func;
>
> > * constant c_sin_lut : sin_lut_type(0 to c_lut_size-1) :=
> > * * gen_sin_lut_func(c_lut_size);
>
> > Thanks,
> > Roy
>
> Use Maclaurin theorem to translation the sin.
>
> Best regards,
> ABC

Any idea how to do that without using reals?

glen herrmannsfeldt
09-22-2008, 06:47 AM
[email protected] wrote:

> I am trying to port some VHDL code that generates a sin LUT (0 to pi/
> 2) at compile time that is configurable based on desired LUT depth and
> resolution to Verilog. This is pretty straightforward in VHDL since
> the synthesis tools support using real values to calculate the sin as
> shown below, but I have been unable to find a way to do this in
> Verilog without hardcoding in the entire LUT.

I don't know if you can do it in verilog in fixed point,
but there is a scaled fixed point sin algorithm in Knuth's
"Metafont: The Program."

-- glen

Kevin Neilson
09-22-2008, 07:10 PM
[email protected] wrote:
> Hi all,
>
> I am trying to port some VHDL code that generates a sin LUT (0 to pi/
> 2) at compile time that is configurable based on desired LUT depth and
> resolution to Verilog. This is pretty straightforward in VHDL since
> the synthesis tools support using real values to calculate the sin as
> shown below, but I have been unable to find a way to do this in
> Verilog without hardcoding in the entire LUT. I am using Synplify Pro
> for synthesis, and as far as I can tell it doesnt support the sin
> function or even Verilog reals at all. If anyone has any ideas on how
> to do this, I'd really appreciate it.
>
>
> Thanks,
> Roy
Synplify doesn't support the $sin function? Hmmm. It's a bit of a
pain, but you could use an integer-based CORDIC function. You can have
as many iterations as required to get the accuracy you desire. You
should be able to use this to get the values to fill the table. -Kevin

Brian Drummond
09-23-2008, 12:49 PM
On Fri, 19 Sep 2008 23:36:47 -0700 (PDT), [email protected] wrote:

>Hi all,
>
>I am trying to port some VHDL code that generates a sin LUT (0 to pi/
>2) at compile time that is configurable based on desired LUT depth and
>resolution to Verilog. This is pretty straightforward in VHDL since
>the synthesis tools support using real values to calculate the sin as
>shown below, but I have been unable to find a way to do this in
>Verilog without hardcoding in the entire LUT.

If all else fails, just add a file write procedure to your VHDL code, to
write the LUT as a Verilog include file ;-)

- Brian