【问题标题】:Quartus and modelsim - compile size castingQuartus 和 modelsim - 编译大小转换
【发布时间】:2014-12-11 13:51:03
【问题描述】:

我会尝试在 Quartus 中编译并在 ModelSim 中模拟一些模块。

看这个:

module somemodule(
   ... inputs, outputs, etc...
);
localparam BUFFER_LEN   = 96;
localparam BUFFER_LENW  = $clog2(BUFFER_LEN);
localparam DATA_WIDTH   = 32;

logic [BUFFER_LENW-1:0] bits_remain;

always_ff @(posedge rd_clk) begin : _proc_bitsremain
    if (state == LOAD) begin
        case (somevalue)
                  1: bits_remain <= DATA_WIDTH * 1;
                  2: bits_remain <= DATA_WIDTH * 2;
            default: bits_remain <= BUFFER_LEN;
        endcase
    end
    else
        bits_remain <= bits_remain - 1;
end
endmodule

所以,我在 modelsim 中编译它。我有 0 个错误和 0 个警告。模拟就是成功,一切都很好。接下来,我在 Quartus 中编译(综合)它,我有这个警告:

Warning (10230): Verilog HDL assignment warning at <location>: 
truncated value with size 32 to match size of target (7)

所以,我理解警告,并通过大小转换来修复它:

module somemodule(
   ... inputs, outputs, etc...
);
localparam BUFFER_LEN   = 96;
localparam BUFFER_LENW  = $clog2(BUFFER_LEN);

logic [BUFFER_LENW-1:0] bits_remain;

always_ff @(posedge rd_clk) begin : _proc_bitsremain
    if (state == LOAD) begin
        case (somevalue)
                  1: bits_remain <= BUFFER_LENW'(DATA_WIDTH * 1);
                  2: bits_remain <= BUFFER_LENW'(DATA_WIDTH * 2);
            default: bits_remain <= BUFFER_LENW'(BUFFER_LEN);
        endcase
    end
    else
        bits_remain <= BUFFER_LENW'(bits_remain - 1);
end
endmodule

在 Quartus 中编译是成功的。但是,如果我再次尝试在 ModelSim 中编译此代码,则会出现错误:

** Error: <location>(148): near "'": syntax error, unexpected '\'', expecting ';'

我错在哪里以及为什么 modelSim 无法编译尺寸转换?

【问题讨论】:

    标签: verilog system-verilog modelsim hardware-programming quartus


    【解决方案1】:

    IEEE 1800-2012 和 IEEE 1800-2009 中的第 6.24 节涵盖了铸造。 IEEE 1800 是 SystemVerilog 标准。我在任何 Verilog 标准中都没有看到它(如果您可以将我指向 IEEE 1364-1995、2001 或 2005 中的部分,请发表评论)。

    强制使用系统verilog编译器可能会解决问题,通常通过将文件扩展名更改为“.sv”或在命令行中添加-sv标志来完成。

    标准并未规定哪些部件仅用于仿真,哪些部件可综合,因此您可能会遇到可以仿真但不能综合的问题。如果我正确地遵循了这个问题,那么现在正好相反。这可能只是对 SystemVerilog 的不同支持级别。

    但是,您可以使用临时变量进行强制转换,或者使用临时变量来捕获额外的位,这些位永远不会被使用并被优化掉。

    reg [W-1:0] temp_two;
    always @* begin
      temp_two = (DATA_WIDTH * 2);
    end
    
    //...
    bits_remain <= temp_two[4:0]; 
    

    或者

    reg [W-5:0] temp_throw_away;
    {temp_throw_away, bits_remain} <= (DATA_WIDTH * 2);
    

    【讨论】:

    • 谢谢,我解决了!但是,我认为,是什么创建了许多临时变量使我的代码可读...对不起我的英语:)
    【解决方案2】:

    语法BUFFER_LENW'(DATA_WIDTH * 1) 的合法性在当前的SystemVerilog 标准中是有问题的。 LRM 仅提及出现在' 之前的正十进制数,其他所有内容都被解释为一种类型。然而,许多工具现在允许使用整数参数,就像您在此处所做的那样。 ModelSim 10.3 及更高版本现在支持 LRM 的此扩展。

    目前有两种合法的方式在 SystemVerilog 中编写此代码。一种是在连接上进行部分选择。

    bits_remain <= {DATA_WIDTH * 2}[BUFFER_LENW-1:0];
    

    另一种方法是使用 typedef 和比特流转换

    typedef logic [BUFFER_LENW-1:0] buffer_width_t;
    buffer_width_t bits_remain;
    
    
    bits_remain = buffer_width_t'(DATA_WIDTH * 2);
    

    【讨论】:

    • Quartus 无法编译这个:bits_remain &lt;= {DATA_WIDTH * 2}[BUFFER_LENW-1:0]; 错误是Error (10170): Verilog HDL syntax error at &lt;location&gt;) near text "["; expecting ";"
    • 另一个建议呢?
    【解决方案3】:

    要将 32 位无符号类型转换为 8 位无符号,您需要从 32 位本地参数中选择所需的位,然后按常规方式执行所需的任何操作。

    localparam MY_CONST_32_BITS = 96;  // parameters always seem to be type cast to 32 bit, even if you pass 8'd96 as the value.
    wire [7:0] my_const_8_bits = MY_CONST_32_BITS[7:0];  // Select lower 8 bits out of 32 bits
    wire [8:0] double_my_const_9_bits = my_const_8_bits * 8'd2;  // 8 bit wide unsigned decimal value 2.
    

    上面的代码在 Altera Quartus 工具中对我来说编译得很好。

    【讨论】:

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