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

Documentation / example usage for Axi4ReadOnlyMasterAgent and Axi4WriteOnlyMasterAgent #1261

Open
KireinaHoro opened this issue Dec 14, 2023 · 5 comments

Comments

@KireinaHoro
Copy link
Contributor

I'm trying to write a simulation bench for an AXI slave DUT. It seems like one should extend these abstract classes and override genAddress, mappingAllocate and mappingFree and then call genCmd to initiate a bus transfer (which would call these overriden callbacks), but it is a bit confusing on how one would implement a simple bus reader / writer in this way. Is there an example on how these classes should be used?

@KireinaHoro
Copy link
Contributor Author

It seems like a lot of data are hard-coded to random; for example:

wQueue.enqueue { () =>
w.data.randomize()
val bytesInBeat = sizeByte - (beatOffsetCache % sizeByte)
if(busConfig.useStrb) w.strb #= ((BigInt(bytesInBeat, simRandom)) << beatOffsetCache) & ((BigInt(1) << size)-1)
if(busConfig.useWUser) w.user.randomize()
if(busConfig.useLast) w.last #= beat == len
}

The write channel StreamDriver always write a randomized data beat with no way to change it to anything meaningful.

@Readon
Copy link
Collaborator

Readon commented Dec 15, 2023

There are some in the lib's tester

@Readon
Copy link
Collaborator

Readon commented Dec 15, 2023

It seems like a lot of data are hard-coded to random; for example:

wQueue.enqueue { () =>
w.data.randomize()
val bytesInBeat = sizeByte - (beatOffsetCache % sizeByte)
if(busConfig.useStrb) w.strb #= ((BigInt(bytesInBeat, simRandom)) << beatOffsetCache) & ((BigInt(1) << size)-1)
if(busConfig.useWUser) w.user.randomize()
if(busConfig.useLast) w.last #= beat == len
}

The write channel StreamDriver always write a randomized data beat with no way to change it to anything meaningful.

Yes, this is normally adopted policy of simulation framework.

@KireinaHoro
Copy link
Contributor Author

KireinaHoro commented Dec 15, 2023

@Readon thanks for the explanation! I see that the intended use case is to have the master generate the commands (in case of writes, with random data) and then have a separate monitor to record the data into something like a scoreboard for comparison with the downstream bus master's behavior.

IMO this model does not work very well with modules that are not a bus adapter (e.g. to another bus protocol / memory interface). For example it couldn't drive a slave that behaves like the following:

  • the master reads from a memory address to get a token
  • the master does something based on the token
  • the master returns the token back to the slave by writing it to a memory address

I can think of overriding (and copying most of) genCmd to allow for a user-defined data packet, but I'm not sure if that's the way to go here.

@andreasWallner
Copy link
Collaborator

andreasWallner commented Dec 17, 2023

I'm not sure that the current MasterAgent is going to help you much here as it is: as far as I can tell it was mainly built for verification of the AXI infrastructure, and the components that would need more targeted reads/writes (like the SlaveFactory) are still being tested with the original cocotb test cases.

Note on genCmd: you normally don't need to call it, the Stream drivers that drive the streams that comprise the bus will take care of that (e.g. Agent.scala@137).

For other busses there are master agents that allow for much more freedom, for AXI there currently isn't.

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

No branches or pull requests

3 participants