Jump to content
    

Посоветуйте - как сделать цепочку из 2х делителей клока на 10 на verilog

19 minutes ago, Mty said:

Касательно вопросов -

1) С внешнего генератора приходит 100Мгц. Я решил его поделить пополам, чтобы было проще с timing constrains и использовать 50. По быстродействию хватает и 50.

2)  Я так и делаю со стробами, надо было переименовать clock_10MHz в strobe_10МГц, а я позабыл, прошу прощения что ввел в заблуждение. Сейчас займусь.

3) Извне 100МГц. Основной я решил сделать 50 пока, этого хватит.

Тогда ClockGen надо немного переделать:

Spoiler
module ClockGen (
    input  wire clock_100MHz,       // 100MHz
    output reg  clock_50MHz,
    output reg  tick_10MHz,
    output reg  tick_1MHz
);

reg [2:0] count_reg10M;     // 3 bit = 8   /счет до 4
reg [3:0] count_reg1M;      // 4 bit = 16  /счет до 9

reg raw_clock_50MHz;

reg counter_10MHz_max;      // регистры синхронного сброса
reg counter_1MHz_max;

    // Генерация Clock 50 MHz
    always @(posedge clock_100MHz)
        begin
            raw_clock_50MHz <= ~raw_clock_50MHz;
        end
        
    // raw_clock_50MHz - is already output of register, it's enough to be a clock
    // Use clock_50MHz as a main clock from now on.
    assign clock_50MHz = raw_clock_50MHz;

    // Генерация Tick 10 MHz (1 cycle pulse per every 5 cycles of clock_50MHz)
    always @(posedge clock_50MHz)
        begin
            if( counter_10MHz_max )
                count_reg10M <= 1'b0;
            else
                count_reg10M <= count_reg10M + 1'b1;
                
            counter_10MHz_max <= ( count_reg10M == 3'd3 );      // Делим на 5 - задаем константу 5-2 
        end
    assign tick_10MHz = counter_10MHz_max;

    // Генерация Tick 1 MHz
    always @(posedge clock_50MHz)
        begin
            if( counter_10MHz_max )
                begin
                    if( counter_1MHz_max )
                        count_reg1M <= 1'b0;
                    else
                        count_reg1M <= count_reg1M + 1'b1;
                        
                    counter_1MHz_max <= ( count_reg1M == 4'd8 );    // Делим на 10 - задаем константу 10-2 
                end 
        end
    assign tick_1MHz = counter_1MHz_max;

endmodule : ClockGen

 

А вообще я вам очень рекомендую для быстрого избавления от детских болезней начинающего почитать книжки Pong Chu - он на интересных примерах "ставит" у обучающихся правильные приемы RTL Coding. Обязательно найдите и почитайте - вам понравится с первого раза, уверяю.

13 minutes ago, Mty said:

А стробы strobe_10МГц strobe_1МГц надо прописывать в SDC файле как clock?

Нет, не надо. Это теперь не клоки, сигналы данных, такие же, как и остальные.

А вот прописать новоявленный clock_50MHz обязательно надо.

Share this post


Link to post
Share on other sites

35 minutes ago, Raven said:

Тогда ClockGen надо немного переделать:

А output reg  tick_10MHz, не надо изменить на wire?

Смысл видимо в том, что только wire может быть glogal clock?

module ClockGen (
	....
    output reg  clock_50MHz,  // <-- здесь видимо wire?
	....
);

	....
	assign clock_50MHz = raw_clock_50MHz;

За совет по книжке спасибо! Видимо эта имелась в виду?
 

"FPGA Prototyping by Verilog Examples"

  • Год издания: 2008

  • Описание: Книга посвящена проектированию цифровых систем на ПЛИС (FPGA) с использованием Verilog. В ней разбираются практические примеры, от базовых логических схем до более сложных периферийных устройств.

  • Особенности:

    • Основы Verilog

    • Примеры проектов для FPGA (Xilinx и Altera)

    • Разбор интерфейсов (UART, VGA, PS/2 и др.)

Share this post


Link to post
Share on other sites

7 часов назад, Mty сказал:

signal_in - он полностью синхронный ... Формируется по основному клоку 50Mгц

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

Share this post


Link to post
Share on other sites

17 hours ago, Mty said:

А output reg  tick_10MHz, не надо изменить на wire?

Смысл видимо в том, что только wire может быть glogal clock?

Вполне возможно - в такие тонкости я не вдавался. Но это же легко сделать в этом коде СlockGen, т.к. выходы сейчас определяются отдельным оператором assign.

17 hours ago, Mty said:

За совет по книжке спасибо! Видимо эта имелась в виду?
"FPGA Prototyping by Verilog Examples"

  • Год издания: 2008

  • Описание: Книга посвящена проектированию цифровых систем на ПЛИС (FPGA) с использованием Verilog. В ней разбираются практические примеры, от базовых логических схем до более сложных периферийных устройств.

  • Особенности:

    • Основы Verilog

    • Примеры проектов для FPGA (Xilinx и Altera)

    • Разбор интерфейсов (UART, VGA, PS/2 и др.)

Эта. В том числе - т.к. вообще у Pong Chu есть штук 5 известных книжек. Последняя, кстати, похожа на эту, только на SystemVerilog. Думаю, вам почти все пригодятся. Многие должны быть в закромах.

Как процесс пошел? Получилось ли достичь желаемого?

Share this post


Link to post
Share on other sites

Коллеги, спасибо всем за советы!

Переписал проект на стробы.
Я хочу задать еще один вопрос по "теории стробов"

Вот так выгладят клоки и стробы сейчас. Верхний клок хардверный, делится на 2 и больще нигде не используется.
Средний- 50 МГц основной клок проекта. Ниже строб шириной 20нс и фронтами, совпадающими с фронтом клока 50.
Как советовали blackfin  и  Freibier

image.png.24e43ccf5af6d9a18f9230b76bb97f83.png

 

Мне непонятно вот что - в момент фронта клока анализируется strobe_10MHz, а он в этот момент как раз сменяется в 0, и не очень то и стабилен.

Не лучше ли двинуть его на четверть периода вправо, чтобы и setup time и hold time были одинаковы для строба?


 

  always @(posedge clock_50MHz)
		begin
			if( strobe_10MHz )
				begin
					counter <= counter + 1'b1;
					...
				end
		end
17 hours ago, Raven said:

Как процесс пошел? Получилось ли достичь желаемого?

Спасибо за книжки, обязательно почитаю. С проектом движется, в эмуляторе заработал, а в железе сбоит рандомно, отсюда и вопрос.

Share this post


Link to post
Share on other sites

4 часа назад, Mty сказал:

Не лучше ли двинуть его на четверть периода вправо, чтобы и setup time и hold time были одинаковы для строба?

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

Share this post


Link to post
Share on other sites

On 3/26/2025 at 1:00 PM, Mty said:

... в момент фронта клока анализируется strobe_10MHz, а он в этот момент как раз сменяется в 0, и не очень то и стабилен.

Сигнал strobe_10MHz получен счетчиком в блоке always @(posedge clock_50MHz) ?

Share this post


Link to post
Share on other sites

5 hours ago, blackfin said:

Сигнал strobe_10MHz получен счетчиком в блоке always @(posedge clock_50MHz) ?

Да, совершенно верно
 

Spoiler

 

	// Генерация Clock 50 MHz - основной клок проекта
	always @(posedge clock_100MHz)
		clock_50MHz <= ~clock_50MHz;

	// Генерация Strobe 10MHz
	always @(posedge clock_50MHz)
		begin
			if( counter_10MHz_max )
				count_reg10M <= 1'b0;
			else
				count_reg10M <= count_reg10M + 1'b1;
				
			counter_10MHz_max <= ( count_reg10M == 3'd3 );		// Делим на 5 - задаем константу 5-2 
		end


	// Генерация Strobe 1MHz
	always @(posedge clock_50MHz)
		begin
			if( counter_10MHz_max )
				begin
					if( counter_1MHz_max )
						count_reg1M <= 1'b0;
					else
						count_reg1M <= count_reg1M + 1'b1;
						
					counter_1MHz_max <= ( count_reg1M == 4'd8 );	// Делим на 10 - задаем константу 10-2 
				end	
		end

	
	// Фильтр выхода
	always @(posedge clock_50MHz)
		begin
			strobe_10MHz <= counter_10MHz_max;
			strobe_1MHz <= counter_1MHz_max & counter_10MHz_max;
		end

UPD: Нашел один внешний сигнал незасинхроненный, может в этом дело.
в 3х разряднм сдвиговом регистре засинхроню, надеюсь достаточно?

					pulse_sync_reg <= {pulse_sync_reg[1:0], async_pulse};
			
					// Детектирование фронта импульса (по возрастанию)
					if( pulse_sync_reg[1] & ~pulse_sync_reg[2] )
						sync_pulse <= 1'b1;	

 

Share this post


Link to post
Share on other sites

On 3/26/2025 at 1:00 PM, Mty said:

Средний - 50 МГц основной клок проекта.

А как этот клок описан в файле *.sdc ?

Share this post


Link to post
Share on other sites

1 hour ago, blackfin said:

А как этот клок описан в файле *.sdc ?

# Установка частоты тактового сигнала 100MHz
create_clock -name clock_100MHz -period 100MHz [get_ports clock_100MHz]
# Основной клок после делителя на 2
create_generated_clock -name {clock_50MHz} -divide_by 2    -source [get_ports {clock_100MHz}] [get_registers {ClockGen:ClockGen1|clock_50MHz}]

image.thumb.png.da6da4242d16cee8e0e7a3e6d588ffb8.png

Вот сигналы с логического анализатора подключенного к пинам CPLD. Частота дискретизации 400МГц
 

UPD: Вроде проблема с нестабильностью ушла. Дело было в одном внешнем сигнале который был не синхронизирован.

Не дает покоя вопрос, не нужно ли стробы завести на глобальные сигналы?

Share this post


Link to post
Share on other sites

2 hours ago, Mty said:

Вот сигналы с логического анализатора подключенного к пинам CPLD. Частота дискретизации 400МГц

400МГц и есть 2.5нС - это точность вашего логического анализатора, он любые сигналы, даже "одновременные" будет выводить {\displaystyle \pm }2.5нС.

Попробуйте вывести ваши 50МГц на несколько ног CPLD и снять одновременно логическим анализатором.

 

Идея отлаживать синхронность сигналов в ПЛИС/CPLD с помощью внешнего логического анализатора - утопия.

Используйте симулятор. В крайнем случае встроенные в ПЛИС средства отладки.

Share this post


Link to post
Share on other sites

6 hours ago, _4afc_ said:

Идея отлаживать синхронность сигналов в ПЛИС/CPLD с помощью внешнего логического анализатора - утопия.

Да, я так и делаю - внутренний симулятор. Анализатором я проверил для контроля.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...