Embed Python for use with HDL

Wanted to show how easy it is to use Python together with Verilog or VHDL. With just a few lines the Python interpreter can be embedded and call tasks or functions in SystemVerilog. I am using the proprietary simulator Questasim in this example.

The SystemVerilog code looks like this

`timescale 1 ns/1 ns
module top;
      import "DPI-C" context task startPython();
      export "DPI-C" task sv_write;

   // Exported SV task.  Can be called by C,SV or Python using c_write
   task sv_write(input int data,address);
      begin
	 $display("sv_write(data = %d, address = %d)",data,address);
      end
   endtask

   initial
     begin
	startPython();
	$display("DONE!!");
     end

endmodule

The C code looks like this

#include
#include "vpi_user.h"
#include "pythonEmbedded.h"

static PyObject * c_write(PyObject *self, PyObject *args) {
  int address,data;
  if(!PyArg_ParseTuple(args, "ii", &data, &address))
    return NULL;
  sv_write(address,data);
  return Py_BuildValue("");
}

static PyMethodDef EmbMethods[] = {
  {"c_write",c_write, METH_VARARGS,"c_write(data,address)"},
  {NULL, NULL, 0, NULL}
};

DPI_DLLESPEC
int startPython(){
    Py_Initialize();
    Py_InitModule("emb", EmbMethods);
    PyRun_SimpleString("import emb\n"
		       "emb.c_write(0,1)\n");
    Py_Finalize();
    return 0;
}

Easiest way to try it out:

git clone http://github.com/oddball/embedPythonInVerilogExample.git
cd embedPythonInVerilogExample
make

Can also view the code online at https://github.com/oddball/embedPythonInVerilogExample

ipxact2systemverilog

Registers in an ASIC are described in many different places, for example in:

  • Actual physical registers
  • Block level test benches
  • Top level test benches
  • Block level models
  • System architectural model
  • Software
  • Software help files
  • Block documentation
  • Chip documentation
  • Chip datasheet

The register descriptions in the datasheet many times covers many hundreds of pages. Imagine if the registers are described independently in these +10 places: how many incompatible descriptions of the same thing will there be?

Clearly there is a need to describe the registers once, and generate all the other descriptions or views from the same source. Luckily the the fellows at http://www.accellera.org/activities/committees/ip-xact/ has set an industry standard to describe registers.

I had a little time over and took the opportunity to write a few registers description generators:

https://github.com/oddball/ipxact2systemverilog

The package contain these generators

ipxact2systemverilog
ipxaxct2vhdl
ipxact2rst

Through the reStructuredText (rst) file there are implicitly 2 other generators

ipxact2pdf
ipxact2html

Through .rst files it is also possible to generate .odt or .doc files, but writing documentation in those formats is an engineering sin.

In order to generate UVM or OVM packages, there are other generators available.
One nice tutorial can be found here

http://www.doulos.com/knowhow/sysverilog/ovm/tutorial_rgm_1/

IP-XACT for Emacs

IP-XACT for Emacs

As we all know, real ASIC Designers use Emacs. Occasionally however good thing come around that does not support Emacs directly.

One of these things are the Spirit Consortium IP-XACT http://www.accellera.org/activities/committees/ip-xact Granted I never really liked anything in IP-XACT, but the possiblitly to use it to describe Registers. But an Industry standard for that, is badly needed.

Validating xml files for IP-XACT is done with XSD files.

Validating xml files could be done with nice tool called MSV. Can be found at http://java.net/downloads/msv/releases/

So validating a yourRegisterFile.xml can be done with

java -jar ~/bin/msv/msv.jar schema/component.xsd yourRegisterFile.xml

Keeping the xml wellformed http://en.wikipedia.org/wiki/Well-formed_document, nXML mode will do for you automaticly

However wouldnt it be nice if Emacs could validate xml against IP-XACT internaly.

That does however require that we change the proveded Schemas from XSD->RNG->RNC. I have not been able got get this to work. But I got a bit on the way.

There is a xslt from Nicolas Debeissat ndebeiss(u guessed it)gmail.com to convert XSD to RNG, And there is a xslt from David.Rosenborg (u guessed it) pantor.com to convert RNG to RNC

So loop over the XSD files from spirit with these commands

xsltproc –output rng/file.rng XSDtoRNG.xsl schema/file.xsd
xsltproc –output rnc/file.rnc RngToRnc/RngToRncText.xsl rng/file.rng

Sadly this does not work perfectly. I am informed that XSD is not one-to-one map to RNG. So there some code to rewrite, so if you feel up to it, please feel free to fix the code.

git clone http://oddball@github.com/oddball/ipxactForEmacs.git
cd ipxactForEmacs
make

Can also view the code online at https://github.com/oddball/ipxactForEmacs

Since I move ar…

Since I move around a bit, I have tcsh script that configure my emacs to the bare minimum of what I need as an ASIC Designer.

That is a decently new versions of VHDL, SPECMAN, and Verilog mode.

To check is out, have a look at

http://github.com/oddball/cfgEmacs/blob/master/cfgEmacs.sh

 

 

 

 

Questasim/Modelsim VHDL warnings

When using Questasim/Modelsim there is a easy trick to get rid of the initial warnings like

** Warning: NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0. Time:0 fs
** Warning: There is an ‘U’|’X’|’W’|’Z’|’-‘ in an arithmetic operand, the result will be ‘X'(es). Time:0 fs
** Warning: CONV_INTEGER: There is an ‘U’|’X’|’W’|’Z’|’-‘ in an arithmetic operand. Time:0 fs

make a file called shutup.do

set StdArithNoWarnings 1
set StdNumNoWarnings 1
set NumericStdNoWarnings 1
run 0 ns;
set StdArithNoWarnings 0
set StdNumNoWarnings 0
set NumericStdNoWarnings 0
# Continue script

Call the file with do shutup.do

Auto Dependency Makefile Example

Despite having written my fair share of Makefiles, every time I need to start from scratch with a new Makefile, I wonder how it is done. Looking at the last Makefile usually don’t help, since they tend to become quite bloated with time. I also read on Wikipedia that the Makedepend program is now viewed as the last resort. Since I always used it, I wanted to see how else to do it.

There are a lot of “Hello World” examples out there, but I seldom find them complete. There for I made one, mostly for myself. It automatically updates the dependencies from all source files.

So in my example I have a src directory that looks like this:

ls -1 src/
classA.cc
classA.hh
classB.cc
classB.hh
main.cc

The main.cc file has one instance of classA and one of classB. The Makefile requires that there is one main.cc file, but there can be any number of class files.

The Makefile looks like this

DIRS    := src
SOURCES := $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cc))
OBJS    := $(patsubst %.cc, %.o, $(SOURCES))
OBJS    := $(foreach o,$(OBJS),./obj/$(o))
DEPFILES:= $(patsubst %.o, %.P, $(OBJS))

CFLAGS   = -Wall -MMD -c
COMPILER = g++

#link the executable
main: $(OBJS)
        $(COMPILER) $(OBJS) -o main

#generate dependency information and compile
obj/%.o : %.cc
        @mkdir -p $(@D)
        $(COMPILER) $(CFLAGS) -o $@ -MF obj/$*.P $<
        @sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
             -e '/^$$/ d' -e 's/$$/ :/' < obj/$*.P >> obj/$*.P;

#remove all generated files
clean:
        rm -f main
        rm -rf obj

#include the dependency information
-include $(DEPFILES)

To see how it works, the easiest thing is to do:

git clone http://github.com/oddball/autoDependMakefileExample.git
cd autoDependMakefileExample
make

PS:

When writing Makefiles, this is nice page to have in the background
http://www.gnu.org/s/hello/manual/make/Automatic-Variables.html

When doing automatic dependencies, this is an excellent article. Even if I find it incomplete
http://mad-scientist.net/make/autodep.html

Trying to figure out what the switches to g++ mean?
http://linux.die.net/man/1/g++

At last but not least. If you ever had a feeling that your recursive make does odd things, you should read this aegis.sourceforge.net/auug97.pdf

Synthesizable Generic Memory

Synthesizable Generic Memory

A Verilog module that can be specialised from a simulation model to a vendor memory, without manually changing a line of RTL!

In an ASIC project a lot a time is needlessly consumed by they way memories are handled . Time is wasted, waiting for new models, instantiating the new models, changing code to fit new vendor memories. Over and over again.  A lot of time is also wasted developing a design, using the real size of a memory, when its faster in the development face to use a smaller memory. This extrapolates very well. No matter the design, if it is not generic, you are not doing it correctly!!

There are also significant SCM and reuse, advantages to using a generic memory.

The general principle is simple

Instantiate a module that depending on parameters (generics) instantiates different memory models.

  • If you have no vendor models, instantiate a generic memory model.
  • If you have vendor models, have a simple switch statement that instantiates the memory of the correct size.

Generate the switch statement with a script that goes through your memory models. Include the switch statement in your code.

Voila! A generic memory that is synthesizable.

So lets show how its done in code

Assume that you have a bunch of memories in a directory.

ls -1 vendorMemModels/
someOnePortVendorMem_2048_8_16.v
someOnePortVendorMem_256_8_16.v

With the naming convention of {vendorName}_{numberOfAddresses}_{width}_{muxfactor}.v
The muxfactor is, as all know, only interesting from a layout point of view.

Traverse your vendor memory models with a script in your favourite language (which of course is Python) and generate some code that looks somewhat like this:

//Automaticly generated file!!!! Do not edit!!!
//fileName : scriptGeneratedListOfVendorOnePortMems.vh
else if((addresses==256)&&(width==8))
  begin
     someOnePortVendorMem_256_8_16 mem(.A (address),
				 .CLK (clk),
				 .CEN (~(readEnable|writeEnable)),
				 .D   (writeData),
				 .WEN (~writeEnable),
				 .OEN (1'b0),
				 .Q   (readData) );
  end
else if((addresses==2048)&&(width==8))
  begin
     someOnePortVendorMem_2048_8_16 mem(.A (address),
				 .CLK (clk),
				 .CEN (~(readEnable|writeEnable)),
				 .D   (writeData),
				 .WEN (~writeEnable),
				 .OEN (1'b0),
				 .Q   (readData) );
  end

That was the automaticly generated part of the switch statement. Lets have a look at the rest.
We need a module to instantiate.

module onePortMem(readData,
		  readEnable,
		  address,
		  clk,
		  writeEnable,
		  writeData);
   //user defined
   parameter               addresses   = 32;
   parameter		   width       = 8;
   parameter 		   muxFactor   = 0;

   //Auto-calculated, user dont touch
   localparam		   addressWidth =clogb2(addresses);

   generate
      if((addresses==0)&&(width==0))
	begin
	   initial
	     begin
		$display("FAIL!! :%m:Parameters, addresses and width can not be set to 0");
		$stop;
	     end
        end
`include "scriptGeneratedListOfVendorOnePortMems.vh"
      else
	begin
	   onePortSimMem   #(.addresses  (addresses),
                             .width      (width),
                             .muxFactor (muxFactor)
			     ) mem (.readData(readData),
				    .readEnable(readEnable),
				    .address(address),
				    .clk(clk),
				    .writeEnable(writeEnable),
				    .writeData(writeData));
	end
   endgenerate
