mrmikehicks Posted October 7, 2011 Report Share Posted October 7, 2011 I am still having a problem trying to read (not write) VHDL architecture signals (not entity ports) using the bind construct. I have sent my sample code off to the Mentor support people and they tell me that bind cannot be used to read VHDL signals, only the VHDL entity ports. They recommend 'signal_spy' which I have used for years, and yet others in this forum have indicated that you can access the VHDL signals in a (read only) mode using the bind construct. Is this just a QuestaSim problem and not an LRM bug? Do I need to put my virtual interface inside a 'program' block and then use bind to embed that program block inside my VHDL DUT?. I have tried using bind in the attached sample code, but it always shows 'z' as the value of the signal when read. Although attached also, here is the interface and some pertinent code snippets. I know I don't fully understand the bind construct, but I think this should work. Any and all help is appreciated. The VHDL Code: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity cpld_glue is port ( cpld_clk : in std_logic; cmd_clk : in std_logic; cmd_dat : in std_logic; cmd_clr : in std_logic; mosfet : out std_logic_vector(6 downto 0); display : out std_logic_vector(3 downto 0); -- 4 bit mode d7:5 tied low d4 tied hi disp_e : out std_logic; disp_wrn : out std_logic; cmd_ack : out std_logic ); end cpld_glue; architecture rtl of cpld_glue is type cur_cmd_smtyp is (wait4clk, wait4clknot, ck_disp_fet, dis_wr_cyc1, dis_wr_cyc2, dis_wr_cyc3, dis_wr_cyc4); signal cur_cmd_state : cur_cmd_smtyp := wait4clk; signal bit_count : unsigned(3 downto 0) := "0000"; signal ser_in_buf : std_logic_vector(7 downto 0); -- 2 extra bits for command decoding -- commands are always write (no read cmds) -- bit(7) selects if write is to display(1) or MOSFETs(0) -- bit(6:0) is the byte to send to the display or MOSFETs [COLOR="Red"]signal cmd_clk1 : std_logic := '0'; signal cmd_clk2 : std_logic := '0';[/COLOR] begin ----------------------------------------------------------------------------- -- sync the cmd_clk and cmd_dat signals to cpld clock ----------------------------------------------------------------------------- ... The signal interface code: interface dut_if_sigs(input logic cmd_clk1, input logic cmd_clk2); endinterface: dut_if_sigs ... The instantiation in the top.sv: module top; import uvm_pkg::*; import agent_pkg::*; import seq_lib_pkg::*; import test_lib_pkg::*; dut_if dut(); cpld_glue myvhdl(dut.cpld_clk, // : in std_logic; dut.cmd_clk, // : in std_logic; dut.cmd_dat, // : in std_logic; dut.cmd_clr, // : in std_logic; dut.mosfet, // : out std_logic_vector(6 downto 0); dut.display, // : out std_logic_vector(3 downto 0); dut.disp_e, // : out std_logic; dut.disp_wrn, // : out std_logic; dut.cmd_ack); // : out std_logic dut_if_sigs sigs(); bind cpld_glue dut_if_sigs sigs(.cmd_clk1(cmd_clk1),.cmd_clk2(cmd_clk2)); // Free running clock initial ... Quote Link to comment Share on other sites More sharing options...
Erling Posted October 11, 2011 Report Share Posted October 11, 2011 It seems the interface reference you are storing in the config_db is a local instance inside top, and not the bound interface. That can not work. I'd recommend not using the config_db for this purpose and instead place all code using interface signals inside the interface. Avoid virtual interfaces in general. Regards, Erling Quote Link to comment Share on other sites More sharing options...
mrmikehicks Posted October 12, 2011 Author Report Share Posted October 12, 2011 Erling, are you suggesting that I put the driver, monitor and scoreboard classes all inside the dut_if interface file since they all use the interface signals. That would also mean putting the bind statement ( bind cpld_glue dut_if_sigs sigs(.cmd_clk1(cmd_clk1),.cmd_clk2(cmd_clk2)); ) inside the interface as well? I will work on that and see if I can get it to work. Thanks Quote Link to comment Share on other sites More sharing options...
Erling Posted October 12, 2011 Report Share Posted October 12, 2011 Erling, are you suggesting that I put the driver, monitor and scoreboard classes all inside the dut_if interface file since they all use the interface signals. No, I suggest that you group signals and code using them (directly) inside an interface (or module), and dispatch that code virtually, i.e transfers control to the "privileged" code which has direct signal access, instead of distributing references to dut signals for everyone to use via the config_db. FWIW, here is one way to bind an interface with code in it to a design entity: Say we have a VHDL architecture with internal signals to be monitored from a testbench, for example: architecture rtl of MyEntity is signal s_clk, s_valid: std_logic; signal s_data: std_logic_vector(15 downto 0); -- much bla bla here driving signals above end architecture rtl; First step is to place the monitor definition in a package (perhaps together with other low level components like coverage collectors and drivers), for example: package MyPkg; class MyDataCollector extends uvm_monitor; uvm_analysis_port #(bit[15:0]) m_dutData; // collected data posted here function new(...); super.new(...); m_dutData = new(...); endfunction: new `uvm_component_utils(MyDataCollector) endclass: MyDataCollector endpackage: MyPkg The implementation of the data collector goes into the interface to be bound to the VHDL architecture above, for example: interface MyEntityIf(logic s_clk, logic s_valid, logic[15:0] s_data); import uvm_pkg::*; import MyPkg::*; class MyDataCollectorImp extends MyDataCollector; task run_phase(...); forever @(posedge s_clk) if (s_valid) m_dutData.write(s_data); endtask: run_phase `uvm_component_utils(MyDataCollectorImp) endclass: MyDataCollectorImp initial // have the factory create MyDataCollectorImp when asked for MyDataCollector factory.set_type_override_by_type(MyDataCollector::get_type(), MyDataCollectorImp::get_type()); endinterface: MyEntityIf The monitor can then be instantiated and connected by the testbench as any other component, for example: package MyTestPkg; import uvm_pkg::*; import MyPkg::*; class MyTestbench extends uvm_env; MyScoreboard m_scoreboard; MyDataCollector m_dataCollector; function void build_phase(...); m_scoreboard = MyScoreboard::type_id::create(); m_dataCollector = MyDataCollector::type_id::create(); endfunction function void connect_phase(...); m_dataCollector.m_dutData.connect(m_scoreboard.m_dutData); endfunction `uvm_component_utils(MyTestbench) endclass: MyTestbench class MyTest extends uvm_test; MyTestbench m_tb; function new...; function void build_phase(...); m_tb = MyTestbench::type_id::create(); endfunction: build_phase task run_phase(...); // have sequences traverse the dut here to have it produce data to be collected endtask: run_phase `uvm_component_utils(MyTest) endclass: MyTest endpackage: MyTestPkg And, finally, instantiation, binding and test program in the top module, for example: module top; MyDutIf dif(); MyDesign dut(dif...); bind MyEntity MyEntityIf eif(.*); program test; import uvm_pkg::*; import MyTestPkg::*; initial run_test(); endprogram: test endmodule: top Using the same technique for regular monitors and drivers will eliminate virtual interfaces altogether, and bound interfaces will then be just more of the same. Hope this helps. Regards, Erling Quote Link to comment Share on other sites More sharing options...
mrmikehicks Posted October 12, 2011 Author Report Share Posted October 12, 2011 Thank You for your time with this, I need to chew on this for a while, but it sounds like a much better method. Mike Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.