V0.9: Back port fixes for putting modpath delays and delay calculations

This commit is contained in:
Cary R 2014-10-27 14:22:49 -07:00
parent bf08fcd5e7
commit b18aedfa80
2 changed files with 56 additions and 29 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005-2011 Stephen Williams <steve@icarus.com>
* Copyright (c) 2005-2014 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
@ -505,10 +505,10 @@ static vvp_time64_t delay_from_edge(vvp_bit4_t a, vvp_bit4_t b,
{
typedef delay_edge_t bit4_table4[4];
const static bit4_table4 edge_table[4] = {
{ DELAY_EDGE_01, DELAY_EDGE_01, DELAY_EDGE_0x, DELAY_EDGE_0z },
{ DELAY_EDGE_10, DELAY_EDGE_10, DELAY_EDGE_1x, DELAY_EDGE_1z },
{ DELAY_EDGE_x0, DELAY_EDGE_x1, DELAY_EDGE_x0, DELAY_EDGE_xz },
{ DELAY_EDGE_z0, DELAY_EDGE_z1, DELAY_EDGE_zx, DELAY_EDGE_z0 }
{ DELAY_EDGE_01, DELAY_EDGE_01, DELAY_EDGE_0z, DELAY_EDGE_0x },
{ DELAY_EDGE_10, DELAY_EDGE_10, DELAY_EDGE_1z, DELAY_EDGE_1x },
{ DELAY_EDGE_z0, DELAY_EDGE_z1, DELAY_EDGE_z0, DELAY_EDGE_zx },
{ DELAY_EDGE_x0, DELAY_EDGE_x1, DELAY_EDGE_xz, DELAY_EDGE_x0 }
};
return array[ edge_table[a][b] ];
@ -818,14 +818,27 @@ static void modpath_src_put_delays (vpiHandle ref, p_vpi_delay delays)
assert( fun );
typedef unsigned char map_array_t[12];
static const map_array_t map_2 = {0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0};
// Only the first six entries are used for the less than twelve maps.
static const map_array_t map_1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const map_array_t map_2 = {0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0};
static const map_array_t map_3 = {0, 1, 2, 0, 2, 1, 0, 0, 0, 0, 0, 0};
static const map_array_t map_6 = {0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0};
static const map_array_t map12 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
const map_array_t*use_map = 0;
switch (delays->no_of_delays) {
case 1:
use_map = &map_1;
break;
case 2:
use_map = &map_2;
break;
case 3:
use_map = &map_3;
break;
case 6:
use_map = &map_6;
break;
case 12:
use_map = &map12;
break;
@ -845,22 +858,26 @@ static void modpath_src_put_delays (vpiHandle ref, p_vpi_delay delays)
}
}
/* Now clean up any to-from-x delays to me the min/max based on
the rules for selecting X delays. This only needs to happen
if the X delays are not already explicitly given. */
/* Now define the to-from-x delays if needed. */
if (delays->no_of_delays <= 6) {
vvp_time64_t t_max = tmp[0];
vvp_time64_t t_min = tmp[1];
for (idx = 1 ; idx < delays->no_of_delays ; idx += 1) {
if (tmp[idx] > t_max) t_max = tmp[idx];
if (tmp[idx] < t_min) t_min = tmp[idx];
}
tmp[DELAY_EDGE_0x] = t_min;
tmp[DELAY_EDGE_x1] = t_max;
tmp[DELAY_EDGE_1x] = t_min;
tmp[DELAY_EDGE_x0] = t_max;
tmp[DELAY_EDGE_xz] = t_max;
tmp[DELAY_EDGE_zx] = t_min;
/* 0->x is the minimum of 0->z and 0->1. */
tmp[DELAY_EDGE_0x] = tmp[DELAY_EDGE_0z] < tmp[DELAY_EDGE_01] ?
tmp[DELAY_EDGE_0z] : tmp[DELAY_EDGE_01];
/* x->1 is the maximum of z->1 and 0->1. */
tmp[DELAY_EDGE_x1] = tmp[DELAY_EDGE_z1] > tmp[DELAY_EDGE_01] ?
tmp[DELAY_EDGE_z1] : tmp[DELAY_EDGE_01];
/* 1->x is the minimum of 1->z and 1->0. */
tmp[DELAY_EDGE_1x] = tmp[DELAY_EDGE_1z] < tmp[DELAY_EDGE_10] ?
tmp[DELAY_EDGE_1z] : tmp[DELAY_EDGE_10];
/* x->0 is the maximum of z->0 and 1->0. */
tmp[DELAY_EDGE_x0] = tmp[DELAY_EDGE_z0] > tmp[DELAY_EDGE_10] ?
tmp[DELAY_EDGE_z0] : tmp[DELAY_EDGE_10];
/* x->z is the maximum of 1->z and 0->z. */
tmp[DELAY_EDGE_xz] = tmp[DELAY_EDGE_1z] > tmp[DELAY_EDGE_0z] ?
tmp[DELAY_EDGE_1z] : tmp[DELAY_EDGE_0z];
/* z->x is the minimum of z->1 and z->0. */
tmp[DELAY_EDGE_zx] = tmp[DELAY_EDGE_z1] < tmp[DELAY_EDGE_z0] ?
tmp[DELAY_EDGE_z1] : tmp[DELAY_EDGE_z0];
}
fun->put_delay12(tmp);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2014 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
@ -67,16 +67,26 @@ double vpip_time_to_scaled_real(vvp_time64_t ti, struct __vpiScope*scope)
vvp_time64_t vpip_scaled_real_to_time64(double val, struct __vpiScope*scope)
{
int units;
if (scope)
units = scope->time_units;
else
units = vpi_time_precision;
int shift = 0;
if (scope) shift = scope->time_units - scope->time_precision;
assert(shift >= 0);
double scale = pow(10.0L, units - vpi_time_precision);
assert(val >= 0);
// Scale to the local precision and then round away from zero.
double scale = pow(10.0L, shift);
val *= scale;
return (vvp_time64_t) val;
vvp_time64_t delay = (vvp_time64_t) (val + 0.5);
// If needed now scale the value to the simulator precision.
if (scope) {
shift = scope->time_precision - vpi_time_precision;
assert(shift >= 0);
for (int lp = 0; lp < shift; lp += 1) delay *= 10;
}
return delay;
}
static int timevar_time_get(int code, vpiHandle ref)