From ardencaple at tesco.net Fri Sep 21 07:56:51 2007 From: ardencaple at tesco.net (Rob MacAulay) Date: Fri, 21 Sep 2007 11:56:51 +0000 (UTC) Subject: Aliases for checking logic values References: <46CE8011.70601@gmail.com> Message-ID: Hi Suraj - I would vote for: x! x? z! z? hi! hi? lo! lo? I would reserve 'zero' and 'one' for numerical values, or not use them. Note that XZ01 corresponds to the four-value logic system. This is generally all you need in RTL, but verilog supports a lot more.. I wouldn't go there unless you have to, though. Rob From ardencaple at tesco.net Fri Sep 21 10:57:35 2007 From: ardencaple at tesco.net (Rob MacAulay) Date: Fri, 21 Sep 2007 14:57:35 +0000 (UTC) Subject: System level testing References: <46B2BC5F.8010506@gmail.com> <46B2BD46.6070509@gmail.com> Message-ID: Hi Suraj, Sorry to have dropped off the radar for so long.. Anyway, I notice you have done two major releases since we last communicated! I have just installed 19.0.0, and been playing around with it. I am starting to refine my system level testing needs, using a RISC system as the target. So here's what I want to do: BACKGROUND: ----------- I ignore the RISC itself to start with - this is usually obtained as a simulator model or somesuch later on. The majority of the work involves describing the system around the RISC, and the interactions with it. So to start with, I will be building a system using a bus functional model, that just initiates bus transactions, And checks the required results. This is not sufficient for all system testing, but it is usually the first step When developing bus-based peripherals, or memory systems. Furthermore, I will develop two bus models: a low speed peripheral bus, and a high-speed bus that connects the RISC to The memories and to the bridge that translates between the high speed bus and the peripheral bus. For a concrete example, I will use an ARM AHB bus as the high speed bus connected to the ARM core and memories, and an APB bridge connecting the AHB bus to a set of peripherals on an APB bus. This is a very typical situation - in the Open Source world, there are also the Wishbone buses, which are similar (and probably better; AHB has some glaring faults) Typically, a verilog hierarchy would look something like this: AHBSys------| (AHB bus) | |---- ARM7TDMI | |---- Memory | |---- AHB2APB | |---- Peripheral1 | |---- Peripheral2 Etc. Also, in a traditional HDL verification setup, outside of all this would be a 'testbench' - this contains models of the environment With which the design has to interact. This may contain very little, if the device is standalone, or it may contain many models: memory external serial port model USB slave or host JTAG host etc.. I have had to develop all these at one time or another More on the external harness later. BUS MODELLING 1 --------------- First of all, let's develop some of the peripheral blocks. This corresponds more to the way you have looked at Ruby-VPI so far. We can develop a simple register based peripheral, that is attached to the APB (peripheral) bus. This will have an interface that Connects to the bus, and a few simple internals. Now we can use Ruby-VPI pretty much as described in the tutorial; we can develop individual tests that manipulate the bus signals In the correct order, read back values, check to see whether they are correct, etc. But, notice that this will become tedious, if we have a lot of tests; we are performing the same actions over and over again. What we want is a set of routines that emulate the bus transactions, so that we can write tests like describe "A peripheral register" do setup do Peripheral.reset! end it "should be reset to zero" do # use a bus read function to obtain the value of reg Peripheral.read(ADDR).should == 0 end it "should be writeable" do # write a value, then read it back # use a bus write and bus read function # not exhaustive.. Peripheral.write(ADDR, TEST_VAL) Peripheral.read(ADDR).should == TEST_VAL end end When implementing in Ruby-VPI, there are some questions we need to ask: 1. Where should we implement the bus functions? At the moment, I have implemented them (successfully) in the _design.rb file, alongside the cycle!, reset! Functions But there are possible issues with this, as we will see later. 2. We need to make sure that we can re-use the tests later on. This means that the address used to access the peripheral and the scope will need to change. So the question is, how should we refer to the DUT? Here we have referenced it explicitly (as Peripheral), but this will not be sufficient later on. BUS MODELLING 2 --------------- The next step is to place several peripherals on a peripheral bus. We will want to develop peripherals in separate verilog files, plus a System level file that connects them together. The first query is just one about the mechanics of Ruby-VPI. How do we include multiple files in the build? One way is to add the files into the filelist generated in the _runner.rake file; this works. However, I don't find it satisfactory. An easier way normally is to use the -y switch, together with diectory names. Only the top level file needs to be given, and the rest are Found by inspection on the directory paths. The problem is that it works for CVER on the command line, but I can't seem to get the arguments Passed in correctly by changing things in the _runner.rake file. That is, it seems to generate a correct command line, but it doesn't work. However, that's a minor (if frustrating) detail. Secondly, we now have several blocks to test, and also, the top level that we are testing has changed. Hence, how do we refer to the different Peripherals? One way is to recognise that we are not performing tests on the peripherals, but on the bus - which is our top level. So the tests should Include statements like: PeriphBus.read(ADDR).should == TEST_VAL But this means we have to edit all our tests now, which is annoying. And later on, we may have to do it again. One way might be to always call Our top level System; a further refinement would be to have the very top level just a wrapper around the actual top level, so that we never Need to change the name of the module in the verilog code. The wrapper will always be called System. BUS MODELLING 3 --------------- Now we want to instantiate our peripheral bus system within the main bus. To start with, this is just an extension of our previous technique. We build the verilog of the complete system, and wrap it with a new System wrapper. We now have to build bus functions that perform main bus functions, and put them in the _design.rb file. This should work, because our tests just use System.read(ADDR).should == TEST_VAL The translation between the main bus and the peripheral bus transactions is now performed by the HDL itself - as it will be in real life. However, we have had to perform major edits to our System_design.rb file, which is not good. What is the best way of abstracting this out? Obviously, we should encapsulate the bus modelling functions somewhere, in say, an AHBBus and APBBus class or module?. However, what would be the best way of getting these functions in scope? Use an 'include' in the System_design.rb file. I'm a bit hazy about the namespace issues here. DISTRIBUTED DESIGN ------------------ But actually, there will probably be several teams developing modules. Ideally we would want to be able to develop the verilog, and more importantly, the tests, and then import these into the top level. So I'm not sure how to do set this up. The top level System would need to import the verilog (which could be done by using library directives), but it would be good to be able to, say, get Ruby-VPI to recursively pull all the required modules from a directory. It is also worth pointing out that one tends to have both project specific libraries, and shared libraries. For example there might be a Library of AHB modules, APB modules, and then some project-specific peripherals. So a project layout might be something like: | |----AHBLib | | | |----verilog | | | |----System | | | | | |---- System_design.rb | | | AHBmodule1.v | | | AHBmodule1_spec.rb | | | AHBmodule2.v | | | AHBmodule2_spec.rb // | | | AHB_helper.rb //bus models | | | System_spec.rb //refers to specs | |----APBLib | | | |----verilog | | | |----System | | | | | |---- System_design.rb | | | APBmodule1.v | | | APBmodule1_spec.rb | | | APBmodule2.v | | | APBmodule2_spec.rb // | | | APB_helper.rb //bus models | | | System_spec.rb //refers to specs | |----MyProject | | | |----verilog | | | |----System | | | | | |---- System_design.rb | | | MyAPBmodule1.v | | | MyAPBmodule1_spec.rb //refers to APBLib | | | MyAHBmodule2.v | | | MyAHBmodule2_spec.rb //refers to AHBLib | | | MyProject_helper.rb //test harness models | | | System_spec.rb //refers to specs here, in AHBLib, APBLib Note that we will also want to integrate revision control into the main project rake files. As pointed out before, the tests either specific to the project, OR referred to from other libs, Will use the bus model referenced in the project, NOT the one used locally in their library test System. TESTING ------- As pointed out above, it should be possible to get hierarchical builds for the verilog (after sorting out those pesky rake problems). However, I am less sure about the Rspec specifications. Ideally, I would want to have the master System_spec.rb file look something like: describe "APBSubstem" do it_should_behave_like "APBModule1" (ADDR1) it_should_behave_like "APBModule2" (AADR2) it_should_behave_like "MyAPBModule1" (AADR3) ..etc Where we refer to 'shared' Rspec behaviour Now there are two issues here: 1. how to set up the namespaces correctly (doable, except I don't know enough about it yet..) 2. we need to parametrise the specs with the actual address / size / etc. of the module This is particularly true of library modules, since they will in general, be parametrisable. Any ideas about point (2)? At the moment it looks impossible, but its difficult to get any hard info About Rspec, the documentation is terrible. I'll have a poke round. Note also, that we would like to have a standard means of assigning addresses, etc. In practice this means a Header file with verilog definitions (enter your verilog to ruby translator). There is one small verilog point Here - it is probably better to use 'parameters' to set addresses, sizes, etc., rather than rely on macro Substitutions (`defines) as these can be set from anywhere within the hierarchy. However, one can use macros In the parameter instantiations, if necessary. BUS MODELS vs CODE ------------------ All the above use the bus functions to perform testing. This works well will the Rspec framework. Eventually, though, we would like to run code. It is possible to modify the bus functions, so that, as well as performing the transaction, they emit Code (possibly assembler code) to execute the same action. So write (ADDR,DATA) gets turned into (pseudo-assembler): load r4, #DATA // load immediate store @#ADDR, r4 // store absolute One point, though, is that the read needs to have an expected value; at the moment the bus function read returns The value so that it can be checked by the Rspec framework. The assember code will need to know the expected value, So would probably need something like expect(ADDR, DATA) // returns value as well, so can use expect (ADDR,DATA).should == DATA becomes: load r4,#DATA load r5,@#ADDR cmp r4,r5 bnz FAIL_EXPECT This approach does mean that the code version can't be checked using the Rspec framework; it gets emitted, assembled Then loaded into a memory model for execution by a harness that uses the real core (or a C model thereof). Again, I can't work out whether Rspec could be made to do anything more clever. STATUS ------ I have got as far as using simple bus models, but these are still at the early stage, i.e. just shoved into the Top_level_design.rb file. I haven't tackled the hierarchy problems yet. If you are interested, I can send you the files (such as they are!) Best Regards (and keep up the good work!) Rob MacAulay From snk at gna.org Tue Sep 25 22:11:07 2007 From: snk at gna.org (Suraj N. Kurapati) Date: Tue, 25 Sep 2007 19:11:07 -0700 Subject: System level testing In-Reply-To: References: <46B2BC5F.8010506@gmail.com> <46B2BD46.6070509@gmail.com> Message-ID: <46F9BFBB.1030103@gna.org> Hello Rob, Sorry for the delayed response, I've been busy lately. You have quite an interesting project there. I am personally excited about it being a real-world application of Ruby-VPI. I read through your requirements and saw two main themes: 1. How to organize and share common code? 2. How to load multiple components into a single simulation? I drafted a plan to address these issues by shifting some of the runner.rake file's responsibilities into the Verilog simulator's embedded Ruby interpreter. Here is what I envision: Rake ------------------------------------------------------------- 1. Specify a user-defined Ruby script that will be loaded by Ruby-VPI once the simulator has been started up. 2. Figure out where all necessary Verilog modules & Verilog libraries are and start the Verilog simulator with them. Verilog simulator ------------------------------------------------ 1. Start up the Ruby interpreter and load Ruby-VPI into it. Ruby-VPI --------------------------------------------------------- 1. Set up the basic verification environment (the nice library for working with VPI handles etc.). 2. Load the user-defined Ruby script that was specified by Rake. 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. Test files ------------------------------------------------------- design.rb: Defines convenience methods on the DUT object. May define other data structures to aid the testing. proto.rb: Uses the concurrency model to emulate the design under test's Verilog implementation. spec.rb: Does some tests on the DUT object. If you want to test multiple Verilog objects, then simply use the vpi_handle_by_name() function to get access to the Verilog objects you want and proceed as usual. whatever.rb: Because the user-defined Ruby script decides what files to load, you are free to organize your tests however you like. As a result, the "design.rb", "proto.rb", and "spec.rb" will now become a mere convention that you can *choose* to follow rather than being forced to follow. ----------------------------------------------------------------- In this manner, we gain the ability to: 1. load as many tests into the simulation as we wish 2. use any files we want (and organize them however we like) to perform the testing I think that this plan will solve most, if not all, of the obstacles you had posed. At the least, it will make Ruby-VPI more general in order to handle a broader variety of applications. I am now proceeding to implement this plan over the next few weeks. Let me know if you have questions. From ardencaple at tesco.net Wed Sep 26 06:36:48 2007 From: ardencaple at tesco.net (Rob MacAulay) Date: Wed, 26 Sep 2007 10:36:48 +0000 (UTC) Subject: System level testing References: <46B2BC5F.8010506@gmail.com> <46B2BD46.6070509@gmail.com> <46F9BFBB.1030103@gna.org> Message-ID: Hi Suraj, Thanks for the reply. > 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. 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. > > 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. > Test files ------------------------------------------------------- > whatever.rb: > > Because the user-defined Ruby script decides what files to > load, you are free to organize your tests however you like. > > As a result, the "design.rb", "proto.rb", and "spec.rb" will > now become a mere convention that you can *choose* to follow > rather than being forced to follow. Nice. 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 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. > ----------------------------------------------------------------- > > In this manner, we gain the ability to: > > 1. load as many tests into the simulation as we wish > > 2. use any files we want (and organize them however we like) to > perform the testing > > I think that this plan will solve most, if not all, of the > obstacles you had posed. At the least, it will make Ruby-VPI more > general in order to handle a broader variety of applications. > Sounds excellent! Rob From snk at gna.org Wed Sep 26 21:25:30 2007 From: snk at gna.org (Suraj N. Kurapati) Date: Wed, 26 Sep 2007 18:25:30 -0700 Subject: System level testing In-Reply-To: References: <46B2BC5F.8010506@gmail.com> <46B2BD46.6070509@gmail.com> <46F9BFBB.1030103@gna.org> Message-ID: <46FB068A.4050706@gna.org> 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. -------------- next part -------------- A non-text attachment was scrubbed... Name: argv.patch Type: text/x-patch Size: 570 bytes Desc: not available Url : http://rubyforge.org/pipermail/ruby-vpi-discuss/attachments/20070926/e728b357/attachment.bin