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

Array support in VPI #237

Closed
mark-mb opened this issue Dec 19, 2016 · 20 comments
Closed

Array support in VPI #237

mark-mb opened this issue Dec 19, 2016 · 20 comments

Comments

@mark-mb
Copy link

mark-mb commented Dec 19, 2016

I was using GHDL and Cocotb to run some tests for a VHDL project, and it looks like GHDL doesn't show arrays on the VPI interface.

For example, with this array:

TYPE ram_type IS ARRAY(depth - 1 DOWNTO 0) OF STD_LOGIC_VECTOR(data_bits - 1 DOWNTO 0);
SIGNAL ram : ram_type;

I get this error in Cocotb:

Send raised exception: r contains no object named ram
  File "/home/markmb/vhdl/cocotb/cocotb/decorators.py", line 197, in send
    return self._coro.send(value)
  File "/home/markmb/Documents/vhdl/test/test_vhdl.py", line 44, in init_test
    mem = dut.mem.r.ram
  File "/home/markmb/vhdl/cocotb/cocotb/handle.py", line 261, in __getattr__
    raise AttributeError("%s contains no object named %s" % (self._name, name))

But I can get the value of all the other signals (std_logic and std_logic_vectors).

Is this a known issue? Is there any intention to add support for arrays in the VPI extension anytime soon?

@Paebbels
Copy link
Member

How is this related to GHDL? It's a Python error message. Cocotb has also a Python to VPI adapter layer written in C and C++. I'm just saying there are several possibilities, where it can fail.

Can you provide a small, but complete example?

@mark-mb
Copy link
Author

mark-mb commented Dec 19, 2016

Sorry for the briefness of the previous message. I now include a smaller test case (below), to replicate the issue. To be clear, I am working with the code from Github for both GHDL and Cocotb

For the code below, I see these elements under dut: num_line, data_out, is_write, data_in, clk. Trying to access mem directly fails with the error I presented in the first message.

Tracking Cocotb code, it seems that the call to vpi_handle_by_name() with parameters main.mem and NULL returns NULL. If I understood correctly how VPI works, this function is implemented on the GHDL side, and NULL means that this element doesn't exist.

VHDL code:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY main IS
    PORT (clk : IN STD_LOGIC;
        data_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
        num_line : IN INTEGER RANGE 15 TO 0;
        is_write : IN STD_LOGIC;
        data_out : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
    );
END main;

ARCHITECTURE structure OF main IS
    TYPE mem_type IS ARRAY(15 DOWNTO 0) OF STD_LOGIC_VECTOR(31 DOWNTO 0);
    SIGNAL mem : mem_type;
BEGIN
    p: PROCESS(clk)
    BEGIN
        IF rising_edge(clk) THEN
            IF is_write = '1' THEN
                mem(num_line) <= data_in;
            END IF;
        END IF;
    END PROCESS;

    data_out <= mem(num_line);
END structure;

Test case for Cocotb:

import cocotb
from cocotb.triggers import Timer, RisingEdge
from cocotb.result import TestFailure

@cocotb.coroutine
def clock_gen(signal):
    while True:
        signal <= 0
        yield Timer(1)
        signal <= 1
        yield Timer(1)

@cocotb.test()
def init_test(dut):
    cocotb.fork(clock_gen(dut.clk))
    clkedge = RisingEdge(dut.clk)

    yield clkedge

    dut.is_write = 1

    for i in range(15):
        dut.data_in = i << 5
        dut.num_line = i
        yield clkedge

    dut.is_write = 0

    dut._log.info("Test run successfully")

    print "Elements in dut:"
    for elem in dut:
        print elem.name

    print ""
    print "Memory: "
    print dut.mem

Makefile

VHDL_SOURCES = $(PWD)/main.vhd
TOPLEVEL = main
MODULE = test_main

COCOTB = /home/markmb/vhdl/cocotb

