[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(¤t_scope->base);
}
void compile_scope_recall(char*symbol)
{
compile_vpi_lookup((vpiHandle*)¤t_scope, symbol);
assert(current_scope);
+ functor_set_scope(¤t_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