diff --git a/vvp/Makefile.in b/vvp/Makefile.in index 35750f69d..faae3736a 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -72,7 +72,7 @@ V = vpi_modules.o vpi_callback.o vpi_cobject.o vpi_const.o vpi_darray.o \ vpip_to_dec.o vpip_format.o vvp_vpi.o O = main.o parse.o parse_misc.o lexor.o arith.o array_common.o array.o bufif.o compile.o \ - concat.o dff.o class_type.o enum_type.o extend.o file_line.o npmos.o part.o \ + concat.o dff.o class_type.o enum_type.o extend.o file_line.o latch.o npmos.o part.o \ permaheap.o reduce.o resolv.o \ sfunc.o stop.o \ substitute.o \ diff --git a/vvp/compile.h b/vvp/compile.h index 627eff35d..eda571e5a 100644 --- a/vvp/compile.h +++ b/vvp/compile.h @@ -1,7 +1,7 @@ #ifndef IVL_compile_H #define IVL_compile_H /* - * Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2016 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 @@ -225,6 +225,10 @@ extern void compile_dff_aset(char*label, unsigned width, bool negedge, struct symb_s arg_a, char*asc_value); +extern void compile_latch(char*label, unsigned width, + struct symb_s arg_d, + struct symb_s arg_e); + extern void compile_enum2_type(char*label, long width, bool signed_flag, std::list*names); extern void compile_enum4_type(char*label, long width, bool signed_flag, diff --git a/vvp/latch.cc b/vvp/latch.cc new file mode 100644 index 000000000..acc8a4ece --- /dev/null +++ b/vvp/latch.cc @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2016 Martin Whitaker (icarus@martin-whitaker.me.uk) + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +# include "compile.h" +# include "schedule.h" +# include "latch.h" +# include +# include +# include +# include +# include + +/* We need to ensure an initial output value is propagated. This is + achieved by scheduling an initial value to be sent to port 3. Any + value received on port 3 will propagate an initial value of 'bx. */ + +vvp_latch::vvp_latch(unsigned width) +: en_(BIT4_X), d_(width, BIT4_X) +{ +} + +vvp_latch::~vvp_latch() +{ +} + +void vvp_latch::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit, + vvp_context_t) +{ + vvp_bit4_t tmp; + + switch (port.port()) { + + case 0: // D + d_ = bit; + if (en_ == BIT4_1) + schedule_propagate_vector(port.ptr(), 0, d_); + break; + + case 1: // EN + assert(bit.size() == 1); + tmp = en_; + en_ = bit.value(0); + if (en_ == BIT4_1 && tmp != BIT4_1) + schedule_propagate_vector(port.ptr(), 0, d_); + break; + + case 2: + assert(0); + break; + + case 3: + port.ptr()->send_vec4(vvp_vector4_t(d_.size(), BIT4_X), 0); + break; + } +} + +void compile_latch(char*label, unsigned width, + struct symb_s arg_d, + struct symb_s arg_e) +{ + vvp_net_t*ptr = new vvp_net_t; + vvp_latch*fun = new vvp_latch(width); + + ptr->fun = fun; + define_functor_symbol(label, ptr); + free(label); + input_connect(ptr, 0, arg_d.text); + input_connect(ptr, 1, arg_e.text); + + vvp_vector4_t init_val = vvp_vector4_t(1, BIT4_1); + schedule_init_vector(vvp_net_ptr_t(ptr,3), init_val); +} diff --git a/vvp/latch.h b/vvp/latch.h new file mode 100644 index 000000000..daf396061 --- /dev/null +++ b/vvp/latch.h @@ -0,0 +1,45 @@ +#ifndef IVL_latch_H +#define IVL_latch_H +/* + * Copyright (c) 2016 Martin Whitaker (icarus@martin-whitaker.me.uk) + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +# include "vvp_net.h" + +/* + * The vvp_latch implements an arbitrary width D-type transparent latch. + * The latch enable is a single bit. Ports are: + * + * port-0: D input + * port-1: EN input + */ +class vvp_latch : public vvp_net_fun_t { + + public: + explicit vvp_latch(unsigned width); + ~vvp_latch(); + + void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit, + vvp_context_t); + + private: + vvp_bit4_t en_; + vvp_vector4_t d_; +}; + +#endif /* IVL_latch_H */ diff --git a/vvp/lexor.lex b/vvp/lexor.lex index 87f927623..d7e7d162f 100644 --- a/vvp/lexor.lex +++ b/vvp/lexor.lex @@ -4,7 +4,7 @@ %{ /* - * Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2016 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 @@ -168,6 +168,7 @@ static char* strdupnew(char const *str) ".functor" { return K_FUNCTOR; } ".import" { return K_IMPORT; } ".island" { return K_ISLAND; } +".latch" { return K_LATCH; } ".modpath" { return K_MODPATH; } ".net" { return K_NET; } ".net/2s" { return K_NET_2S; } diff --git a/vvp/parse.y b/vvp/parse.y index 832c53c98..eb207a0a7 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -1,7 +1,7 @@ %{ /* - * Copyright (c) 2001-2015 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2016 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 @@ -86,7 +86,7 @@ static struct __vpiModPath*modpath_dst = 0; %token K_CONCAT K_CONCAT8 K_DEBUG K_DELAY K_DFF_N K_DFF_N_ACLR %token K_DFF_N_ASET K_DFF_P K_DFF_P_ACLR K_DFF_P_ASET %token K_ENUM2 K_ENUM2_S K_ENUM4 K_ENUM4_S K_EVENT K_EVENT_OR -%token K_EXPORT K_EXTEND_S K_FUNCTOR K_IMPORT K_ISLAND K_MODPATH +%token K_EXPORT K_EXTEND_S K_FUNCTOR K_IMPORT K_ISLAND K_LATCH K_MODPATH %token K_NET K_NET_S K_NET_R K_NET_2S K_NET_2U %token K_NET8 K_NET8_2S K_NET8_2U K_NET8_S %token K_PARAM_STR K_PARAM_L K_PARAM_REAL K_PART K_PART_PV @@ -522,6 +522,11 @@ statement | T_LABEL K_DFF_P_ASET T_NUMBER symbol ',' symbol ',' symbol ',' symbol ',' T_SYMBOL ';' { compile_dff_aset($1, $3, false, $4, $6, $8, $10, $12); } + /* LATCH nodes have an output and take 2 inputs. */ + + | T_LABEL K_LATCH T_NUMBER symbol ',' symbol ';' + { compile_latch($1, $3, $4, $6); } + /* The various reduction operator nodes take a single input. */ | T_LABEL K_REDUCE_AND symbol ';'