【问题标题】:regarding always block in implementing ARM cpu in verilog关于在verilog中实现ARM cpu时总是阻塞
【发布时间】:2019-04-24 00:06:44
【问题描述】:

我正在尝试在 Verilog 中的 ARM CPU 中实现寄存器文件。 我对verilog很陌生,所以遇到了麻烦。

我想让寄存器文件在它的第 15 个寄存器中保存值 PC+8,在寄存器号 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 中。但是,如果我这样做,我是否必须将 always @(posedge clk) 中的所有语句都设为阻塞赋值 '=' 以使其按顺序进行并首先分配 15 和 0?

我对阻塞和解除阻塞分配的理解不是很清楚,所以我不确定这是否可行。

【问题讨论】:

  • 您能否提供有关 A1、A2、...的提示?那些变量?常数?你修改了模块中的regtister15, ...的值吗?
  • @Serge A1, A2 是寄存器文件的输入,用于指定将哪个寄存器的值移交给 outreg1 和 outreg2。如果 A1 为 13,则 outreg1 的值为 13 美元,依此类推

标签: arm verilog cpu


【解决方案1】:

因此,这看起来像是尝试使用“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 在同一个'posedge clk' 处提供另一个翻牌B,翻牌B 将捕获A 的输出,因为它存在于posege 之前。这就是硬件的行为方式。在这种情况下,使用阻塞分配,模拟的结果将是不可预测的,具体取决于模拟器的实现。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多