Add a check for one real driver and rework the uwire check.
At the moment we only support one real driver. This patch adds a combined error routine for a uwire or a real net with multiple drivers. We display the top level net in the hierarchy. It also reworks the nexus data_type calculation.
This commit is contained in:
parent
bebdcd5adf
commit
dba157600c
|
|
@ -58,16 +58,30 @@ static ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex)
|
||||||
static ivl_variable_type_t signal_data_type_of_nexus(ivl_nexus_t nex)
|
static ivl_variable_type_t signal_data_type_of_nexus(ivl_nexus_t nex)
|
||||||
{
|
{
|
||||||
unsigned idx;
|
unsigned idx;
|
||||||
|
ivl_variable_type_t out = IVL_VT_NO_TYPE;
|
||||||
|
|
||||||
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
|
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
|
||||||
|
ivl_variable_type_t vtype;
|
||||||
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
|
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
|
||||||
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
|
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
|
||||||
if (sig == 0) continue;
|
if (sig == 0) continue;
|
||||||
|
|
||||||
return ivl_signal_data_type(sig);
|
vtype = ivl_signal_data_type(sig);
|
||||||
|
if (out == IVL_VT_NO_TYPE && vtype == IVL_VT_BOOL) {
|
||||||
|
out = vtype;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (out != IVL_VT_LOGIC && vtype == IVL_VT_LOGIC) {
|
||||||
|
out = vtype;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (vtype == IVL_VT_REAL) {
|
||||||
|
out = vtype;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return IVL_VT_NO_TYPE;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_C4_repeated_constant(char bit_char, unsigned width)
|
static void draw_C4_repeated_constant(char bit_char, unsigned width)
|
||||||
|
|
@ -537,6 +551,70 @@ static char* draw_island_port(ivl_island_t island, int island_input_flag,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine is called to display an error message when a uwire or
|
||||||
|
* wire real has multiple drivers.
|
||||||
|
*/
|
||||||
|
typedef enum mdriver_type_e {
|
||||||
|
MDRV_UWIRE = 0,
|
||||||
|
MDRV_REAL = 1
|
||||||
|
} mdriver_type_t;
|
||||||
|
|
||||||
|
static void display_multi_driver_error(ivl_nexus_t nex, unsigned ndrivers,
|
||||||
|
mdriver_type_t type)
|
||||||
|
{
|
||||||
|
unsigned idx;
|
||||||
|
unsigned scope_len = -1;
|
||||||
|
ivl_signal_t sig = 0;
|
||||||
|
/* Find the signal. */
|
||||||
|
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
|
||||||
|
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
|
||||||
|
ivl_signal_t tsig = ivl_nexus_ptr_sig(ptr);
|
||||||
|
if (tsig != 0) {
|
||||||
|
ivl_scope_t scope;
|
||||||
|
unsigned len;
|
||||||
|
if (ivl_signal_local(tsig)) continue;
|
||||||
|
|
||||||
|
/* If this is not a local signal then find the signal
|
||||||
|
* that has the shortest scope (is the furthest up
|
||||||
|
* the hierarchy). */
|
||||||
|
scope = ivl_signal_scope(tsig);
|
||||||
|
assert(scope);
|
||||||
|
len = strlen(ivl_scope_name(scope));
|
||||||
|
if (len < scope_len) {
|
||||||
|
scope_len = len;
|
||||||
|
sig = tsig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(sig);
|
||||||
|
|
||||||
|
fprintf(stderr, "%s:%u: vvp.tgt error: ",
|
||||||
|
ivl_signal_file(sig), ivl_signal_lineno(sig));
|
||||||
|
switch (type) {
|
||||||
|
case MDRV_UWIRE:
|
||||||
|
if (ivl_signal_type(sig) != IVL_SIT_UWIRE) {
|
||||||
|
fprintf(stderr, "(implicit) ");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "uwire");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MDRV_REAL:
|
||||||
|
assert(ivl_signal_type(sig) == IVL_SIT_TRI);
|
||||||
|
if (ivl_signal_data_type(sig) != IVL_VT_REAL) {
|
||||||
|
fprintf(stderr, "(implicit) ");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "wire real");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);;
|
||||||
|
}
|
||||||
|
fprintf(stderr, " \"%s\" must have a single driver, found (%u).\n",
|
||||||
|
ivl_signal_basename(sig), ndrivers);
|
||||||
|
vvp_errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function draws the input to a net into a string. What that
|
* This function draws the input to a net into a string. What that
|
||||||
* means is that it returns a static string that can be used to
|
* means is that it returns a static string that can be used to
|
||||||
|
|
@ -711,22 +789,7 @@ static void draw_net_input_x(ivl_nexus_t nex,
|
||||||
/* A uwire is a tri with only one driver. */
|
/* A uwire is a tri with only one driver. */
|
||||||
if (res == IVL_SIT_UWIRE) {
|
if (res == IVL_SIT_UWIRE) {
|
||||||
if (ndrivers > 1) {
|
if (ndrivers > 1) {
|
||||||
unsigned uidx;
|
display_multi_driver_error(nex, ndrivers, MDRV_UWIRE);
|
||||||
ivl_signal_t usig = 0;
|
|
||||||
/* Find the uwire signal. */
|
|
||||||
for (uidx = 0 ; uidx < ivl_nexus_ptrs(nex) ; uidx += 1) {
|
|
||||||
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, uidx);
|
|
||||||
usig = ivl_nexus_ptr_sig(ptr);
|
|
||||||
if (usig != 0) break;
|
|
||||||
}
|
|
||||||
assert(usig);
|
|
||||||
|
|
||||||
fprintf(stderr, "%s:%u: vvp.tgt error: uwire \"%s\" must "
|
|
||||||
"have a single driver, found (%u).\n",
|
|
||||||
ivl_signal_file(usig),
|
|
||||||
ivl_signal_lineno(usig),
|
|
||||||
ivl_signal_basename(usig), ndrivers);
|
|
||||||
vvp_errors += 1;
|
|
||||||
}
|
}
|
||||||
res = IVL_SIT_TRI;
|
res = IVL_SIT_TRI;
|
||||||
}
|
}
|
||||||
|
|
@ -757,6 +820,11 @@ static void draw_net_input_x(ivl_nexus_t nex,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We currently only support one driver on real nets. */
|
||||||
|
if (ndrivers > 1 && signal_data_type_of_nexus(nex) == IVL_VT_REAL) {
|
||||||
|
display_multi_driver_error(nex, ndrivers, MDRV_REAL);
|
||||||
|
}
|
||||||
|
|
||||||
level = 0;
|
level = 0;
|
||||||
while (ndrivers) {
|
while (ndrivers) {
|
||||||
unsigned int inst;
|
unsigned int inst;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue