-
Notifications
You must be signed in to change notification settings - Fork 0
Patgen Dev Notes
Stephen McGinty edited this page Feb 28, 2020
·
5 revisions
These are planning notes on how the patgen internals should be constructed, there is a ticket for discussing it here: https://github.com/Origen-SDK/o2/issues/90
- In Rust, AST nodes should always be added via constructors, not direct struct literal creation
- Good app note here on how to enforce that: https://words.steveklabnik.com/structure-literals-vs-constructors-in-rust
- The constructor should append the new node to the AST immediately upon creation – code triggering a cycle must not have to think about whether it should be appended to a currently open reg transaction vs. the top-level, the node constructors will deal with that.
- This will avoid multiple change points if a node struct field is added
- However, most AST node creation should be done by API methods, e.g. my_pin.drive(), vs. creating a Pin action node directly, though the latter will always be available throughout the Rust domain.
- AST nodes are immutable upon construction
- The AST itself should be thought of as immutable except for the following permitted mutations:
- New nodes can (of course) be appended
- New nodes can be inserted, e.g. before_last_cycle
- Nodes can be deleted
- The above exceptions are removed and the AST is fully immutable once the frontend pattern definition stage is complete and backend generation (rendering) begins
- All mutations (e.g. clean up, optimizations, compressions) are then done by processing (walking) the AST and outputting a new one, these are called stages for the rest of this document.
- Only the master AST needs to be kept in static memory, derivatives could be ephemeral and can generally be discarded as processing moves onto the next stage.
- A new mutable static should be added here similar to DUT, propose it is called TESTS - https://github.com/Origen-SDK/o2/blob/master/rust/origen/src/lib.rs#L36
- Name chosen instead of ‘PATTERNS’ since this could/should grow to include things that are not strictly in the pattern domain and it is more like a representation of the current test – e.g. could include pin force/measure nodes, etc.
- Propose to have a separate one for test programs in future, e.g. FLOWS to avoid borrow issues
- A key concern here will be memory usage, the master AST should be permanently stored until generation is completed, but there needs to the concept of scratch/temporary storage that can be reclaimed as these structures could be big and have a lot of duplication as generation moves through stages.
-
src/core/tests.rs
should define this singleton and it should have the following properties:-
master_nodes: Vec<AstNode>
- All master nodes (those created during frontend generation) created should be stored in here.- The node's index in this vector is its ID
-
master_nodes[0]
is the top-level of the current AST - A method should be available to clear this at the start of the next test generation, similar to the target change method in Dut
- Individual nodes are never deleted from here, deleting a node from the AST will mean removing its ID from its parent node's children vector.
-
stage_nodes: Vec<Vec<AstNode>>
- Nodes created by processing the master AST to the next stage and from processing one stage to the next. Note that it is a vector of vectors.- A method should be available to request storage for a new stage. That should create a new
Vec<AstNode>
if none is available and return its index to the caller. The caller would be responsible for storing the ID of their allocated stage bank. - A method should be available to declare that a stage bank can be discarded.
- Within each bank it will operate the same as
master_nodes
withstage_nodes[n][0]
being the top-level node of the given stage.
- A method should be available to request storage for a new stage. That should create a new
-
active_temp_nodes: Vec<usize>
- For keeping track of which stage node banks are still reserved. If an existing bank is not listed in here then it can be cleared and re-used for another stage.
-
- All node struct definitions should be in module
src/ast
(could also besrc/core/ast
, but thinking this deserves its own top-level entity since it will be referred to a lot I think). - Probably a lot of sub-modules below this, e.g.
src/ast/reg.rs
src/ast/pin.rs
src/ast/tester.rs
src/ast/tester/v93k.rs
src/ast/jtag.rs
- There should generally be a 1:1 mapping between an API method and an AST node, e.g.
tester.cycle()
andtester.wait()
should map to similarly named nodes insrc/ast/tester.rs
. - ATE-specific APIs should be similarly mapped, an API method like
tester.v93k.do_x()
should map to aDoX
node in thesrc/ast/v93k.rs
module.
- Generally, APIs should be used to cross the Rust/Python boundary and not direct node creation. That said, if @coreyeng can or already does provides some macro-magic to expose all the AST structs and their constructors then so be it, though the AST node structure should really be Origen-internal private and not part of the public API.