【问题标题】:Rewrite code using generate statement (Verilog HDL)使用生成语句重写代码 (Verilog HDL)
【发布时间】:2021-04-06 03:43:09
【问题描述】:

我正在尝试使用生成语句 (Verilog HDL) 重写此代码:

integer j;
always@(posedge cpu_clk) begin
        // ACCU_RST
        if(RAM[3][7]) begin
            RAM[3][7] <= 1'b0;
            for(j = 10; j <= 15; j = j + 1)
                RAM[j] <= 8'b0;
        end
        
        // CPU write
        RAM[addr + 0] <= in_valid && cmd && (addr + 0 <= 9 || addr + 0 >= 16) ? data_in[8 * 0 + 7:8 * 0] : RAM[addr + 0];
        RAM[addr + 1] <= in_valid && cmd && (addr + 1 <= 9 || addr + 1 >= 16) ? data_in[8 * 1 + 7:8 * 1] : RAM[addr + 1];
        RAM[addr + 2] <= in_valid && cmd && (addr + 2 <= 9 || addr + 2 >= 16) ? data_in[8 * 2 + 7:8 * 2] : RAM[addr + 2];
        RAM[addr + 3] <= in_valid && cmd && (addr + 3 <= 9 || addr + 3 >= 16) ? data_in[8 * 3 + 7:8 * 3] : RAM[addr + 3];

        //CPU read
        out_valid <= !cmd && in_valid;
        out_data[8 * 0 + 7:8 * 0] <= !cmd && in_valid ? RAM[addr + 0] : out_data[8 * 0 + 7:8 * 0];
        out_data[8 * 1 + 7:8 * 1] <= !cmd && in_valid ? RAM[addr + 1] : out_data[8 * 1 + 7:8 * 1];
        out_data[8 * 2 + 7:8 * 2] <= !cmd && in_valid ? RAM[addr + 2] : out_data[8 * 2 + 7:8 * 2];
        out_data[8 * 3 + 7:8 * 3] <= !cmd && in_valid ? RAM[addr + 3] : out_data[8 * 3 + 7:8 * 3];
end

如果我尝试这个,我会收到以下错误:

// CPU write
    for(i = 0; i <= 3; i = i + 1) begin
        if(in_valid && cmd && (addr + i <= 9 || addr + i >= 16)) 
            RAM[addr + i] <=  data_in[8 * i + 7:8 * i];
    end
    //CPU read
    out_valid <= !cmd && in_valid;
    for(i = 0; i <= 3; i = i + 1) begin
        if(in_valid && !cmd) 
            out_data[8 * i + 7:8 * i] <=  RAM[addr + i];
    end

错误:i 不是一个常数值。

(错误指向 data_in[8 * i + 7:8 * i] 和 out_data[8 * i + 7:8 * i])

另一种尝试,使用两个 always 块,一个用于生成,一个用于 ACCU_RST 产生多个 RAM 驱动程序(duh)。

最后一次尝试:

genvar i;
always@(posedge cpu_clk) begin
    if(ACCU_RST) begin
        RAM[3][7] <= 1'b0;
        for(j = 10; j <= 15; j = j + 1)
            RAM[j] <= 8'b0;
    end
    
    // CPU write cmd
    for(i = 0; i <= 3; i = i + 1) begin :CPU_W
        if(in_valid && cmd && (addr + i <= 9 || addr + i >= 16)) 
            RAM[addr + i] <=  data_in[8 * i + 7:8 * i];
    end

    //CPU read cmd
    out_valid <= !cmd && in_valid;
    for(i = 0; i <= 3; i = i + 1) begin :CPU_R
        if(in_valid && !cmd) 
            out_data[8 * i + 7:8 * i] <=  RAM[addr + i];
    end
end

产生:

错误:不允许对非寄存器 i 进行程序分配, 左边应该是 reg/integer/time/genvar

(并指向 i = 0 和 i = i + 1)。

【问题讨论】:

    标签: verilog hdl


    【解决方案1】:

    为此,您不应使用生成块。 generate for 循环必须存在于 always 块之外。并且一个值只能在一个 always 块中分配才能被合成。以下面的例子为例,当addr==0 在第三个循环(i==2),addr==1 在第二个循环(i==1),addr==2 在第一个循环( i==0)。三个独立的 always 块,这是一个可综合的错误。

    genvar i;
    generate
    for(i=0; i<4; i++) begin
      always @(posedge clk)
        if (in_valid && cmd && (addr + i <= 9 || addr + i >= 16)) 
          RAM[addr + i] <=  data_in[8*i + 7 : 8*i];
    end
    endgenerate
    

    跳过生成并在 always 块内使用标准 for 循环。使用索引部分选择(参考 herehere):

    integer i; // <-- not genvar
    always @(posedge cpu_clk) begin
        /* ... your other code ... */
    
        // CPU write cmd
        for (i = 0; i < 4; i = i + 1) begin :CPU_W
            if (in_valid && cmd && (addr + i <= 9 || addr + i >= 16)) 
                RAM[addr + i] <=  data_in[ 8*i +: 8];
        end
    
        //CPU read cmd
        out_valid <= !cmd && in_valid;
        for (i = 0; i < 4; i = i + 1) begin :CPU_R
            if (in_valid && !cmd)
                out_data[ 8*i +: 8] <=  RAM[addr + i];
        end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-27
      相关资源
      最近更新 更多