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

Pattern atomize #9

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Conversation

redxeth
Copy link
Member

@redxeth redxeth commented May 30, 2018

RFCS for pattern atomization concept. Wanting to open up this topic for discussion and feedback.

View the RFC here - https://github.com/redxeth/rfcs/blob/e3ff5de27609c42f1952055bbe366a892386af51/0000-pattern-atomization.md

@ginty
Copy link
Member

ginty commented May 30, 2018

Good proposal @redxeth, I like the additional functionality it would add.

Some initial thoughts/comments as I read through it...

  • Do you think this should be a global operation, or limited to certain models as defined by the application? Basically, should the API be Origen::Regs.clean! or is your example implying that you would give control of this at a model level? e.g. dut.my_block.clean!.

  • I wonder if the API might read better if it talked in terms of snapshots? dut.my_block.take_snapshot, dut.my_block.restore_from_last_snapshot!. I can see some advantages of not being too register-specific in the API, since we could potentially extend it to create a complete snapshot of the model in future, including for example pins, instance variables, etc.

  • How do you envisage generating the atoms for a full test flow? I'm assuming you would you just generate the list of pattern molecules (a crap name, but trying to mean the container for all the pattern atoms that would be burst together in a test), with the program generator providing the referenced.list of molecules like it does today.

  • Assuming we go with the above, how would you handle when concurrent pattern generation tries to generate the same atoms at the same time? A couple of approaches I can think of: we implement some kind of locking mechanism to prevent concurrent generation of the same atom, later ones just overwrite earlier ones and the last one wins. Or else we build some kind of molecule look-up table...

    • You could generate the full list of molecules (i.e. the same pattern list you would use today when we don't have such a feature available) in a new pat gen mode whereby it skipped pattern writing and instead wrote out some kind of database which was a lookup table of what atoms were called by each molecule, and a complete list of unique atoms. This database should also provide the info on which pattern will be responsible for generating each atom, e.g. the first one to reference it in the list.

    • We then generate the molecule list again in atomize mode (normal mode, would generate fully self contained patterns as it does today and as implied by your RFC, that will be useful for simulation and execution in other environments that don't support pattern bursts). In atomize mode it would create the atom patterns whenever the atomize method was called, but only if called by the molecule pattern which was assigned as being responsible for generating the atom, otherwise it would just execute the code without creating the atom.

    • The molecule database would then be useful in program generation because you can still describe it in terms of molecules, but when it comes to generating the pattern call lines, you can consult the database and insert the multiple patterns that make up the burst instead of the molecule name. I.e. keep the atoms as a pattern source concern rather than a test program source concern.

    • The above is indicating a 4 step generation (as opposed to 2-step today: generate the program then the patterns):

      • Generate the program to get the molecule list
      • Generate the molecule list to create the database
      • Generate the molecule list again to create the atoms
      • Generate the final program which now has access to the molecule/atom database

Just some ideas to think about, but I think we really need to flesh this stuff out in the RFC since I think there are a lot more corner cases and challenges with the actual pattern and program generation side of things vs. the register dirty tracking which is the focus of the RFC so far.

@redxeth
Copy link
Member Author

redxeth commented May 30, 2018

@ginty thanks for the feedback. I was thinking only in terms of register tracking since for patterns that's the only thing that initially it seemed I needed to worry about. And pin states.

Let me answer your bullets one by one:

  • Yes clean and clean! would be global register methods like write and write!

  • Initially was only thinking in terms of a 'clean' state. But I could see wanting more. Perhaps a save_state where you indicate the state you're saving, e.g. reg.save_state(:trimmed) and reg.restore_state(:trimmed). Makes it more clear what's going on. I could see extended the save state idea to the entire model. The API could be developed so that it's not tied to being part of the Register model but that it only be the first use case of the API.

  • I was thinking a complete referenced.list would be generated for all pattern atoms a test flow required. The application would have to keep track of the 'molecule', e.g patset or burst, that they needed for a particular test. But I could see extending the capability like you suggest to make the 'molecule' something the user doesn't have to worry about. Initially I didn't like the idea of extending the pattern 'atom' metaphor to 'molecules' as it's a bit cheeky, but the more I think about it the more 'molecule' sounds good as it implies a pattern burst that is using pattern atomization. There could also be checks to give an error if 2 atoms don't get along, i.e. have a conflict (are 'not bonding' so to speak).

  • The referenced.list would have just one copy of an atom file by design, not the pattern molecules. Those would be used by whatever aspect of a test program does the atom arranging (e.g. pattern set sheet or RDI code). (these sub-bullets do not correspond to your sub-bullets 1:1).

    • That said, I have found that the connection between program and pattern generation to be weakly linked only using a pattern name as it does today. Using only the pattern name to pass meta info requires using a pattern dispatcher and name parser type thing, which is often overkill. Test flow options and such could be added to an enhanced referenced.list (or better name), and thus the pattern generator makes similarly named patterns with different options as 'blah_v1', 'blah_v2' as is done today with test instances. Could even provide a comment indicating the options used in each one.
    • In this scenario the pattern atom could be completely defined in this new referenced.list. Don't really need to call it a database, as that implies storing it separately to me and I really want it to be more of a more meta-type patset sheet.
    • As for generation I'd keep it program, then generation as today if using an enhanced referenced.list (maybe call it pattern_source_info.xml). Maybe add an option to do a 'pre-program' step-- where you only generate the pattern meta-data when generating a program (see what I did there-- added an NVM joke-- it would origen pp ;-))

Perhaps I would define v1 and v2 of the atomization upgrade in the RFC that imply different phases of it.

@ginty
Copy link
Member

ginty commented May 31, 2018

Yes clean and clean! would be global register methods like write and write!

I would call those individual register methods, so you propose calling that on individual registers directly, rather than say for all registers or for all registers owned by a particular model. So the app will be responsible for keeping track of which registers to clean then?

From your other comments it seems that I misunderstood the first time around. From the way you wrote atomize(options) do ... end I envisaged this as something you would use in your patgen logic:

def some_operation
  atomize(options) do |atom|
    block_select(blah)
  end
  atomize(options) do |atom|
    erase(blah)
  end
end

But then on the other hand, you are talking about manually managing the list of atoms required for a particular test and about generating the atoms directly - in which case I can't see how the above would work, how would you launch the generation of an atom embedded within code like that?

If atomize is really a top-level wrapper, then what does it do over and above the existing API for pattern creation?

# pattern/block_select.rb
Pattern.create skip_startup: true, skip_shutdown: true do
  block_select
end

# pattern/erase.rb
Pattern.create skip_startup: true, skip_shutdown: true do
  erase
end

If that's more like what we are talking about, how does the register stuff fit into that?

At least in the block select case, you don't really want to reset the registers that it touches, so above is probably fine.

For the second one, I could see two approaches that might work well, add a new Pattern.create option that will tell Origen to keep track of the registers that are touched by the body of this pattern and then restore them at the end:

Pattern.create skip_startup: true, skip_shutdown: true, restore_regs: true do
  erase
end

Or add a switch to tell Origen to treat all incoming register states as undefined:

Pattern.create skip_startup: true, skip_shutdown: true, reg_states_undefined: true do
  erase
end

WIth all register states marked as undefined, it would mean that any application code that asked for values X in register Y, would always apply that and not skip an operation because it thinks the value is already there - i.e. you are telling it basically not to rely on reset values.

This last approach seems the safest to me.

@redxeth
Copy link
Member Author

redxeth commented May 31, 2018

So the app will be responsible for keeping track of which registers to clean then?

Origen would be responsible for tracking which registers are at what state. Instead of clean let's talk about restore_state which would be like a reset done on register today. Capability from Origen.

I envisaged this as something you would use in your patgen logic:

I envision it that was as well.

But then on the other hand, you are talking about manually managing the list of atoms required for a particular test and about generating the atoms directly - in which case I can't see how the above would work, how would you launch the generation of an atom embedded within code like that?

Not sure what you mean by manually here, the application handling it? In my above comments I kinda changed my mind a bit while I wrote so it can be confusing.

So ignore this:

The application would have to keep track of the 'molecule', e.g patset or burst, that they needed for a particular test.

I would want ultimately for the program generation side to not have to worry at all about whether or not we are doing pattern atomization. So how to do that since the patset sheet (or equivalent) has to know the exact pattern filenames. It's a bit of chicken-and-egg (and hence your 4-step process above).

(Was writing a BUNCH here, but decided after a bit to update the original proposal so it's more clear. Will try to address your concerns).

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.

2 participants