My Verilog代码如下所示。该模块实现了一个具有地址寄存器的查找表ROM,该寄存器在时钟脉冲上递增。对其输出进行解码以得到32位数。我不明白为什么k需要成为一个注册。事实上,我不希望k在地址寄存器改变后有一个时钟延迟。如何指定addr
的解码?
(注意,这似乎与SO上类似命名的其他问题无关,因为我已经检查过了 - 我不想在输出上有一个寄存器。我只是想异步解码计数寄存器的输出。也许我'混淆了< =运算符,我假设它总是生成一个时钟寄存器,但也许我应该总是使用< =。)
module k_rom (input clk, input reset, output [31:0] k);
// Constants defined by the SHA-2 standard.
reg [5:0] addr;
always @ (addr)
begin
case(addr)
6'h00: k = 32'h428a2f98;
6'h01: k = 32'h71374491;
6'h02: k = 32'hb5c0fbcf;
6'h03: k = 32'he9b5dba5;
6'h04: k = 32'h3956c25b;
6'h05: k = 32'h59f111f1;
6'h06: k = 32'h923f82a4;
6'h07: k = 32'hab1c5ed5;
6'h08: k = 32'hd807aa98;
6'h09: k = 32'h12835b01;
6'h0a: k = 32'h243185be;
// other constants not shown for brevity
6'h3c: k = 32'h90befffa;
6'h3d: k = 32'ha4506ceb;
6'h3e: k = 32'hbef9a3f7;
6'h3f: k = 32'hc67178f2;
endcase
end
always @ (posedge clk)
begin
if(reset)
addr <= 6'b0;
else
addr <= addr + 6'b1;
end
endmodule
答案 0 :(得分:6)
程序块中作业的 LHS 必须为reg
类型。过程赋值语句将值分配给reg
,integer
,real
或time
变量,不能将值分配给wire
。请注意,reg
可以保留或存储某些值,具体取决于某些触发事件,而wire
无法存储任何值。
此处,k
持有某个值,直到addr
信号发生变化。此后,它必须是reg
类型。
默认情况下,output
信号的类型为wire
。将k
声明为output reg [31:0] k
。
module k_rom (input clk, input reset, output reg [31:0] k);
在上面的代码中,使用阻止分配(=
)和非阻塞分配(<=
)似乎是正确的。
对组合逻辑(=
块)使用阻止分配(always @(addr)
)。对顺序逻辑(<=
块)使用非阻止分配(always @(posedge clk)
)。
但您可能更愿意使用always @(*)
(或always_comb
代替SystemVerilog)代替always @(addr)
作为自动敏感列表。
请参阅this PDF了解reg
和wire
之间的区别。