Как мне перенаправить/регенерировать входной тактовый сигнал на выходной контакт в моем дизайне FPGA (Verilog)

У меня есть АЦП, который требует, чтобы я отправил ему 20 тактовых импульсов при запросе на чтение данных из его внутреннего регистра (после того, как я запустил его для чтения данных с моего датчика).

Я смог отлично смоделировать это в ModelSim, но я новичок в Verilog и не осознавал, что у меня возникнут проблемы во время синтеза при создании последовательности импульсов следующим образом:

reg [4:0] counter = 5'b10100;
parameter counter = 0;

always (posedge clk and negedge clk) 
  begin
   if (counter > 0)
     begin
       counter <= counter - 1;
       serial_out <= ~serial_out; 
     end
  end

Я попытался разбить это на 2 блока always: один, который устанавливает для serial_out значение 1 в posedge clk, а другой устанавливает для serial_out значение 0 во время negedge clk, оба проверяют, больше ли счетчик 0. Это проблематично, потому что я пытаюсь управлять счетчик в двух местах и ​​получить сообщение об ошибке «не удается разрешить несколько постоянных драйверов для сетевого счетчика..»

Возможно, есть лучший способ сделать это?

Я видел несколько сообщений, предлагающих удвоить частоту clk, чтобы считывать данные с часов. Это сработает, но мне нужно поддерживать частоту 30 МГц (не могу перейти на 60 МГц по другим причинам).

Как бы вы предложили мне условно маршрутизировать/реплицировать 20 импульсов моих постоянно включенных периодических входных тактовых импульсов с частотой 30 МГц на выходной контакт?

Любая помощь будет оценена.

Вам нужно использовать закрытые часы. electronics.stackexchange.com/questions/352464/…
Спасибо, я только что переработал свой FSM и включил закрытые часы. Симуляция проходит проверку. Думаю, теперь у меня есть хорошая последовательность импульсов, с которой можно работать, когда я занимаюсь синтезом.

Ответы (1)

Я бы предложил использовать выходной триггер DDR. Как вы это реализуете, зависит от того, какую FPGA вы используете. Для Xilinx это будет примитив ODDR или ODDR2. Для Altera это ALTDDIO_OUT.

Я использую D-триггер с выходом, поступающим в логический элемент AND с помощью оператора assign. Симуляция проходит проверку. Я хотел бы управлять контактом GPIO напрямую с этой последовательностью импульсов (служит последовательными часами). Я вижу, что вы упоминаете использование ALTDDIO_OUT.
Тот факт, что симуляция подтвердилась, не означает, что она будет хорошо работать на FPGA, особенно с точки зрения ввода-вывода.
Хорошо, я новичок в этом. Почему требуется ALTDDIO_OUT по сравнению с выводом D-триггера через некоторые неблокирующие операторы во время синтеза? Я использую Quartus Prime, кстати.
ALTDDIO_OUT — это специальная логика, которая переключается между двумя сигналами при изменении часов. Вы могли бы сделать то же самое с триггерами, если бы они тактировались на двойной частоте, поскольку вам нужно реагировать на спадающий фронт тактового сигнала, но выделенная логика выигрывает, поскольку вы можете просто подать на нее два тривиальных сигнала (которые должны быть переданы после низкого уровня '1'→ высокий переход, а '0'после высокого→низкий переход).
Проблема в том, как спроектирована ПЛИС. Выходные контакты обычно могут управляться либо логикой матрицы, либо триггером. Задержка от триггера постоянна и предсказуема. Задержка от логики фабрики не является и будет варьироваться в зависимости от логики, размещения и будет варьироваться от устройства к устройству. Проблема не в триггере, проблема в том, чтобы поместить логику между триггером и выводом, особенно если вы хотите поддерживать определенное временное соотношение между этим выводом и другими выводами, которые могут напрямую управляться триггерами.
Кроме того, задержка для триггеров DDR и обычных триггеров одинакова, поэтому, если вы генерируете инвертированные часы с помощью триггера DDR, практически гарантировано правильное соотношение времени с данными, которые синхронизируются с теми же часами из IOB. шлепки.