关于总是阻止在verilog中实现ARM cpu

问题描述 投票:0回答:1

我正在尝试在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 clk)中使用阻塞赋值'='使所有语句按顺序排列并首先分配15和0?

我对阻塞和解除阻塞任务的理解不是很清楚,所以我不确定这是否有效。

arm verilog cpu
1个回答
2
投票

因此,这似乎是尝试将输入值'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在同一个'posedge clk'中输入另一个翻牌圈B,翻牌圈B将会抓住A的输出,因为它存在于posedge之前。这是硬件的行为方式。对于阻塞分配,在这种情况下,模拟的结果将是不可预测的,这取决于模拟器实现。

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

© www.soinside.com 2019 - 2024. All rights reserved.