Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AXIStream: self.width = len(self.bus.tdata) TypeError: object of type 'NoneType' has no len() #42

Open
garmin-brandonb opened this issue Apr 20, 2022 · 19 comments

Comments

@garmin-brandonb
Copy link

garmin-brandonb commented Apr 20, 2022

cocotb=1.6.2
cocotbext-axi = 0.1.16
Active HDL 11.1

When I define an
axis_source = AxiStreamSource(AxiStreamBus.from_prefix(dut, "bfm_m_axis"), dut.clk_in, dut.reset)
and axis_sink = AxiStreamSink(AxiStreamBus.from_prefix(dut, "bfm_s_axis"), dut.clk_in, dut.reset)
I get the error self.width = len(self.bus.tdata) TypeError: object of type 'NoneType' has no len() on the axis_sink.

Here is my entity:

port(
    clk_in          : in std_logic := '0';
    reset           : in std_logic := '0';

    bfm_m_axis_tdata    : in std_logic_vector(DATA_WIDTH-1 downto 0) := (others => '0');
    bfm_m_axis_tvalid   : in std_logic := '0';
    bfm_m_axis_tid      : in std_logic_vector(ID_WIDTH-1 downto 0) := (others => '0');
    bfm_m_axis_tdest    : in std_logic_vector(DEST_WIDTH-1 downto 0):= (others => '0');
    bfm_s_axis_tready   : in std_logic := '0';

    bfm_s_axis_tdata    : out std_logic_vector(DATA_WIDTH-1 downto 0) := (others => '0');
    bfm_s_axis_tvalid   : out std_logic := '0';
    bfm_s_axis_tid      : out std_logic_vector(ID_WIDTH-1 downto 0) := (others => '0');
    bfm_s_axis_tdest    : out std_logic_vector(DEST_WIDTH-1 downto 0):= (others => '0');
    bfm_m_axis_tready   : out std_logic := '0'

);
end entity;

However, if I remove either the source or sink object then remove the corresponding signals in the entity it runs fine.

@alexforencich
Copy link
Owner

Strange. What does dir(dut) return?

@garmin-brandonb
Copy link
Author