include $(COCOTB)/makefiles/Makefile.inc
include $(COCOTB)/makefiles/Makefile.sim

@tgingold
Copy link
Member

tgingold commented Dec 20, 2016 via email

@tgingold
Copy link
Member

tgingold commented Jun 9, 2017

Verilog has a limited support of arrays (aka memory), so I am not sure how they are handled in vpi.
OTOH, SystemVerilog has a much better support of them.

I have to investigate...

@putsplut
Copy link

Tristin,
I've been walking through the interactions of cocotb and ghdl over the weekend. I'll try to summarize what I've seen. I'm not sure why mark-mb saw the error when accessing dut.mem, but I suspect it is caused by an iterator call when he attempts to print the RAM content.

I've been experimenting with accessing bits of a std_logic_vector and elements of a record. In both cases, cocotb calls vpi_handle_by_name, passing in the full name to specify the vector or record. This step succeeds, and a handle is returned. In the case of a vector/array, the indexing access follows with a call to vpi_handle_by_index. This fails (not implemented), so cocotb falls back to calling vpi_iterate, using vpiRange as the argument. This is also unsupported. cocotb then tries a third time, using vpi_handle_by_name, where the name looks like "sliced_rec.ivec[0]", where ivec happens to be my std_logic_vector on the entity of a module named sliced_rec. The name search finds "sliced_rec", but then fails to find "ivec[0]", as expected since the immediate member is "ivec", not "ivec[0]". Since the original poster is attempting to print the ram content, I suspect cocotb is trying to iterate on the ram directly and failing at that point.

