-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Attach TLError LogicalTreeNodes to subsystem LogicalTreeNode #2410
Changes from 2 commits
595e0e9
0e08326
8ad2f8a
f5db4b4
86ba877
bf52274
ba744ca
5b6f37c
1910582
042c8af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// See LICENSE.SiFive for license details. | ||
|
||
package freechips.rocketchip.diplomaticobjectmodel.model | ||
|
||
|
||
case class OMErrorDevice( | ||
memoryRegions: Seq[OMMemoryRegion], | ||
interrupts: Seq[OMInterrupt], | ||
specifications: Seq[OMSpecification], | ||
mwachs5 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
_types: Seq[String] = Seq("OMErrorDevice", "OMDevice", "OMComponent", "OMCompoundType") | ||
) extends OMDevice |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -134,7 +134,21 @@ abstract class BaseSubsystem(implicit p: Parameters) extends BareSubsystem | |||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
lazy val logicalTreeNode = new SubsystemLogicalTreeNode() | ||||||||||||||||||||||||||||||||||||||
lazy val logicalTreeNode = { | ||||||||||||||||||||||||||||||||||||||
val subsystemLogicalTreeNode = new SubsystemLogicalTreeNode() | ||||||||||||||||||||||||||||||||||||||
val builtInDevices = Seq( | ||||||||||||||||||||||||||||||||||||||
pbus.builtInDevices, | ||||||||||||||||||||||||||||||||||||||
fbus.builtInDevices, | ||||||||||||||||||||||||||||||||||||||
mbus.builtInDevices, | ||||||||||||||||||||||||||||||||||||||
cbus.builtInDevices | ||||||||||||||||||||||||||||||||||||||
mwachs5 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||
for (builtIn <- builtInDevices) { | ||||||||||||||||||||||||||||||||||||||
builtIn.errorOpt.foreach { error => | ||||||||||||||||||||||||||||||||||||||
mwachs5 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
LogicalModuleTree.add(subsystemLogicalTreeNode, error.logicalTreeNode) | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if this is more readable, but how about:
Suggested change
? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looking at this again, I'm not sure why I didn't just do this to be consistent
Suggested change
but I dunno. I guess the your version looks the best to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think @albertchen-sifive 's is more what I'm used to in the code base, but either change looks good and symmetrical :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. more importantly. I just realized that we are overriding this field. so I guess this stuff should go in an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I had forgotten about the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that would force evaluation of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that should be fine, since we have a pattern of doing this in a number of places. The logicalTreeNodes are only really meant to create the tree of nodes without fulling evaluated the nodes, somewhat analogous to Diplomatic nodes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't get how |
||||||||||||||||||||||||||||||||||||||
subsystemLogicalTreeNode | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,5 +20,5 @@ class FrontBus(params: FrontBusParams)(implicit p: Parameters) | |
with CanHaveBuiltInDevices | ||
with CanAttachTLMasters | ||
with HasTLXbarPhy { | ||
attachBuiltInDevices(params) | ||
val builtInDevices = attachBuiltInDevices(params) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there a reason this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this just seemed like the least intrusive way of adding it. the val can go in but it does look like the attach method is unconditionally called everywhere that the trait is mixed in. and the devices are already optionally attached based on the params. so yeah, it makes sense to me to have the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but that seems like a cake-pattern and we're trying to avoid that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We should all be clear on why we are (or are not?) avoiding the cake pattern in future code, since it's rarely the case that we would conclude "X is always bad and we should never do X again". Not having a shared understanding of what the root problems actually are could lead to bandwagoning and scapegoating where we dump a solution without knowing why and end up building a new solution that runs into similar problems. My impression of why the way we have used the cake pattern has been problematic is because:
See https://kubuszok.com/2018/cake-antipattern/ for a detailed blog post on the Scala cake pattern and why the author at least considers it to be an antipattern. See specifically "Adding dependencies", which provides a concrete example of a god class, and "Initialization order", which describes the ordering and initialization issues. With these points in mind, my personal response would be that to best avoid the two problems above without also making a huge architectural change to the existing code would be to decouple the interface from the implementation. We should not let the amount of typing required dictate what the interface should be. If we think that if a module says that it "can have built-in devices" should imply that we can retrieve said built-in devices under a uniform interface, then I think it is a good idea to define a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @richardxia I'm not sure what you are concretely suggesting, or what you need to know to make a concrete suggestion There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I need to know what a Let me flip this onto you: Is there a reason this val should go into the trait CanHaveBuiltInDevices? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't actually know what a I would think that I propose having an abstract There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That sounds like a reasonable proposal to me, and I agree with the |
||
} |
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 more of a question for me to learn more about Scala than about whether this is the right or wrong thing to do.
Since this is only used in one place, in an anonymous class instance, what's the practical difference between defining this as a sealed trait + anonymous class instance vs. defining a (final) case class and assigning the members normally? I think I can appreciate this technique being used for non-sealed traits, but the fact that this is sealed is interesting to me.
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 the main difference I care about vs a final case class is that the case class generates a bunch of methods and extends stuff that I don't think are appropriate/useful. like case class extends
serializable
whichTLError
andTLZero
definitely are not and it generates stuff like unapply that I don't want exposed because that API will probably be broken.sealed is for similar reasons. to prevent anyone else from creating
BuiltInDevices
outside ofattachBuiltInDevices
and just narrow down the API surface area.just my personal preference, maybe I'm being a too cautious or this isn't the right approach? open to changing this.
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.
No, I think it's a good idea to limit API surface area. I was mostly wondering
sealed trait
vsfinal case class
and notsealed trait
vs(not sealed) trait
. I hadn't thought of the extra methods and traits that case classes provide as being extra stuff that consumers could possibly depend on that would become later liabilities, but now that you point it out, I agree, especially because this data structure is, at the moment, an arbitrary bundle of "stuff", and we may want to reserve the right to change this in the future.