rPLL в проектах для микросхем FPGA Gowin

В самом первом проекте для платы Marsohod3GW я уже делал двоичный счетчик и выводил его биты на восемь светодиодов платы. Теперь я хочу немного усложнить проект, а именно, добавлю в него PLL. Ведь PLL это одна из наиболее важных частей любого проекта ПЛИС. PLL позволяет получить нужную частоту из имеющейся входной частоты. На нашей плате подается 100МГц CLK от внешнего кварцевого генератора.

Итак, взяв за основу первый проект _clk_counter создадим путём копирования новый проект _clk_pll_counter. Напомню, что все проекты (уже созданные и отлаженные) для платы Marsohod3GW находятся в репозитории на гитхаб https://github.com/marsohod4you/Marsohod3GW

Открываю проект в среде Gowin FPGA Designer.
Теперь через меню Tools запускаю IP Core Generator. Выглядит он вот так:

IpCoreGenRPLL

Выбираю тип нового компонента CLOCK -> rPLL. Двойной клик открывает диалоговое окно, с помощью которого можно редактировать параметры нового экземпляра rPLL. Давайте разберемся, как задавать параметры rPLL.

Окно создания нового экземпляра rPLL или редактирования ранее созданного rPLL выглядит примерно вот так:

rPLL

Я красным цветом сделал комментарии, чтобы немного прояснить, как всем этим можно пользоваться. Пока я рассматриваю самый простой вариант. Это PLL без возможности перестройки на лету (хотя такая возможность есть), то есть статический PLL с фиксированными параметрами, а именно я хочу получить на выходе 25МГц. На самом деле в простом режиме (General Mode) всё что мне нужно, это в окошке желаемой частоты написать 25 и нажать кнопку Calculate. Диалоговое окно само посчитает, возможны ли такие параметры и сообщит мне результат. Конечно, в данном примере 25МГц легко получаются путем деления 100МГц на 4.

Компонент rPLL довольно сложный и имеет много дополнительных возможностей. Согласно документации внутренняя структура rPLL выглядит вот так:

rPLL structure

Кроме выходного сигнала clkout можно получить дополнительный сигнал clkoutp, который имеет точно такую же частоту, как и clkout, но может иметь другую фазу или скважность.

Можно получить дополнительную выходную частоту clkoutd, это такая же частота, как clkout (или clkoutp), но дополнительно поделенная на заданный делитель. Вот только жаль, что делитель может быть только четным.

Еще один возможный дополнительный выходной сигнал это clkoutd3. Выходная частота с фиксированным делителем 3.

Согласитесь, что возможности такого PLL довольно широкие. Если еще учесть, что на самом деле rPLL еще и можно на ходу перестраивать, то совсем интересно становится. В этой статье я не буду касаться вопросов динамического конфигурирования rPLL, как нибудь в другой раз. Сейчас же просто вставим использование модуля rPLL в наш проект и испытаем.

Исходный код модуля верхнего уровня для нашей платы будет выглядеть вот так:

module top(
   input CLK, KEY0, KEY1,
   input [7:0] ADC_D,
   input [7:0] FTD,
   input [7:0] FTC,
   input FTB0,
   input FTB2,
   output FTB1,
   output FTB3,
   output ADC_CLK,
   output [7:0] LED,
   output [18:0] IO,
   output TMDS_CLK_N,
   output TMDS_CLK_P,
   output [2:0] TMDS_D_N,
   output [2:0] TMDS_D_P
);

wire pll_out_clk;
wire pll_locked;
Gowin_rPLL rpll(
   .clkin( CLK ),
   .clkout( pll_out_clk ),
   .lock( pll_locked )
);

reg [28:0]cnt = 0;
reg [7:0]moving_bit;
always @( posedge pll_out_clk )
begin
   cnt <= cnt + 1;
   moving_bit <= cnt[26] ?
   8'h01 << cnt[25:23] :
   8'h80 >> cnt[25:23] ;
end

assign LED = KEY0 ? cnt[28:21] : moving_bit;

//Serial_RX -> Serial_TX
assign FTB1 = FTB0;
assign FTB3 = FTB2;

assign IO = 0;

assign ADC_CLK = 1'b0;

assign TMDS_CLK_N = 1'b0;
assign TMDS_CLK_P = 1'b0;
assign TMDS_D_N = 4'd0;
assign TMDS_D_P = 4'd0;

endmodule

Теперь сигнал входной тактовой частоты CLK идет на Gowin_rPLL rpll и его выходной сигнал pll_out_clk подается на счетчик. Чтобы проект был не совсем скучным я добавил сюда еще второй режим отображения на светодиодах. Если нажать кнопку KEY0 платы Marsohod3GW, то вместо двоичного счета на светодиодах будет отображаться один светящийся бит, который перемещается от младшего бита к старшему и назад по кругу. И это работает!

В завершении я хотел бы добавить, что Verilog модуль Gowin_rPLL является параметризованным и ему можно задавать умножитель FBDIV_SEL  и делитель частоты IDIV_SEL  через параметры. Однако помните, что значения указываемыt в параметрах должны быть на единицу меньше, чем требуется. Например, хотим получить 25МГц из 100МГц. Умножитель должен быть 1, а делитель 4. Значит параметры нужно ставить FBDIV_SEL=0, а IDIV_SEL=3.

 

Добавить комментарий