Netlist Viewers

netlistviewer

Sometimes it is helpful to use one of the Netlist Viewers.

// FPGA
if(get_now == 1'b1) begin
    rx_shift <= {rx2, rx_shift[7:1]}; //LSB first
end

assign get_now = (async_count ==  9 || async_count == 17 || async_count == 25
               || async_count == 33 || async_count == 41 || async_count == 49
               || async_count == 57 || async_count == 65 )? 1'b1 : 1'b0;

netlistviewer2

How come the comparators, Equal*, are with the 32-bit width? Yes, in Verilog the integers are considered to be the type signed 32-bit. I should have explicitly written 16’h9, 16’h11, etc.

assign get_now = (async_count == 16'h9  || async_count == 16'h11 || async_count == 16'h19
               || async_count == 16'h21 || async_count == 16'h29 || async_count == 16'h31
               || async_count == 16'h39 || async_count == 16'h41 )? 1'b1 : 1'b0;

VoilĂ !

netlistviewer3

FIFO

fifo3
https://www.altera.com/en_US/pdfs/literature/ug/ug_fifo.pdf

If you receive some data, say via a serial interface, you may wish to temporarily store the received data in a FIFO.

fifo2

A sequence of data, 40h, 41h, 42h, … is fed into a 256 words FIFO, and a delayed sequence of 20h, 21h, 22h, …is coming out of the FIFO.

if (! almost_empgy) rdreq <= 1'b1;
defparam
  scfifo_componet.almost_emtpy_value = 32; // hex 20

Signal Tap II Logic Analyzer

SignalTap

The SignalTap II Logic Analyzer is a tool to capture and display real-time signals in your FPGA device.

It works, but I still do not understand the details..

NCO

wave61

A simple verison of a numerically controlled oscillator is implemented, and a 600Hz sine wave is generated. The red trace shows the MSB to the D/A converter.

//--------- 16-bit phase accumulator ---------------------
reg [15:0] phase_acc;
reg [15:0] phase_delta;

always @ (posedge clk_myown or negedge res_n)
begin
  if ( res_n == 1'b0 ) begin
     phase_acc   <= 16'h0000;
     phase_delta <= 16'h0040;
  end
  else if (daword_up == 1'b1) begin // 48kHz
     phase_delta <= (1'b0)? {5'b0_0000, rx_data, 3'b000} : 16'b0000_0011_0011_0011;
     phase_acc <= phase_acc + phase_delta;
     sound_index <= phase_acc[15:7];
  end
end

The Line 12 shows that the frequency control word (FCW), phase_delta, can be given via a serial interface.

Serial Communication with FPGA (2)

wave57

Now sending the value of an 8-bit counter with a serial interface. The yellow trace shows the LSB of the received word.

// Arduino
void setup() {
  Serial.begin(9600); //default 8-bit no parity, one stop bit
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
 }

int thisByte = 0x00;

void loop() {
  Serial.write(thisByte);
  delay(4);
  thisByte = thisByte + 1;
  if(thisByte == 256) thisByte = 0;
}
// FPGA
if(get_now == 1'b1) begin
    rx_shift <= {rx2, rx_shift[7:1]}; //LSB first
end

assign get_now = (async_count ==  9 || async_count == 17 || async_count == 25
               || async_count == 33 || async_count == 41 || async_count == 49
               || async_count == 57 || async_count == 65 )? 1'b1 : 1'b0;

Serial Communication with FPGA

wave53

Serial interface is a simple way to communicate between your PC and your device, including an FPGA. An Arduino board is used as a USB-to-serial converter, sending a word 8’b1010_1010 and 8’b1100_1100 alternatively.

wave54

A simple logic in an FPGA generates a sampling pulse for the serial data. Note that the first “0” is a start bit, which does not have to be sampled.

Clickless CW Sidetone (3)

wave45

Using a PCM5102A dac with typical performance of SNR 112dB, Dynamic Range 112dB, THD+N@-1dBFS -93dB.

wave49

The envelope is shaped as a raised cosine over 512 samples at Fs=48kHz.

wave46

wave47

reg signed [15:0] sine_table;
always @(sound_index) begin
    case (sound_index) 
        7'b0000000: begin sine_table <= 16'b0000000000000000; end //      0:         0 
//
        7'b1001111: begin sine_table <= 16'b1111010111110110; end //     79:     -2570 
reg signed [15:0] shape;
always @(envelope) begin
    case (envelope) 
        9'b 000000000 : begin shape <= 16'b0000000000000000; end //   0:     0 
//
        9'b 111111111 : begin shape <= 16'b0111111111111110; end // 511: 32766 
reg signed [31:0] mult; // sine_table: signed 16bit, shape: signed 16-bit
always @(sound_index) begin
   mult <= shape * sine_table;
end
always @ (posedge clk_myown or negedge res_n)
 begin
  if ( res_n == 1'b0 )
   daword <= 6'b00_0000;
  else begin
   daword <= daword + 6'b00_0001;
   if ( daword[4:0] == 5'b0_0000 ) // for each 32-bit, or for each L and R
	dadata <= {mult[30:0], 1'b0};
   else
	dadata <= {dadata[30:0], 1'b0};
  end
 end

wave48

The sidetone signal is analogue captured at Fs=48kHz.

Audio DAC (4)

wave43

You may prefer 600Hz (=48kHz/80) to 375Hz (=48kHz/128) for sidetone. If this is the case, you divide the interval [0, 2pi] into 80 sections rather than into 128.

wave44

Should I use a numerically controlled oscillator (NCO) so that only a single table is required for creating a signal with arbitrary frequency?

Direct_digital_synthesizer_block_diagram
https://en.wikipedia.org/wiki/Direct_digital_synthesizer

I do not think so.

Generic_NCO
https://en.wikipedia.org/wiki/Numerically_controlled_oscillator

Phase jitter caused by truncating the phase accumulator output of N-bit into M-bit is avoidable in our situation, because only some particular frequencies, such as 607.6Hz (=48kHz/79), 600Hz (=48kHz/80), and 592.6Hz (=48kHz/81), are of our interest as far as sidetone is concerned.

Audio DAC (3)

wave42

Now, a sine wave.

sinetable

A table of 16-bit signed resolution is used with the address of 7-bit for the interval [0, 2pi].

Audio DAC (2)

wave40

O.K. It works. The value of an 8-bit counter and 24 zeros are fed into a dac with Fs = 48kHz. (Note that 48kHz divided by 256 makes 187.5Hz.)

wave41

This figure shows that the dac has a eight times oversampling FIR interpolation filter.