如何将 SV 接口信号绑定到 VHDL 类型?
How to bind a SV interface signal to a VHDL type?
我正在尝试将接口绑定到我的 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;
我的接口模块实例化和绑定语句如下所示:
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) Type ('dut_fsm_type') of VHDL hierarchical reference, used
as actual expression in bind statement, must be defined in a package.
知道如何处理吗?
根据错误消息,听起来您需要在 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
混合语言模拟往往很棘手。我不是 100% 相信这会奏效,但应该会让你朝着正确的方向前进。
我设法让它在我的模拟器 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,但这对我不起作用。错误消息要求我转换而不是分配。
最好的方法是使用如上所述的包。
如果您在 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
//////////////////////////////
我正在尝试将接口绑定到我的 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;
我的接口模块实例化和绑定语句如下所示:
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) Type ('dut_fsm_type') of VHDL hierarchical reference, used as actual expression in bind statement, must be defined in a package.
知道如何处理吗?
根据错误消息,听起来您需要在 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
混合语言模拟往往很棘手。我不是 100% 相信这会奏效,但应该会让你朝着正确的方向前进。
我设法让它在我的模拟器 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,但这对我不起作用。错误消息要求我转换而不是分配。
最好的方法是使用如上所述的包。
如果您在 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
//////////////////////////////