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.
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.
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()
.
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
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
...
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.