diff --git a/ivl_target.h b/ivl_target.h index f20e4f2b9..9a0cf99ca 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: ivl_target.h,v 1.143 2005/02/19 02:43:38 steve Exp $" +#ident "$Id: ivl_target.h,v 1.144 2005/03/03 04:34:42 steve Exp $" #endif #ifdef __cplusplus @@ -576,6 +576,9 @@ extern unsigned ivl_expr_width(ivl_expr_t net); /* * Memory. + * Memories are declared in Verilog source as 2 dimensional arrays of + * reg bits. This means that they are simple arrays of vectors. The + * vectors in the array are called "words". * * ivl_memory_name (DEPRECATED) * @@ -583,6 +586,13 @@ extern unsigned ivl_expr_width(ivl_expr_t net); * This returns the base name of the memory object. The base name * does not include the name of the scopes that contains the object. * + * ivl_memory_root + * The root of the memory is the value to add to a calculated + * address to get to a canonical (0-based) address. This value is + * used when external code wishes to access a word. All the + * compiled references to the word within the compiled design are + * converted to cannonical form by the compiler. + * * ivl_memory_size * ivl_memory_width * These functions return the dimensions of the memory. The size is @@ -1527,6 +1537,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.144 2005/03/03 04:34:42 steve + * Rearrange how memories are supported as vvp_vector4 arrays. + * * Revision 1.143 2005/02/19 02:43:38 steve * Support shifts and divide. * diff --git a/tgt-stub/Makefile.in b/tgt-stub/Makefile.in index 989b92e6b..a9cf4a77d 100644 --- a/tgt-stub/Makefile.in +++ b/tgt-stub/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.14 2004/12/12 18:15:06 steve Exp $" +#ident "$Id: Makefile.in,v 1.15 2005/03/03 04:34:42 steve Exp $" # # SHELL = /bin/sh @@ -52,7 +52,7 @@ dep: $(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o mv $*.d dep -O = stub.o statement.o +O = stub.o memory.o statement.o ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl diff --git a/tgt-stub/memory.c b/tgt-stub/memory.c new file mode 100644 index 000000000..1676e29d6 --- /dev/null +++ b/tgt-stub/memory.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2000-2005 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 + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * 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: memory.c,v 1.1 2005/03/03 04:34:42 steve Exp $" +#endif + +# include "config.h" +# include "priv.h" +# include + +void show_memory(ivl_memory_t mem) +{ + fprintf(out, " mem [%u] %s [%u] \n", + ivl_memory_width(mem), + ivl_memory_basename(mem), + ivl_memory_size(mem), + ivl_memory_root(mem)); +} diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index f72d20f0d..6a05fa44e 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: stub.c,v 1.111 2005/02/19 02:43:39 steve Exp $" +#ident "$Id: stub.c,v 1.112 2005/03/03 04:34:42 steve Exp $" #endif # include "config.h" @@ -1080,12 +1080,15 @@ static int show_scope(ivl_scope_t net, void*x) for (idx = 0 ; idx < ivl_scope_vars(net) ; idx += 1) show_variable(ivl_scope_var(net, idx)); - for (idx = 0 ; idx < ivl_scope_events(net) ; idx += 1) - show_event(ivl_scope_event(net, idx)); - for (idx = 0 ; idx < ivl_scope_sigs(net) ; idx += 1) show_signal(ivl_scope_sig(net, idx)); + for (idx = 0 ; idx < ivl_scope_mems(net) ; idx += 1) + show_memory(ivl_scope_mem(net, idx)); + + for (idx = 0 ; idx < ivl_scope_events(net) ; idx += 1) + show_event(ivl_scope_event(net, idx)); + for (idx = 0 ; idx < ivl_scope_logs(net) ; idx += 1) show_logic(ivl_scope_log(net, idx)); @@ -1122,6 +1125,9 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.112 2005/03/03 04:34:42 steve + * Rearrange how memories are supported as vvp_vector4 arrays. + * * Revision 1.111 2005/02/19 02:43:39 steve * Support shifts and divide. * diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 9482a8ab5..a6766bd83 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: eval_expr.c,v 1.115 2005/02/15 07:12:55 steve Exp $" +#ident "$Id: eval_expr.c,v 1.116 2005/03/03 04:34:42 steve Exp $" #endif # include "vvp_priv.h" @@ -1467,11 +1467,15 @@ static struct vector_info draw_signal_expr(ivl_expr_t exp, unsigned wid) return res; } +/* + * Draw code to evaluate a memory word index expression and write the + * value into index register 3. This expression converts the run-time + * calculated value to cannonical form that the %load/mv takes. + */ void draw_memory_index_expr(ivl_memory_t mem, ivl_expr_t ae) { int root = ivl_memory_root(mem); unsigned width = ivl_memory_width(mem); - width = (width+3) & ~3; switch (ivl_expr_type(ae)) { case IVL_EX_NUMBER: { @@ -1493,14 +1497,14 @@ void draw_memory_index_expr(ivl_memory_t mem, ivl_expr_t ae) unknown_flag = 1; break; } - fprintf(vvp_out, " %%ix/load 3, %lu;\n", (v-root)*width); + fprintf(vvp_out, " %%ix/load 3, %lu;\n", v-root); fprintf(vvp_out, " %%mov 4, %c, 1;\n", unknown_flag?'1':'0'); break; } case IVL_EX_ULONG: { unsigned v = ivl_expr_uvalue(ae); - fprintf(vvp_out, " %%ix/load 3, %u;\n", (v-root)*width); + fprintf(vvp_out, " %%ix/load 3, %u;\n", v-root); fprintf(vvp_out, " %%mov 4, 0, 1;\n"); break; } @@ -1511,8 +1515,6 @@ void draw_memory_index_expr(ivl_memory_t mem, ivl_expr_t ae) clr_vector(addr); if (root>0) fprintf(vvp_out, " %%ix/sub 3, %u;\n", root); - if (width>1) - fprintf(vvp_out, " %%ix/mul 3, %u;\n", width); break; } } @@ -1523,7 +1525,6 @@ static struct vector_info draw_memory_expr(ivl_expr_t exp, unsigned wid) unsigned swid = ivl_expr_width(exp); ivl_memory_t mem = ivl_expr_memory(exp); struct vector_info res; - unsigned idx; draw_memory_index_expr(mem, ivl_expr_oper1(exp)); @@ -1533,12 +1534,8 @@ static struct vector_info draw_memory_expr(ivl_expr_t exp, unsigned wid) res.base = allocate_vector(wid); res.wid = wid; - for (idx = 0 ; idx < swid ; idx += 1) { - if (idx) - fprintf(vvp_out, " %%ix/add 3, 1;\n"); - fprintf(vvp_out, " %%load/m %u, M_%s;\n", - res.base+idx, vvp_memory_label(mem)); - } + fprintf(vvp_out, " %%load/mv %u, M_%s, %u;\n", + res.base, vvp_memory_label(mem), swid); /* Pad the signal value with zeros. */ if (swid < wid) @@ -2130,6 +2127,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag) /* * $Log: eval_expr.c,v $ + * Revision 1.116 2005/03/03 04:34:42 steve + * Rearrange how memories are supported as vvp_vector4 arrays. + * * Revision 1.115 2005/02/15 07:12:55 steve * Support constant part select writes to l-values, and large part select reads from signals. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 64e8abb74..78976e566 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_process.c,v 1.101 2005/02/15 07:12:55 steve Exp $" +#ident "$Id: vvp_process.c,v 1.102 2005/03/03 04:34:42 steve Exp $" #endif # include "vvp_priv.h" @@ -29,6 +29,7 @@ # include static int show_statement(ivl_statement_t net, ivl_scope_t sscope); +static void draw_eval_expr_into_integer(ivl_expr_t expr, unsigned ix); unsigned local_count = 0; unsigned thread_count = 0; @@ -71,14 +72,12 @@ unsigned bitchar_to_idx(char bit) * nexus. */ -static void set_to_lvariable(ivl_lval_t lval, unsigned idx, +static void set_to_lvariable(ivl_lval_t lval, unsigned bit, unsigned wid) { ivl_signal_t sig = ivl_lval_sig(lval); unsigned part_off = ivl_lval_part_off(lval); - assert(idx == 0); - if (ivl_lval_mux(lval)) { unsigned skip_set = transient_id++; @@ -112,6 +111,8 @@ static void set_to_lvariable(ivl_lval_t lval, unsigned idx, } } +#if 0 +/* OBSOLETE */ static void set_to_memory(ivl_memory_t mem, unsigned idx, unsigned bit) { if (idx) @@ -119,6 +120,20 @@ static void set_to_memory(ivl_memory_t mem, unsigned idx, unsigned bit) fprintf(vvp_out, " %%set/m M_%s, %u;\n", vvp_memory_label(mem), bit); } +#endif + +/* + * This function writes the code to set a vector to a memory word. The + * idx is the thread register that contains the address of the word in + * the memory, and bit is the base of the thread vector. The wid is + * the width of the vector to be written to the word. + */ +static void set_to_memory_word(ivl_memory_t mem, unsigned idx, + unsigned bit, unsigned wid) +{ + fprintf(vvp_out, " %%set/mv M_%s, %u, %u;\n", + vvp_memory_label(mem), bit, wid); +} /* * This generates an assign to a single bit of an lvalue variable. If @@ -173,7 +188,7 @@ static void assign_to_memory(ivl_memory_t mem, unsigned idx, * This function, in addition to setting the value into index 0, sets * bit 4 to 1 if the value is unknown. */ -void draw_eval_expr_into_integer(ivl_expr_t expr, unsigned ix) +static void draw_eval_expr_into_integer(ivl_expr_t expr, unsigned ix) { struct vector_info vec; int word; @@ -226,7 +241,6 @@ static void set_vec_to_lval(ivl_statement_t net, struct vector_info res) for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { unsigned skip_set = transient_id++; unsigned skip_set_flag = 0; - unsigned idx; unsigned bit_limit = wid - cur_rbit; lval = ivl_stmt_lval(net, lidx); @@ -246,25 +260,14 @@ static void set_vec_to_lval(ivl_statement_t net, struct vector_info res) bit_limit = ivl_lval_width(lval); if (mem) { - for (idx = 0 ; idx < bit_limit ; idx += 1) { - unsigned bidx = res.base < 4 - ? res.base - : (res.base+cur_rbit); - set_to_memory(mem, idx, bidx); - cur_rbit += 1; - } -#if 0 - for (idx = bit_limit; idx < ivl_lval_pins(lval); idx += 1) - set_to_memory(mem, idx, 0); -#else - assert(0); -#endif + set_to_memory_word(mem, 3, res.base, res.wid); + } else { unsigned bidx = res.base < 4 ? res.base : (res.base+cur_rbit); - set_to_lvariable(lval, 0, bidx, bit_limit); + set_to_lvariable(lval, bidx, bit_limit); cur_rbit += bit_limit; } @@ -342,6 +345,7 @@ static int show_stmt_assign_vector(ivl_statement_t net) bit_limit = ivl_lval_width(lval); if (mem) { +#if 0 for (idx = 0 ; idx < bit_limit ; idx += 1) { set_to_memory(mem, idx, bitchar_to_idx(bits[cur_rbit])); @@ -352,7 +356,9 @@ static int show_stmt_assign_vector(ivl_statement_t net) for (idx = bit_limit ; idx < ivl_lval_width(lval) ; idx += 1) set_to_memory(mem, idx, 0); - +#else + assert(0); +#endif } else { /* Here we have the case of a blocking @@ -388,7 +394,7 @@ static int show_stmt_assign_vector(ivl_statement_t net) } /* write out the value into the .var. */ - set_to_lvariable(lval, 0, vect.base, vect.wid); + set_to_lvariable(lval, vect.base, vect.wid); clr_vector(vect); } @@ -1560,6 +1566,9 @@ int draw_func_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.102 2005/03/03 04:34:42 steve + * Rearrange how memories are supported as vvp_vector4 arrays. + * * Revision 1.101 2005/02/15 07:12:55 steve * Support constant part select writes to l-values, and large part select reads from signals. * diff --git a/vvp/README.txt b/vvp/README.txt index 16cbce37b..ceaf74160 100644 --- a/vvp/README.txt +++ b/vvp/README.txt @@ -1,7 +1,7 @@ /* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * - * $Id: README.txt,v 1.57 2005/02/07 22:42:42 steve Exp $ + * $Id: README.txt,v 1.58 2005/03/03 04:33:10 steve Exp $ */ VVP SIMULATION ENGINE @@ -289,25 +289,28 @@ functor pointer, though. MEMORY STATEMENTS: +Memories are arrays of words, each word a vvp_vector4_t vector of the +same width. The memory is cannonically addressed as a 1-dimensional +array of words, although indices are stored with the memory for +calculating a canonical address from a multi-dimensional address. + Three types of memory statement perform (1) creation of a memory, (2) connecting a read port to an existing memory, and (3) initializing the memory's contents.