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

WIP: Adding structure to represent a give node/context point in RTI tree. #1299

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

benreynwar
Copy link
Contributor

Currently the RTI codebase is somewhat difficult to work on because there are lots of factors (RTI node structure, context, bounds location, whether it's in a signal or generic) that are needed to properly describe a point in the RTI tree.

In this pull request I added an RTII (Run Time Instance Information) structure that gathers this data into a single structure. These structures will be generated dynamically as required. Avhpi handles for signals/ports/generics/constants and their subcomponents will contain one of these RTII structures.

My hope is that this will make the codebase simpler to understand, and easier to implement new features.

This is not a branch that should be merged, I've just put in this pull request to get some feedback on the idea of creating this structure, and to get suggestions for alternative ways of approaching this.

My current plan is:

  1. Use RTII to support std_logic_vector and bit_vector in generics and constants.
  2. Support array of bit_vector, array of integer, multi-dimensional arrays in signal/port/generic/constants
  3. Support records in signal/port/generic/constant
  4. Support nested records and arrays.

@tgingold
Copy link
Member

tgingold commented May 11, 2020 via email

-- Just in here so we have a constant that we can harmlessly include
-- include in another package to force compilation.
FISH : constant Natural := 2;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need that. You can always do:

with Grt.Rtiis;
pragma Unreferenced (Grt.Rtiis);

-- from the Rti and the Ctxt, but we also store it here so we don't have
-- to determine it too often.
Layout_Addr : Address;
-- If the Base_Rti is unbound then this is the address of the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe create: subtype Layout_Address is Address; to clarify the use of the address ?

-- be instatiated many times in the design, an RTII node
-- represents one specfic instance of that node.
type Ghdl_Rtii is record
-- Whether it is a signal/port or a generic/constant.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fear it is confusing to have both Ghdl_Rtii and Ghdl_Rtii_Type. What about Ghdl_Object_Rtii and Ghdl_Type_Rtii ?


-- Get a indexed child of an Rtii.
function Get_Rtii_Child(Rtii : Ghdl_Rtii; Index : Ghdl_Index_Type)
return Ghdl_Rtii;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some style differences: space before '(', return aligned, 2 spaces after '--'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a formatting checker you're using in emacs?

Base_Record := To_Ghdl_Rtin_Type_Record_Acc(
To_Ghdl_Rtin_Subtype_Composite_Acc(Rtii.Typ.Rti).Basetype);
when others =>
Internal_Error("get_record_child");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a function to get the base type of a record type/subtype.

-- Get the length of this dimension so we can check whether
-- the index is valid.
Idx_Rti := Get_Base_Type (Base_Array.Indexes (Rtii.Typ.Dim));
Extract_Range (Bounds_Addr, Idx_Rti, Rng);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the multi-dim arrays should be flattened (as if they had only one dimension). That could simplify the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. I need to check how this is handled in VPI and VHPI and then try to stay close to that.

Layout_Addr := Rtii.Typ.Layout_Addr;
when others =>
Internal_Error("get_array_child");
end case;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should create a function to get layout_addr and base_array from the type rtii.

@benreynwar
Copy link
Contributor Author

Thanks for taking the time to look at this.
I'll make these changes after work today, and also modify the avhpi handles so that they actually use these structures. That should give us a better idea of whether this is the right direction to go in.

@tgingold
Copy link
Member

tgingold commented May 12, 2020 via email

@benreynwar
Copy link
Contributor Author

benreynwar commented May 12, 2020

I've got lots of bugs to fix here :). I expect I'll have something ready for you to take a look at again by the end of next weekend.

@tgingold
Copy link
Member

tgingold commented May 12, 2020 via email

@benreynwar
Copy link
Contributor Author

Any hints on why the llvm & gcc tests are failing?

@tgingold
Copy link
Member

tgingold commented May 14, 2020 via email

@benreynwar
Copy link
Contributor Author

Makes sense. Thanks.

@benreynwar
Copy link
Contributor Author

I've made most of the changes you suggested. The only one I haven't implemented so far was adding a Layout_Address type, which I plan to do, I'm just waiting until I'm sure I understand exactly how all these addresses are used.

This branch is passing all the tests, which I think is more likely to indicate gaps in the tests, rather than that this is ready to merge :). My main concern is that I will break the generation of wave dumps. To check this I'm going to add a test that creates wave dumps and then confirm that these wave dumps are unchanged when the test is run in this branch.

The main change in this branch since last time that you looked at it, is that I'm now using the RTII structure in the Avhpi handle. It's ready for you to take a look at it now if you'd like, or you can wait until I've tested it more thoroughly.

@benreynwar
Copy link
Contributor Author

