Computing sine and cosine on FPGA typically involves CORDIC. However, James Bowman coded some efficient implementations of the transcendental functions using Chebyshev polynomial approximation. As opposed to CORDIC which takes several iterations (typically the result converge of one bit per iteration), this design uses only combinatorial statements.

The `isin` Verilog module computes 16-bit signed output from a 16-bit signed input. Its use can be demonstrated on the TinyFPGA BX:

```module top (
input CLK,    // 16MHz clock
output USBPU,  // USB pull-up resistor
output PIN_1,
output PIN_2,
output PIN_3,
output PIN_4,
output PIN_5,
output PIN_6,
output PIN_7,
output PIN_8
);
// drive USB pull-up resistor to '0' to disable USB
assign USBPU = 0;

////////
// generate a sine wave
////////

reg [23:0] f_counter = 0;
always @(posedge CLK) begin
f_counter <= f_counter + 1;
end

wire [15:0] sin;
isin mySin (
.x(f_counter[23:8]),
.s(sin)
);

assign {PIN_8, PIN_7, PIN_6, PIN_5, PIN_4, PIN_3, PIN_2, PIN_1} = {~sin,sin[14:8]};

endmodule
```

This generates a digital signal on PIN_1~8. Since `isin` produces 16-bit signed results (from -32768 to 32767), the output is shifted to the positive scale (from 0 to 65535). This operation is simply done by inverting the MSB (`{~sin,sin[14:8]}`). Due to two's complement representation, using signed values produce this funny-looking wave.

Using a simple testbench is helpful to validate (even simple) designs. As shown below, the result of the simulation can be exported to GTKWave. The design behaves as expected. The next step is to convert this signal to the analog domain and analyze it using an oscilloscope. Since the TinyFPGA's ICE40LP8K doesn't integrate a DAC, we can use a discrete DAC or a R-2R resistor ladder network like this:  While it is fairly easy to make a resistor ladder from a bunch of resistors, I used a 8-bit R2R conveniently packaged in SIP.

I hooked everything on a breadboard. Since ground pin is next to PIN_1 on the TinyFPGA BX, there is no need for any wiring (PIN_9 analog output can be left floating on the FPGA). Below is the final wave as shown on a cheap portable oscilloscope: If you prefer to describe your digital designs using Python, I reimplemented the `isin`/`ìcos` module using Migen. A possible upgrade of this module would be to support arbitrary precision—which would be harder to achieve in pure Verilog.