['AXI_ADDR_WIDTH', 'AXI_DATA_WIDTH', 'AXI_ID_WIDTH', 'DATA_WIDTH', 'DEST_WIDTH', 'EMMC_CONTROLLER_INST', 'ID_WIDTH', 'KEEP_WIDTH', 'M_COUNT', 'SLAVE_0', 'SLAVE_1', 'S_COUNT', '_HierarchyObject__get_sub_handle_by_name', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_child_path', '_compat_mapping', '_def_file', '_def_name', '_discover_all', '_discovered', '_fullname', '_handle', '_id', '_invalid_sub_handles', '_len', '_log', '_name', '_path', '_sub_handle_key', '_sub_handles', '_type', 'bfm_m_axis_tdata', 'clk_400khz', 'clk_52mhz', 'clk_gen_inst', 'clk_in', 'emmc_clk_i', 'emmc_data_in', 'get_definition_file', 'get_definition_name', 'mmc_tester_inst', 'pll_locked', 'reset', 'sys_clk']

@alexforencich
Copy link
Owner

Odd, the only signal I see in that list is bfm_m_axis_tdata. If cocotb doesn't see the signal, then cocotbext-axi can't connect to it. It's not clear if this is a cocotb issue or a simulator issue.

@garmin-brandonb
Copy link
Author

My colleague is using cocotb 1.4 and cocotbext-axi 0.1.4 and it works for him.

@garmin-brandonb
Copy link
Author

We are both using Active HDL

@alexforencich
Copy link
Owner

Well, possibly it's a cocotb issue related to VHPI. I think you should take this missing signal issue over to the cocotb github and open an issue there because if cocotb doesn't get all of the signal names from the simulator, then cocotbext-axi simply isn't going to be able to operate on those signals.

@garmin-brandonb
Copy link
Author

I can still access these signals from my python test, for instance I can do print("bfm_s_axis_tdata", dut.bfm_s_axis_tdata) and it will return some value.

@alexforencich
Copy link
Owner

Right, I suspect it is some sort of enumeration issue. If you ask for a specific signal, it gives you the signal. But if you ask for all of the signals, something is broken and cocotb doesn't give you all of the signals, only some subset of the signals. cocotbext-axi works by asking for all of the signals and then prefix-matching against those. Well I suppose in this case, it isn't really cocotbext-axi doing that either, instead it's the Bus object in cocotb-bus that does this that cocotbext-axi uses, which is part of cocotb.

I suspect that cocotb and/or activehdl have some sort of issue in how signals are enumerated in VHPI, so you should raise this issue on the cocotb github.

@garmin-brandonb
Copy link
Author

Alright, I posted something in Gitter but they pointed me here, so I'll ping them back with your response :)

@garmin-brandonb
Copy link
Author

So I think it is something to do with the Bus class because if I put a Verilog wrapper around my VHDL testbench then it finds all the signals and works.

@alexforencich
Copy link
Owner

If it works with a Verilog wrapper, then that pretty much confirms that this is some sort of VHPI issue between ccootb and activehdl, as cocotb uses VPI when interacting with Verilog code and VHPI when interacting with VHDL code.

@garmin-brandonb
Copy link
Author

Thanks for your speedy responses, I appreciate it!

@Botnic
Copy link

Botnic commented Sep 16, 2022

Hi @jackbpdx

Have you found a way to run VHDL directly? I run into a similar problem while testing Aldec Riviera.

@Botnic
Copy link

Botnic commented Sep 16, 2022

I was able to make my tests work by using the following workaround:

Before defining the my driver, I touch each signal once:

    dut.SAxis_Tstrb.setimmediatevalue(0)
    dut.SAxis_Tdata.setimmediatevalue(0)
    dut.SAxis_Tkeep.setimmediatevalue(0)
    dut.SAxis_Tuser.setimmediatevalue(0)
    dut.SAxis_Tid.setimmediatevalue(0)  

    dut.MAxis_Tstrb.setimmediatevalue(0)
    dut.MAxis_Tdata.setimmediatevalue(0)
    dut.MAxis_Tkeep.setimmediatevalue(0)
    dut.MAxis_Tuser.setimmediatevalue(0)
    dut.MAxis_Tid.setimmediatevalue(0)  

    # Add data drivers
    self.source_driver = AxiStreamSource(AxiStreamBus(dut, "SAxis"), dut.Clk, dut.Rst)
    self.destination_driver = AxiStreamSink(AxiStreamBus(dut, "MAxis"), dut.Clk, dut.Rst)

No Idea why, but it makes the test work again (I used to run the same test with Modelsim before)

@alexforencich
Copy link
Owner

yeah, this definitely seems to be some sort of simulator API related issue, not sure if it's on the cocotb end or the simulator end. Has anyone reported this to cocotb? I don't use VHDL or have access to riviera, so I can't test this on my end.

@garmin-brandonb
Copy link
Author

garmin-brandonb commented Sep 22, 2022

@Botnic Hi yes, I have been using that exact same method as a workout to get cocotb to recognize my bus signals. @alexforencich I made a comment about it in Gitter however, I don't think anyone really responded. I have scoured Gitter and have not seen anyone else reporting this issue. I found it hard to believe I was the only one running into this issue. It worked in cocotb 1.4 as far as I know. Once we upgraded to 1.6 I saw the issue, I also tested 1.5 and it persisted there too. Also, I believe this is an issue with the bus class because cocotb recognizes all other non bus signals in the ports at the top level.

@cmarqu
Copy link

cmarqu commented Sep 27, 2022

Shot in the dark - does it help to run dut._discover_all() before trying to access the bus?
See e.g. https://github.com/cocotb/cocotb/blob/master/tests/test_cases/test_sv_interface/test_sv_if.py#L12

@garmin-brandonb
Copy link
Author

Shot in the dark - does it help to run dut._discover_all() before trying to access the bus? See e.g. https://github.com/cocotb/cocotb/blob/master/tests/test_cases/test_sv_interface/test_sv_if.py#L12

Hey @cmarqu I tried it and it did not work.

@garmin-brandonb
Copy link
Author

@cmarqu @Botnic @alexforencich I rolled back cocotb-bus to version 0.1.1 and the issue seemed to go away. I don't have use setimmediatevalue to work around the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants