如何将SV接口信号绑定到VHDL类型?

时间:2016-11-23 23:23:06

标签: vhdl system-verilog uvm questasim

我正在尝试将接口绑定到我的VHDL模块。我要绑定的信号在模块中定义如下:

TYPE dut_fsm_type is (
                           IDLE_STATE,
                           WAIT_STATE,
                           IDENTIFY_STATE,
                           LATCH_STATE,
                           DONE_STATE,
                           ERROR_STATE
                          );
signal dut_fsm_state       : dut_fsm_type;
signal prev_dut_fsm_state  : dut_fsm_type;

我对interface module和bind语句的实例化看起来像这样:

bind my_dut my_intf my_intf_0 (.*,
                               .fsm_state     (tb.u_dut.dut_fsm_state),
                               .prev_fsm_state(tb.u_dut.prev_dut_fsm_state)
                              );

我不知道输入信号fsm_state的长度应该是多少,所以我只需将它设置为32位。

interface my_intf (
  input bit[31:0] fsm_state,
  input bit[31:0] prev_fsm_state
);

当我尝试在questasim 10.4中编译时,我收到以下消息:

  

(vopt-2245)使用VHDL分层参考的类型(' dut_fsm_type')   作为绑定语句中的实际表达式,必须在包中定义。

知道怎么处理这个吗?

3 个答案:

答案 0 :(得分:3)

根据错误消息,听起来您需要在SystemVerilog端定义等效类型,并且需要在包中定义。因此,添加波纹管包并修改接口端口应该可以正常工作。

package typdef_pkg;
  typedef enum  {
    IDLE_STATE,
    WAIT_STATE,
    IDENTIFY_STATE,
    LATCH_STATE,
    DONE_STATE,
    ERROR_STATE
  } dut_fsm_type;
endpackage : typdef_pkg

interface my_intf (
  input typdef_pkg::dut_fsm_type fsm_state,
  input typdef_pkg::dut_fsm_type prev_fsm_state
);
...
endinterface

混合语言模拟往往很棘手。我并非百分之百地确信这会有效,但应该让你朝着正确的方向前进。

答案 1 :(得分:2)

我设法让它在我的模拟器Questasim 10.4a上工作。

1)将VHDL代码中的TYPE定义移动到单独的包中:

// File: types_pkg.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

package types_pkg is
    TYPE dut_fsm_type is (
                          IDLE_STATE,
                          WAIT_STATE,
                          IDENTIFY_STATE,
                          LATCH_STATE,
                          DONE_STATE,
                          ERROR_STATE
                         );
end types_pkg;

2)我在systemVerilog包中定义了自己的enum my_fsm_state

//my_pkg.sv
typedef enum {
             IDLE_STATE,
             WAIT_STATE,
             IDENTIFY_STATE,
             LATCH_STATE,
             DONE_STATE,
             ERROR_STATE        
             } my_fsm_states;

3)我的接口模块端口定义有一个4位的输入端口,以适应我的FSM的6种状态

interface my_intf (
  input          clk,
  input [4:0]    fsm_state,
  input [4:0]    prev_fsm_state
);

4)我的绑定声明和以前一样:

bind my_dut my_intf my_intf_0 (.*,
                               .fsm_state     (tb.u_dut.dut_fsm_state),
                               .prev_fsm_state(tb.u_dut.prev_dut_fsm_state)
                              );

5)现在,在我的界面模块中,我使用静态强制转换将fsm_stateprev_fsm_state投射到m_fsm_states枚举变量。

interface my_intf (
  input          clk,
  input [4:0]    fsm_state,
  input [4:0]    prev_fsm_state
);

always @(posedge clk)
begin
  if (my_fsm_states'(fsm_state) == WAIT_STATE) begin
    // Do something
  end
  else if (my_fsm_states'(fsm_state) == IDLE_STATE) begin
    // Do something
  end
  else if .... // So on..

end

有点俗气,但它有效。

我在这里使用白皮书来实现这一目标:https://www.mentor.com/products/fv/resources/overview/binding-systemverilog-to-vhdl-components-using-questa-f43cc1c4-6607-44e3-8dc0-515bf2c08abc

虽然这不起作用。他们使用assign而不是static_cast,但这对我不起作用。错误消息要求我投射而不是分配。

答案 2 :(得分:0)

最好的方法是使用如上所述的包。

如果您在 VHDL 中将 FSM 定义为:

TYPE state_type IS (idle,shift_wait, shift_dio, shift_sync, sync_ready, sync_update);
state_type  CURSTATE_I;//your signal to bind

如果您使用的是 Synopsys,请将 typedef 定义为:

typedef enum {idle=0,shift_wait=1, shift_dio=2, shift_sync=3, sync_ready=4, sync_update=5} my_fsm_states; //it should be in a package

否则您将只有 X。重要的是将整数映射 =0,=1.... 等映射到每个州名。

///////////my_pkg.sv
typedef enum {idle=0,shift_wait=1, shift_dio=2, shift_sync=3, sync_ready=4, sync_update=5} my_fsm_states; //it should be in a package

/////////// if_in_internals.sv
interface if_in_internals;
     my_fsm_states shift_fsm;     
endinterface
 
 
MODULE EXPOSER
/////////// module_in_internals_exposer.sv
module in_internals_exposer#(string expose_name, string expose_path_format) ( 
        my_fsm_states shift_fsm 
    );
    if_in_internals intf();  
    assign intf.shift_fsm                       =  shift_fsm;
    initial begin
    ..... e.g.  uvm_config_db#(virtual if_in_internals)::set(uvm_root::get(), expose_path, {"internals", ".if"},  intf);
    end
endmodule
 
///////////top_level.sv - where you want to place your hierarchy bind interface
bind i_top_wrp in_internals_exposer#("3",  "*.i_%0d.*") if_internals_expose (        
            .shift_fsm                      (dut.U01.U06.U02.U_USE_U03.U03.U01.CURSTATE_I)        
        );
end
//////////////////////////////