0

我将尝试在 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无法编译尺寸铸件?

4

3 回答 3

0

BUFFER_LENW'(DATA_WIDTH * 1)在当前的 SystemVerilog 标准中,语法的合法性是有问题的。LRM 只提到出现在 the 之前的正十进制数',其他所有内容都被解释为一种类型。然而,许多工具现在允许使用整数参数,就像您在此处所做的那样。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);
于 2014-12-12T01:37:05.473 回答
0

铸造在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);
于 2014-12-11T14:14:56.520 回答
0

要将 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 工具中对我来说编译得很好。

于 2020-05-22T08:21:20.177 回答