Делители частоты на Verilog: дробные и целые коэффициенты деления

Содержание

Что такое цифровые делители частоты?

Цифровой делитель частоты — это устройство, которое принимает входной сигнал с определенной частотой и выдает сигнал с более низкой частотой. Этот процесс осуществляется путем деления входной частоты на определенное число, называемое коэффициентом деления. Основные компоненты цифрового делителя частоты включают в себя триггеры, счетчики и логические схемы. Например, если входной сигнал имеет частоту 1 МГц, а коэффициент деления равен 10, то выходной сигнал будет иметь частоту 100 кГц.

Применение цифровых делителей частоты

Цифровые делители частоты находят широкое применение в различных областях:

  1. Телекоммуникации: В системах связи для синхронизации сигналов и упрощения обработки данных.
  2. Аудио- и видеотехника: В аудиопроцессорах и видеокодировщиках для обеспечения нужной частоты сигнала.
  3. Компьютерные системы: В тактировании процессоров и других компонентов для поддержания стабильной работы.
  4. Цифровая обработка сигналов: Для изменения частоты сигналов в системах анализа и обработки данных.

Делитель частоты на целое число Verilog

Данный блок делится на 2 составляющих: для коэффициента деления равным 2^n и для остальных целых чисел.

Делитель частоты с коэффициентом деления равным 2^n

Данный делитель реализовать легче всего, потому что состоит только из одних T-триггеров связанных последовательно. Например:

  • Коэф. деления = 8(2^3). Количество последовательно соединенных триггеров равно 3.
  • Коэф. деления = 32(2^5). Кол-во триггеров = 5
  • Коэф. деления = 2^n. Кол-во триггеров = n
