ネットリスト・ビューワ

netlistviewer

時々は、ネットリスト・ビューワを使うのも有用です。

// 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

比較器Equal*は、なぜ32-bit幅なのでしょうか?そうです、Verilogでは、整数はsigned 32-bitなのです。16’h9, 16’h11等々と明示的に書くべきでした。

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;

そらね!

netlistviewer3

FIFO

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

例えばシリアルインターフェースを介してデータを受け取った場合、あなたはその受け取ったデータをFIFOに一時的に保管しておきたいかも知れません。

fifo2

40h, 41h, 42h, …というデータ列が256語のFIFOに入力され、20h, 21h, 22h, …という遅延されたデータ列がFIFOから出てきています。

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

Signal Tap II ロジック・アナライザ

SignalTap

SignalTap II ロジック・アナライザは、あなたのFPGA内部のリアルタイム信号をキャプチャして表示するためのツールです。

一応動くのですが、細かいところが未だ良く分かりません。

数値制御発信器(NCO)

wave61

簡単な数値制御発信器を実装して、600Hzの正弦波を生成しています。赤色のトレースは、D/A変換器へのMSBです。

//--------- 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

第12行に示されているように、周波数制御ワード(FCW), phase_delta,を、シリアルインターフェースを介して与えることもできます。

FPGAとシリアル通信 (2)

wave57

シリアルインターフェースを介して、8-bitカウンターの値を送出しています。黄色のトレースは、受信されたワードのLSBを示しています。

// 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;

FPGAとシリアル通信

wave53

シリアル・インターフェースは、あなたのPCとあなたのデバイス(FPGAとか)とを通信させる簡単な方法です。Arduinoボードを使って、USBからシリアルへの変換を行い、2つのワード8b1010_1010と8’b1100_1100とを交互に送出しています。

wave54

FPGA内の簡単な論理が、シリアルデータをサンプルするためのパルスを生成しています。最初のゼロはスタートビットなので、サンプルする必要は無いことに注意して下さい。

クリックの無いCWサイドトーン (3)

wave45

DA変換器PCM5102Aを使っています。これの典型的な性能は、SNR 112dB、Dynamic Range 112dB、THD+N@-1dBFS -93dBです。

wave49

包絡線はFs=48kHzで512サンプルにわたって整形されています。

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

サイドトーン信号は、Fs=48kHzでアナログキャプチャされました。

オーディオ用DA変換器 (4)

wave43

あなたはサイドトーンとして、600Hz (=48kHz/80)の方を、375Hz (=48kHz/128)よりも好むかも知れません。そのような場合には、区間[0, 2pi]を、128ではなく80のセクションに分割します。

wave44

私は数値制御発信器(NCO)を使うべきでしょうか?そうすれば、任意の周波数の信号を生成するのに1個のテーブルだけで済みます。

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

私は、そうは思いません。

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

N-bitの位相累算器出力をM-bitに切り捨てることによりもたらされる位相ジッタは、我々の状況では回避可能なものです。何故ならば、サイドトーンに関する限りは、特定の周波数、例えば、607.6Hz (=48kHz/79)、600Hz (=48kHz/80)、もしくは、592.6Hz (=48kHz/81)にしか興味が無いからです。

オーディオ用DA変換器 (2)

wave40

O.K. 動いているようです。8-bitカウンターの値と24個のゼロが、Fs = 48kHzでDA変換器に供給されています。(48kHzを256で割ると、187.5Hzになることに注意して下さい。)

wave41

この図は、DA変換器が8倍のオーバーサンプリングFIRフィルタを内蔵していることを示しています。