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

Simple Divider-Only PLL for Multiclock RTL Simulation #676

Merged
merged 20 commits into from
Oct 1, 2020

Conversation

davidbiancolin
Copy link
Contributor

@davidbiancolin davidbiancolin commented Sep 17, 2020

This subsumes #659.

Provides the mechanism to specify clock frequencies by name per interim advise from SiFive, reusing the PLL from #659. (I've applied all the comments from the PR). At a high level, users provide "assigner" functions that accept the name of a clock and return an Option[Double]. Users can register new functions by appending to `ClockFrequencyAssignment. The clock schemes from before have been collapsed one. You request a multiclock design by (1) providing an assigner, and (2) ensuring the rest of the target has the right CDCs.

TODOs:

  • Should harness side clock generation should be driven by the chosen PLL reference frequency?
  • Figure out reset handling
    • Handle in follow up PR
  • Port FireSim to use the string-based frequency specification.

* [Word from on high is that Strings are in...]
* Overrides the take field of all clocks in a group, by attempting to apply a
* series of assignment functions:
* (name: String) => freq-in-MHz: Option[Double]
Copy link
Contributor

Choose a reason for hiding this comment

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

The assigners shouldn't override any take frequencies already specified by the node, right?
chipsalliance/rocket-chip#2641 is giving us some control over take frequencies

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was meaning to ask about that. It seemed to me that in the short run it made sense to blow away all taken frequencies because it would be less surprising, but it's trivial to not do that.

Copy link
Contributor

Choose a reason for hiding this comment

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

If the primary means of controlling frequencies is through various WithTileClockFreq(freq) fragments, we could just change the underlying implementation of those fragments to use the rocketchip API when its ready.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that sounds good.

I'm still a little concerned about specifying absolute frequencies; i do think it would be preferable to be able to specify constraints on derived frequencies but we can punt on that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Re: absolute frequencies. I think the more important part is the relative frequencies but it is easy to calculate the ratio with 100 being the default.

Copy link
Contributor

@colinschmidt colinschmidt left a comment

Choose a reason for hiding this comment

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

Looks good.

clk_out = clk_in;
end
end else begin
reg [DIV_COUNTER_WIDTH - 1: 0] count = '0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this '0 any thing special or just a way to avoid specifying the width?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The latter. I'm lazy.

* This is a Seq of assignment functions, that accept a clock name and return an optional frequency.
* Functions that appear later in this seq have higher precedence that earlier ones.
* If no function returns a non-empty value, the value specified in
* [[DefaultClockFrequencyKey]] will be used -- DFU.
Copy link
Contributor

Choose a reason for hiding this comment

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

What does DFU mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

:andrewemoji:


// Imports for multiclock sketch
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this sketch forth coming? Or is this just dead 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.

Yeah this can deleted.

class WithDMIDTM extends Config((site, here, up) => {
case ExportDebug => up(ExportDebug, site).copy(protocols = Set(DMI))
})

class WithNoDebug extends Config((site, here, up) => {
case DebugModuleKey => None

Copy link
Contributor

Choose a reason for hiding this comment

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

Remove empty newline

* [Word from on high is that Strings are in...]
* Overrides the take field of all clocks in a group, by attempting to apply a
* series of assignment functions:
* (name: String) => freq-in-MHz: Option[Double]
Copy link
Contributor

Choose a reason for hiding this comment

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

Re: absolute frequencies. I think the more important part is the relative frequencies but it is easy to calculate the ratio with 100 being the default.

)

/**
* Generates a digttal-divider-only PLL model that verilator can simulate.
Copy link
Contributor

Choose a reason for hiding this comment

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

typo digital

val (outClocks, ClockGroupEdgeParameters(_, outSinkParams, _, _)) = node.out.head

val referenceFreq = refSinkParam.take.get.freqMHz
println(s"Idealized PLL Frequency Summary")
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should also dump this in an artefact, along with the requested freqs and what is being generated for them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Any thoughts about the format?

@@ -194,7 +194,7 @@ class FireSimArianeConfig extends Config(
//* Multiclock Configurations
//*********************************************************************************/
class FireSimMulticlockRocketConfig extends Config(
new WithFireSimRationalTileDomain(2, 1) ++
new chipyard.config.WithTileFrequency(6400.0) ++ //lol
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it make more sense to set pbus freq to 1600, and set this to 3200? Is this to avoid changing UART stuff?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

UART and NIC stuff, yes.

* If no function returns a non-empty value, the value specified in
* [[DefaultClockFrequencyKey]] will be used -- DFU.
*/
case object ClockFrequencyAssignersKey extends Field[Seq[(String) => Option[Double]]](Seq.empty)
Copy link
Contributor

@jerryz123 jerryz123 Sep 28, 2020

Choose a reason for hiding this comment

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

Why not just make this Map[String, Option[Double]]
Is it to support the partial string matching?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was the original motivation. I thought about making it a regex, but then i just settled on doing a more general thing. If you wanted to use the core idx as an argument you could do that with this very simply.

}
// Assign resets. The synchronization scheme is still WIP.
for ((name, clockBundle) <- clockGroupBundle.member.elements) {
if (name.contains("core")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does this only need to be synchronized for the cores?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This just matches what was done before. I've been punting on it. The general problem is: in what order should these resets be deasserted, and how should the user specify that (if they don't want to provide their own clocking scheme)? Simply synchronizing them will result in the fastest domains coming out of reset first, which may or may not not be desired. In any case, we have the same problem the idealizedPLL.

As an aside, I have tried synchronizing everything and it seems to just work for FireSim.

Un elated, maybe we should start building our library of PRCI diplomatic widgets and write a synchronizer node. We probably also need a lengthener, as alluded to in some of henry's PRs.

@jerryz123 jerryz123 self-requested a review September 30, 2020 21:40
@davidbiancolin davidbiancolin merged commit 45d40eb into dev Oct 1, 2020
@davidbiancolin davidbiancolin deleted the diplomatic-clocks-pll-redux branch October 1, 2020 05:30
@alonamid alonamid mentioned this pull request Nov 24, 2020
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.

3 participants