Как назначить значения RAM в начальном блоке в Yosys?

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

module rom (
    input clk,
    input [5:0] addr,
    output reg [15:0] data);

    reg [15:0] mem [0:63];

    initial begin
        mem[0] = 1;
        mem[1] = 2;
    end

    always @(posedge clk)
        data <= mem[addr];

endmodule

Yosys выдает это предупреждение:

$ yosys -q -p "synth_ice40 -blif rom.blif" rom.v
Warning: Blocking assignment to memory in line rom.v:9 is handled like a non-blocking assignment.
Warning: Blocking assignment to memory in line rom.v:10 is handled like a non-blocking assignment.

Если я игнорирую предупреждение (или изменяю начальные назначения на неблокирующие), я нахожу экспериментально, что ОЗУ не получает свои правильные значения до тех пор, пока через несколько тактов после включения питания.

Разве нельзя использовать начальный блок таким образом? Обсуждение проблемы #50 в репозитории yosys github предлагает пример модуля mem2reg_with_two_always_blocks что говорит о том, что так и должно быть. Но при компиляции этого модуля выдается то же предупреждение.

1 ответ

Решение

Я нахожу экспериментально, что ОЗУ не получает правильные значения до тех пор, пока после включения питания не произойдет несколько тактов.

К сожалению, вы не говорите, как вы это делаете. Я предполагаю, что вы используете синтез iCE40 и запускаете его аппаратно с программированием SRAM, потому что это соответствует известной проблеме с аппаратным обеспечением iCE40.

Смотрите также здесь и здесь для получения дополнительной информации.

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

Проблема также может быть воспроизведена при использовании инструментов решетки. Это аппаратная ошибка. Поток синтеза ничего не может с этим поделать.

Ваш код HDL в порядке и должен давать списки соединений с инициализированными ресурсами памяти при использовании потока, который поддерживает инициализированные памяти (такие как синтез iCE40 или синтез Xilinx 7-серии).


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

initial begin
    mem[0] = 1;
    mem[1] = mem[0];
end

Я хочу выразить намерение, что инициализация происходит в (или раньше!) Начале временного шага 0.

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

Другие вопросы по тегам