Rob MacAulay wrote: >> Rake ------------------------------------------------------------- >> >> 2. Figure out where all necessary Verilog modules & Verilog >> libraries are and start the Verilog simulator with them. >> > > Theoretically, this shouldn't be too difficult. > The way I do this using simulator only scripts (TCL based, normally) > is to set up some variables that point to libraries: > > APBLIB = /path/to/apblib/src > FOUNDRYLIB = /path/to/foundrycelllib > FOUNDRYCELLS = mycelllib.v > > and so on. > > Then we pass these to the simulator using some -y library directives: > > -y #{APBLIB} -y #{FOUNDRYLIB} -v #{FOUNDRYCELLS} > > we simply give cver the name of the top level file, and it will pull in > all the required files. For gate level simulations, we need to specify > any cell libraries using -v > > Where we have different configurations, we will need to define different > libraries. As you pointed out in an earlier post, this can be done by > setting up some different targets in the rake file. > > An alternative way to do this might be to use verilog configurations, > but I haven't tried that yet. Also, it is nice to be able to use older > simulators as well. Rake should be pretty good as this sort of thing.
Rake and Ruby are excellent for this kind of thing. Take a look at the FileList data structure offered by Rake, it is very powerful. > Note that I have had problems getting the library names into cver - as > far as I can see, the command line passed to cver is OK, but it barfs > on the -y directive. However, launching cver on the command line is fine. Rake only prints out the entire command string, rather than showing you what the argv[] really is, before running a command. So, although the entire command string may appear correct, it may be the case that argv[] contains an element which contains multiple arguments: ["-y #{APBLIB} -y #{FOUNDRYLIB}", "-v #{FOUNDRYCELLS}"] To debug your problem, we need to inspect the real argv[] that is being passed to the command. Apply the attached "argv.patch" to lib/ruby-vpi/rake.rb, rerun your test, and make sure that the arguments (which you find are being ignored) aren't being jumbled into a single string in the argv[]. >> User-defined Ruby script ----------------------------------------- >> >> 1. Figures out what Verilog modules are going to be tested. >> >> 2. Figures out what Ruby files are going to do the testing. >> >> 3. Associates them together and starts the simulation. >> >> For example: >> >> designHandle = vpi_handle_by_name("whatever", nil) >> testFiles = Dir['path/to/files/*.whatever'] >> >> RubyVPI.load_test( designHandle, testFiles ) >> >> Here, the RubyVPI.load_test() method will: >> >> 1. Create a temporary module (a sandbox). >> >> 2. Define a constant named "DUT" inside the sandbox. >> >> 3. Load all the test files into the sandbox. > > This might not be necessary, as this could be done by setting up the > environment > to start with, as explained above. > > However, I guess your point here is that we could re-use tests defined in > another library 'as-is' by calling them in a smart manner from this file. > Nice. Precisely. What I wrote above is just the basic idea. I'll add some better functions which wrap these common tasks so you don't have to do much heavy lifting in the end. > My main queries at the moment are > 1. where should I put code like bus functional models > 2. where should I put top level test models The answer to these two questions is: it's up to you. With this new plan, the user is totally in charge of organizing their test(s). The sample project layout that you drew in your original post seems like a reasonable approach to this problem. I can imagine the following scenario: You have a single "dispatch" script which (1) loads the Ruby versions of AHBLib and APBLib as necessary and (2) loads one or more tests into the simulation. You can use environment variables to tell the dispatch script which tests to load... or an even better approach is to use simple YAML files to express this information. YAML[1] is a very simple data format supported natively by Ruby. Using it, you can express your test loading recipes like so: $ irb -r yaml -r pp pp YAML.load %{ - design: the VPI path to your DUT files: - foo_spec.rb - foo_whatever.rb - and so on - design: another VPI path to another DUT files: just_one_file_this_time.txt } [{"files"=>["foo_spec.rb", "foo_whatever.rb", "and so on"], "design"=>"the VPI path to your DUT"}, {"files"=>"just_one_file_this_time.txt", "design"=>"another VPI path to another DUT"}] This is a contrived example, but you get the idea. [1] http://yaml4r.sourceforge.net/cookbook/ > 3. ..and I am a bit unclear about what gets called in what order > but I guess that would become explicit when you implement these changes. The order of operation is the same as the order in which I laid out the plan: from top to bottom. That is, the flow of execution starts with Rake and finally end with the test files.
diff -rN -u -w old-ruby-vpi/lib/ruby-vpi/rake.rb new-ruby-vpi/lib/ruby-vpi/rake.rb --- old-ruby-vpi/lib/ruby-vpi/rake.rb 2007-09-26 18:01:07.000000000 -0700 +++ new-ruby-vpi/lib/ruby-vpi/rake.rb 2007-09-26 18:01:07.000000000 -0700 @@ -10,7 +10,8 @@ # An improved sh() that also accepts arrays as arguments. def sh *aArgs, &aBlock - old_sh(*collect_args(aArgs).reject {|i| i.to_s.empty?}, &aBlock) + p args = collect_args(aArgs).reject {|i| i.to_s.empty?} + old_sh(*args, &aBlock) end # Collects the given arguments into a single, sparse array.