Skip to content

Add valid & done to DataPortInterface#274

Open
RossComputerGuy wants to merge 2 commits intointel:mainfrom
MidstallSoftware:feat/dataport-valid
Open

Add valid & done to DataPortInterface#274
RossComputerGuy wants to merge 2 commits intointel:mainfrom
MidstallSoftware:feat/dataport-valid

Conversation

@RossComputerGuy
Copy link
Copy Markdown
Contributor

@RossComputerGuy RossComputerGuy commented Dec 14, 2025

Description & Motivation

Adds a valid output to DataPortInterface. This makes it possible to know whether the read or write has completed successfully.

Adds a done output to DataPortInterface. This makes it possible to know whether the read or write has completed.

Related Issue(s)

Seems like #146 is somewhat related since this allows for polling if valid is set and knowing that marks things are valid.

Testing

Ensure test/memory_model.dart passes

Backwards-compatibility

Is this a breaking change that will not be backwards-compatible? If yes, how so?

Documentation

Does the change require any updates to documentation? If so, where? Are they included?

@RossComputerGuy RossComputerGuy changed the title Add valid to DataPortInterface Add valid & done to DataPortInterface Dec 14, 2025
@RossComputerGuy RossComputerGuy force-pushed the feat/dataport-valid branch 2 times, most recently from 6f3c66b to e08aeef Compare December 21, 2025 00:52
@RossComputerGuy RossComputerGuy force-pushed the feat/dataport-valid branch 2 times, most recently from daaacdd to d62d867 Compare January 1, 2026 01:00
Copy link
Copy Markdown
Contributor

@mkorbel1 mkorbel1 left a comment

Choose a reason for hiding this comment

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

Thank you for the thoughtful contribution! A few questions and comments

DataPortGroup.data
]);

