задержка часов ice40, анализ синхронизации вывода

У меня есть ice40, который управляет часами и вводом данных ASIC.

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

Я решил эту проблему, используя цепочку инверторов для задержки внутренних часов ice40 без задержки часов, управляющих ASIC. Таким образом, возрастающие часы достигают ASIC до того, как изменятся выходные данные ice40. Но это вызывает несколько вопросов:

  1. Является ли моя стратегия — использование цепочки инверторов для задержки внутренних часов ice40 — хорошей стратегией?

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

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

Обратите внимание, что задержки asic_dataX короче задержки clk_out, что указывает на проблему.

Есть ли способ получить эту информацию от yosys/nextpnr?

Спасибо за любое понимание!


person Dave Keck    schedule 14.07.2020    source источник
comment
Каковы аргументы против изменения данных по заднему фронту, если clk чувствителен к переднему фронту? SPI делает это, например. Вы можете выполнить поиск модуля spi verilog, чтобы найти несколько примеров.   -  person Christian B.    schedule 15.07.2020
comment
Спасибо за предложение Кристиан, это может сработать. Первоначально я игнорировал решения, связанные с инвертированием часов (поскольку время удержания выхода ASIC слишком мало, чтобы можно было считывать данные с negege). Но, может быть, я могу сделать все чувствительным к положению, за исключением того, что выходные флопы ice40 будут чувствительны к negege. Мне все еще нужно выяснить временные последствия для логики, которая управляет флопами negege: либо логика должна быть достаточно быстрой, чтобы превзойти negege (+t_setup), либо достаточно медленной, чтобы ввод на флопах negege не был потревожен в negege (+t_hold).   -  person Dave Keck    schedule 18.07.2020


Ответы (1)


Вместо того, чтобы возиться с задержками, я бы рекомендовал использовать устоявшиеся методы. Например, SPI simple синхронизирует данные на одном крае и изменяет их на другом: Источник https://www.ti.com/lit/an/slaa734a/slaa734a.pdf.

Логика реализации этого довольно проста. Вот пример реализации ведомого SPI:

module SPI_slave #(parameter WIDTH = 6'd16, parameter phase = 1'b0,
                   parameter polarity = 1'b0, parameter bits = 5) (
    input wire rst,
    input wire CS,
    input wire SCLK,
    input wire MOSI,
    output reg MISO,  
    output wire data_avbl,
    input wire [WIDTH-1:0] data_tx,
    output reg [WIDTH-1:0] data_rx
    );

reg [bits:0]    bitcount;
reg [WIDTH-1:0] buf_send;            

assign clk          = phase ^ polarity ^ SCLK;
assign int_rst      = rst | CS;
assign tx_clk       = clk | CS;
assign data_avbl    = bitcount == 0;            
                               
always @(negedge tx_clk or posedge rst) begin
    MISO <= rst ? 1'b0 : buf_send[WIDTH-1];
end

always @(posedge clk or posedge int_rst) begin  
    if (int_rst) begin
        bitcount    <= WIDTH;
        data_rx     <= 0;
        buf_send    <= 0;
    end else begin    
        bitcount    <= (data_avbl ? WIDTH : bitcount) - 1'b1;                
        data_rx     <= { data_rx[WIDTH-2:0], MOSI };
        buf_send    <= bitcount == 1 ? data_tx[WIDTH-1:0] : { buf_send[WIDTH-2:0], 1'b0};
    end   
end

endmodule

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

person Christian B.    schedule 18.07.2020