複素周波数変換といっても、特別なミキサーではなく、ローカルオシレータの位相を90°変えて、それぞれ周波数変換するだけです。
ミキサは、乗算器なのでIPジェネレータで10bit×10bit、出力16bitの乗算器を生成します。
ローカルオシレータは、以前作成したDDSを使います。
ソースです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
module Complex_Mixer( input mixCLK, input mixRST, input signed [9:0] mixSIG, input [26:0] mixFREQ, output signed [15:0] mixOUT_Q, output signed [15:0] mixOUT_I ); wire signed [9:0] mixLO_Q, mixLO_I; reg signed [9:0] mix_Q, mix_I; IQ_DDS IQ_DDS(.ddsCLK(mixCLK), .ddsRST(mixRST), .ddsFREQ(mixFREQ), .ddsSIN_OUT(mixLO_Q), .ddsCOS_OUT(mixLO_I)); multi10x10 multi1(.CLK(mixCLK), .A(mixSIG), .B(mix_Q), .P(mixOUT_Q)); multi10x10 multi2(.CLK(mixCLK), .A(mixSIG), .B(mix_I), .P(mixOUT_I)); always @(posedge mixCLK) begin mix_Q <= mixLO_Q; mix_I <= mixLO_I; end endmodule |
テストベンチです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
module Mixer_sim; reg clk, rst; wire signed [9:0] sig; reg [26:0] freq; wire [15:0] out_q, out_i; reg [9:0] add = 0; reg signed [9:0] mem[0:1023]; parameter STEP = 12.5; Complex_Mixer Complex_Mixer(.mixCLK(clk), .mixRST(rst), .mixSIG(sig), .mixFREQ(freq), .mixOUT_Q(out_q), .mixOUT_I(out_i)); always begin clk <= 0; #(STEP/2); clk <= 1; #(STEP/2); end always @(posedge clk) begin if(rst) add = 0; else add = add + 1; end assign sig = mem[add]; initial begin $readmemb("simrom.txt",mem); freq <= 27'h147ae1; //800kHz rst = 0; #(STEP*5); rst = 1; #(STEP*2); rst = 0; #(STEP*100); $finish; end endmodule |
ローカルオシレータは800kHz、入力信号は780kHzに設定しました。
シミュレーション結果です。
1580kHzのQ信号、I信号が出力されています。
時間軸を縮めてみます。
20kHzの信号に1580kHzの信号が重畳されているのが判ります。