Как назначить значения 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.
Это то, что делает любой начальный блок, независимо от того, используются ли в нем блокирующие или неблокирующие назначения.