V0.9: Back port fixes for putting modpath delays and delay calculations
This commit is contained in:
parent
bf08fcd5e7
commit
b18aedfa80
59
vvp/delay.cc
59
vvp/delay.cc
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue