Skip to content

Commit

Permalink
Merge pull request #1065 from steveicarus/vvp-undriven-net-initialisa…
Browse files Browse the repository at this point in the history
…tion

vvp undriven net initialisation
  • Loading branch information
steveicarus authored Jan 20, 2024
2 parents 151a14d + fc9fcb0 commit 8f1fcc9
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 23 deletions.
52 changes: 52 additions & 0 deletions ivtest/vpi/br_gh1041.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <vpi_user.h>

static PLI_INT32 start_cb(struct t_cb_data *cb)
{
static struct t_vpi_value val;
vpiHandle wire;

(void)cb; // suppress unused parameter warning

wire = vpi_handle_by_name("test.w4", NULL);
if (wire) {
val.format = vpiIntVal;
val.value.integer = 1;
vpi_put_value(wire, &val, NULL, vpiNoDelay);
} else {
vpi_printf("Failed to get handle for w4\n");
}

wire = vpi_handle_by_name("test.w8", NULL);
if (wire) {
val.format = vpiIntVal;
val.value.integer = 1;
vpi_put_value(wire, &val, NULL, vpiNoDelay);
} else {
vpi_printf("Failed to get handle for w8\n");
}

wire = vpi_handle_by_name("test.wr", NULL);
if (wire) {
val.format = vpiRealVal;
val.value.real = 1.0;
vpi_put_value(wire, &val, NULL, vpiNoDelay);
} else {
vpi_printf("Failed to get handle for wr\n");
}

return 0;
}

static void register_cb(void)
{
struct t_cb_data cbd = {};

cbd.reason = cbStartOfSimulation;
cbd.cb_rtn = start_cb;
vpi_register_cb(&cbd);
}

void (*vlog_startup_routines[])(void) = {
register_cb,
0
};
20 changes: 20 additions & 0 deletions ivtest/vpi/br_gh1041.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module test;
wire w4;
tri0 w8;
wire real wr;

reg failed = 0;

initial begin
#0;
$display("w4 %b w8 %b wr %f", w4, w8, wr);
if (w4 !== 1'b1) failed = 1;
if (w8 !== 1'b1) failed = 1;
if (wr != 1.0) failed = 1;

if (failed)
$display("FAILED");
else
$display("PASSED");
end
endmodule
74 changes: 74 additions & 0 deletions ivtest/vpi/br_gh1041b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <vpi_user.h>

static void step(void);

static vpiHandle w;

static PLI_INT32 tick_cb(struct t_cb_data *cb)
{
static struct t_vpi_value val = { .format = vpiIntVal };
static int idx;

(void)cb;

++idx;
val.value.integer = idx & 1;
vpi_put_value(w, &val, NULL, vpiNoDelay);
step();
return 0;
}

/* Request a callback after a delay. */

static void step(void)
{
static struct t_vpi_time now = { .type = vpiSimTime, .low = 2 };
static struct t_cb_data cbd =
{ .reason = cbAfterDelay, .cb_rtn = tick_cb, .time = &now };

/* Callback after delay. */

vpi_register_cb(&cbd);
}

/* Callback function - simulation is starting. */

static PLI_INT32 start_cb(struct t_cb_data *cb)
{
static struct t_vpi_value val = { .format = vpiIntVal };

(void)cb;

w = vpi_handle_by_name("test.w", NULL);
if (!w)
vpi_printf("No handle!\n");
vpi_printf("Got handle for %s\n", vpi_get_str(vpiFullName, w));
val.value.integer = 0;
vpi_put_value(w, &val, NULL, vpiNoDelay);
step();
return 0;
}

/* VPI initialisation. */

static void start(void)
{
static struct t_vpi_time now = { .type = vpiSimTime };
static struct t_cb_data cbd = { .reason = cbStartOfSimulation,
.time = &now, .cb_rtn = start_cb };

/* At this point VPI objects do not exist,
* so request a callback once they do.
*/

vpi_register_cb(&cbd);
}

/* This is a table of registration functions. This table is the external
* symbol that the VVP simulator looks for when loading this .vpi module.
*/

void (*vlog_startup_routines[])(void) = {
start,
0
};
18 changes: 18 additions & 0 deletions ivtest/vpi/br_gh1041b.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module test(w);
input wire w;
wire a, b;


initial begin
#11 $finish;
end

assign b = 0;

assign a = !w | b;

always @(a) begin
$display($time, ": Wire a is now ", a);
end
endmodule

4 changes: 4 additions & 0 deletions ivtest/vpi_gold/br_gh1041.gold
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Compiling vpi/br_gh1041.c...
Making br_gh1041.vpi from br_gh1041.o...
w4 1 w8 1 wr 1.000000
PASSED
10 changes: 10 additions & 0 deletions ivtest/vpi_gold/br_gh1041b.gold
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Compiling vpi/br_gh1041b.c...
Making br_gh1041b.vpi from br_gh1041b.o...
Got handle for test.w
0: Wire a is now 1
2: Wire a is now 0
4: Wire a is now 1
6: Wire a is now 0
8: Wire a is now 1
10: Wire a is now 0
vpi/br_gh1041b.v:7: $finish called at 11 (1s)
2 changes: 2 additions & 0 deletions ivtest/vpi_regress.list
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ br_gh308 normal br_gh308.c br_gh308.gold
br_gh317 normal br_gh317.c br_gh317.gold
br_gh496 normal,-g2009 br_gh496.c br_gh496.gold
br_gh1037 normal,-g2009 br_gh1037.c br_gh1037.gold
br_gh1041 normal br_gh1041.c br_gh1041.gold
br_gh1041b normal br_gh1041b.c br_gh1041b.gold
br_ml20191013 normal br_ml20191013.c br_ml20191013.gold
by_index normal by_index.c by_index.gold
by_name normal by_name.c by_name.log
Expand Down
8 changes: 5 additions & 3 deletions tgt-vvp/draw_net_input.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2022 Stephen Williams ([email protected])
* Copyright (c) 2001-2024 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
Expand Down Expand Up @@ -651,18 +651,20 @@ static void draw_net_input_x(ivl_nexus_t nex,
nex_data->flags |= nex_flags;

/* If the nexus has no drivers, then send a constant HiZ or
0.0 into the net. */
0.0 into the net. Use a lower case 'c' prefix for the
constant to inform vvp that this is an undriven value. */
if (ndrivers == 0) {
unsigned wid = width_of_nexus(nex);
int pull = (res == IVL_SIT_TRI0) || (res == IVL_SIT_TRI1);
/* For real nets put 0.0. */
if (signal_data_type_of_nexus(nex) == IVL_VT_REAL) {
nex_private = draw_Cr_to_string(0.0);
nex_private[0] = 'c';
} else {
unsigned jdx;
char*tmp = malloc((pull ? 3 : 1) * wid + 5);
nex_private = tmp;
strcpy(tmp, pull ? "C8<" : "C4<");
strcpy(tmp, pull ? "c8<" : "c4<");
tmp += strlen(tmp);
switch (res) {
case IVL_SIT_TRI:
Expand Down
38 changes: 32 additions & 6 deletions vvp/compile.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2021 Stephen Williams ([email protected])
* Copyright (c) 2001-2024 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
Expand Down Expand Up @@ -891,9 +891,20 @@ void compile_vpi_time_precision(long pre)
*
* The real value is sign * (mant ** exp).
*/
static bool crstring_header_test(const char*str)
{
if ((str[0] != 'C') && (str[0] != 'c'))
return false;
if ((str[1] != 'r') || (str[2] != '<'))
return false;

return true;
}

bool crstring_test(const char*str)
{
if (strncmp(str, "Cr<", 3) != 0) return false;
if (!crstring_header_test(str))
return false;
const char*tp = strchr(str, '>');
if (tp == 0) return false;
if (tp[1] != 0) return false;
Expand All @@ -906,6 +917,8 @@ bool crstring_test(const char*str)

double crstring_to_double(const char*label)
{
assert(crstring_header_test(label));

const char*cp = label+3;
assert(*cp == 'm');
cp += 1;
Expand Down Expand Up @@ -956,14 +969,21 @@ void input_connect(vvp_net_t*fdx, unsigned port, char*label)

vvp_vector4_t tmp = c4string_to_vector4(label);

// Inputs that are constants are schedule to execute as
// Inputs that are constants are scheduled to execute as
// soon at the simulation starts. In Verilog, constants
// start propagating when the simulation starts, just
// like any other signal value. But letting the
// scheduler distribute the constant value has the
// additional advantage that the constant is not
// propagated until the network is fully linked.
schedule_set_vector(ifdx, tmp);
// For constants that initialise an undriven net, we
// schedule execution before time 0, to make sure it
// occurs before any sensitive processes are started
// or VPI callbacks are executed.
if (label[0] == 'c')
schedule_init_vector(ifdx, tmp);
else
schedule_set_vector(ifdx, tmp);

free(label);
return;
Expand All @@ -973,7 +993,10 @@ void input_connect(vvp_net_t*fdx, unsigned port, char*label)
if (c8string_test(label)) {

vvp_vector8_t tmp = c8string_to_vector8(label);
schedule_set_vector(ifdx, tmp);
if (label[0] == 'c')
schedule_init_vector(ifdx, tmp);
else
schedule_set_vector(ifdx, tmp);

free(label);
return;
Expand All @@ -985,7 +1008,10 @@ void input_connect(vvp_net_t*fdx, unsigned port, char*label)

double tmp = crstring_to_double(label);

schedule_set_vector(ifdx, tmp);
if (label[0] == 'c')
schedule_init_vector(ifdx, tmp);
else
schedule_set_vector(ifdx, tmp);
free(label);
return;
}
Expand Down
8 changes: 4 additions & 4 deletions vvp/lexor.lex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

%{
/*
* Copyright (c) 2001-2018 Stephen Williams ([email protected])
* Copyright (c) 2001-2024 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
Expand Down Expand Up @@ -263,17 +263,17 @@ static char* strdupnew(char const *str)

/* Handle some specialized constant/literals as symbols. */

"C4<"[01xz]*">" {
[Cc]"4<"[01xz]*">" {
yylval.text = strdup(yytext);
assert(yylval.text);
return T_SYMBOL; }

"C8<"[01234567xz]*">" {
[Cc]"8<"[01234567xz]*">" {
yylval.text = strdup(yytext);
assert(yylval.text);
return T_SYMBOL; }

"Cr<m"[a-f0-9]*"g"[a-f0-9]*">" {
[Cc]"r<m"[a-f0-9]*"g"[a-f0-9]*">" {
yylval.text = strdup(yytext);
assert(yylval.text);
return T_SYMBOL; }
Expand Down
4 changes: 2 additions & 2 deletions vvp/schedule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1147,15 +1147,15 @@ void schedule_simulate(void)
delete cur;
}

sim_started = true;

if (verbose_flag) {
vpi_mcd_printf(1, " ...execute StartOfSim callbacks\n");
}

// Execute start of simulation callbacks
vpiStartOfSim();

sim_started = true;

signals_capture();

if (verbose_flag) {
Expand Down
Loading

0 comments on commit 8f1fcc9

Please sign in to comment.