Сгенерируйте тактовую частоту 40 МГц на FPGA с тактовой частотой 100 МГц.

Я пытаюсь сгенерировать тактовую частоту 40 МГц на FPGA 100 МГц, и я нахожу это своего рода борьбой с использованием кода Verilog.

Я перенаправил часы на пин, чтобы проверить функциональность 100Mhz:

assign pin1= clock; //gives me a 100MHz clock
assign pin2= ~clock;  //gives me a 100MHz inverse clock

Блок always:

reg clock1;
reg [4:0] prescaler1;

always @(posedge clk) begin
    if(reset==1'b1)begin
        clock1=1'b0;
        prescaler1=2'b0;
    end else begin
        if(prescaler1==2'b01) begin
            clock1=~clock1;
            prescaler1=1'b0;
        end else begin
            prescaler1=prescaler1+1'b1;
            clock1=clock1;
        end
    end
end

Это дает мне 50, 25, 16,66 и 12,5 МГц в зависимости от того, установлен ли прескалер на 0, 1, 2, 3.

Есть ли хитрость, как это сделать?

Это Zedboard Zynq-7000 Z-7020. XPS позволяет назначить 4 такта фабрики PL, но я считаю, что они должны быть кратны 33 МГц.

В чем разница между ARM_PLL, IO_PLL и DRR_PLL?

Есть ли в FPGA петля фазовой автоподстройки частоты внутри?
Если есть PLL, x4 с PLL, чтобы получить 400 МГц, разделить-10 с предварительным делителем или внешним компонентом, чтобы получить 40 МГц?
Пожалуйста, сообщите нам имя устройства FPGA. В ПЛИС есть блоки изменения тактовой частоты (CMB), такие как DCM, PLL, MMCM, для выполнения этой работы. Все поставщики предоставляют генераторы IP Core для генерации компонента CMB в соответствии с вашими требованиями: ClockIn = 100 МГц, ClockOut0 = 40 МГц.

Ответы (4)

Простой прескалер, который вы реализовали, следует формуле

ф о ты т "=" ф М а с т е р ÷ ( 2 * ( 1 + п р е с с а л е р Н ) )
где fMaster — вход главного тактового сигнала 100 МГц, а prescalerN — значение перезагрузки прескалера. Нет целочисленного делителя (100 МГц/2), который дает 40 МГц. Это ограничение реализации предварительного делителя в программируемой логике общего назначения.

Многие FPGA включают в себя специализированные блоки генерации тактовых импульсов, такие как PLL (фазовая автоподстройка частоты). Это специализированная аналоговая схема, реализованная на кремнии FPGA, которую можно настроить для работы с более быстрым внутренним тактовым сигналом, чем применяемый главный тактовый генератор. Таким образом, внешняя тактовая частота 100 МГц может быть удвоена до 200 МГц или, может быть, до 400 МГц. В PLL используется принцип контура управления, аналогичный тому, что используется в операционных усилителях, для обеспечения стабильной более высокой внутренней частоты из стабильного внешнего опорного сигнала более низкой частоты.

Некоторые Xilinx FPGA имеют DCM (Digital Clock Manager). Altera называет такие вещи «мегафункцией», если я правильно помню, должна быть мегафункция для PLL. Зависит от того, какую именно FPGA вы используете. Обратитесь к основному техническому паспорту FPGA.

Если у вас нет PLL, вам нужен счетчик деления на 5 (до 20 МГц), версия того же счетчика с задержкой 1,5 цикла (используйте противоположный фронт тактового сигнала для 0,5 цикла) и логический элемент XOR (с исправленной версией). , вентиля ИЛИ будет достаточно, так как оба сигнала никогда не равны «1» одновременно)

Это даст вам сигнал 40 МГц с постоянным соотношением 40% (но не 50% ... отредактировано!)

Обратите внимание, что вентиль ИЛИ добавит некоторый перекос по отношению к прямому делению часов. Если ваша FPGA имеет регистры DDR, вы можете очистить это.

process(clk)
variable count : natural range 0 to 4;
begin
  if rising_edge(clk) then
    if count = 4 then
      count  := 0;
      clk_20 <= '1';
    else
      count  := count + 1;
      clk_20 <= '0';
    end if;
    clk_20d1 <= clk_20;   -- delay, thanks to signal assignment semantics
  end if;
end process;

process(clk)
begin
  if falling_edge(clk) then
    clk_20d15 <= clk_20d1; -- +0.5 cycle delay
  end if;
end process;

clk_40 <= clk20 or clk_20d15;

Должно быть просто перевести на Verilog.

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

Вот веб-страница с примером кода на VHDL (извините, без verilog): дробное-тактовое-деление-двойной-модуль

Используя эти методы, вы сможете получить 40-мегагерцовый сигнал из 100-мегагерцового тактового сигнала, но имейте в виду, что джиттер будет увеличиваться, и вы можете получить сигнал, который не имеет 50-процентного рабочего цикла.

Поскольку вы работаете с FPGA: проверьте, содержит ли ваша FPGA диспетчер цифровых часов. Это аппаратные блоки, которые могут генерировать широкий диапазон частот из существующих часов, сначала умножая частоту, а затем разделяя ее. Вы получите лучшую производительность от цифрового диспетчера часов, чем от написанного от руки предварительного делителя с двойным модулем.

Лучшим способом будет PLL, как упоминалось в других ответах, - умножьте на 4, затем разделите на 10. Вы можете сделать x2/5, но это не даст вам 50% рабочего цикла (может быть, это не проблема).


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

wire clock2x;
wire clock2xDelay;
assign clock2x = clock100M ^ clock2xDelay;
assign clock2xDelay = ...; //I need to be clock2x delayed by about 5ns

reg [2:0] divider;
always @ (posedge clock2x or posedge reset) begin
  if (reset) begin
    divider <= 3'b0;
  end else if (divider == 3'd4) begin
    divider <= 3'b0;
  end else begin
    divider <= divider + 3'b1
  end
end
assign clock50M = divider[1]; // 40% Duty cycle, 50MHz clock

Приведенный выше код не совсем завершен — вы заметите, что clock2xDelay не завершен. По сути, именно здесь должен произойти интересный момент, и это будет зависеть от вашего устройства. В основном вам нужно добавить достаточную задержку (через задержку цепочки переноса, задержки LUT и т. д.), чтобы XOR создавал достаточно широкий импульс, чтобы не вызывать ошибок синхронизации минимальной ширины импульса. Синтезатору также нужно сказать, чтобы он не оптимизировал цепочку задержки.

Этот код не рекомендуется, так как асинхронная задержка зависит от температуры и характеристик устройства, что приводит к дрожанию часов.