Таким образом, это выглядит как попытка переназначения входных значений 'register0, ... register15' в набор 'outreg1 ...' с использованием 'A1 ...' в качестве манипуляторов карты.
В этом случае вы не можете использовать блок initial
.Начальный блок запускается только один раз в симуляции в начале и не может реагировать на входные изменения.Они также не синтезируются.Поскольку вы сказали, что 'registerN' также являются входными данными, вам лучше создать 2 разных Always_blocks;
reg[31:0] register[15:0];
always @*
begin
register[15] = register15;//register15 is the input holding PC+8 as it's value
register[0] = 32'h00000000;
end
always @(posedge clk)
begin
outreg1 <= register[A1];// outreg1,2 are outputs (values of register A1, A2)
outreg2 <= register[A2];
end
Разница между блокирующими и неблокирующими назначениями заключается в том, что при неблокирующих назначениях будет назначено реальное значениек переменным позже, после того, как вся оценка поставлена для всех таких блоков в проекте.Это позволяет симуляции вести себя как аппаратные средства в отношении флопов и защелок.то есть, если у вас есть один флоп A
, кормящий другой флоп B
в том же 'posedge clk', флоп B
поймает выход A
, как он существовал до поседжа.Так ведет себя аппаратная часть.При блокирующих назначениях результат моделирования будет непредсказуемым в этом случае, в зависимости от реализации симулятора.
Таким образом, практическое правило заключается в использовании неблокирующего назначения для всех «выходов» always
блоки, представляющие защелки и провалы.Все остальное должно быть блокирующим.Это означает, что блоки flop / latch могут использовать блокировку для промежуточных переменных при необходимости, но этого лучше избегать.