Rework ivl_file_table_* interface and fix most vvp/examples.

Rework the ivl_file_table_* interface to be more generic and easier
to use. Also all the vvp examples except for memory.vvp have been
fixed to run correctly with the current vvp. Someone with a bit more
experience will need to fix memory.vvp.
This commit is contained in:
Cary R 2008-01-02 10:42:23 -08:00 committed by Stephen Williams
parent c866be421e
commit 07c6e51a58
20 changed files with 186 additions and 138 deletions

View File

@ -48,9 +48,9 @@ ivl_expr_uvalue
ivl_expr_value
ivl_expr_width
ivl_file_table_dump
ivl_file_table_get
ivl_file_table_init
ivl_file_table_index
ivl_file_table_item
ivl_file_table_size
ivl_logic_attr
ivl_logic_attr_cnt

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2007 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2008 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
@ -28,15 +28,6 @@
static StringHeap api_strings;
struct ltstr
{
bool operator()(const char*s1, const char*s2) const
{
return strcmp(s1, s2) < 0;
}
};
static map<const char*, unsigned, ltstr> file_names;
/* THE FOLLOWING ARE FUNCTIONS THAT ARE CALLED FROM THE TARGET. */
extern "C" const char*ivl_design_flag(ivl_design_t des, const char*key)
@ -495,44 +486,67 @@ extern "C" unsigned ivl_expr_width(ivl_expr_t net)
return net->width_;
}
extern "C" void ivl_file_table_dump(FILE*fp)
/*
* ivl_file_table_index puts entries in the map as needed and returns
* the appropriate index.
* ivl_file_table_size returns the number of entries in the table.
* ivl_file_table_item returns the file name for the given index.
*/
struct ltstr
{
assert(fp);
unsigned size = file_names.size();
fprintf(fp, "# The file index is used to find the file name in the "
"following table.\n:file_names %u;\n", size);
/* We want to print the names in index order so convert the map
* to a vector in the correct order. */
vector<const char*> names(size);
map<const char*, unsigned, ltstr>::iterator cur;
for (cur = file_names.begin(); cur != file_names.end(); cur++) {
names[(*cur).second] = (*cur).first;
bool operator()(const char*s1, const char*s2) const
{
return strcmp(s1, s2) < 0;
}
};
static map<const char*, unsigned, ltstr> fn_map;
static vector<const char*> fn_vector;
for (unsigned idx = 0; idx < size; idx++) {
fprintf(fp, " \"%s\";\n", names[idx]);
}
static void ivl_file_table_init()
{
/* The first two index entries do not depend on a real
* file name and are always available. */
fn_vector.push_back("N/A");
fn_map["N/A"] = 0;
fn_vector.push_back("<interactive>");
fn_map["<interactive>"] = 1;
}
extern "C" unsigned ivl_file_table_get(const char*name)
extern "C" const char* ivl_file_table_item(unsigned idx)
{
if (fn_vector.empty()) {
ivl_file_table_init();
}
assert(idx < fn_vector.size());
return fn_vector[idx];
}
extern "C" unsigned ivl_file_table_index(const char*name)
{
if (fn_vector.empty()) {
ivl_file_table_init();
}
if (name == NULL) return 0;
/* The new index is the current map size. This is inserted only
* if the file name is not currently in the map. */
file_names.insert(make_pair(name, file_names.size()));
return file_names[name];
pair<map<const char*, unsigned, ltstr>::iterator, bool> result;
result = fn_map.insert(make_pair(name, fn_vector.size()));
if (result.second) {
fn_vector.push_back(name);
}
return result.first->second;
}
extern "C" void ivl_file_table_init()
extern "C" unsigned ivl_file_table_size()
{
assert(file_names.empty());
if (fn_vector.empty()) {
ivl_file_table_init();
}
/* The first two index entries do not depend on a real file name
* and are always available. */
file_names["N/A"] = 0;
file_names["<interactive>"] = 1;
return fn_vector.size();
}
extern "C" const char* ivl_logic_attr(ivl_net_logic_t net, const char*key)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2007 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2008 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
@ -291,7 +291,7 @@ void draw_vpi_task_call(ivl_statement_t tnet)
{
char call_string[1024];
sprintf(call_string, " %%vpi_call %u %u \"%s\"",
ivl_file_table_get(ivl_stmt_file(tnet)),
ivl_file_table_index(ivl_stmt_file(tnet)),
ivl_stmt_lineno(tnet), ivl_stmt_name(tnet));
draw_vpi_taskfunc_args(call_string, tnet, 0);
}
@ -304,7 +304,7 @@ struct vector_info draw_vpi_func_call(ivl_expr_t fnet, unsigned wid)
res.base = allocate_vector(wid);
res.wid = wid;
sprintf(call_string, " %%vpi_func %u %u \"%s\", %u, %u",
ivl_file_table_get(ivl_expr_file(fnet)),
ivl_file_table_index(ivl_expr_file(fnet)),
ivl_expr_lineno(fnet), ivl_expr_name(fnet), res.base, res.wid);
draw_vpi_taskfunc_args(call_string, 0, fnet);
@ -318,7 +318,7 @@ int draw_vpi_rfunc_call(ivl_expr_t fnet)
int res = allocate_word();
sprintf(call_string, " %%vpi_func/r %u %u \"%s\", %d",
ivl_file_table_get(ivl_expr_file(fnet)),
ivl_file_table_index(ivl_expr_file(fnet)),
ivl_expr_lineno(fnet), ivl_expr_name(fnet), res);
draw_vpi_taskfunc_args(call_string, 0, fnet);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2007 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2008 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
@ -2088,7 +2088,7 @@ static struct vector_info draw_sfunc_expr(ivl_expr_t exp, unsigned wid)
res.base = allocate_vector(wid);
res.wid = wid;
fprintf(vvp_out, " %%vpi_func %u %u \"%s\", %u, %u;\n",
ivl_file_table_get(ivl_expr_file(exp)),
ivl_file_table_index(ivl_expr_file(exp)),
ivl_expr_lineno(exp), ivl_expr_name(exp),
res.base, res.wid);
return res;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2007 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2008 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
@ -211,7 +211,7 @@ static int draw_sfunc_real(ivl_expr_t exp)
if (ivl_expr_parms(exp) == 0) {
res = allocate_word();
fprintf(vvp_out, " %%vpi_func/r %u %u \"%s\", %d;\n",
ivl_file_table_get(ivl_expr_file(exp)),
ivl_file_table_index(ivl_expr_file(exp)),
ivl_expr_lineno(exp), ivl_expr_name(exp), res);
} else {

View File

@ -79,9 +79,6 @@ int target_design(ivl_design_t des)
return -1;
}
/* Initialize the file name table. */
ivl_file_table_init();
draw_execute_header(des);
{ int pre = ivl_design_time_precision(des);
@ -106,7 +103,13 @@ int target_design(ivl_design_t des)
rc = ivl_design_process(des, draw_process, 0);
/* Dump the file name table. */
ivl_file_table_dump(vvp_out);
unsigned size = ivl_file_table_size();
fprintf(vvp_out, "# The file index is used to find the file name in "
"the following table.\n:file_names %u;\n", size);
unsigned idx;
for (idx = 0; idx < size; idx++) {
fprintf(vvp_out, " \"%s\";\n", ivl_file_table_item(idx));
}
fclose(vvp_out);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2007 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2008 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
@ -1331,7 +1331,7 @@ static int show_system_task_call(ivl_statement_t net)
if (parm_count == 0) {
fprintf(vvp_out, " %%vpi_call %u %u \"%s\";\n",
ivl_file_table_get(ivl_stmt_file(net)),
ivl_file_table_index(ivl_stmt_file(net)),
ivl_stmt_lineno(net), ivl_stmt_name(net));
clear_expression_lookaside();
return 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2005 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2008 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
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_scope.c,v 1.160 2007/04/12 04:40:37 steve Exp $"
#endif
# include "vvp_priv.h"
#ifdef HAVE_MALLOC_H
@ -1959,7 +1956,7 @@ static void draw_lpm_sfunc(ivl_lpm_t net)
{
unsigned idx;
fprintf(vvp_out, "L_%p .sfunc %u %u \"%s\"", net,
ivl_file_table_get(ivl_lpm_file(net)), ivl_lpm_lineno(net),
ivl_file_table_index(ivl_lpm_file(net)), ivl_lpm_lineno(net),
ivl_lpm_string(net));
/* Print the function type descriptor string. */

View File

@ -12,7 +12,7 @@ main .scope module, "main" "main";
; The bit range is given for the purposes of VPI access. The range
; corresponds to the declaration "reg [7:0] test", so leads to an 8
; bit wide vector.
test .var "test", 7, 0;
test .var "test", 7 0;
; The %assign/v0 opcode assigns a vector to the .var at the label,
; with the given delay. The width of the vector from index register0.
@ -20,22 +20,25 @@ test .var "test", 7, 0;
T0 %ix/load 0, 8 ; Set the width of the vector to 8.
%assign/v0 test, 2, 0 ;
%delay 3;
%vpi_call "$display", "test = %b", test;
%delay 3, 0;
%vpi_call 0 0 "$display", "test = %b", test;
%assign/v0 test, 2, 1 ;
%delay 1;
%vpi_call "$display", "test = %b", test;
%delay 2;
%vpi_call "$display", "test = %b", test;
%delay 1, 0;
%vpi_call 0 0 "$display", "test = %b", test;
%delay 2, 0;
%vpi_call 0 0 "$display", "test = %b", test;
%assign/v0 test, 2, 2 ;
%delay 3;
%vpi_call "$display", "test = %b", test;
%delay 3, 0;
%vpi_call 0 0 "$display", "test = %b", test;
%assign/v0 test, 2, 3 ;
%delay 3;
%vpi_call "$display", "test = %b", test;
%delay 3, 0;
%vpi_call 0 0 "$display", "test = %b", test;
%end;
.thread T0;
:file_names 2;
"N/A";
"<interactive>";

View File

@ -1,6 +1,6 @@
:vpi_module "system";
; Copyright (c) 2001 Stephen Williams (steve@icarus.com)
; Copyright (c) 2001-2008 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
@ -36,18 +36,21 @@
; properly. This is a very trivial functor propagation that is initiated
; by the %set instruction.
main .scope "main";
main .scope module, "main";
V_main.a .var "a", 0, 0;
V_main.b .net "b", 0, 0, V_main.a;
V_main.a .var "a", 0 0;
V_main.b .net "b", 0 0, V_main.a;
code
%set V_main.a, 0;
%delay 1;
%vpi_call "$display", "a=%b, b=%b", V_main.a, V_main.b;
%set V_main.a, 1;
%delay 1;
%vpi_call "$display", "a=%b, b=%b", V_main.a, V_main.b;
%set/v V_main.a, 0, 1;
%delay 1, 0;
%vpi_call 0 0 "$display", "a=%b, b=%b", V_main.a, V_main.b;
%set/v V_main.a, 1, 1;
%delay 1, 0;
%vpi_call 0 0 "$display", "a=%b, b=%b", V_main.a, V_main.b;
%end;
.thread code;
:file_names 2;
"N/A";
"<interactive>";

View File

@ -1,6 +1,6 @@
:vpi_module "system";
; Copyright (c) 2001 Stephen Williams (steve@icarus.com)
; Copyright (c) 2001-2008 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
@ -42,8 +42,8 @@
; endmodule
;
S_main .scope "main";
S_test .scope "test", S_main;
S_main .scope module, "main";
S_test .scope task, "test", S_main;
; This code in the implementation of the thread that goes into the
@ -51,9 +51,9 @@ S_test .scope "test", S_main;
; job and prints a failure.
.scope S_test;
T_0/1 ;
%delay 5;
%vpi_call "$display", "FAILED -- thread wasn't disabled";
%vpi_call "$finish";
%delay 5, 0;
%vpi_call 0 0 "$display", "FAILED -- thread wasn't disabled";
%vpi_call 0 0 "$finish";
%end;
; This is the main thread. Fork the thread under test, delay for a
@ -63,12 +63,15 @@ T_0/1 ;
.scope S_main;
T_0 ;
%fork T_0/1, S_test;
%delay 1;
%delay 1, 0;
%disable S_test ; This is the statement that I'm testing.
%join;
%vpi_call "$display", "PASSED";
%vpi_call 0 0 "$display", "PASSED";
%end;
.thread T_0;
:file_names 2;
"N/A";
"<interactive>";

View File

@ -1,6 +1,6 @@
:vpi_module "system";
; Copyright (c) 2001 Stephen Williams (steve@icarus.com)
; Copyright (c) 2001-2008 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
@ -34,19 +34,22 @@
; endmodule
;
main .scope "main";
main .scope module, "main";
V_main.a .var "a", 0, 0;
V_main.a .var "a", 0 0;
V_main.b .event posedge, V_main.a;
code
%set V_main.a, 0;
%delay 1;
%set V_main.a, 1;
%set/v V_main.a, 0, 1;
%delay 1, 0;
%set/v V_main.a, 1, 1;
%end;
.thread code;
loop %wait V_main.b;
%vpi_call "$display", "Got a posedge.";
%vpi_call 0 0 "$display", "Got a posedge.";
%jmp loop;
.thread loop;
:file_names 2;
"N/A";
"<interactive>";

View File

@ -1,6 +1,6 @@
:vpi_module "system";
; Copyright (c) 2001 Stephen Williams (steve@icarus.com)
; Copyright (c) 2001-2008 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
@ -19,15 +19,18 @@
; This sample demonstrates the behavior of %fork and %join.
S_main .scope "main";
S_main .scope module, "main";
child %vpi_call "$display", "I'm a child";
child %vpi_call 0 0 "$display", "I'm a child";
%end;
parent %fork child, S_main;
%vpi_call "$display", "I'm a parent";
%vpi_call 0 0 "$display", "I'm a parent";
%join;
%vpi_call "$display", "reaped";
%vpi_call 0 0 "$display", "reaped";
%end;
.thread parent;
:file_names 2;
"N/A";
"<interactive>";

View File

@ -1,6 +1,6 @@
:vpi_module "system";
; Copyright (c) 2001 Stephen Williams (steve@icarus.com)
; Copyright (c) 2001-2008 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
@ -31,6 +31,9 @@
main .scope module, "main";
code
%vpi_call "$display", "Hello, World.";
%vpi_call 0 0 "$display", "Hello, World.";
%end;
.thread code;
:file_names 2;
"N/A";
"<interactive>";

View File

@ -1,6 +1,6 @@
:vpi_module "system";
; Copyright (c) 2001 Stephen Williams (steve@icarus.com)
; Copyright (c) 2001-2008 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
@ -34,18 +34,19 @@
; notice that the Vmain.value1 label is automatically converted to a
; vpiHandle by the compiler when the %vpi_call statement is compiled.
Smain .scope "main";
Smain .scope module, "main";
Vmain.value1 .var "value1", 3, 0;
Vmain.value1 .var "value1", 3 0;
T00 %set Vmain.value1[0], 1;
%set Vmain.value1[1], 0;
%set Vmain.value1[2], 0;
%set Vmain.value1[3], 0;
T00 %movi 8, 1, 4; Load a 4 bit value (1) into location 8.
%set/v Vmain.value1, 8, 4;
%vpi_call "$display", "value = %b", Vmain.value1;
%vpi_call 0 0 "$display", "value = %b", Vmain.value1;
%end;
.thread T00;
:file_names 2;
"N/A";
"<interactive>";

View File

@ -1,6 +1,13 @@
:vpi_module "system";
; Copyright (c) 2001 Stephen Williams (steve@icarus.com)
; IMPORTANT NOTE:
;
; This example uses constructs that are no longer supported. It will
; not run with the current vvp implementation!
; Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com)
; Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
;
; This source code is free software; you can redistribute it

View File

@ -12,7 +12,7 @@ main .scope module, "main" "main";
; The bit range is given for the purposes of VPI access. The range
; corresponds to the declaration "reg [7:0] test", so leads to an 8
; bit wide vector.
test .var "test", 7, 0;
test .var "test", 7 0;
; The %set/v opcode writes a value to the target .var vector. The
; first operand is the label of the .var object. The second and
@ -20,16 +20,19 @@ test .var "test", 7, 0;
; be made into the vector to write.
T0 %set/v test, 0, 8 ;
%vpi_call "$display", "test = %b", test;
%vpi_call 0 0 "$display", "test = %b", test;
%set/v test, 1, 8 ;
%vpi_call "$display", "test = %b", test;
%vpi_call 0 0 "$display", "test = %b", test;
%set/v test, 2, 8 ;
%vpi_call "$display", "test = %b", test;
%vpi_call 0 0 "$display", "test = %b", test;
%set/v test, 3, 8 ;
%vpi_call "$display", "test = %b", test;
%vpi_call 0 0 "$display", "test = %b", test;
%end;
.thread T0;
:file_names 2;
"N/A";
"<interactive>";

View File

@ -1,6 +1,6 @@
:vpi_module "system";
; Copyright (c) 2001 Stephen Williams (steve@icarus.com)
; Copyright (c) 2001-2008 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
@ -23,8 +23,8 @@
; module main;
; reg [3:0] A, B;
; wire [3:0] Q = A + B;
:
: initial begin
;
; initial begin
; A = 2;
; B = 3;
; #1 $display("%b %b = %b", A, B, Q);
@ -36,26 +36,25 @@
; passed to the statement.
S_main .scope "main";
S_main .scope module, "main";
A .var "A", 3, 0;
B .var "B", 3, 0;
A .var "A", 3 0;
B .var "B", 3 0;
Q .net "Q", 3 0, add;
add .arith/sum 4, A[0], A[1], A[2], A[3], B[0], B[1], B[2], B[3];
add .arith/sum 4, A, B;
Q .net "Q", 3, 0, add[0], add[1], add[2], add[3];
start %set A[0], 0;
%set A[1], 1;
%set A[2], 0;
%set A[3], 0;
%set B[0], 1;
%set B[1], 1;
%set B[2], 0;
%set B[3], 0;
start %movi 8, 2, 4; Load a 4 bit value (2) into location 8
%set/v A, 8, 4;
%movi 8, 3, 4; Ditto except the value is 3
%set/v B, 8, 4;
%delay 1;
%delay 1, 0;
%vpi_call "$display", "%b + %b == %b", A, B, Q;
%vpi_call 0 0 "$display", "%b + %b == %b", A, B, Q;
%end;
.thread start;
:file_names 2;
"N/A";
"<interactive>";

View File

@ -1,6 +1,6 @@
:vpi_module "system";
; Copyright (c) 2001 Stephen Williams (steve@icarus.com)
; Copyright (c) 2001-2008 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
@ -28,10 +28,13 @@
; This tests that the special $time symbol references the vpiHandle for
; the system time.
main .scope "main";
main .scope module, "main";
code
%delay 45;
%vpi_call "$display", "Hello, Clock: ", $time;
%delay 45, 0;
%vpi_call 0 0 "$display", "Hello, Clock: ", $time;
%end;
.thread code;
:file_names 2;
"N/A";
"<interactive>";

View File

@ -1,7 +1,10 @@
:vpi_module "system";
main .scope "main";
main .scope module, "main";
T0 %vpi_call "$display", "Display the number: %b", 5'b0zx1;
T0 %vpi_call 0 0 "$display", "Display the number: %b", 5'b0zx1;
%end;
.thread T0;
:file_names 2;
"N/A";
"<interactive>";