参数化函数错误

Parameterized function errors

我正在尝试编写以下 systemverilog 代码,其中不同的参数可以用于函数,因此只需更改参数而不是使用参数化模块就可以重用相同的函数。

我的以下代码编译没有错误,但是当我尝试使用测试平台进行模拟时,它在 Modelsim 中给出错误 211。我看到有人建议它与 Modlesim 的版本有关,所以我尝试了 2 个不同的版本,但它给出了相同的错误。我认为这不是 modelsim 版本问题,因为有些功能可以正常工作,但有些功能不行。

代码非常简单,应该可以。但是当第二个函数调用第一个函数时会发生错误。你能看到模拟失败的任何错误吗?

   /************This package is used in the module*************/

    package RealARITH;


    typedef struct {
        int  WIDTH_INT;
        int  WIDTH_FRAC;
        int SIG_TYPE;
        } FixP;


    /************1st parameterized function*************/

    virtual class resize_verilog 
   # (parameter Total_width_InB = 3, 
   parameter Total_width_InA = 4);

   static function [Total_width_InB-1:0] resize_verilog(input logic     [Total_width_InA-1:0] InA);

    logic [Total_width_InB-1:0] InB;

    InB = $signed(InA);
    if (Total_width_InA > Total_width_InB)
    InB[Total_width_InB-1] = InA[Total_width_InA-1];

   return InB;

   endfunction
   endclass

   /***************the 2nd parameterized function that uses the 1st function*/

   virtual class align_un
   # (
   parameter FixP InA_FixP = {2,3,1},
   parameter FixP InB_FixP = {2,3,1},
   parameter ExtraMSB = 0);

   static function [InB_FixP.WIDTH_INT+InB_FixP.WIDTH_FRAC+1:0]   RealALIGN_SIGNED(input logic    [InA_FixP.WIDTH_INT+InA_FixP.WIDTH_FRAC+InA_FixP.SIG_TYPE-1:0] InA);

   localparam Total_width_InA =     InA_FixP.WIDTH_INT+InA_FixP.WIDTH_FRAC+InA_FixP.SIG_TYPE;
   localparam Total_width_InB = InB_FixP.WIDTH_INT + InA_FixP.WIDTH_FRAC + 1;


   logic [Total_width_InB-1:0] InB;

   InB = resize_verilog #   (.Total_width_InA(Total_width_InA),.Total_width_InB(Total_width_InB))::resize_verilog(InA);  

   return InB;


   endfunction

endclass    

endpackage

/************module where the 2nd function  called from package********/

module test_align
import RealARITH::*; 
(
input logic [15:0] A,
output logic [18:0] B1);

parameter FixP InA = {5,10,1};
parameter FixP InB1 = {10,8,1};

assign B1 = align_un #(.InA_FixP(InA),.InB_FixP(InB1),.ExtraMSB(1))::RealALIGN_SIGNED(A);

endmodule 


/**************testbench***********************/

module test_align_tb;

logic [15:0] A;
logic [18:0] B1;

test_align DUT (.*);

initial 

begin

A = '0; 

# 10

A = 16'b0000000110000001;

end

endmodule 

/****************  Code ends here ***************************/

显示的错误在这里给出:

