[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gEDA: iSDF




Hi Steve,

This is version 0.0 of iSDF, an SDF annotator for Icarus VVP.

  http://www.nevis.columbia.edu/~stephan/sdf.tar.gz

Features:
   
  * complete Standard Delay File (SDF) parser.

  * support for absolute IOPATH and INTERCONNECT delays in vvp.

Installation:

  1. checkout Icarus Verilog from CVS, http://www.icarus.com/eda/verilog/
  2. apply the attached patch, and add the file verilog/vvp/vvp.h
  3. build and install Icarus verilog
  4. download sdf.tar.gz, and unpack next to verilog/
  5. ./configure; make; make install

The result is sdf.vpi, which will only load with vvp, not vvm.
sdf.vpi provides $sdf_annotate("File", scope).

The patched iverilog.conf provides the target flag `-t sdf', which runs
vvp with sdf.vpi loaded.

I'll appreciate any kind of feedback.

Cheers
Stephan


Index: iverilog.conf
===================================================================
RCS file: /home/demon/anoncvs/verilog/iverilog.conf,v
retrieving revision 1.16
diff -u -r1.16 iverilog.conf
--- iverilog.conf	2001/11/29 01:58:18	1.16
+++ iverilog.conf	2002/01/03 21:21:09
@@ -74,6 +74,9 @@
 [-tvvp]
 <ivl>%B/ivl %[v-v] %y %Y %W %s %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fcprop -Fnodangle %f %m -o%o -- -
 
+[-tsdf]
+<ivl>%B/ivl %[v-v] %y %Y %W %s %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -fVPI_MODULE_LIST=system,sdf -Fcprop -Fnodangle %f %m -o%o -- -
+
 # --
 # The vvm target uses the <ivl> string to take the preprocessed code from
 # standard input, compile it with the vvm code generator and write the
Index: vvp/delay.h
===================================================================
RCS file: /home/demon/anoncvs/verilog/vvp/delay.h,v
retrieving revision 1.2
diff -u -r1.2 delay.h
--- vvp/delay.h	2001/12/06 03:31:24	1.2
+++ vvp/delay.h	2002/01/03 21:21:10
@@ -65,8 +65,8 @@
 
 struct vvp_delay_s {
       vvp_delay_s(unsigned);
-      unsigned delay(unsigned char idx) { return del[tab[idx]]; }
-      unsigned size() { return tab[14]+1; }
+      unsigned delay(unsigned char idx) { return this ? del[tab[idx]] : 0; }
+      unsigned size() { return this ? tab[14]+1 : 0; }
     protected:
       vvp_delay_s(const unsigned char *t);
     private:
Index: vvp/functor.cc
===================================================================
RCS file: /home/demon/anoncvs/verilog/vvp/functor.cc,v
retrieving revision 1.37
diff -u -r1.37 functor.cc
--- vvp/functor.cc	2001/12/18 05:32:11	1.37
+++ vvp/functor.cc	2002/01/03 21:21:11
@@ -60,6 +60,11 @@
       functor_allocate(1);
 }
 
+unsigned functor_limit()
+{
+      return functor_count;
+}
+
 /*
  * Allocate normally is just a matter of incrementing the functor_count
  * and returning a pointer to the next unallocated functor. However,
Index: vvp/functor.h
===================================================================
RCS file: /home/demon/anoncvs/verilog/vvp/functor.h,v
retrieving revision 1.42
diff -u -r1.42 functor.h
--- vvp/functor.h	2001/12/18 05:32:11	1.42
+++ vvp/functor.h	2002/01/03 21:21:12
@@ -116,6 +116,11 @@
 extern vvp_ipoint_t functor_allocate(unsigned wid);
 
 /*
+** Return the number of allocated functors
+*/
+extern unsigned functor_limit();
+
+/*
  * Given an ipoint_t pointer, return a C pointer to the functor. This
  * is like a pointer dereference. The point parameter must have been
  * returned from a previous call to functor_allocate.
Index: vvp/vpi_mcd.cc
===================================================================
RCS file: /home/demon/anoncvs/verilog/vvp/vpi_mcd.cc,v
retrieving revision 1.5
diff -u -r1.5 vpi_mcd.cc
--- vvp/vpi_mcd.cc	2001/07/16 18:40:19	1.5
+++ vvp/vpi_mcd.cc	2002/01/03 21:21:13
@@ -107,6 +107,10 @@
 	int len;
 	int rc;
 
+	// don't print to stderr twice
+	if (mcd_table[1].fp == mcd_table[2].fp  &&  (mcd&6) == 6)
+	      mcd &= ~2;
+
 	rc = len = 0;
 	for(i = 0; i < 31; i++) {
 		if( (mcd>>i) & 1) {
@@ -121,6 +125,15 @@
 		return rc;
 	else
 		return len;
+}
+
+int vvp_printf(unsigned int mcd, const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  int r = vpi_mcd_vprintf(mcd,fmt,ap);
+  va_end(ap);
+  return r;
 }
 
 int vpi_mcd_fputc(unsigned int mcd, unsigned char x)
Index: vvp/vpi_priv.h
===================================================================
RCS file: /home/demon/anoncvs/verilog/vvp/vpi_priv.h,v
retrieving revision 1.24
diff -u -r1.24 vpi_priv.h
--- vvp/vpi_priv.h	2001/10/31 04:27:47	1.24
+++ vvp/vpi_priv.h	2002/01/03 21:21:13
@@ -239,6 +239,14 @@
 extern int vpip_get_time_precision(void);
 extern void vpip_set_time_precision(int pres);
 
+
+/*
+**  Functions defined in vpi_scope.cc, to keep track of functor scope.
+*/
+
+extern vpiHandle ipoint_get_scope(vvp_ipoint_t ipt);
+extern void functor_set_scope(vpiHandle scope);
+
 /*
  * $Log: vpi_priv.h,v $
  * Revision 1.24  2001/10/31 04:27:47  steve
Index: vvp/vpi_scope.cc
===================================================================
RCS file: /home/demon/anoncvs/verilog/vvp/vpi_scope.cc,v
retrieving revision 1.10
diff -u -r1.10 vpi_scope.cc
--- vvp/vpi_scope.cc	2001/11/02 05:43:11	1.10
+++ vvp/vpi_scope.cc	2002/01/03 21:21:14
@@ -23,6 +23,7 @@
 # include  "compile.h"
 # include  "vpi_priv.h"
 # include  "symbols.h"
+# include  "functor.h"
 #ifdef HAVE_MALLOC_H
 # include  <malloc.h>
 #endif
@@ -97,6 +98,93 @@
       return 0;
 }
 
+/*
+**  Keeping track of functor scope.  When the scope changes during
+**  compilation, we record the current number of functors in a list.
+**
+**  Why are we doing this?  The SDF annotator needs this for
+**  INTERCONNECT delays.  The INTERCONNECT delay is specified between
+**  a source modules output port and a target module input port, which
+**  are connected with a wire.  The vpiSignal for both ports point to
+**  the same functor output, together with all other ports that may be
+**  connected to the same wire.  The SDF annotator need to find those
+**  functors which are inside the scope of the target module, which
+**  are driven by the source functor.  And even this is only an
+**  aproximation, in case the wire is connected to multiple inputs of
+**  the same module.  But those should have the same delays anyway.
+**
+*/
+
+struct functor_scope_s {
+      vpiHandle scope;
+      unsigned start;
+};
+
+static struct functor_scope_s * functor_scopes = 0;
+static unsigned n_functor_scopes = 0;
+static unsigned a_functor_scopes = 0;
+
+void functor_set_scope(vpiHandle scope)
+{
+      unsigned nfun = functor_limit();
+
+      if (n_functor_scopes) {
+	    functor_scope_s *last = &functor_scopes[n_functor_scopes - 1];
+
+	    if (last->scope == scope) {
+		  return;
+	    }
+	    
+	    if (last->start == nfun) {
+		  last->scope = scope;
+		  return;
+	    }
+      }
+      
+      n_functor_scopes += 1;
+      if (n_functor_scopes >= a_functor_scopes) {
+	    a_functor_scopes += 512;
+	    functor_scopes = (struct functor_scope_s *)
+		  realloc(functor_scopes, 
+			  a_functor_scopes*sizeof(struct functor_scope_s));
+	    assert(functor_scopes);
+      }
+
+      functor_scope_s *last = &functor_scopes[n_functor_scopes - 1];
+      last->start = nfun;
+      last->scope = scope;
+}
+
+/*
+**  Lockup the scope of a functor.
+**
+**  Cannot use bserach, since we are not looking for an exact match
+*/
+vpiHandle ipoint_get_scope(vvp_ipoint_t ipt)
+{
+      if (n_functor_scopes == 0)
+	    return NULL;
+
+      unsigned fidx = ipt/4;
+      
+      unsigned first = 0;
+      unsigned last = n_functor_scopes;
+      while (first < last) {
+	    unsigned next = (first+last)/2;
+	    functor_scope_s *cur = &functor_scopes[next];
+
+	    if (cur->start > fidx)
+		  last = next;
+	    else if (next == first)
+		  break;
+	    else 
+		  first = next;
+      }
+
+      functor_scope_s *cur = &functor_scopes[first];
+      return cur->scope;
+}
+
 static const struct __vpirt vpip_scope_module_rt = {
       vpiModule,
       0,
@@ -175,19 +263,19 @@
       struct __vpiScope*scope = new struct __vpiScope;
 
       switch(type[2]) {
-	  case 'd': /* type == module */
+	  case 'd': /* type == moDule */
 	    scope->base.vpi_type = &vpip_scope_module_rt;
 	    break;
-	  case 'n': /* type == function */
+	  case 'n': /* type == fuNction */
 	    scope->base.vpi_type = &vpip_scope_function_rt;
 	    break;
-	  case 's': /* type == task */
+	  case 's': /* type == taSk */
 	    scope->base.vpi_type = &vpip_scope_task_rt;
 	    break;
-	  case 'r': /* type == fork */
+	  case 'r': /* type == foRk */
 	    scope->base.vpi_type = &vpip_scope_fork_rt;
 	    break;
-	  case 'g': /* type == begin */
+	  case 'g': /* type == beGin */
 	    scope->base.vpi_type = &vpip_scope_begin_rt;
 	    break;
 	  default:
@@ -217,12 +305,15 @@
       } else {
 	    scope->scope = 0x0;
       }
+
+      functor_set_scope(&current_scope->base);
 }
 
 void compile_scope_recall(char*symbol)
 {
       compile_vpi_lookup((vpiHandle*)&current_scope, symbol);
       assert(current_scope);
+      functor_set_scope(&current_scope->base);
 }
 
 struct __vpiScope* vpip_peek_current_scope(void)
#ifndef __vvp_H
#define __vvp_H
/*
 * Copyright (c) 2000 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */
#if !defined(WINNT)
#ident "$Id$"
#endif

int vvp_printf(unsigned int mcd, const char *fmt, ...);
#define VVP_PRINT_INFO    4
#define VVP_PRINT_WARNING 6
#define VVP_PRINT_ERROR   6

/*
** $Log$
*/
#endif // __vvp_H

-- 
Stephan Böttcher                  FAX: +49-4181-925676
Itzenbütteler Straße 130          Tel: +49-4181-32582
21266 Jesteburg                   mailto:stephan@nevis.columbia.edu
Germany                           http://www.nevis.columbia.edu/~stephan