Convention for passing arguments to non-Silicon subblocks/helpers - origen-sdk

Sorry if the title is a bit confusing, but what are the options/conventions that Origen provides for setting up subblocks that aren't necessarily silicon models, or are just general helpers?
For example, I have a scan helper plugin that guides the user through creating a scan test program. I'd like to add a list of options/customizations to the top-level app. There are a few ways to do this:
I can add a list of attr_readers/methods. I think this looks a bit ugly though and adds a bunch of stuff to the toplevel that isn't used by anything else, and it blows up $dut.methods.
I could use parameters as defined here: http://origen-sdk.org/origen/guides/models/parameters/ and just call of them in the scan tester app. But looking at the guides I don't think that is the desired use case. It looks more like context switching, but maybe that was just the example use case.
I could add a scan_tester.setup method or something on the toplevel. This just seems unnecessary though since its basically doing the same thing as #2, but requires a 'setup' method to be called. Yeah, its only 1 line, but if you mess up or forget to add that line then you've got some debug to do avoided by #2 (I can print a warning for example if the scan parameters aren't provided to help warn of typos, etc.).
I can set it up as a subblock (currently how I've got it), but this doesn't really fit. Scan isn't a silicon model, so base address is useless, but required. It has no registers, etc.
Then there's other 'Ruby' things I could do (setup via on_create, use global variable etc.) but these all seem not as great as any of the options above for one reason or another (mainly, more setup required on my part than using any of the existing options).
Any one of these would work. But from a convention standpoint, which direction should my scan tester setup go? Is there another option I hadn't considered? I'd lean towards option #2 as it looks the cleanest.
Thanks

This is a really good question.
There are actually two other options:
Add application config parameters from the plugin: http://origen-sdk.org/origen/release_notes/#v0_7_24
Define a constant as used by the JTAG and other early plugins: http://origen-sdk.org/jtag/#How_To_Use
I think #2 is using parameters in a way that was not originally intended, maybe it could work though but I just can't picture it.
I don't really like #5 or #6 since they provide application-level and class-level configuration, which is sometimes what you want, but often these days I see the need more for (DUT) instance-level configuration.
So, my best answer here is that I don't know, but you are touching on a good point that we need to have an official API or at least a recommendation for this.
I think you should be open to the possibility of adding something new to Origen for this if you can think of something better.
As I'm writing this, I suppose #5 would also support instance-level configuration, albeit a bit long-winded:
def initialize(options = {})
Origen.app.config.scan_chain_length = 6
end

My comment wouldn't keep its format, so here it is but looks better:
#Ginty
What would you think of a 'component' API. For example, we could have:
# components.rb
component(:scan, TIPScan::ScanTester,
# options
wgl_dir: ..., # defaults to Origen.app.root/pattern/wgl
custom_sort: proc do {|wgl_name| ...},
)
# then we can do things like:
$dut.scan #=> TIPScan instance
$dut.component(:scan) #=> same as above
$dut.components #=> [TIPScan instance, ...]
$dut.has_component(:scan) #=> true etc.
Pretty much just a stripped down subblock class to handle these. I think our IAR/C compilers and even CATI could benefit from this and make the setup cleaner and more customizable.

Related

Declarative Pipeline using env var as choice parameter value

Disclaimer: I can achieve the behavior I’m looking for with Active Choices plugin, BUT I really want this to work in a Jenkinsfile and controlled with scm because it’s tedious to configure the Active Choices on each job we may need them on. And with it being separate from the Jenkinsfile creation, it’s then one job defined in multiple places. :(
I am looking to verify if this is possible, because I can’t get the syntax right, if it is possible. And I haven’t been able to find any examples online:
pipeline {
environment {
ARTIFACTS = lib.myfunc() // this works well
}
parameters {
choice(name: "Artifacts", choices: ARTIFACTS) // I can’t get this to work
}
}
I cannot use the function inline in the declaration of the parameter. The errors were clear about that, but it seems as though I should be able to do what I’ve written out above.
I am not home, so I do not have the exceptions handy, but I will add them soon. They did not seem very helpful while I was working on this yesterday.
What have I tried?
I’ve tried having the the function return a List Because it requires a list according to the docs, and I’ve also tried (illogically) returning a String in the precise syntax of a list of strings. (It was hacky, like return "['" + artifacts.join("', '") + "']" to look like ['artifact1.zip', 'artifact2.zip']
I also tried things like "$ARTIFACTS" and ${ARTIFACTS} in desperation.
the list of choices has to be supplied as String containing new line characters (\n): choices: 'TESTING\nSTAGING\nPRODUCTION'
I was tipped off by this article:
https://st-g.de/2016/12/parametrized-jenkins-pipelines
Related to a bug:
https://issues.jenkins.io/plugins/servlet/mobile#issue/JENKINS-40358
:shrug:
First, we need to understand that Jenkins starts running your pipeline code by presenting you with Parameters page. Once you've set up the parameters, and pressed Build, then a node is allocated, variables are set, and your code starts to run.
But in your pipeline, as presented above, you want to run some code to prepare the parameters.
This is not how Jenkins usually works. It's definitely not doing the following: allocating a node, setting the variables, running some of your code until parameters clause is reached, stopping all that, presenting you with GUI, and then continuing where it left off. Again, it's not how Jenkins works.
This is why, when writing a new pipeline, your first option to build it is Build and not Build with Parameters. Jenkins hasn't run your code yet; it doesn't have any idea if there are any parameters. When running for the first time, it will remember the parameters (and any choices, if were) as were configured for this (first) run, so in the second run you will see the parameters as configured in the first run. (Generally, in run number n you will see the result of configuration in run number n-1.)
There are a number of ways to overcome this.
If having a "somewhat recent" (and not "current and absolutely up-to-date") situation fits you, your code may need minor changes to work — second time. (I don't know what exactly lib.myfunc() returns but if it's a choice of Development/Staging/Production this might be good enough.)
If having a "somewhat recent" situation is an absolute no-no (e.g. your lib.myfunc() returns the list of git branches, and "list of branches as of yesterday" is unacceptable), then your only solution is ActiveChoice. ActiveChoice allows you to run some code before showing you the Build with Parameters GUI (with script approval etc.).

How to print function call timeline?

I would like to print location and function name of each function during a run.
It would help during debug to identify which function is called when multiple functions have the same name in different places.
It is possible but time costly to add by hand message such as:
println!("(function_name) file = {}, line = {}",file!(),line!());
Do you know such a solution? Have you suggestions to identify easily which function is called and who calls it?
The easiest option would probably be to use something like dtrace or ebpf: hook onto the "function entry" probe (not sure what it's called in linux / ebpf land but I'd think it exists) and just print the relevant information. You may want to add stack-based indentation though, and of course because of compiler optimisations you might have functions going missing. And you might get the mangled names which is not great, but de-mangling is a thing.
You might be able to do something similar by running your program in gdb and creating some sort of programmatic breakpoints which print and immediately continue?
Alternatively, a module-level attribute procedural macro could work: if you get a token stream for the entire module, it might be possible to automatically inject logging data into every function header.

Can I alter Python source code while executing?

What I mean by this is:
I have a program. The end user is currently using it. I submit a new piece of source code and expect it to run as if it were always there?
I can't find an answer that specifically answers the point.
I'd like to be able to say, "extend" or add new features (rather than fix something that's already there on the fly) to the program without requiring a termination of the program (eg. Restart or exit).
Yes, you can definitely do that in python.
Although, it opens a security hole, so be very careful.
You can easily do this by setting up a "loader" class that can collect the source code you want it to use and then call the exec builtin function, just pass some python source code in and it will be evaluated.
Check the package
http://opensourcehacker.com/2011/11/08/sauna-reload-the-most-awesomely-named-python-package-ever/ . It allows to overcome certain raw edges of plain exec. Also it may be worth to check Dynamically reload a class definition in Python

Creating a spec helper in rubymotion

I have some common methods used in a couple different specs, I want to extract them to some place like a spec helper that is accessible from all specs. Anyone know how to do this?
Here is something that sorta quacks like a spec_helper.
# _spec_helper.rb
module SpecHelper
::App::Persistence = {}
# global `before :each` ish
def self.extended(base)
base.before do
::App::Persistence.clear
end
end
def foo_helper
end
end
And then use it:
# my_view_spec.rb
describe "MyView" do
extend SpecHelper
before do
foo_helper
end
...
Two things to bear in mind:
Spec helper file is named in such way that it gets loaded first (leading underscore)
When running individual specs (e.g. files=my_view_spec.rb) helper file must go along - files=spec/my_view_spec.rb,spec/_spec_helper.rb
I just throw my common methods used in specs as they are (not encapsulated in a Module or anything) in a spec/support/utilities.rb file and Rubymotion seems to pick them up fine, though I don't know if this is the "proper" way to do this.
According to current http://www.rubymotion.com/developer-center/articles/testing/#_spec_helpers
Spec helpers are created under the spec/helpers directory of a RubyMotion project. An example could be spec/helpers/extension.rb.

Getting echofunc.vim to work

I came across echofunc.vim today (from a link in SO). Since I'm rubbish at remembering the order of function parameters, it looked like a very useful tool for me.
But the documentation is a bit lean on installation! And I've not been able to find any supplementary resources on the internet.
I'm trying to get it running on a RHEL box. I've copied the script into ~/.vim/plugin/echofunc.vim however no prompt when I type in a function name followed by '('. I've tried adding
let g:EchoFuncLangsUsed = ["php","java","cpp"]
to my .vimrc - still no prompting.
I'm guessing it needs to read from a dictionary somewhere - although there is a file in /usr/share/vim/vim70/ftplugin/php.vim, this is the RH default and does not include an explicit function list.
I'm not too bothered about getting hints on the functions/methods I've defined - just trying to get hints for the built-in functions. I can see there is a dictionary file available here which appears to provide the resources required for echofunc.vim, I can't see how I set this up.
TIA,
It expects a tags file, the last line of the description describes exactly how to generate it:
ctags -R --fields=+lS .
It works here with PHP but not with JS. Your mileage may vary.
I didn't know about this plugin, thanks for the info.
You should try phpcomplete.vim, it shows a prototype of the current function in a scratchpad. It is PHP only, though.

Resources