# Attempting stack trace sig 11
# Signal caught: signo [11]
# vsim_stacktrace.vstf written
# Current time Fri Feb 13 10:42:19 2015
# QuestaSim Stack Trace
# Program = vsim
# Id = "10.3"
# Version = "2014.01"
# Date = "Jan  6 2014"
# Platform = linux_x86_64
# 0    0x00007fefec1e40ca: '/home/sshahabu/Structure_test6_align_again/test.sv:49'
# 1    0x00000000007160a8: '<unknown (@0x7160a8)>'
# 2    0x0000000000716dd4: '<unknown (@0x716dd4)>'
# 3    0x00007fefec1e5cd6: '/home/sshahabu/Structure_test6_align_again/test.sv:17'
# 4    0x0000000000575364: '<unknown (@0x575364)>'
# 5    0x00007fefec1e48b4: '/home/sshahabu/Structure_test6_align_again/test.sv:49'
# 6    0x0000000000575364: '<unknown (@0x575364)>'
# 7    0x00007fefec1e76eb: '/home/sshahabu/Structure_test6_align_again/test.sv:71'
# 8    0x0000000000581a1c: '<unknown (@0x581a1c)>'
# 9    0x00000000006f0d07: '<unknown (@0x6f0d07)>'
# 10   0x00007fefec1e3b6e: '<unknown (@0x7fefec1e3b6e)>'
# 11   0x0000000000581a1c: '<unknown (@0x581a1c)>'
# 12   0x00000000006f0d07: '<unknown (@0x6f0d07)>'
# 13   0x00000000006f0f8c: '<unknown (@0x6f0f8c)>'
# 14   0x00000000006f11c9: '<unknown (@0x6f11c9)>'
# 15   0x00000000006f1f0e: '<unknown (@0x6f1f0e)>'
# 16   0x000000000074ff98: '<unknown (@0x74ff98)>'
# 17   0x0000000000751207: '<unknown (@0x751207)>'
# 18   0x0000000000aba60d: '<unknown (@0xaba60d)>'
# 19   0x00000000013c3a1f: '<unknown (@0x13c3a1f)>'
# 20   0x00000000013c4bd9: '<unknown (@0x13c4bd9)>'
# 21   0x000000000140739a: '<unknown (@0x140739a)>'
# 22   0x000000000140fecf: '<unknown (@0x140fecf)>'
# 23   0x00000000013c5ef3: '<unknown (@0x13c5ef3)>'
# 24   0x00000000013d0d84: '<unknown (@0x13d0d84)>'
# 25   0x00000000013c4bd9: '<unknown (@0x13c4bd9)>'
# 26   0x000000000140739a: '<unknown (@0x140739a)>'
# 27   0x00000000014101f0: '<unknown (@0x14101f0)>'
# 28   0x00000000013c35c3: '<unknown (@0x13c35c3)>'
# 29   0x00000000013d6088: '<unknown (@0x13d6088)>'
# 30   0x00000000013c4bd9: '<unknown (@0x13c4bd9)>'
# 31   0x00000000013c5826: '<unknown (@0x13c5826)>'
# 32   0x00000000013c5ba6: '<unknown (@0x13c5ba6)>'
# 33   0x0000000001102c3c: '<unknown (@0x1102c3c)>'
# 34   0x0000000001420bf1: '<unknown (@0x1420bf1)>'
# 35   0x0000000001469f81: '<unknown (@0x1469f81)>'
# 36   0x00000000014366ad: '<unknown (@0x14366ad)>'
# 37   0x00000000014369e5: '<unknown (@0x14369e5)>'
# 38   0x00000000012e02b6: '<unknown (@0x12e02b6)>'
# 39   0x000000000089c9cb: '<unknown (@0x89c9cb)>'
# End of Stack Trace


** Fatal: (SIGSEGV) Bad pointer access. Closing vsimk.
** Fatal: vsimk is exiting with code 211.
(Exit codes are defined in the QuestaSim messages appendix
of the QuestaSim User's Manual.)

第17行代码:

virtual class resize_verilog 
# (parameter Total_width_InB = 3, 
parameter Total_width_InA = 4);

第49行代码:

 InB = resize_verilog # (.Total_width_InA(Total_width_InA),.Total_width_InB(Total_width_InB))::resize_verilog(InA);

第71行:

assign B1 = align_un #(.InA_FixP(InA),.InB_FixP(InB1),.ExtraMSB(1))::RealALIGN_SIGNED(A);

问题是你在哪里定义localparam。不允许在任务和函数内部定义参数,参见 IEEE Std 1800-2012 § 13.3 Tasks 和 § 13.4 Functions。这应该是一个编译错误。

将定义移到函数定义之上,运行时崩溃将消失。这也将允许您在函数定义中使用本地参数标识符。

其他注意事项:用结构字面量和数组字面量赋值时,重新开始使用'{}而不是{}。参考IEEE Std 1800-2012§5.10结构文字和§5.11数组文字

virtual class align_un
  #(
  parameter FixP InA_FixP = '{2,3,1},
  parameter FixP InB_FixP = '{2,3,1},
  parameter ExtraMSB = 0);

localparam Total_width_InA = InA_FixP.WIDTH_INT+InA_FixP.WIDTH_FRAC+InA_FixP.SIG_TYPE;
localparam Total_width_InB = InB_FixP.WIDTH_INT + InA_FixP.WIDTH_FRAC + 1;

  static function logic [Total_width_InB-1:0]  RealALIGN_SIGNED(
      input logic [Total_width_InA-1:0]  InA);
    logic [Total_width_InB-1:0] InB;
    InB = resize_verilog#(
      .Total_width_InA(Total_width_InA),
      .Total_width_InB(Total_width_InB)
      )::resize_verilog(InA);
    return InB;
  endfunction : RealALIGN_SIGNED
endclass : align_un