-
Notifications
You must be signed in to change notification settings - Fork 348
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
Comments
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? |
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 Tracking Cocotb code, it seems that the call to 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 |
On 19/12/16 22:32, Patrick Lehmann wrote:
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.
It is highly possible that cocotb uses a VPI interface not yet supported
by ghdl.
|
Verilog has a limited support of arrays (aka memory), so I am not sure how they are handled in vpi. I have to investigate... |
Tristin, 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. |
Hello,
I will have a look. It has been a long time since I haven't read that code.
I think that vhpi_handle_by_index is still able to return a vhpi handle for an element of an array; see VhpiIndexedName.
I also have to read about new vpi features from systemverilog.
Tristan.
|
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. |
The message is clear!
|
Tristan, |
That's great!
I am not sure what do you mean by Loc. But arrays are always stored in memory from left to right.
So for
x: std_logic_vector(7 downto 0)
-> the first address is x(7), the second is x(6) ...
x: std_logic_vector(0 to 7)
-> the first address is x(0), the second is x(1) ...
|
Tristan, What works:
What doesn't work yet:
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. |
Great, I will have a look.
|
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. Putsplut |
The iterator inside Find_By_Name looks for all children of Scope. The type of the children is given by Rel.
Currently Find_By_Name is called for declarations, and scopes (see Vpi_Handle_By_Name_Internal).
So if you also want to support record elements, you need to also iterator on record elements, and add be support to have support for them in Avhpi.
|
Any updates on this issue? |
@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? |
Any updates or plans to resolve this issue? I would also greatly benefit from it being resolved. |
@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:
|
Is this actually on going? I'm having issues on handling array-like types with GHDL and cocotb GHDL array types not handling #3540 |
I am wondering if the VPI part should be rewritten to be more accurate. |
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:
I get this error in Cocotb:
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?
The text was updated successfully, but these errors were encountered: