-
Notifications
You must be signed in to change notification settings - Fork 24
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
Generic CSR Functionality #151
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i really like this approach, looking good!
lib/src/memory/csr.dart
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
split into multiple files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about even more files? :)
let's try to aim for 1 class per file (except for small, supporting classes)
@@ -1,5 +1,6 @@ | |||
// Copyright (C) 2023-2024 Intel Corporation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update date year
I'm late to commenting on this PR. I didn't see a test for the legalValues restriction. Sometimes it helps to have short burst tests for pieces of functionality to provide a 'smoke test'. It's harder to find in a longer sequence of setup, though easier to amortize that over multiple tests. A strategy could be to setup the CR you want to use at the beginning of a group test and then do a bunch of shorter 'test' functions underneath: group('CSR big test', () {
// setup CRs here
... bunch of code
// end setup CRs
test('feature access one', () {
});
test ('feature access two', () {
});
...
}); |
Need a doc (csr.md) where you can describe the overall architecture and feature set. Could be just a few short paragraphs, maybe a code example with init and with access and a bit of inspiration on how clean this is. |
…f just on a full register. Adding validation on reset and legal values to ensure that they fit within their allotted bits.
lib/src/memory/csr_config.dart
Outdated
/// Helper to derive a reset value for the register from its fields. | ||
/// | ||
/// Only should be used if a reset value isn't explicitly provided. | ||
int resetValueFromFields() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this API be exposed publicly? since it might not be the "real" reset value if a resetValue
for the whole register is provided. you could make it private or even @internal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually used in a encapsulating class (CsrBlock). Is there an annotation that enables the proper protections given this information?
lib/src/memory/csr.dart
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about even more files? :)
let's try to aim for 1 class per file (except for small, supporting classes)
lib/src/memory/csr.dart
Outdated
bool get isBackdoorWritable => config.isBackdoorWritable; | ||
|
||
/// Getter for the field configuration of the CSR | ||
List<CsrFieldConfig> get fields => config.fields; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this Csr
Logic object is created at the point of time when it is constructed, but the fields
property of the config could theoretically be changed by a user after the fact, meaning this fields
property could become out of sync from the actual Logic
s present. This would be silly to do intentionally, but it should be possible to prevent accidentally doing something like that. This ties into that making fields
unmodifiable idea from other comments. We should decide how we want these configuration objects to behave: should they be immutable? should they be copied at the time they are consumed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the point. My opinion is that they should be immutable within an encapsulating HW object (i.e., passed during construction, readable to users, but not modifiable). I'm guessing there's nice Dart syntax to do this?
lib/src/memory/csr.dart
Outdated
for (var i = 0; i < elements.length; i++) { | ||
// if the given field is reserved or read only | ||
// take the current value instead of the new value | ||
final chk1 = rsvdIndices.contains(i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here and for chk2
, why not just move the checking condition into the if
condition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it was a vestige of code I ended up refactoring. But is that a big deal?
lib/src/memory/csr.dart
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adding a comment to track that we need some documentation added to the doc
area for how to use these
lib/src/memory/csr_config.dart
Outdated
/// Method to validate the configuration of a single register. | ||
/// | ||
/// Must check that its fields are mutually valid. | ||
void validate() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is intended to call these validate functions? should hardware validate upon construction? is the user expected to call it before using it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardware calls all of these functions appropriately and automatically upon construction/build. But I decided it's perfectly valid to also allow a user to call the validate function independently on the config object if they want.
lib/src/memory/csr_config.dart
Outdated
/// register validation is called separately (i.e., in Csr HW construction). | ||
void validate() { | ||
// at least 1 register | ||
if (registers.isEmpty) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this have to be illegal? is an empty block so bad?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it's not terrible but it doesn't really make sense to me....
lib/src/memory/csr_config.dart
Outdated
/// based on the maximum block base address. Note that we independently | ||
/// validate the block offset width relative to the base addresses | ||
/// so we can trust the simpler analysis here. | ||
int minAddrBits() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should these be private helper functions rather than public API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are currently called outside of the class (during HW construction for validation) but by an encapsulating class. If there's a better annotation, I'm open but also I kind of like having them be public (why not allow users to call them?).
Description & Motivation
Adding a mechanism to generically generate a module to define, read and write control/status registers (CSRs). This functionality includes automatic construction of CSRs based on configuration objects down to the granularity of register fields.
Related Issue(s)
N/A
Testing
Added unit tests (csr_test.dart)
Backwards-compatibility
New functionality so no breaking changes.
Documentation
A new document describing all functionality will be added.