调试错误“不允许对非寄存器k进行程序分配”

时间:2016-04-17 04:47:22

标签: verilog lookup-tables

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

1 个答案:

答案 0 :(得分:6)

程序块中作业的 LHS 必须为reg类型。过程赋值语句将值分配给regintegerrealtime变量,不能将值分配给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了解regwire之间的区别。