Балансный Фазовый Детектор на Verilog

Содержание

Сводка

Фазовый детектор – это устройство, используемое для определения разницы в фазе между сигналами. Он играет важную роль в различных областях, таких как радиосвязь, медицинская техника, радары, телекоммуникации и многое другое.

В данной статье мы рассмотрим Балансный Фазовый Детектор написанный на языке Verilog. Укажем про особенности и применение кода в своих проектах.

Реализация Балансного Фазового Детектора на языке Verilog

В данном случае код написан и синтезирован в Проприетарное ПО Quartus 2. Для пользователей ПО Vivado от компании Xilinx или другими синтезаторами написан более простой код для автоматизированного вычисления.

Модуль BFD(Balanced Phase Detector) включает 2 экземпляра модуля:

  • single_port_rom — имитирующий ROM. Данного модуль использует ресурсы памяти ПЛИС, а не регистровую память.
  • signed_multiply — модуль умножения с учетом знака.

BFD также входит счетчик counter, написанный в модуле верхнего уровня, и параметры:

  • FREQ — частота сигнала. Данный показатель написан через параметр, полагаясь на знание несущей частоты сигнала. Если в схеме присутствует Частотный Детектор, то можно сделать как входной сигнал, но придется менять код адресации к памяти.
  • ADC_FREQ — частота дискретизации АЦП.
  • DW — битовая длина внутренних линий.

Управляющие и информационные сигналы:

  • i_signal — входной сигнала значения с АЦП.
  • i_clk — внутренний тактовый сигнал ПЛИС.
  • o_fd — выходной сигнал фазового детектора.
Данный код на Verilog является простой и эффективным реализацией фазового детектора, который в большинстве случаев используется для демодуляции сигналов.
`default_nettype wire module BFD #( parameter FREQ = 100, parameter ADC_FREQ = 10_000, parameter DW = 16 ) ( input [(DW - 1): 0] i_signal, input i_clk, output [(DW) - 1: 0] o_fd ); localparam ADDR_DEPTH = 100; //INTEL FPGA // localparam ADDR_DEPTH = ADC_FREQ / FREQ; //XILINX FPGA reg [6: 0] counter; // INTEL // reg [$clog2(ADDR_DEPTH): 0] counter; // XILINX FPGA wire [(DW - 1): 0] cos_val; initial begin counter = 0; end single_port_rom #(DW, ADDR_DEPTH) rom1(counter, i_clk, cos_val); signed_multiply #(DW) mult(i_signal, cos_val, o_fd); always @(i_clk) begin if (ADDR_DEPTH == counter) counter <= 0; else counter <= counter + 1; end endmodule module single_port_rom #(parameter DATA_WIDTH=8, parameter ADDR_WIDTH=8) ( input [(ADDR_WIDTH-1):0] addr, input clk, output reg [(DATA_WIDTH-1):0] q ); // Объявление Памяти reg [DATA_WIDTH-1:0] rom[2**ADDR_WIDTH-1:0]; genvar i; initial begin $readmemb("cos_val.txt", rom); // INTEL // для других синтезаторов через for используя $cos end always @ (posedge clk) begin q <= rom[addr]; end endmodule module signed_multiply #(parameter WIDTH=8) ( input signed [WIDTH-1:0] dataa, input signed [WIDTH-1:0] datab, output [2*WIDTH-1:0] dataout ); assign dataout = dataa * datab; endmodule

Особенности

Результатом выхода фазового детектора является следующая формула:

Формула Балансного Смесителя
Рисунок 1. Формула Балансного Смесителя.

Для получения получения фазовой составляющей нужно на выход поставить фильтр ФНЧ с частотой среза меньше 2f. Выходные данные будут представлять собой низкочастотную составляющую.

Следует заметить, что при не правильных расчетах глубины Памяти ROM или счетчика counter, меняется частота косинуса. На результирующем сигнале появятся колебания равные разности частот целевого и гармонического сигнала.