endmodule // onePortMem

Since I am a firm believer on version control, I put some executable example code on github.com. There I have also made some code for two port memories. The Makefile requires that you have a proprietary simulation tool (Modelsim/Questasim) in your path. If you don’t have it, feel free to update the Makefile for other tools and commit it.
In order to check it out and run it :

git clone http://github.com/oddball/genMem.git
cd genMem
make

Also possible to view the code online at  https://github.com/oddball/autoDependMakefileExample

In my example code there is a lot of issues that I have not touched. I have not touched them because I don’t want to cloud the general idea. But they are as well overcomeable. The main issue is BIST. BIST’s come in wide variety of forms. If they are parameterised, which they seldom are, it would be possible to solve the problem with including them in the Module “onePortMem”. Most likely they are not. Then it is possible to specialise them in the same manor as the memories. Can be nicely done with putting an BIST interface in a SystemVerilog interface and then specialise that interface in each project (when the specifics of the BIST interface is known). But there are other ways to handle it. It is also possible to handle write-masks etc, but again I have not put it here, because it clouds the concept.

The concept of “active-low” is a menace (except for reset which is generally accepted). It has caused numerous bugs, so I don’t use it in the module “onePortMem”.

PS: Most companies require the http_proxy environment variable to be set to something useful. And of unknown reason its not set per default. It should be done something like this in BASH:

export http_proxy="http://host:port/"

Emacs: VHDL: Update sensitivity lists

Emacs: VHDL: Update sensitivity lists

Have you ever had problems getting Emacs to update your sensitivity lists in a VHDL file? Out of the box, everything works if both the Entity and Architecture declaration exist in the same file.

However, many do place those in separate files. The most common naming convention is to put the Entity declaration in a file called {EntityName}-e.vhd and the default Architecture declaration in a file called {EntityName}-a.vhd. For example:

whatever-e.vhd
whatever-a.vhd

If you then try to update the sensitivity list in Architecture file, Emacs and VHDL mode do not know where to find the port declarations and just skip updating the list. Luckily its Emacs, so of course it is configurable. You can either work your way through the menus: Options->Customize Emacs etc. Or you can fix it in your .emacs file.

(custom-set-variables
 '(vhdl-array-index-record-field-in-sensitivity-list nil)
 '(vhdl-entity-file-name (quote (".*" . "\\&-e")))
 )

After that, Emacs looks for the Entity declaration in a file named {EntityName}-e.vhd

PS1: Setting “vhdl-array-index-record-field-in-sensitivity-list” to nil is not necessary, however I find that it works better if you have a lot of generics. And of course you do, right?

PS2: Notice that even if VHDL is case-insensitive Emacs is not. So naming the entity “Stupid” will make Emacs look for a file called “Stupid-e.vhd” and not “stupid-e.vhd”

