I am trying to bind an interface to my VHDL module. The signal that I want to bind to is defined as follows in the module:
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;
My instantiation of the interface module and bind statement looks something like this:
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)
);
I had no idea what length my input signal fsm_state should be, so I just set it to 32 bits.
interface my_intf (
input bit[31:0] fsm_state,
input bit[31:0] prev_fsm_state
);
When I try to compile in questasim 10.4, I get the following message:
(vopt-2245) Type ('dut_fsm_type') of VHDL hierarchical reference, used as actual expression in bind statement, must be defined in a package.
Any idea how to handle this?
I managed to get it working on my simulator Questasim 10.4a.
1) Move the TYPE definition in the VHDL code to a separate package:
// 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) I defined my own enum my_fsm_state
in my systemVerilog package:
//my_pkg.sv
typedef enum {
IDLE_STATE,
WAIT_STATE,
IDENTIFY_STATE,
LATCH_STATE,
DONE_STATE,
ERROR_STATE
} my_fsm_states;
3) My interface module port definition had an input port of 4 bits to accomodate the 6 states of my FSM
interface my_intf (
input clk,
input [4:0] fsm_state,
input [4:0] prev_fsm_state
);
4) My bind statement was as before:
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) Now, in my interface module, I use a static cast to cast fsm_state
and prev_fsm_state
to m_fsm_states
enum variable.
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
Kinda tacky but it works.
I used the whitepaper here to get this going: https://www.mentor.com/products/fv/resources/overview/binding-systemverilog-to-vhdl-components-using-questa-f43cc1c4-6607-44e3-8dc0-515bf2c08abc
Although this didn't work exactly. They use an assign
instead of a static_cast, but that didn't work for me. The error message asked me to cast instead of assign.