Verilog generate/genvar在always块中

Verilog generate/genvar在always块中,verilog,Verilog,我试图让一个模块通过ISE12.4中的语法检查,但它给了我一个我不理解的错误。首先是代码片段: parameter ROWBITS = 4; reg [ROWBITS-1:0] temp; genvar c; generate always @(posedge sysclk) begin for (c = 0; c < ROWBITS; c = c + 1) begin: test temp[c] <= 1'b0;

我试图让一个模块通过ISE12.4中的语法检查,但它给了我一个我不理解的错误。首先是代码片段:

parameter ROWBITS = 4;

reg [ROWBITS-1:0] temp;

genvar c;
generate
    always @(posedge sysclk) begin
        for (c = 0; c < ROWBITS; c = c + 1) begin: test
            temp[c] <= 1'b0;
        end
    end
endgenerate
参数行位=4;
寄存器[行位-1:0]温度;
genvar c;
生成
始终@(posedge sysclk)开始
对于(c=0;c<行位;c=c+1)开始:测试

temp[c]您需要反转生成块内的嵌套:

genvar c;
generate
    for (c = 0; c < ROWBITS; c = c + 1) begin: test
        always @(posedge sysclk) begin
            temp[c] <= 1'b0;
        end
    end
endgenerate
genvarc;
生成
对于(c=0;c<行位;c=c+1)开始:测试
始终@(posedge sysclk)开始

在一个模块中,Verilog基本上包含两个结构:项和语句。语句总是可以在过程上下文中找到,其中包括begin..end、函数、任务、always块和initial块之间的任何内容。项目(如生成构件)直接列在模块中。For循环和大多数变量/常量声明都可以存在于这两种上下文中

在代码中,似乎希望将for循环作为generate项进行计算,但该循环实际上是always块的过程上下文的一部分。要将For循环视为generate循环,它必须位于模块上下文中。generate..endgenerate关键字完全是可选的(某些工具需要它们),没有任何效果。有关如何计算生成循环的示例,请参见

//Compiler sees this
parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
genvar c;

    always @(posedge sysclk) //Procedural context starts here
    begin
        for (c = 0; c < ROWBITS; c = c + 1) begin: test
            temp[c] <= 1'b0; //Still a genvar
        end
    end
//编译器看到了这个
参数行位数=4;
寄存器[行位-1:0]温度;
genvar c;
始终@(posedge sysclk)//过程上下文从这里开始
开始
对于(c=0;c<行位;c=c+1)开始:测试

temp[c]如果您不介意编译/生成文件,那么您可以使用预处理技术。这使您能够生成一个干净的Verilog文件,该文件通常更易于调试,并减少了模拟器问题

我使用ERB(嵌入式Ruby)从模板生成verilog文件

生成的模块_name.v

parameter ROWBITS = 4 ;
always @(posedge sysclk) begin
  temp[0] <= 1'b0;
  temp[1] <= 1'b0;
  temp[2] <= 1'b0;
  temp[3] <= 1'b0;
end
参数行位=4;
始终@(posedge sysclk)开始

temp[0]如果希望将
temp
的所有位分配到同一个always块中,则不需要生成块

parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always @(posedge sysclk) begin
    for (integer c=0; c<ROWBITS; c=c+1) begin: test
        temp[c] <= 1'b0;
    end
end
参数行位=4;
寄存器[行位-1:0]温度;
始终@(posedge sysclk)开始
对于(整数c=0;c对于verilog,只需执行

parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always @(posedge sysclk) begin
  temp <= {ROWBITS{1'b0}}; // fill with 0
end
参数行位=4;
寄存器[行位-1:0]温度;
始终@(posedge sysclk)开始

temp简单地说,在always进程中不使用
generate
,而是使用generate创建参数化进程或实例化特定模块,您可以在其中组合
if-else
case
。因此,您可以将此生成和crea移动到特定进程或实例化,例如

module #(
parameter XLEN = 64,
parameter USEIP = 0
)
(
 input clk,
input rstn,
input [XLEN-1:0] opA,
input [XLEN-1:0] opB,
input [XLEN-1:0] opR,
input en
);

generate 
case(USEIP)
0:begin
always @(posedge clk or negedge rstn)
begin
if(!rstn)
begin
 opR <= '{default:0};
end
else
begin
if(en)
 opR <= opA+opB;
else
opR <= '{default:0};
end
end
end
1:begin
  superAdder #(.XLEN(XLEN)) _adder(.clk(clk),.rstm(rstn), .opA(opA), .opB(opB), .opR(opR), .en(en));
end
endcase

endmodule
模块#(
参数XLEN=64,
参数USEIP=0
)
(
输入时钟,
输入rstn,
输入[XLEN-1:0]运算放大器,
输入[XLEN-1:0]opB,
输入[XLEN-1:0]opR,
输入en
);
生成
案例(USEIP)
0:开始
始终@(posedge clk或negedge rstn)
开始
如果(!rstn)
开始

opR感谢您的快速响应。我担心会是这样。问题的一部分是我想用for循环生成一系列if语句或case选择器,这不能在单独的always块中完成。是否有任何方法可以在单个always块中生成所有代码,或者genvar就是无法做到这一点?
parameter ROWBITS = 4 ;
always @(posedge sysclk) begin
  temp[0] <= 1'b0;
  temp[1] <= 1'b0;
  temp[2] <= 1'b0;
  temp[3] <= 1'b0;
end
parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always @(posedge sysclk) begin
    for (integer c=0; c<ROWBITS; c=c+1) begin: test
        temp[c] <= 1'b0;
    end
end
parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always @(posedge sysclk) begin
        temp <= '0; // fill with 0
    end
end
parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always @(posedge sysclk) begin
  temp <= {ROWBITS{1'b0}}; // fill with 0
end
module #(
parameter XLEN = 64,
parameter USEIP = 0
)
(
 input clk,
input rstn,
input [XLEN-1:0] opA,
input [XLEN-1:0] opB,
input [XLEN-1:0] opR,
input en
);

generate 
case(USEIP)
0:begin
always @(posedge clk or negedge rstn)
begin
if(!rstn)
begin
 opR <= '{default:0};
end
else
begin
if(en)
 opR <= opA+opB;
else
opR <= '{default:0};
end
end
end
1:begin
  superAdder #(.XLEN(XLEN)) _adder(.clk(clk),.rstm(rstn), .opA(opA), .opB(opB), .opR(opR), .en(en));
end
endcase

endmodule