Scan coverage estimate

Scan coverage estimate

Have you ever been trying to figure out why you don’t get the desired 100% coverage when you are synthesizing your design, just to find yourself waiting for the project synthesis script to finish.

I have many times. So I have written a minimal script that does nothing, but reporting the scan coverage estimate. Since it does nothing but the thing you want, it is very very fast.

Make a file scan_estimate.tcl

#Read your HDL files
read_file -format vhdl{ /path/to/design-e.vhd \
            /path/to/design-a.vhd}

# Sadly you need a technology, the default tech does not have test models
set search_path     { /path/to/your/tech/lib }; #most likely, last dirname is synopsys
set target_library   { some_vendor_name_and_techname.db };

create_clock clk -period 5.0; #We dont care about freq, but need a clock
compile -exact_map -scan
create_port -direction in scan_en; #We need a scan enable port
set_dft_signal -view existing_dft -type Reset -port rstn -active_state 0
set_dft_signal -view existing_dft -type ScanClock -timing [list 40 60] -port clk
set_dft_signal -view existing_dft -type ScanEnable -active_state 1 -port scan_en
set_scan_configuration
create_test_protocol
insert_dft

#report the scan coverage estimate
dft_drc -coverage_estimate

Start your DesignCompiler in a shell

dc_shell -gui

In your dc-shell type

source scan_estimate.tcl

Many times the project synthesis script takes hours and hours. But reporting just a small design typically takes a minute or less. Thus cutting down turnaround times, and freeing up the very expensive DesignCompiler license for actual work.