2012年10月29日月曜日

ロラン

北海道でロランの鉄塔を見かけました。GPSが一般化しているなか、とうの昔に運用を終えているものと思い込んでいたので意外です。この十勝太ロランC局は全国3カ所のうちの一つで、周波数100kHz、出力1500kW、鉄塔高さは193m。残念ながら来年2月1日付で廃止となるそうです。




近くまで行きたいところ、立入禁止の看板があり近付けません。
内部の様子は、一般公開に参加された方の記事に詳しいです。記事の最後に、アメリカ沿岸警備隊の管轄時に勤務されていた方のコメントが残っていてグっと来ます。



周囲にはのどかな風景が広がっています。27日の写真ですが、同じ日本とは思えない??





これは少し離れた場所。まるで現代アートのよう。


2012年9月28日金曜日

40MHz/入力レンジ80dBのUSB-FPGA信号処理実験基板

おじさん工房APB-3が、CQ出版から発売されます。
Spartan-6 FPGAと高速A/D, D/A搭載と言うことで、リリースを心待ちにしていました。
部品実装済みのプリント基板に、コネクタ・スイッチ類のはんだ付けが必要な半完成品キットで、価格は42,000円。トラ技の11月号から解説記事の連載がスタートするそうです。

2012年9月15日土曜日

FPGA FMトランスミッタ: レベルメータをつける

変調度メータを動かしてみました。プリエンファシスをオンにすると、高音のレベルが持ち上げられて思いっきり過変調になります。わかってはいましたが、これほどとは思っていませんでしたから、実際に目にして驚きました。





FPGA FMトランスミッタ: 設定用レジスタをつける

操作パネルからFPGA基板への機能設定は、某チップのSPI(もどき)を真似ることにしました。想定している信号波形と、レジスタの仕様は次の通りです。

SPIインターフェース信号波形


FPGA内 機能設定用レジスタ





2012年8月28日火曜日

FPGA FMトランスミッタ: ステレオセパレーションの測定

FPGA FMステレオチューナに接続してステレオセパレーションを測ってみました。チューナのセパレーション特性と比較すると、1kHz以上はチューナの特性に依存していてそれ以下は、トランスミッタの特性が見えているように思います。デジタルフィルタの特性のためにf特が波を打つならわかりますが、低域に向けて単調にセパレーションが低下するのは何故でしょう。

ステレオセパレーション

Lch 1kHz 100%変調(Lチャンネル)

Lch 1kHz 100%変調(Rチャンネルへの漏話)

2012年8月11日土曜日

FPGA FMトランスミッタ: FM変調器

FM変調器については、過去の記事(FM変調器(1)FM変調器(2)FM変調器(3))に書いてますので、今回は具体的なところを書きます。と、言ってもお手軽なCoreGenを使いましたので簡単にできあがってしましました。

CoreGenの設定
DDSの位相アキュムレータは32ビットにしてあります。

DDS Compilerの設定1

DDS Compilerの設定2

DDS Compilerの設定3

DDS Compilerの設定4

DDS Compiler IP Symbol

周波数設定値
D/Aコンバータの動作クロックは77.824MHzですので、基本波としてFM放送波帯の周波数を生成することはできませんが、イメージ成分なら利用できます。例えば、83.5MHzが欲しいとき、DDSで5.676MHzを生成すれば、77.824MHz ±5.676MHz のイメージが出るので83.5MHzだけをフィルタで取り出すという手法があります。
※FMトランスミッタの製作スタート時の発想は、10.7MHzを生成して外付けのアップコンでFM放送波帯に変えようというものでした。

