# Computing a sine table

Status
Not open for further replies.

#### Binome

##### Full Member level 3
Hi,
I have to precompute a sine table to use it as multiplying values in an entity. I read this thread where the FvM's solution (third message) seems very interesting. Only, I don't know how to write the VHDL file(s) to implement this, Modelsim is complaining every time I try to compile it.
What should I do?

#### TrickyDicky

how is it complaining, and where is your code.

#### Binome

##### Full Member level 3
My code is:
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.math_real.all;

entity sincos_lut is
port
(
reset : std_logic
);
end sincos_lut;

architecture rtl of sincos_lut is

TYPE SINTAB IS ARRAY(0 TO 7) OF STD_LOGIC_VECTOR (7 DOWNTO 0);
SIGNAL SINROM: SINTAB;

BEGIN

GENROM:
FOR idx in 0 TO 7 GENERATE
CONSTANT x: REAL := SIN(real(idx)*MATH_PI/real(8));
CONSTANT xn: UNSIGNED(7 DOWNTO 0) := CONV_UNSIGNED(INTEGER(x*real(8)),8);
BEGIN
SINROM(idx) <= STD_LOGIC_VECTOR(xn);
END GENERATE;

end rtl;
Modelsim is complaining about unsigned and conv_unsigned that are unknown.

#### TrickyDicky

That is because you have not included the package that contains them, ieee.std_logic_arith, but you should not use this package as it is not a vhdl standard package. You should use numeric_std instead.

#### K-J

That is because you have not included the package that contains them, ieee.std_logic_arith, but you should not use this package as it is not a vhdl standard package. You should use numeric_std instead.
Actually, it was FvM who led Binome down the wrong path since it was his code that Binome is basically having troubles compiling.

@Binome: As Tricky mentions, the package ieee.std_logic_arith (which contains the 'conv_unsigned' function) is not really a VHDL standard, it is however a defacto standard since it has been in use a long time and is still actively being used. It has a few issues though which make numeric_std the better choice. You simply add a 'use work.ieee.numeric_stc.all;' statement just like the 'use ieee.std_logic_1164.all' statement that you already have.

Ieee.numeric_std contains a function called 'to_unsigned' which converts integers to a representation of an 'unsigned' value. That function takes two arguments just like 'conv_unsigned'. The first argument is the integer you would like to convert; the second argument defines how many bits are to be in this unsigned representation. These arguments are exactly the same as 'conv_unsigned' so the bottom line is that you simply need to do a text substitution of 'conv_unsigned' to 'to_unsigned'.

Extending this a bit, you could ask yourself why bother making the rom table be an array of std_logic_vectors when they are intended to hold unsigned? Rather than this...
TYPE SINTAB IS ARRAY(0 TO 7) OF STD_LOGIC_VECTOR (7 DOWNTO 0);
TYPE SINTAB IS ARRAY(0 TO 7) OF unsigned (7 DOWNTO 0);

By using the correct data types in the first place, you avoid cluttering the code with type conversions. In this case, you have
SINROM(idx) <= STD_LOGIC_VECTOR(xn);
Which, if SINROM was an array of unsigned like you intend it to be, could be simply...
SINROM(idx) <= xn;

Or even more simply, get rid of xn completly and have...
SINROM(idx) <= to_unsigned((INTEGER(x*real(8)),8));
or
SINROM(idx) <= to_unsigned((INTEGER(x*8.0),8));

Actually, since your table is computing sine values you really don't want to use unsigned, they should be type signed like this...
TYPE SINTAB IS ARRAY(0 TO 7) OF signed (7 DOWNTO 0);

Taking this to the final conclusion, sin(x) is always between -1.0 and +1.0 so your table should be an array of fixed point signed values like this...
TYPE SINTAB IS ARRAY(0 TO 7) OF sfixed (1 DOWNTO -6);

Then you would need the conversion function to convert between real and sfixed. This function is included in the fixed point package: to_sfixed to be specific.

Kevin Jennings

Last edited:

#### syedshan

Hi all,

Well K-J and TrickyDricky are waaaayyyy too experienced and awesome, but considering myself a beginner I will share what I did for one of my VLSI assignment recently.

I made the sine values using Matlab, then save that data in the text file, using which I then made the ROM using Xilinx core gen and store that data in that ROM,
If that you want to be the solution. I hope it helps...

Bests,
Shan

#### FvM

##### Super Moderator
Staff member
Actually, it was FvM who led Binome down the wrong path since it was his code that Binome is basically having troubles compiling.

I really love these ignorant statements.

The said post doesn't but mention the principle option to calculate sine tables in VHDL, showing an incomplete code snippet without library imports.. There are dozens of posts discussing the topic in detail, showing different ways to achieve whatever you want. In so far, getting stuck with this particular code snippet mainly reveals sloppy search.

I basically agree about better using ieee.numeric_std and unsigned (or preferably signed) type for the sine table. The code snippet under discussion has been however cut from an existing application as is and wasn't edited for educational purposes. The problem is that Binome doesn't realize which libraries are presumed by the code, although this is quite obvious, I think. The same problem arises when people copy arbitray code parts from textbook or the internet. I won't blame the books in this case.

P.S.:
I made the sine values using Matlab, then save that data in the text file, using which I then made the ROM using Xilinx core gen and store that data in that ROM,
If that you want to be the solution. I hope it helps...

The circle closes. The one and only purpose of the linked post is to show, that you don't necessarily need to refer to the long-winded usage of external tools to calculate sine or similar tables. But of course you can, if it's convenient for you. In fact the method can be reasonable for very large tables, because the cordic based compile time sine calculation in ieee.math_real is somewhat time consuming.

Last edited:

Status
Not open for further replies.