Skip to content

Org file infrastructure#214

Merged
ginty merged 3 commits intomasterfrom
org_infrastructure
Jan 19, 2018
Merged

Org file infrastructure#214
ginty merged 3 commits intomasterfrom
org_infrastructure

Conversation

@ginty
Copy link
Copy Markdown
Member

@ginty ginty commented Jan 18, 2018

This adds the ability to generate org files (Origen vector file format) as described in this RFC: Origen-SDK/rfcs#7

This is not intended to be a user-facing feature, but is internal architecture for use within Origen and its plugins to generate org files or to otherwise capture and process sequences of operations.

To open an Org File for read or write

Origen::OrgFile.open("some_id") do |org_file|
 
end

# Or without the block
org_file = Origen::OrgFile.open("some_id")

org_file.close

By default, the Org file will be created at #{Origen.root}/pattern/org/#{current_target}/#{id}.org, though the open method will accept :path and :filename options is you want to change it.

The only API the org_file object itself really provides to the application space is to check whether or not the underlying file exists:

org_file.exist?    # => True if the corresponding .org file is found on disk

To Read an Org File

An example of reading and executing an Org file is shown below:

org_file.read_line do |operations, cycles|  # => [[<object>, method, *args], [<object>, ...]], cycles
  operations.each do |object, operation, *args|
    object.send(operation, *args)
  end
end

To Write an Org File

The org_file instance is not intended to be written to directly by application code. Rather objects such as the pins, tester, etc. can be enabled to record the operations that are performed on them into the currently open org file:

pin(:tdo).record_to_org_file    # Start recording all default method accesses on this object

# Temporarily pause recording then resume again
pin(:tdo).stop_recording_to_org_file do
  pin(:tdo).expect_lo
end

pin(:tdo).stop_recording_to_org_file

# You can call start again later if you want to
pin(:tdo).record_to_org_file(only: [:assert])   # Only record calls to the assert method

# Or to extend the default methods that are recorded
pin(:tdo).record_to_org_file(also: [:my_method1, :my_method2])

Giving objects record capability

This PR enables this recording feature on Pins and PinCollections (groups).

It can be quite easily enabled for other objects like this:

class MyObj
  include Origen::OrgFile::Interceptable

  # Any class including the interceptable module must define this method to return a global
  # path to the object. i.e. this is string that will get written to the org file to represent the object
  # that is the target of the given operation, and the Org file reader must be able to eval this to
  # have the object returned
  def global_path_to
    "dut.some_accessor(#{id})"   # e.g. "dut.pins(:tdo)"
  end
end

By default the above won't capture any methods unless the user defines them when calling
record_to_org_file as shown in the above examples.

To define a default set of methods to be captured for the given class, define a method like
this:

def org_file_intercepted_methods
  [:my_method1, :my_method2, ...]
end

A note on self!

TL:DR - If you include OrgFile::Interceptable in a class, never use the self keyword with that class's methods, use myself instead.

The capture works here by wrapping the object being recorded with a thin wrapper object which intercepts all operations called on the object and selectively records them as they go past before always passing on to the underlying object.

In order for the org file to be an accurate reflection of what a pattern does, it is vital that an un-wrapped copy of the object being recorded never finds its way into user space. i.e. if the application calls an operation on an un-wrapped object then it will not be be recorded.

I think the only way to generate such a reference to the un-wrapped object is when calling self from within the object's own methods.
Unfortunately, self, being a keyword rather than a method, is one of the few things that you can't override in Ruby.
So to get around that I created the myself method which returns the wrapped version of the object rather than the un-wrapped version you would get from self.

Generally all you need to do here is find/replace self with myself and you will see that in the Pin and PinCollection classes in this PR.

Notes on creating an Org file generator

@coreyeng, I think this is mostly all useful to you to help create the org file output of a whole pattern so that it can be replayed without the whole app being available.

I think we probably don't want to create an Org file tester driver, rather I would add a --org-file switch to origen g.

Then enable interceptable on the OrigenTesters base class and when you see the switch being set, open up an org file and call record on the tester and all DUT pins.

The tester.cycle method may need some special handling, currently there is a Origen::OrgFile.cycle method that should be called whenever a cycle occurs.

@ginty ginty requested review from coreyeng and pderouen January 18, 2018 15:29
@coreyeng
Copy link
Copy Markdown
Member

Thanks for this! This looks good. I can pull it down soon and start messing with it. I'll trial it with some basics on Linux then move it over to Windows.

Is the simulator ready to actually replay sims yet? I saw that it can sample them but did it have the replay feature as well?

@ginty
Copy link
Copy Markdown
Member Author

ginty commented Jan 19, 2018

@coreyeng, yes the replay feature is working as described in the PR.

I'll go ahead and merge this now since I want to get OrigenSim installed globally in our environment for a project I am working on, obviously we can open another PR to tweak if necessary once you starto to use this.

Thanks!

@ginty ginty merged commit 4ad41ba into master Jan 19, 2018
@ginty ginty deleted the org_infrastructure branch January 19, 2018 09:31
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