As suspected this pull request is currently totally breaking the generation of wave file dumps.
I'm going to create some tests for the GHW dumps in a separate pull request before I come back to this (#1323).

@benreynwar
Copy link
Contributor Author

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.

@umarcor umarcor removed this from the v1.0 milestone Feb 3, 2021
@umarcor umarcor added this to the v2.0 milestone Feb 3, 2021
@umarcor umarcor mentioned this pull request Feb 19, 2021
@benreynwar
Copy link
Contributor Author

So I've haven't worked on this for ages, and have mostly forgotten where I was at.

What I do remember was that it was really, really hard, and I wasn't making very much progress. I felt like I was having to reverse engineer the grt structure because it wasn't clearly defined anywhere. I think a first step is probably making the grt more comprehensible. I'd be curious to hear what people with a better understanding of ghdl think the proper approach would be.

@benreynwar
Copy link
Contributor Author

Much of what I was doing was creating structures to capture the runtime information. But I wasn't touching any of the code related to actually creating that data in the first place. I think a more sensible approach would be to use the same structures both for creating the runtime information in the first place, and for accessing it later for use with VPI or VHPI.

@tgingold
Copy link
Member

tgingold commented Apr 23, 2021 via email

@umarcor
Copy link
Member

umarcor commented Apr 25, 2021

@benreynwar thanks for bringing this discussion.

Let me ping @marlonjames, who's been working on VHPI.

@marlonjames
Copy link
Contributor

My (very slow) incremental work on the VHPI implementation hasn't taken me this far yet, so I don't have any useful input. I agree that it's better to avoid dual maintenance.

@benreynwar
Copy link
Contributor Author

Currently there's not only dual maintenance between the AST and the RTI, but also between where the RTIs are created and the various places that they are used. There's a lot of logic about interpreting the various absolute and offset addresses that is repeated independently and is confusing. It would be nice if we could capture all of the logic about the various kinds of offsets in one place. That's kind of what I was trying to do last year with the RTII structure, but I was only looking at making sense of the data after it had already been constructed in memory. It would also be nice to share structures with the code that is setting up the memory in the first place. I'm probably missing a lot of the subtlety.

A different option would be to only use JIT (or code generation in the same process). So the AST would be available and just have to be decorated with info (addresses/offsets) from the code generation. No more RTIs. I think that would simplify VPI or VHPI.

This sounds like a big change. @tgingold, you can much better judge whether this is worth it. Do you think it is?

@tgingold
Copy link
Member

tgingold commented Apr 28, 2021 via email

@umarcor
Copy link
Member

umarcor commented Apr 28, 2021

Some might already know, but others might be mislead by my activity. Let me clarify that I'm no expert on the LRM, on Ada or on GHDL internals. The AST, RTI, GRT, etc. are really blurry in my mind. Hence, please excuse me if any of the following comments don't make sense.

What I do remember was that it was really, really hard, and I wasn't making very much progress. I felt like I was having to reverse engineer the grt structure because it wasn't clearly defined anywhere. I think a first step is probably making the grt more comprehensible. I'd be curious to hear what people with a better understanding of ghdl think the proper approach would be.

My perception is that this feeling is shared by all the people that tries to develop some tool on top of GHDL:

I know not all of those areas are using exactly the same types/tree. But all of them need to somehow understand either the AST or the RTI or some variation/subset of both.

That's kind of what I was trying to do last year with the RTII structure, but I was only looking at making sense of the data after it had already been constructed in memory. It would also be nice to share structures with the code that is setting up the memory in the first place. I'm probably missing a lot of the subtlety.

It seems that you are proposing some heavy internal refactoring with no other initial purpose than reshaping the codebase. I believe that can be a very exciting activity for several of us to try helping. @Blebowski has been doing some arbitrary cleanups in this sense, at his own will. Ben, Tristan, maybe any of you can point us to where should we look for "cleaning up the code that is setting up the memory"? Related to Tristan's comment about JIT, my perception is that all that offset nightmare is not only a matter of code cleanness, but might also be forced by the complexity of supporting two compilation strategies.

For context, the discussion about switching GHDL to a JIT only solution was brought previously in the context of top-level generics. See #1388. As Tristan commented, switching to JIT would imply getting rid of the GCC backend/build. However, LLVM supports JIT. When we last talked about it, there were two main features missing from LLVM which were supported by GCC: debugging and code coverage. Since then, debugging is supported with LLVM too. Yet, code coverage is still possible with GCC only, and that's the main reason for many users of GHDL to pick that backend, specially in aero-space-mil industries. Therefore, a nice strategy would be to investigate how to do coverage with LLVM and document/advertise it for moving the user base to mcode and LLVM only. As @Blebowski commented in #1695, that would reduce the maintenance burden.

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

Successfully merging this pull request may close these issues.

None yet

5 participants