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

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

У меня есть шаблон для делителя частоты, который делит часы на 5. Предполагается, что у него есть одна серьезная проблема, но я не могу точно понять, в чем она заключается.

введите описание изображения здесь

Варианты, которые у меня есть, чтобы исправить эту проблему:

  • Х==(000|001|100), Y==(001)
  • Х==(000|001|010|011), Y==(010|011)
  • Х==(001|010|011), Y==(000)
  • И а) и в) верны!

Я потратил время, чтобы отобразить сигналы в исходном проекте и в варианте номер 3, так как думал, что это и есть ответ.

http://imgur.com/dD30q

Я перевел часы на полтакта, упс. Хотя ничего менять не должен. Остальное делается вручную.

У кого-нибудь здесь есть хорошие предложения?

Ответы (3)

У него должна быть одна серьезная проблема

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

В качестве примера предположим, что у вас есть эта наивная реализация генератора полного переноса (по крайней мере, 2 входа из 3 верны), а именно

Y = ABC + AB(!C) + A(!B)C + (!A)BC

Если ваши сигналы ABC переключаются со 111 на 011, есть шанс, в зависимости от задержек распространения, что выход Y, который должен быть 1 все время, дает вам короткий сбой 0. Что в основном происходит, так это то, что выход истинность должна переходить от одного термина к другому: в этом случае ABC -> (!A)BC. Если член (!A)BC имеет большую задержку распространения, чем член ABC для перехода 1 -> 0 на A, то оба члена ABC и (!A)BC могут быть равны 0 в течение короткого периода времени, и вы получите 0 в качестве вывода.

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

Y = AB + BC + CA

В вашем случае возможны две причины глюков.

Во-первых, X и Z изменяются почти одновременно, но в вашем случае, согласно вашим временным диаграммам, этого не должно происходить.

Во-вторых, комбинационная логика, которая производит X, подвержена сбоям. Мы не знаем, как это реализовано, поэтому трудно сказать.

Самое простое решение в любом случае — подключить к выходу триггер с тем же тактовым входом, что и другие ваши триггеры. Современные триггеры имеют такие характеристики выборки/удержания, что любая задержка распространения >= 0 и < (тактовый период - время установки) будет давать стабильные выходные данные без сбоев, поэтому, если ваш тактовый период не очень быстр, любой сбой на входе триггер стабилизируется к началу временного окна установки на следующем фронте тактового сигнала.

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

Я пропустил, что это был тактовый выход. Глюки почти наверняка являются «основной проблемой». Я думал, что один из ответов имеет более оптимальное логическое решение (меньше ворот).

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

Q0 := !Q1 и !Q2;
Q1 := Q0;
Q2 := Q1;

Этот счетчик будет проходить через последовательность: 000 001 011 110 100 (значение 101 достигнет действительного состояния через два такта; 010 или 111 достигнет действительного состояния через один такт). Любой его бит может быть использован в качестве двойного выхода.

Возьмите выход этого счетчика и подайте его на защелку, которая срабатывает на противоположном фронте тактового сигнала. «ИЛИ» выхода этого счетчика с первым даст желаемую форму сигнала.

Не надо так усложнять. Я сделал для деления на 3. Вы можете обобщить его или жестко закодировать для деления на 5, просто изменив значение c1 и элементов чувствительности. Ниже приведен код:

module clk ();
reg clk,clkout;
initial clk =0;
initial clkout = 0;
int c1,c2,c3;
always #5 clk = ~clk;
always@(posedge clk or negedge clk)
begin
c1 <= c1 +1;

if (c1 == 5)
begin
c1 <= 0;
end

//
end

always@(posedge clk or negedge clk)
begin
if(c1==0 || c1 == 3)
begin
clkout = ~clkout;
end
end


endmodule
Вы должны отформатировать свой код, это очень трудно читать
Выделите текст и нажмите {}кнопку кода на панели инструментов редактора. Обратите внимание, что вы, похоже, предоставили программу для чего-то, не сказав, что это за что-то. Также обратите внимание, что вопрос касается логики, а не программирования. Наконец, посмотрите, что ОП принял ответ семь лет назад.
@DHANESH: nidhin добавил теги кода, но вам нужно правильно сделать отступ в коде и объяснить, как это отвечает на вопрос.