DDSの周波数設定値に適切な重み付けをした音声信号を重畳すればFM変調できたことになります。周波数偏移は、音声のフルスケールで200%変調、すなわち±150kHzになるように合わせます。DDSの動作クロックは77.824MHz、位相アキュムレータは32ビットなので周波数設定入力のMSBから9ビット目以降に音声信号 を接続すれば77.824MHz ×(2^23 / 2^32)  = 152kHzの変調度になります。このため事前に音声信号の振幅を150/152倍しておきます。(mod_level.v)
また、音声信号は2の補数形式のためストレートバイナリ形式に変換します。すると、入力信号のない無音時でも音声信号のMSBビットが立つことになり、あたかも周波数設定値にオフセットがかかったように見えます。従って周波数設定値は、このオフセット分を相殺した数値とします。

DDSの周波数設定値

測定結果
DDSで5.676MHzを発生させて、イメージの83.5MHzを見てみます。最初の2枚は、緑色がアナログ入力、黄色がデジタル入力で無音の場合です。デジタル入力の場合、ソースによってはDCオフセットがあるらしく、ぴょこっと周波数がずれてしまうことがありました。DCカット用にハイパスフィルタが必要だと思います。
3枚目は広帯域のスプリアスの様子です。77.824MHzのクロック周波数のほかイメージ成分2本が見えますが、わけのわからないノイズが多すぎます。スプリアスはフィルタを使えば取り除くことができるのでしょうが、仮に送信機のエキサイタとして利用するには素地が良くない気がしますが、チューナの試験用としてなら十分使えます。
訳のわからないノイズは、基板設計の拙さによって他のデバイスのノイズを受けてしまっているからと思っています。

83.5MHz ステレオモード(SPAN 200kHz)

83.5MHz モノラルモード(SPAN 200kHz)

スプリアス(83.5MHz、SPAN 40MHz)

次に、基本波を見てみます。最初の2枚は、緑色がアナログ入力、黄色がデジタル入力で無音の場合です。イメージよりノイズレベルが低く、コーデックのノイズがよく見えます。
3枚目は、広帯域(DC-20MHz)のスペクトラムで、目立ったスプリアスもなく良い感じです。やはりこれを所定の周波数までアップコンしたいところですね。
4枚目と5枚目は、1kHz 100%変調相当での占有周波数帯域幅です。

5.676MHz ステレオモード(SPAN 200kHz)

5.676MHz モノラルモード(SPAN 200kHz)

スプリアス( 5.676MHz、SPAN 20MHz)

5.676MHz ステレオモード占有帯域幅

5.676MHz モノラルモード占有帯域幅


fm_mod.v

module fm_mod(
  mod_i, mod_o, clk, reset, mod_set
  );

  input [23:0] mod_i;
  output [13:0] mod_o;
  input clk;
  input reset;
  input mod_set;

  wire [13:0] mod_o;
  wire [31:0] mod_data;
  reg [31:0] pinc_in;

//  parameter [24:0] FREQ_OFFSET = 32'h22B286BC;  // 10.7MHz
  parameter [31:0] FREQ_OFFSET = 32'h122BCA1A;  // 5.676MHz(83.5MHz)
//  parameter [24:0] FREQ_OFFSET = 32'h2229E50D7;  // 10.676MHz(88.5MHz)

  assign mod_data = {8'b0, (mod_i[23:0] ^ 24'h800000)};

  always @(posedge clk or posedge reset)
    begin
      if (reset)
        pinc_in <= FREQ_OFFSET + 32'h00800000;
      else
        pinc_in <= FREQ_OFFSET + mod_data;
    end

  dds_mod dds_mod (
    .clk(clk),
    .pinc_in(pinc_in),
    .sine(mod_o));

endmodule


mod_level.v

