关于始终阻止在Verilog中实现ARM cpu

时间:2018-11-21 12:10:48

标签: arm verilog cpu

我正在尝试在Verilog中的ARM CPU中实现寄存器文件。 我是verilog的新手,所以遇到了麻烦。

我想让寄存器文件将PC + 8的值保存在第15个寄存器中,并将寄存器号0的开头保存为0,以便寄存器文件在输入以下内容时能够将PC + 8作为输出:读寄存器之一是15,依此类推。

当前,我已经编写了这样的代码

reg[31:0] register[15:0];   

initial 
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

但是,当“寄存器读取”发生时,我想使其全部以clk的姿势发生。但是,如果这样做,我是否必须将所有语句始终以@(posedge clk)的形式分配为阻塞分配'=',以使其依次进行并首先分配15和0?

我对阻止和取消阻止分配的了解还不是很清楚,因此我不确定是否可行。

1 个答案:

答案 0 :(得分:2)

因此,这看起来像是尝试使用“ A1 ...”作为映射操纵器将输入值“ register0,... register15”重新映射到一组“ outreg1 ...”。

在这种情况下,您不能使用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在相同的'posege clk'处给另一个翻牌B喂食,则翻牌B将捕获A的输出,就像摆在翻牌之前一样。这就是硬件的行为方式。在这种情况下,使用阻塞分配会导致仿真结果无法预测,具体取决于模拟器的实现。

因此,经验法则是对表示锁存器和触发器的always块的所有“输出”使用非阻塞分配。其他所有内容都必须被阻止。这意味着触发器/锁存器块可以在需要时对中间变量使用阻塞,但是最好避免。