Код на Verilog, RTL, временная диаграмма и отчет о компиляции делителя на 8 приведены ниже:
module DIV3X0 ( input wire clk, // тактовый сигнал input wire ena, // сигнал включения input wire reset, // сигнал асинхронного сброса output wire divide_clk // результирующий сигнал ); reg trig0 = 0; reg trig1 = 0; reg trig2 = 0; assign divide_clk = trig2; always @ (posedge clk, posedge reset) begin if (reset) begin trig0 <= 0; // сброс end else if (ena) begin trig0 <= ~trig0; // end end always @ (posedge trig0, posedge reset) begin if (reset) begin trig1 <= 0; end else begin trig1 <= ~trig1; end end always @ (posedge trig1, posedge reset) begin if (reset) begin trig2 <= 0; end else begin trig2 <= ~trig2; end end endmodule

Рисунок 1. RTL, временная диаграмма и отчет о компиляции делителя частоты

Делители частоты с коэффициентом деления с любым целым числом

Существует три схемы построения делителя частоты:

  • Делитель частоты через сумматор
  • Делитель частоты через T-триггеры
  • Делитель частоты с пользовательским счетчиком

Каждый тип имеет свои особенности, преимущества и недостатки, о которых расскажем в следующих главах.

Все последующие примеры имеют следующие входные и выходные сигналы:

  • o_result — результирующий сигнал
  • i_clk — тактовый сигнал, который будет поделен
  • i_ena — сигнал включения
  • i_reset(i_rst) — сигнал сброса

Делитель частоты через сумматор

Принцип работы делителя частоты через сумматор заключается в увеличение счетчика на 1. При достижении определенного значения происходит сброс счетчика. Модуль имеет всего один параметр(parameter) DIVCLK, указывающий на коэффициент деления. Коэффициент деление может принимать любое целое положительное число. Также есть локальные параметры(localparam) INCRS(четность коэф деления) и DW_C(кол-во регистров счетчика), которые рассчитываются автоматически. Код делителя частоты с сумматором:

module DIVNX0 #( parameter DIVCLK = 16 ) ( output wire o_result, input wire i_clk, i_ena, i_reset ); localparam INCRS = DIVCLK % 2; localparam DW_C = $clog2(DIVCLK); reg [DW_C: 0] counter = 0; always @(posedge i_clk, posedge i_reset) if (i_reset) counter <= 0; else begin if (i_ena) counter <= counter + 1; if ((DIVCLK - 1) == counter) begin counter <= 0; end end generate if (INCRS == 0) begin assign o_result = (DIVCLK / 2 - 1) < counter; end else begin assign o_result = (((DIVCLK / 2) > counter[(DW_C): 0]) | _delay_clk); reg _delay_clk = 0; always @(negedge i_clk, posedge i_reset) begin if (i_reset) begin _delay_clk <= 0; end else begin if ((DIVCLK / 2 - 1) == counter) begin _delay_clk <= 1; end else begin _delay_clk <= 0; end end end end endgenerate endmodule
RTL, отчет о компиляции и временная диаграмма делителя частоты с сумматором и четным коэффициентом деления(16)
Рисунок 2. RTL, отчет о компиляции и временная диаграмма делителя частоты с сумматором и четным коэффициентом деления(16)
RTL, отчет о компиляции и временная диаграмма делителя частоты с сумматором и нечетным коэффициентом деления(11)
Рисунок 3. RTL, отчет о компиляции и временная диаграмма делителя частоты с сумматором и нечетным коэффициентом деления(11)

Единственным достоинством данной модуля является легкая читабельность кода и RTL.

Недостатки:

  • Нельзя применить в высокочастотных схемах, потому что минимальный период = задержки на упорядочивание + tsum(задержка сумматора) + 2*tsum(задержка мультиплексора)
  • С увеличением коэффициентом деления:
    • сильно возрастает затраты в логических клетках
    • увеличивается задержка кратно

Делитель частоты через T-триггеры

Делитель частоты на T-триггерах является модифицированной прошлого типа. Счетчик на D-триггерах, сумматор и мультиплексоры заменяются на счетчик из T-триггеров. Дальней принцип взаимодействия остается тот же. Как и в прошлом типе блок generate помогает оптимизировать структуру и затраты модуля и реализуя разные RTL под четные и не четные коэффициенты деления.

module code_chelich1_g #( parameter DIVCLK = 11 ) ( output wire o_result, input wire i_clk, i_ena, i_reset ); localparam INCRS = DIVCLK % 2; localparam DW_C = $clog2(DIVCLK); reg [DW_C: 0] counter = 0; assign eq_reset = (((2 << DW_C) - 1) - (DIVCLK - 1)) == counter; genvar i; generate for (i = 0; i < (DW_C + 1); i = i + 1) begin if (i == 0) begin always @(posedge i_clk, posedge i_reset, posedge eq_reset) if (i_reset || eq_reset) counter[0] <= 0; else begin if (i_ena) counter[0] <= ~counter[0]; end end else begin always @(posedge counter[i - 1], posedge i_reset, posedge eq_reset) if (i_reset || eq_reset) counter[i] <= 0; else begin counter[i] <= ~counter[i]; end end end endgenerate generate if (INCRS == 0) begin assign o_result = (((2 << DW_C) - 1) - (DIVCLK / 2)) < counter; end else begin reg _delay_clk = 0; assign o_result = ((((2 << DW_C) - 1) - DIVCLK / 2) > counter[(DW_C): 0]) | _delay_clk; always @(negedge i_clk, posedge i_reset) begin if (i_reset) begin _delay_clk <= 0; end else begin if ((((2 << DW_C) - 1) - DIVCLK / 2) == counter) begin _delay_clk <= 1; end else begin _delay_clk <= 0; end end end end endgenerate endmodule
RTL, отчет о компиляции и временная диаграмма делителя частоты с T-триггером и четным коэффициентом деления(14)
Рисунок 4. RTL, отчет о компиляции и временная диаграмма делителя частоты с T-триггером и четным коэффициентом деления(14)
RTL, отчет о компиляции и временная диаграмма делителя частоты с T-триггером и нечетным коэффициентом деления(11)
Рисунок 5. RTL, отчет о компиляции и временная диаграмма делителя частоты с T-триггером и нечетным коэффициентом деления(11)

Недостатки: —

Достоинства:

  • Можно использовать в высокочастотных схемах. Минимальный период = задержки на упорядочивании + Txnor + 2*Tor.
  • С увеличением коэффициентом деления
    • Задержка не растет и не уменьшается
    • Рост затрачиваемых логических клеток не высок

Делитель частоты через пользовательский счетчик

Принцип работы делителя через пользовательский счетчик основан на состояниях счетчика, кол-во которых равно коэффициенту деления. Счетчик поочередно перебирает состояния, при котором один бит их всех битов в определенный период будет равен логической единице 1. Данный бит называется основным битом, с помощью которого происходит деление тактового сигнала. Если коэф. деления нечетный, добавляется вспомогательный бит который чувствительный к положительному части тактового сигнала и спадающему фронту основного бита.

module code_chelich2 ( input wire i_clk, input wire i_rst, output wire o_result ); localparam DIVIDE = 11; localparam DW_SC = $clog2(DIVIDE); reg [(DW_SC - 1): 0] COUNT_STATE; reg DELAY_STATE; always @(posedge i_clk, posedge i_rst) if (i_rst) COUNT_STATE <= 0; else case(COUNT_STATE) 4'd0000 : COUNT_STATE <= 4'd0001; 4'd0001 : COUNT_STATE <= 4'd0011; 4'd0011 : COUNT_STATE <= 4'd0101; 4'd0101 : COUNT_STATE <= 4'd1001; 4'd1001 : COUNT_STATE <= 4'd1101; 4'd1101 : COUNT_STATE <= 4'd0100; 4'd0100 : COUNT_STATE <= 4'd0110; 4'd0110 : COUNT_STATE <= 4'd1000; 4'd1000 : COUNT_STATE <= 4'd1010; 4'd1010 : COUNT_STATE <= 4'd1100; 4'd1100 : COUNT_STATE <= 4'd0000; default : COUNT_STATE <= 4'd0000; endcase always @(i_clk, i_rst, COUNT_STATE[3]) if (i_rst) DELAY_STATE <= 0; else if(!i_clk) DELAY_STATE <= COUNT_STATE[0] & COUNT_STATE[3]; assign o_result = COUNT_STATE[0] | (i_clk & DELAY_STATE); endmodule
RTL, отчет о компиляции и временная диаграмма делителя частоты с пользовательским счетчиком и нечетным коэффициентом деления(11)
Рисунок 6. RTL, отчет о компиляции и временная диаграмма делителя частоты с пользовательским счетчиком и нечетным коэффициентом деления(11)

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

Достоинства: С низким коэффициентом деления (2, 3) минимальная задержка

Делитель частоты с дробными коэффициентом деления

В интернете куча примеров с проектированием «делителя частоты с дробными числами», но это не делители. В основном применяют делитель частоты с пользовательским счетчиком и называют его делителем частоты с дробным коэффициентом деления (- _ -). На самом деле это не совсем так…

  • Результирующий сигнал имеет коэффициент заполнения не равный 50%.
  • При увеличении коэффициента деления заполняемость будет стремиться к 50%, но никогда не будет равна ей.

Также многие умники применяют тип делителя, у которого два входных тактового сигнала. Один несущий, другой в 10 или 100 раз превышающий несущий. Это делитель частот без комментариев…

Заключение

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

FAQ (Часто задаваемые вопросы)

1. Что такое коэффициент деления?

Коэффициент деления — это число, на которое делится частота входного сигнала для получения выходной частоты. Например, если коэффициент деления равен 4, то выходная частота будет в 4 раза меньше входной.

2. Какие типы цифровых делителей частоты существуют?

Существуют различные типы цифровых делителей частоты, включая асинхронные, синхронные и программируемые делители. Наиболее применяем делители с сумматором, t-триггером и пользовательским счетчиком. Каждый тип имеет свои особенности и области применения.

3. Можно ли использовать цифровые делители частоты в аудиосистемах?

Да, цифровые делители частоты широко используются в аудиосистемах для управления частотой звуковых сигналов и улучшения качества звука.

4. Какова роль триггеров в цифровых делителях частоты?

Триггеры используются для создания и поддержания стабильных временных интервалов, что важно для точного деления частоты сигнала.

5. В чем отличие асинхронных и синхронных делителей частоты?

Асинхронные делители работают без синхронизации с внешним тактовым сигналом, что может привести к накоплению ошибок. Синхронные делители работают с синхронизацией, обеспечивая более точное и стабильное деление частоты.