我正在尝试将接口绑定到我的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') 作为绑定语句中的实际表达式,必须在包中定义。
知道怎么处理这个吗?
答案 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_state
和prev_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
//////////////////////////////