module mod_level(
  ml_i, ml_o,
  clk, reset, ml_thru
  );

  input [23:0] ml_i;
  output [23:0] ml_o;
  input clk;  // 64fs
  input reset;
  input ml_thru;

  reg [5:0] state64;
  reg [23:0] input_reg;
  reg [23:0] output_reg;
  reg [23:0] ml_o;
  wire latch_out;
  wire ml_thru;

  // State counter
  always @(posedge clk or posedge reset)
    begin
      if (reset)
        state64 <= 0;
      else if (state64 == 63)
        state64 <= 0;
      else
        state64 <= state64 + 1;
    end

  assign latch_out = (state64 ==7);

  // Attenuation
  always @(posedge clk or posedge reset)
    begin
      if (reset)
        begin
          input_reg <= 0;
          output_reg <= 0;
        end

      else
        begin
          case (state64)
            0:  input_reg <= ml_i;
            1:  // GAIN * (505/512)
              output_reg <= {input_reg[23], input_reg[23:1]}
                        + {{2{input_reg[23]}}, input_reg[23:2]};
            2:  output_reg <= output_reg
                        + {{3{input_reg[23]}}, input_reg[23:3]};
            3:  output_reg <= output_reg
                        + {{4{input_reg[23]}}, input_reg[23:4]};
            4:  output_reg <= output_reg
                        + {{5{input_reg[23]}}, input_reg[23:5]};
            5:  output_reg <= output_reg
                        + {{6{input_reg[23]}}, input_reg[23:6]};
            6:  output_reg <= output_reg
                        + {{9{input_reg[23]}}, input_reg[23:9]};
          endcase
        end
    end

  //  output data register
  always @(posedge clk or posedge reset)
    begin
      if (reset)
        ml_o <= 0;
      else if (ml_thru)
        ml_o <= ml_i;
      else if (latch_out)
        ml_o <= output_reg;
    end

endmodule

2012年8月10日金曜日

FPGA FMトランスミッタ: CICフィルタ

4,864kHzから77.824MHzへサンプルレート変換を行うためCICフィルタを使います。細かいことはわかりませんが、お手軽にCoreGenを使ってみます。

CoreGenの設定
CoreGen画面の中で特性を確認できます。通過域はコンポジット信号、阻止域はサンプルレート4,864kHzへのコンポジット信号の折り返しです。
サンプルレートの変換比16、CIC4段にしてあります。(3段にしたらうまく動かず・・・)

通過域(0~55kHz): 0 ~ 0.001414 [πrad/sample]
阻止域(4,809~4,919kHz): 0.1236 ~ 0.1264 [πrad/sample]

この周波数特性を見ると、阻止域のリップルが0.0066dBになっています。

CICフィルタの周波数特性

CIC Compilerの設定1

CIC Compilerの設定2

CIC Compilerの設定3

CIC Compiler IP Symbol

特性の測定
FIRフィルタと同様に152ksps 10kHzを信号源としてスペクトルを確認します。図で緑色がフィルタなし、黄色がフィルタありです。5MHz付近に向かってフィルタの効果が出ていることがわかります。

CICフィルタ出力(DC-5MHz)

CICフィルタ出力(DC-20MHz)

続いて、32倍オーバサンプリングFIRフィルタとCICフィルタをカスケード接続してみます。図で緑色がFIRフィルタのみ、黄色がFIRフィルタとCICフィルタの組み合わせです。ベースバンドをのぞきサンプルレート77.824MHzの半分の周波数までの信号が除去されていることがわかります。

FIR + CICフィルタ出力(DC-5MHz)

FIR + CICフィルタ出力(DC-20MHz)

FIR + CICフィルタ出力(15-50MHz)

cic16x.v

module cic16x(
  cic16x_i, cic16x_o, clk, reset, cic16x_thru
  );

  input [23:0] cic16x_i;
  output [23:0] cic16x_o;
  input clk;
  input reset;
  input cic16x_thru;

  wire [19:0] din;
  wire [31:0] dout;
  
  assign din = cic16x_i[23:4];
  assign cic16x_o = cic16x_thru ? cic16x_i : dout[31:8];

  // CIC Filter
  cicip cicip (
    .din(din),  // input [19:0] din
    .clk(clk),
    .dout(dout)  // output [31:0] dout
//    .rdy(rdy),  // output rdy
//    .rfd(rfd));  // output rfd
    );

endmodule