A record has the same basic issue in that there is no iterator method to step inside of the base object (not sure that's the correct nomenclature).

Looking at the vpi_handle_by_index operation, there is full knowledge that the vhpiPortDeclK is a std_logic_vector - if I call Get_Verilog_Wire(aRef.Ref, Info), then Info reports vtype => vcd_stdlogic_vector. What I'm not seeing is a way to generate another vpi/vhpi handle to an element of that vector.

I'm not sure where to proceed from there.
Regards,
putsplut

@tgingold
Copy link
Member

tgingold commented Feb 26, 2018 via email

@ghost
Copy link

ghost commented Mar 12, 2018

I'm currently running into this issue as well. For some of our designs we use arrays and records for scalability and without the ability to read/write arrays from cocotb we simply cannot properly simulate these designs. A possible workaround would be to use a different simulator but the point of using GHDL is that we don't have to pay for an expensive simulator license.

@tgingold
Copy link
Member

tgingold commented Mar 14, 2018 via email

@putsplut
Copy link

Tristan,
I've done some work and a lot of reading (including the VHDL LRM). I don't have indexing working yet, but I at least have something that you can start with, plus a minimal test case. I'm traveling for a few days, so I won't be able to do anything before late next week at the earliest.
One question I do have: If I have a x : std_logic_vector(7 downto 0), the first index position seems to give me x(7). There is a mapping from Loc (for example, my Loc was 296) to an address. Should I expect that Loc 297 would be x(6)? (I don't have the code in front of me, so I can't be more specific at the moment.)
Brian

@tgingold
Copy link
Member

tgingold commented Mar 15, 2018 via email

@putsplut
Copy link

Tristan,
I've pushed my code to github:putsplut/ghdl
This is by no means complete. Hopefully its at least helpful.

What works:

  • access elements of a std_logic_vector on a port or in a signal.

What doesn't work yet:

  • I haven't dealt with records yet.
  • I don't think I'm indexing correctly. I'm taking an index value of 0 to mean x'left, but this seems incorrect for a vector of std_logic_vector(7 downto 4), based upon an error message I got from cocotb. Fixing this should not be hard once I know what the correct behavior is. I'll compare to Riviera Pro and Modelsim at some point.
  • An array of something other than std_logic / bit does not work. This means x as array(0 to 1) of std_logic_vector(7 downto 0) would not be accessible. I'm not sure if such is supported by VPI. Current issue is in grt-vcd.adb:314, where it returns Vcd_Bad at an indexed location (ie x[0]) since it is still a composite type, not Vcd_Bit or Vcd_Stdlogic_Vector.

In grt-vcd.adb, I do have a question about my selecting Vcd_Driving around line 406. It seems like it should be based upon the context of the signal, but I'm uncertain how to determine whether the original "signal" was a signal or a constant.

I do wonder if time is better spent creating a VHPI interface around your avhpi code instead of trying to extend the VPI interface.

@tgingold
Copy link
Member

tgingold commented Mar 25, 2018 via email

@putsplut
Copy link

putsplut commented Apr 7, 2018

Tristin,

I have pushed up two new commits to my github account. The first change fixes the indexing ordering such that the expected result is achieved whether the vector is (12 downto 4) or (17 to 24).

The second provides the sample VHDL file I'm working against, along with a cocotb python script, and the log from running that script and VHDL against Aldec Riviera 2016.02 (2017.10 has a bug).

The access of a record element fails. The call stack would look something like this:

 vpi_handle_by_name("coco_test.foo_in.a", NULL)
 Vpi_Handle_By_Name_Internal("coco_test.foo_in.a", NULL)
 Find_By_Name(Base, VhpiDecls OR VhpiInternalRegions, Name, El, Err)

where Base is

 base.kind => VhpiPortDeclK

and

 base.obj.obj_type.kind => ghdl_rtik_record_type

I think I need some guidance on how the iterator inside Find_By_Name should operate.
While it is tested further down in my script, I think a very similar situation may arise on multi-dimensional vectors or generally vectors of composite types.

Putsplut

@tgingold
Copy link
Member

tgingold commented Apr 9, 2018 via email

@kammoh
Copy link
Contributor

kammoh commented Jan 3, 2019

Any updates on this issue?
I don't think this is necessarily a cocotb related issue because vpi_handle_by_name fails for any array of non-scalar. It seems like in Rti_To_Vcd_Kind function (src/grt/grt-vcd.adb) the case Rti_To_Vcd_Kind (Rti.Element) evaluates to others and thus Rti_To_Vcd_Kind returns Vcd_Bad.
Unfortunately I have no familiarity with Ada or ghdl code-base and I can't move any further :(
It seems the issue is not resolved in @putsplut code either.
I would highly appreciate it if you could please give another shot at the issue @tgingold and @Paebbels.

@benreynwar
Copy link
Contributor

@xnorme I saw you were doing a bunch of work on the vpi for ghdl. I'd really like to get array and record support working nicely. Is that something you are already working on? Should I start working on this independently or is there an ongoing effort that I can help with?

@jwprice100
Copy link

Any updates or plans to resolve this issue? I would also greatly benefit from it being resolved.

@umarcor
Copy link
Member

umarcor commented Feb 19, 2021

@jwprice100, check @benreynwar's PRs: https://github.com/ghdl/ghdl/pulls?q=is%3Apr+sort%3Aupdated-desc+author%3Abenreynwar+. The state since June 2020 is:

#1249 (comment)

I'm continuing to very slowly work on this. If anyone is impatient and would like to have a crack themselves, I won't be at all offended if you take over :).

#1299 (comment)

Just an update, since I haven't made any changes to this issue for ages. I've been using this branch at work for the last month without issues, so it likely doesn't break too much.
I'm very slowly working on improving the VPI using this branch as the base. In the mean time I don't think it's worth merging in this branch until I've made sufficient improvements to the VPI support to justify this branch.

@franhervas99
Copy link

Is this actually on going? I'm having issues on handling array-like types with GHDL and cocotb GHDL array types not handling #3540
Thank you in advance!

@tgingold
Copy link
Member

I am wondering if the VPI part should be rewritten to be more accurate.

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

No branches or pull requests

10 participants