setPorts([
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thought: do we want to make these integrity signals optional/nullable via a flag and hardware components can dynamically choose whether to generated related logic based on their presence?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Maybe, though would that just be not connecting those up then? If they're not connected, I think ROHD would just not generate those.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One other consideration here is backwards compatibility. Making them nullable allows for existing implementations using DataPortInterface not to have to do anything should they not want to.

If(
wrPort.en & wrPort.addr.eq(entry),
then: [
wrPort.valid < 1,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wonder if including valid and done as part of the RF would impact synthesis' ability to identify these as RFs? Also, I wonder if this generates more logic than is necessary (i.e., can we just do an address range check and a shift-register instead of a per-entry case statement, and would that synthesize differently)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Afaict, it doesn't impact yosys's ability to generate RF's. Yosys doesn't even recognize RF's as memories. Also, there's a chance that yosys would just optimize it better than how we have it. Though, idk if we even need an address range check. We might be able to get away with just having wrPort.valid < wrPort.en.

Logic get data => port('data');

/// Whether the data was successfully read or written
Logic get valid => port('valid');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thought: does calling this valid overload the terminology related to "ready/valid" protocols in a confusing way? @desmonddak what do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think valid is the most sensible name since it lets you know whether the request was able to complete. In terms of reading, that means data is valid. In terms of writing, it means the address which was written to is valid.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it would probably be good to add some testing for when valid and done should be false

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Been trying to but the sim is being picky.

Copy link
Copy Markdown
Contributor

@kimmeljo kimmeljo left a comment

Choose a reason for hiding this comment

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

Per the discussion on the ports being required versus optional, for backward compatibility reasons, I'd make the case that they should be optional. This can (probably will) simplify the change set for this PR.

DataPortGroup.data
]);

setPorts([
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One other consideration here is backwards compatibility. Making them nullable allows for existing implementations using DataPortInterface not to have to do anything should they not want to.

@desmonddak
Copy link
Copy Markdown
Contributor

desmonddak commented Jan 20, 2026

The dilemma we face is that we are going to start using the DataPortInterface in many different ways for components and we may need to architect it so that there are derived from a base Interface class representing the simplest possible memory accessor. Right now, we are overloading it with byte output control, for example, whereas the simplest interface probably should not have that.

Furthermore, we are extending it with a valid bit to call it ValidDataPortInterface in https://github.com/intel/rohd-hcl/pull/259/files#diff-1db666ec943a7d409d08eda2bc00935cd71160c8ae7ae14b471fe5458fc5dde7 (see the first 100 lines of the cache.dart file).

In that same PR, we are also extending the Fifo to be ready/valid.

If we add valid/done to the base memory, we may later find it difficult to create a broad array of memory components (CAM/TCAM/RF/FIFO/SRAM/WriteBuffer) with the various configurations they need. So I want to be careful incrementally extending DataPortInterface as we probably should architect an Interface hierarchy of data interfaces that will give us this more general capability to our data interfaces across this spectrum of components (to be built eventually). Already, I think we should factor out the byte enable somehow and only configure it for components that support byte-enable.

I think the fork in the road is: do we add nullable Logic and parameters to this DataPortInterface or do we inherit from a simpler Interface class of address+data and build up the various kinds of interfaces for memory components, as well as a hierarchy of memory components that inherit from Memory or RF or SRAM and have more and more features.

For now, I would propose a nullable interface to keep this PR simple, but I am a bit concerned about the concept of 'done' when we want to build a read/valid protocol set of components and 'done' is introducing new semantics potentially.

@RossComputerGuy
Copy link
Copy Markdown
Contributor Author

Per the discussion on the ports being required versus optional, for backward compatibility reasons, I'd make the case that they should be optional. This can (probably will) simplify the change set for this PR.

Yeah, that is a good idea.

The dilemma we face is that we are going to start using the DataPortInterface in many different ways for components and we may need to architect it so that there are derived from a base Interface class representing the simplest possible memory accessor. Right now, we are overloading it with byte output control, for example, whereas the simplest interface probably should not have that.

I wouldn't really consider this overloading since having a way to indicate the success & completion of an access is good.

Furthermore, we are extending it with a valid bit to call it ValidDataPortInterface in https://github.com/intel/rohd-hcl/pull/259/files#diff-1db666ec943a7d409d08eda2bc00935cd71160c8ae7ae14b471fe5458fc5dde7 (see the first 100 lines of the cache.dart file).

In that same PR, we are also extending the Fifo to be ready/valid.

Ah, I wasn't aware of that PR doing it.

If we add valid/done to the base memory, we may later find it difficult to create a broad array of memory components (CAM/TCAM/RF/FIFO/SRAM/WriteBuffer) with the various configurations they need. So I want to be careful incrementally extending DataPortInterface as we probably should architect an Interface hierarchy of data interfaces that will give us this more general capability to our data interfaces across this spectrum of components (to be built eventually). Already, I think we should factor out the byte enable somehow and only configure it for components that support byte-enable.

I think the fork in the road is: do we add nullable Logic and parameters to this DataPortInterface or do we inherit from a simpler Interface class of address+data and build up the various kinds of interfaces for memory components, as well as a hierarchy of memory components that inherit from Memory or RF or SRAM and have more and more features.

I think the nullable way is simpler for this PR. I am not sure about the other way. The thing that I mainly needed from this was knowing when memory, registers, and CSRs access was done and valid.

For now, I would propose a nullable interface to keep this PR simple, but I am a bit concerned about the concept of 'done' when we want to build a read/valid protocol set of components and 'done' is introducing new semantics potentially.

Imo, ready isn't a great name either since it sounds like it mostly fits read since a write being ready sounds like the data port is ready to be written into and not that it is done writing.

@desmonddak
Copy link
Copy Markdown
Contributor

I think in the intervening interval, we merged a PR with significant filesystem reorganization, which means you currently have merge conflicts. I think you should consider a new interface that inherits (which may make it easier for the future I mentioned, which was to consider a tree of data-oriented interfaces for memory-like devices. Or you can proceed with a Logic? add to the existing. The interface is a contract, so if we push too much into the bottom, then there are more exceptions to document for rudimentary components (like a flop-based RF would probably have few features supported).

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

Successfully merging this pull request may close these issues.

4 participants