Skip to content

Latest commit

 

History

History

sine2fmem

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

sine2fmem

Generate a table of sine values between 0-90° (0 - π/2 radians).

The generated table is suitable for loading into memory with Verilog $readmemh() or using with the Project F Library.

Licensed under the MIT License. See the LICENSE file for details.

Usage

sine2fmem.py rows width
  • rows - number of entries in the table (default 256)
  • width - width of hex value in bits (default 16)

I recommend using a power of two for the number of rows to make wrapping simple.

Use in Verilog

The Project F Library includes a module, sine_table.sv, that works with these tables. You can find a guide to using sine_table.sv on the blog: FPGA Sine Table.

To load these data into memory yourself, see Initialize Memory in Verilog for advice on using this data in Verilog with $readmemh().

Examples

Small Table

16 entries with 8-bit values 0x00 - 0xFF:

$ ./sine2fmem.py 16 8
// Generated by sine2fmem.py from Project F
// Learn more at https://github.com/projf/fpgatools
00  // 000: sin(0.0000) = 0.0000
19  // 001: sin(0.0982) = 0.0980
32  // 002: sin(0.1963) = 0.1951
4A  // 003: sin(0.2945) = 0.2903
62  // 004: sin(0.3927) = 0.3827
79  // 005: sin(0.4909) = 0.4714
8E  // 006: sin(0.5890) = 0.5556
A2  // 007: sin(0.6872) = 0.6344
B5  // 008: sin(0.7854) = 0.7071
C6  // 009: sin(0.8836) = 0.7730
D5  // 010: sin(0.9817) = 0.8315
E2  // 011: sin(1.0799) = 0.8819
ED  // 012: sin(1.1781) = 0.9239
F5  // 013: sin(1.2763) = 0.9569
FB  // 014: sin(1.3744) = 0.9808
FF  // 015: sin(1.4726) = 0.9952

Large Table

1024 entries with 32-bit values 0x00000000 - 0xFFFFFFFF:

$ ./sine2fmem.py 1024 32
// Generated by sine2fmem.py from Project F
// Learn more at https://github.com/projf/fpgatools
00000000  // 000: sin(0.0000) = 0.0000
006487EB  // 001: sin(0.0015) = 0.0015
00C90FC6  // 002: sin(0.0031) = 0.0031
012D9782  // 003: sin(0.0046) = 0.0046
01921F10  // 004: sin(0.0061) = 0.0061
01F6A660  // 005: sin(0.0077) = 0.0077
025B2D62  // 006: sin(0.0092) = 0.0092
02BFB407  // 007: sin(0.0107) = 0.0107
...

Handling 1.0

sine(90°) == 1.0, but handling this in our table leads to wider values.

For example, without any limit, the last few values we'd get for 64 rows and 8-bit width:

...
FF  // 060: sin(1.4726) = 0.9952
FF  // 061: sin(1.4972) = 0.9973
100  // 062: sin(1.5217) = 0.9988
100  // 063: sin(1.5463) = 0.9997

All but the last two entries in our table are 8-bit as requested, but there are a couple of 9-bit values at the end that would break Verilog memory initialization.

The sine2fmem.py script avoids this problem by limiting the maximum value to (2^width)-1.

For example, with an 8-bit width, the maximum value is limited to 0xFF:

...
FF  // 060: sin(1.4726) = 0.9952
FF  // 061: sin(1.4972) = 0.9973
FF  // 062: sin(1.5217) = 0.9988
FF  // 063: sin(1.5463) = 0.9997

See sine_table.sv for an example of how to handle 1.0 with these tables.