From 97d2389cb09b8a5be8838c7ec2c4cc1321c25d13 Mon Sep 17 00:00:00 2001 From: Jared Casper Date: Sat, 20 Nov 2010 18:25:47 -0800 Subject: [PATCH 1/6] Allow SystemVerilog [size] dimension for unpacked arrays. IEEE 1800-2005/9 says "each fixed-size dimension shall be represented by an address range, such as [1:1024], or a single positive number to specify the size of a fixed-size unpacked array, as in C. In other words, [size] becomes the same as [0:size-1]." This patch implements that translation in the parser. It issues a warning when doing so when the generation flag is less than 2005-sv. --- parse.y | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/parse.y b/parse.y index a6bc54cf2..7bc27cee2 100644 --- a/parse.y +++ b/parse.y @@ -3463,6 +3463,19 @@ dimensions tmp->push_back(index); $$ = tmp; } + | '[' expression ']' + { if (generation_flag < GN_VER2005_SV) { + warn_count += 1; + cerr << @2 << ": warning: Use of SystemVerilog [size] dimension. " + << "Use at least -g2005-sv to remove this warning." << endl; + } + list *tmp = new list; + index_component_t index; + index.msb = new PENumber(new verinum((uint64_t)0, integer_width)); + index.lsb = new PEBinary('-', $2, new PENumber(new verinum((uint64_t)1, integer_width))); + tmp->push_back(index); + $$ = tmp; + } | dimensions '[' expression ':' expression ']' { list *tmp = $1; index_component_t index; @@ -3471,6 +3484,19 @@ dimensions tmp->push_back(index); $$ = tmp; } + | dimensions '[' expression ']' + { if (generation_flag < GN_VER2005_SV) { + warn_count += 1; + cerr << @2 << ": warning: Use of SystemVerilog [size] dimension. " + << "Use at least -g2005-sv to remove this warning." << endl; + } + list *tmp = $1; + index_component_t index; + index.msb = new PENumber(new verinum((uint64_t)0, integer_width)); + index.lsb = new PEBinary('-', $3, new PENumber(new verinum((uint64_t)1, integer_width))); + tmp->push_back(index); + $$ = tmp; + } /* This is used to express the return type of a function. */ function_range_or_type_opt From b6ff4039b1b58c3e5dffec04630dbd562a5b58e0 Mon Sep 17 00:00:00 2001 From: Jared Casper Date: Sun, 23 Jan 2011 16:21:54 -0800 Subject: [PATCH 2/6] SystemVerilog 'N bit vectors. Adds a is_single_ flag to the verinum class to indicate it came from a 'N bit vector and needs to be handled accordingly. --- elab_expr.cc | 2 +- lexor.lex | 19 +++++++++++++++++-- verinum.cc | 27 +++++++++++++++------------ verinum.h | 5 +++++ 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 4fe9dadf9..b2f741d4d 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -3166,7 +3166,7 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode) min_width_ = 1; signed_flag_ = value_->has_sign(); - if ((mode < LOSSLESS) && !value_->has_len()) + if ((mode < LOSSLESS) && !value_->has_len() && !value_->is_single()) mode = LOSSLESS; return expr_width_; diff --git a/lexor.lex b/lexor.lex index 48ad58070..f254245ac 100644 --- a/lexor.lex +++ b/lexor.lex @@ -329,6 +329,14 @@ TU [munpf] return BASED_NUMBER; } \'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext); return BASED_NUMBER; } +\'[01xzXZ] { + if (generation_flag < GN_VER2005_SV) { + cerr << yylloc.text << ":" << yylloc.first_line << ": warning: " + << "Using SystemVerilog 'N bit vector. Use at least " + << "-g2005-sv to remove this warning." << endl; + } + yylval.number = make_unsized_binary(yytext); + return BASED_NUMBER; } [0-9][0-9_]* { yylval.number = make_unsized_dec(yytext); @@ -684,6 +692,7 @@ void lex_end_table() verinum*make_unsized_binary(const char*txt) { bool sign_flag = false; + bool single_flag = false; const char*ptr = txt; assert(*ptr == '\''); ptr += 1; @@ -693,8 +702,13 @@ verinum*make_unsized_binary(const char*txt) ptr += 1; } - assert(tolower(*ptr) == 'b'); - ptr += 1; + assert((tolower(*ptr) == 'b') || (generation_flag >= GN_VER2005_SV)); + if (tolower(*ptr) == 'b') { + ptr += 1; + } else { + assert(sign_flag == false); + single_flag = true; + } while (*ptr && ((*ptr == ' ') || (*ptr == '\t'))) ptr += 1; @@ -734,6 +748,7 @@ verinum*make_unsized_binary(const char*txt) verinum*out = new verinum(bits, size, false); out->has_sign(sign_flag); + out->is_single(single_flag); delete[]bits; return out; } diff --git a/verinum.cc b/verinum.cc index 1b576c224..0c4629e4a 100644 --- a/verinum.cc +++ b/verinum.cc @@ -43,12 +43,12 @@ extern "C" long int lround(double x) static verinum::V add_with_carry(verinum::V l, verinum::V r, verinum::V&c); verinum::verinum() -: bits_(0), nbits_(0), has_len_(false), has_sign_(false), string_flag_(false) +: bits_(0), nbits_(0), has_len_(false), has_sign_(false), is_single_(false), string_flag_(false) { } verinum::verinum(const V*bits, unsigned nbits, bool has_len__) -: has_len_(has_len__), has_sign_(false), string_flag_(false) +: has_len_(has_len__), has_sign_(false), is_single_(false), string_flag_(false) { nbits_ = nbits; bits_ = new V [nbits]; @@ -111,7 +111,7 @@ static string process_verilog_string_quotes(const string&str) } verinum::verinum(const string&s) -: has_len_(true), has_sign_(false), string_flag_(true) +: has_len_(true), has_sign_(false), is_single_(false), string_flag_(true) { string str = process_verilog_string_quotes(s); nbits_ = str.length() * 8; @@ -149,7 +149,7 @@ verinum::verinum(const string&s) } verinum::verinum(verinum::V val, unsigned n, bool h) -: has_len_(h), has_sign_(false), string_flag_(false) +: has_len_(h), has_sign_(false), is_single_(false), string_flag_(false) { nbits_ = n; bits_ = new V[nbits_]; @@ -158,7 +158,7 @@ verinum::verinum(verinum::V val, unsigned n, bool h) } verinum::verinum(uint64_t val, unsigned n) -: has_len_(true), has_sign_(false), string_flag_(false) +: has_len_(true), has_sign_(false), is_single_(false), string_flag_(false) { nbits_ = n; bits_ = new V[nbits_]; @@ -171,7 +171,7 @@ verinum::verinum(uint64_t val, unsigned n) /* The second argument is not used! It is there to make this * constructor unique. */ verinum::verinum(double val, bool) -: has_len_(false), has_sign_(true), string_flag_(false) +: has_len_(false), has_sign_(true), is_single_(false), string_flag_(false) { bool is_neg = false; double fraction; @@ -281,6 +281,7 @@ verinum::verinum(const verinum&that) bits_ = new V[nbits_]; has_len_ = that.has_len_; has_sign_ = that.has_sign_; + is_single_ = that.is_single_; for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) bits_[idx] = that.bits_[idx]; } @@ -292,6 +293,7 @@ verinum::verinum(const verinum&that, unsigned nbits) bits_ = new V[nbits_]; has_len_ = true; has_sign_ = that.has_sign_; + is_single_ = false; unsigned copy = nbits; if (copy > that.nbits_) @@ -300,7 +302,7 @@ verinum::verinum(const verinum&that, unsigned nbits) bits_[idx] = that.bits_[idx]; if (copy < nbits_) { - if (has_sign_) { + if (has_sign_ || that.is_single_) { for (unsigned idx = copy ; idx < nbits_ ; idx += 1) bits_[idx] = bits_[idx-1]; } else { @@ -311,7 +313,7 @@ verinum::verinum(const verinum&that, unsigned nbits) } verinum::verinum(int64_t that) -: has_len_(false), has_sign_(true), string_flag_(false) +: has_len_(false), has_sign_(true), is_single_(false), string_flag_(false) { int64_t tmp; @@ -348,6 +350,7 @@ verinum& verinum::operator= (const verinum&that) has_len_ = that.has_len_; has_sign_ = that.has_sign_; + is_single_ = that.is_single_; string_flag_ = that.string_flag_; return *this; } @@ -570,9 +573,9 @@ verinum pad_to_width(const verinum&that, unsigned width) } verinum::V pad = that[that.len()-1]; - if (pad==verinum::V1 && !that.has_sign()) + if (pad==verinum::V1 && !that.has_sign() && !that.is_single()) pad = verinum::V0; - if (that.has_len() && !that.has_sign()) { + if (that.has_len() && !that.has_sign() && !that.is_single()) { if (pad==verinum::Vx) pad = verinum::V0; if (pad==verinum::Vz) @@ -606,9 +609,9 @@ verinum cast_to_width(const verinum&that, unsigned width) } verinum::V pad = that[that.len()-1]; - if (pad==verinum::V1 && !that.has_sign()) + if (pad==verinum::V1 && !that.has_sign() && !that.is_single()) pad = verinum::V0; - if (that.has_len() && !that.has_sign()) { + if (that.has_len() && !that.has_sign() && !that.is_single()) { if (pad==verinum::Vx) pad = verinum::V0; if (pad==verinum::Vz) diff --git a/verinum.h b/verinum.h index acab1d673..24ea075d7 100644 --- a/verinum.h +++ b/verinum.h @@ -70,6 +70,10 @@ class verinum { bool has_sign(bool flag) { has_sign_ = flag; return has_sign_; } bool has_sign() const { return has_sign_; } + // A number "is single" if it comes from a SystemVerilog 'N bit vector + bool is_single(bool flag) { is_single_ = flag; return is_single_; } + bool is_single() const { return is_single_; } + // A number is "defined" if there are no x or z bits in its value. bool is_defined() const; bool is_zero() const; @@ -103,6 +107,7 @@ class verinum { unsigned nbits_; bool has_len_; bool has_sign_; + bool is_single_; // These are some convenience flags that help us do a better // job of pretty-printing values. From 8c7365fb368422edae610f2ef6c8f4eedfa27d3e Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Fri, 25 Mar 2011 18:55:59 +0000 Subject: [PATCH 3/6] Fix for over-enthusiastic pruning of expressions. The minimum width for expressions containing a literal number was being incorrectly calculated, leading to loss of information in some circumstances. --- elab_expr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elab_expr.cc b/elab_expr.cc index b2f741d4d..24a61469b 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -3163,7 +3163,7 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode) { expr_type_ = IVL_VT_LOGIC; expr_width_ = value_->len(); - min_width_ = 1; + min_width_ = expr_width_; signed_flag_ = value_->has_sign(); if ((mode < LOSSLESS) && !value_->has_len() && !value_->is_single()) From f057ce08599784a45737ce4fa1a65744627686c2 Mon Sep 17 00:00:00 2001 From: Pawel Szostek Date: Mon, 28 Mar 2011 18:59:04 +0200 Subject: [PATCH 4/6] Basic VHDL configuration parsing The bison grammar has been extended in order to parse configuration statements. Parsing remains very primitive but principal constructs can be now recognized. --- vhdlpp/parse.y | 223 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 214 insertions(+), 9 deletions(-) diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 06bff00a8..5d0148e26 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -165,7 +165,7 @@ architecture_body FILE_NAME(tmp, @1); bind_architecture_to_entity($4, tmp); if ($11 && tmp->get_name() != $11) - errormsg(@2, "Architecture name doesn't match closing name\n"); + errormsg(@2, "Architecture name doesn't match closing name.\n"); delete[]$2; delete[]$4; delete $8; @@ -214,6 +214,31 @@ association_list | association_element ; +//TODO: this list is only a sketch +binding_indication + : K_use entity_aspect_opt + port_map_aspect_opt + generic_map_aspect_opt + ; + +binding_indication_semicolon_opt + : binding_indication ';' + | + ; + +block_configuration + : K_for IDENTIFIER + use_clauses_opt + configuration_items_opt + K_end K_for ';' + { delete[] $2; } + ; + +block_configuration_opt + : block_configuration + | + ; + block_declarative_item : K_signal identifier_list ':' subtype_indication ';' { /* Save the signal declaration in the block_signals map. */ @@ -230,16 +255,17 @@ block_declarative_item port_clause_opt K_end K_component identifier_opt ';' { perm_string name = lex_strings.make($2); - if ($7 && name != $7) { - errormsg(@7, "Identifier %s doesn't match component name %s\n", + if($7) { + if (name != $7) + errormsg(@7, "Identifier %s doesn't match component name %s.\n", $7, name.str()); - } + delete[] $7; + } ComponentBase*comp = new ComponentBase(name); if ($4) comp->set_interface($4); block_components[name] = comp; delete[]$2; - delete[]$7; } /* Various error handling rules for block_declarative_item... */ @@ -250,7 +276,12 @@ block_declarative_item { errormsg(@1, "Syntax error in block declarations.\n"); yyerrok; } | K_component IDENTIFIER K_is_opt error K_end K_component identifier_opt ';' - { errormsg(@4, "Syntax error in component declaration.\n"); yyerrok; } + { errormsg(@4, "Syntax error in component declaration.\n"); + delete[] $2; + if($7) { + delete[] $7; + } + yyerrok; } ; /* @@ -268,6 +299,13 @@ block_declarative_items_opt | ; +component_configuration + : K_for component_specification + binding_indication_semicolon_opt + block_configuration_opt + K_end K_for ';' + ; + component_instantiation_statement : IDENTIFIER ':' IDENTIFIER port_map_aspect_opt ';' { sorrymsg(@1, "Component instantiation statements are not supported.\n"); @@ -283,6 +321,28 @@ component_instantiation_statement } ; +component_specification + : instantiation_list ':' IDENTIFIER + { sorrymsg(@1, "Component specifications are not supported.\n"); + delete[] $3 + } + ; + +configuration_declaration + : K_configuration IDENTIFIER K_of IDENTIFIER K_is + configuration_declarative_part + block_configuration + K_end K_configuration_opt identifier_opt ';' + { + sorrymsg(@1, "Configuration declaration is not yet supported.\n"); + } + | K_configuration error K_end K_configuration_opt identifier_opt ';' + { errormsg(@2, "Too many errors, giving up on configuration declaration.\n"); + if($5) delete $5; + yyerrok; + } + ; + concurrent_signal_assignment_statement : name LEQ waveform ';' { perm_string targ_name = lex_strings.make($1); @@ -304,6 +364,35 @@ concurrent_statement : component_instantiation_statement | concurrent_signal_assignment_statement ; +//TODO: this list is only a sketch. It must be filled out later +configuration_declarative_item + : use_clause + ; + +configuration_declarative_items + : configuration_declarative_items configuration_declarative_item + | configuration_declarative_item + ; + +configuration_declarative_part + : configuration_declarative_items + | + ; + +configuration_item + : block_configuration + | component_configuration + ; + +configuration_items + : configuration_items configuration_item + | configuration_item + ; + +configuration_items_opt + : configuration_items + | + ; context_clause : context_items | ; @@ -332,6 +421,17 @@ design_units direction : K_to { $$ = false; } | K_downto { $$ = true; } ; /* As an entity is declared, add it to the map of design entities. */ +entity_aspect + : K_entity IDENTIFIER {sorrymsg(@1, "Entity aspect not yet supported.\n"); delete $2;} + | K_configuration IDENTIFIER {sorrymsg(@1, "Instatiation lists not yet supported.\n"); delete $2;} + | K_open + ; + +entity_aspect_opt + : entity_aspect + | + ; + entity_declaration : K_entity IDENTIFIER K_is entity_header K_end K_entity_opt identifier_opt';' { Entity*tmp = new Entity(lex_strings.make($2)); @@ -346,6 +446,7 @@ entity_declaration if($7) { if(tmp->get_name() != $7) { errormsg(@1, "Syntax error in entity clause. Closing name doesn't match.\n"); + yyerrok; } delete $7; } @@ -483,6 +584,14 @@ factor $$ = tmp; } ; +generic_map_aspect_opt + : generic_map_aspect + | + ; + +generic_map_aspect + : K_generic K_map '(' association_list ')' + ; identifier_list : identifier_list ',' IDENTIFIER @@ -501,6 +610,20 @@ identifier_list identifier_opt : IDENTIFIER { $$ = $1; } | { $$ = 0; } ; + +instantiation_list + : identifier_list + { + sorrymsg(@1, "Instatiation lists not yet supported"); + delete $1; + } + | K_others + | K_all + { + sorrymsg(@1, "Instatiation lists not yet supported"); + } + ; + /* The interface_element is also an interface_declaration */ interface_element : identifier_list ':' mode subtype_indication @@ -544,8 +667,8 @@ library_clause /* Collapse the primary_unit and secondary_unit of the library_unit into this single set of rules. */ library_unit - : entity_declaration - | architecture_body + : primary_unit + | secondary_unit ; logical_name : IDENTIFIER { $$ = $1; } ; @@ -579,11 +702,71 @@ name } ; +package_declaration + : K_package IDENTIFIER K_is + package_declarative_part_opt + K_end K_package_opt identifier_opt ';' + { sorrymsg(@4, "Package declaration not supported yet.\n"); + if($7) { + if($2 != $7) { + errormsg(@1, "Syntax error in package clause. Closing name doesn't match.\n"); + yyerrok; + } + delete $7; + } + delete $2; + } + | K_package error K_end K_package_opt identifier_opt ';' + { errormsg(@2, "Syntax error in package clause.\n"); + yyerrok; + } + ; + +/* TODO: this list must be extended in the future + presently it is only a sketch */ +package_body_declarative_item + : use_clause + ; + +package_body_declarative_items + : package_body_declarative_items package_body_declarative_item + | package_body_declarative_item + ; +package_body_declarative_part_opt + : package_body_declarative_items + | + ; + +/* TODO: this list is only a sketch + it must be extended in the future */ +package_declarative_item + : use_clause + ; +package_declarative_items + : package_declarative_items package_declarative_item + | package_declarative_item + ; + +package_declarative_part_opt + : package_declarative_items + | + ; + +package_body + : K_package K_body IDENTIFIER K_is + package_body_declarative_part_opt + K_end K_package_opt identifier_opt ';' + { + delete[] $3; + if($8) delete[] $8; + } + ; + port_clause : K_port '(' interface_list ')' ';' { $$ = $3; } | K_port '(' error ')' ';' - { errormsg(@1, "Syntax error in port list\n"); + { errormsg(@1, "Syntax error in port list.\n"); yyerrok; $$ = 0; } @@ -616,8 +799,18 @@ primary { $$ = $2; } ; +primary_unit + : entity_declaration + | configuration_declaration + | package_declaration + ; + relation : shift_expression { $$ = $1; } ; +secondary_unit + : architecture_body + | package_body + ; /* The *_use variant of selected_name is used by the "use" clause. It is syntactically identical to other selected_name rules, but is a convenient place to attach use_clause actions. */ @@ -699,6 +892,16 @@ use_clause { errormsg(@1, "Syntax error in use clause.\n"); yyerrok; } ; +use_clauses + : use_clauses use_clause + | use_clause + ; + +use_clauses_opt + : use_clauses + | + ; + waveform : waveform_elements { $$ = $1; } @@ -729,7 +932,9 @@ waveform_element /* Some keywords are optional in some contexts. In all such cases, a similar rule is used, as described here. */ K_architecture_opt : K_architecture | ; +K_configuration_opt: K_configuration| ; K_entity_opt : K_entity | ; +K_package_opt : K_package | ; K_is_opt : K_is | ; %% From 162b26c101c3d16a56d5a2e8802bc754d248c074 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 27 Mar 2011 12:01:58 -0700 Subject: [PATCH 5/6] Add more complete support for vhdl local signals. These signals are declared in the architecture and are local to the module. The Architecture already parsed and stored these signal declarations, but this patch adds the ability to actually emit these signals in the generated code. In the process of doing this, I had to regularize the elaboration and emit of VTypes, so that it can be used in multiple places, not just in entity headers (for ports). I also added support for bit selects of signals. This effected a couple places in the parser, and expressions in general. --- vhdlpp/Makefile.in | 7 +++-- vhdlpp/architec.cc | 4 +-- vhdlpp/architec.h | 8 +++-- vhdlpp/architec_elaborate.cc | 29 +++++++++++++++++ vhdlpp/architec_emit.cc | 12 +++++++- vhdlpp/debug.cc | 5 ++- vhdlpp/entity.h | 10 ++---- vhdlpp/entity_elaborate.cc | 54 +++----------------------------- vhdlpp/entity_emit.cc | 28 ++--------------- vhdlpp/expression.cc | 8 ++++- vhdlpp/expression.h | 3 ++ vhdlpp/expression_emit.cc | 8 ++++- vhdlpp/parse.y | 28 +++++++++-------- vhdlpp/vsignal.cc | 14 +++++++++ vhdlpp/vsignal.h | 4 +++ vhdlpp/vtype.h | 15 +++++++++ vhdlpp/vtype_elaborate.cc | 60 ++++++++++++++++++++++++++++++++++++ vhdlpp/vtype_emit.cc | 53 +++++++++++++++++++++++++++++++ 18 files changed, 245 insertions(+), 105 deletions(-) create mode 100644 vhdlpp/architec_elaborate.cc create mode 100644 vhdlpp/vtype_elaborate.cc create mode 100644 vhdlpp/vtype_emit.cc diff --git a/vhdlpp/Makefile.in b/vhdlpp/Makefile.in index 0fc330b40..1cacd3e45 100644 --- a/vhdlpp/Makefile.in +++ b/vhdlpp/Makefile.in @@ -59,10 +59,11 @@ LIBS = @LIBS@ @EXTRALIBS@ M = StringHeap.o LineInfo.o -O = main.o architec.o compiler.o entity.o entity_elaborate.o \ - expression.o vsignal.o vtype.o lexor.o lexor_keyword.o parse.o \ +O = main.o architec.o architec_elaborate.o compiler.o entity.o entity_elaborate.o \ + expression.o vsignal.o vtype.o vtype_elaborate.o \ + lexor.o lexor_keyword.o parse.o \ parse_misc.o vhdlreal.o vhdlint.o debug.o \ - architec_emit.o entity_emit.o expression_emit.o \ + architec_emit.o entity_emit.o expression_emit.o vtype_emit.o \ $M all: dep vhdlpp@EXEEXT@ diff --git a/vhdlpp/architec.cc b/vhdlpp/architec.cc index 7a67b9ae5..cacee181a 100644 --- a/vhdlpp/architec.cc +++ b/vhdlpp/architec.cc @@ -44,8 +44,8 @@ Architecture::Statement::~Statement() { } -SignalAssignment::SignalAssignment(perm_string targ_name, list&rv) -: target_name_(targ_name) +SignalAssignment::SignalAssignment(ExpName*name, list&rv) +: lval_(name) { rval_.splice(rval_.end(), rv); } diff --git a/vhdlpp/architec.h b/vhdlpp/architec.h index ec1342ad2..9b25bc2ad 100644 --- a/vhdlpp/architec.h +++ b/vhdlpp/architec.h @@ -27,6 +27,7 @@ class ComponentBase; class Entity; class Expression; +class ExpName; class Signal; /* @@ -63,6 +64,9 @@ class Architecture : public LineInfo { perm_string get_name() const { return name_; } + // Elaborate this architecture in the context of the given entity. + int elaborate(Entity*entity); + // Emit this architecture to the given out file in the context // of the specified entity. This method is used by the // elaborate code to display generated code to the specified @@ -91,14 +95,14 @@ class Architecture : public LineInfo { class SignalAssignment : public Architecture::Statement { public: - SignalAssignment(perm_string target_name, std::list&rval); + SignalAssignment(ExpName*target, std::list&rval); ~SignalAssignment(); int emit(ostream&out, Entity*entity, Architecture*arc); virtual void dump(ostream&out) const; private: - perm_string target_name_; + ExpName*lval_; std::list rval_; }; diff --git a/vhdlpp/architec_elaborate.cc b/vhdlpp/architec_elaborate.cc new file mode 100644 index 000000000..c815d05ea --- /dev/null +++ b/vhdlpp/architec_elaborate.cc @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 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 + */ + +# include "architec.h" +# include "entity.h" +# include "expression.h" +# include +# include + +int Architecture::elaborate(Entity*entity) +{ + return 0; +} diff --git a/vhdlpp/architec_emit.cc b/vhdlpp/architec_emit.cc index d71f45386..888e1fad7 100644 --- a/vhdlpp/architec_emit.cc +++ b/vhdlpp/architec_emit.cc @@ -20,6 +20,7 @@ # include "architec.h" # include "entity.h" # include "expression.h" +# include "vsignal.h" # include # include # include @@ -27,6 +28,13 @@ int Architecture::emit(ostream&out, Entity*entity) { int errors = 0; + + for (map::iterator cur = signals_.begin() + ; cur != signals_.end() ; ++cur) { + + errors += cur->second->emit(out, entity, this); + } + for (list::iterator cur = statements_.begin() ; cur != statements_.end() ; ++cur) { @@ -52,7 +60,9 @@ int SignalAssignment::emit(ostream&out, Entity*ent, Architecture*arc) Expression*rval = rval_.front(); out << "// " << get_fileline() << endl; - out << "assign " << target_name_ << " = "; + out << "assign "; + errors += lval_->emit(out, ent, arc); + out << " = "; errors += rval->emit(out, ent, arc); diff --git a/vhdlpp/debug.cc b/vhdlpp/debug.cc index c9afc9052..5bcdb4cca 100644 --- a/vhdlpp/debug.cc +++ b/vhdlpp/debug.cc @@ -127,7 +127,8 @@ void Signal::dump(ostream&out) const void SignalAssignment::dump(ostream&out) const { out << " SignalAssignment file=" << get_fileline() << endl; - out << " " << target_name_ << " <= ..." << endl; + lval_->dump(out, 4); + out << " <= ..." << endl; for (list::const_iterator cur = rval_.begin() ; cur != rval_.end() ; ++cur) { @@ -218,6 +219,8 @@ void ExpName::dump(ostream&out, int indent) const { out << setw(indent) << "" << "ExpName(\"" << name_ << "\")" << " at " << get_fileline() << endl; + if (index_) + index_->dump(out, indent+6); } void ExpUAbs::dump(ostream&out, int indent) const diff --git a/vhdlpp/entity.h b/vhdlpp/entity.h index 10ddf2317..691d6f008 100644 --- a/vhdlpp/entity.h +++ b/vhdlpp/entity.h @@ -24,11 +24,11 @@ # include # include "StringHeap.h" # include "LineInfo.h" +# include "vtype.h" typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT } port_mode_t; class Architecture; -class VType; class InterfacePort : public LineInfo { public: @@ -99,13 +99,7 @@ class Entity : public ComponentBase { std::maparch_; Architecture*bind_arch_; - enum vtype_t { VNONE, VBOOL, VLOGIC }; - struct decl_t { - bool signed_flag; - vtype_t type; - long msb, lsb; - }; - map declarations_; + map declarations_; int elaborate_ports_(void); }; diff --git a/vhdlpp/entity_elaborate.cc b/vhdlpp/entity_elaborate.cc index 47e38fcac..d79347b8c 100644 --- a/vhdlpp/entity_elaborate.cc +++ b/vhdlpp/entity_elaborate.cc @@ -78,6 +78,9 @@ int Entity::elaborate() << "." << endl; errors += elaborate_ports_(); + + errors += bind_arch_->elaborate(this); + return errors; } @@ -90,11 +93,7 @@ int Entity::elaborate_ports_(void) ; cur != ports.end() ; ++cur) { InterfacePort*cur_port = *cur; - decl_t cur_decl; - cur_decl.type = VNONE; - cur_decl.signed_flag = false; - cur_decl.msb = 0; - cur_decl.lsb = 0; + VType::decl_t cur_decl; const VType*type = cur_port->type; if (type == 0) { @@ -105,50 +104,7 @@ int Entity::elaborate_ports_(void) continue; } - if (const VTypePrimitive*use_type = dynamic_cast(type)) { - switch (use_type->type()) { - case VTypePrimitive::BOOLEAN: - case VTypePrimitive::BIT: - cur_decl.type = VBOOL; - break; - case VTypePrimitive::STDLOGIC: - cur_decl.type = VLOGIC; - break; - case VTypePrimitive::INTEGER: - cur_decl.type = VBOOL; - cur_decl.msb = 31; - cur_decl.lsb = 0; - break; - } - - } else if (const VTypeArray*arr_type = dynamic_cast(type)) { - const VTypePrimitive*base = dynamic_cast(arr_type->element_type()); - assert(base != 0); - - switch (base->type()) { - case VTypePrimitive::BOOLEAN: - case VTypePrimitive::BIT: - cur_decl.type = VBOOL; - break; - case VTypePrimitive::STDLOGIC: - cur_decl.type = VLOGIC; - break; - case VTypePrimitive::INTEGER: - cur_decl.type = VLOGIC; - assert(0); - break; - } - - cur_decl.msb = arr_type->dimension(0).msb(); - cur_decl.lsb = arr_type->dimension(0).lsb(); - cur_decl.signed_flag = arr_type->signed_vector(); - - } else { - cerr << get_fileline() << ": error: " - << "I don't know how to map port " << cur_port->name - << " type " << typeid(*cur_port->type).name() << "." << endl; - errors += 1; - } + type->elaborate(cur_decl); declarations_[cur_port->name] = cur_decl; } diff --git a/vhdlpp/entity_emit.cc b/vhdlpp/entity_emit.cc index 236d92c3f..2f6faa19f 100644 --- a/vhdlpp/entity_emit.cc +++ b/vhdlpp/entity_emit.cc @@ -51,7 +51,7 @@ int Entity::emit(ostream&out) ; cur != ports.end() ; ++cur) { InterfacePort*port = *cur; - decl_t&decl = declarations_[port->name]; + VType::decl_t&decl = declarations_[port->name]; if (sep) out << sep; else sep = ", "; @@ -81,32 +81,10 @@ int Entity::emit(ostream&out) out << ";" << endl; - for (map::const_iterator cur = declarations_.begin() + for (map::const_iterator cur = declarations_.begin() ; cur != declarations_.end() ; ++cur) { - switch (cur->second.type) { - case VNONE: - out << "// N type for " << cur->first << endl; - break; - case VLOGIC: - out << "wire logic "; - if (cur->second.signed_flag) - out << "signed "; - if (cur->second.msb != cur->second.lsb) - out << "[" << cur->second.msb - << ":" << cur->second.lsb << "] "; - out << cur->first << ";" << endl; - break; - case VBOOL: - out << "wire bool "; - if (cur->second.signed_flag) - out << "signed "; - if (cur->second.msb != cur->second.lsb) - out << "[" << cur->second.msb - << ":" << cur->second.lsb << "] "; - out << cur->first << ";" << endl; - break; - } + cur->second.emit(out, cur->first); } errors += bind_arch_->emit(out, this); diff --git a/vhdlpp/expression.cc b/vhdlpp/expression.cc index 823b52fff..a5c583912 100644 --- a/vhdlpp/expression.cc +++ b/vhdlpp/expression.cc @@ -87,12 +87,18 @@ ExpLogical::~ExpLogical() } ExpName::ExpName(perm_string nn) -: name_(nn) +: name_(nn), index_(0) +{ +} + +ExpName::ExpName(perm_string nn, Expression*ix) +: name_(nn), index_(ix) { } ExpName::~ExpName() { + delete index_; } ExpUAbs::ExpUAbs(Expression*op1) diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index ec540acd0..b62497c05 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -156,14 +156,17 @@ class ExpName : public Expression { public: ExpName(perm_string nn); + ExpName(perm_string nn, Expression*index); ~ExpName(); + public: // Base methods int emit(ostream&out, Entity*ent, Architecture*arc); bool is_primary(void) const; void dump(ostream&out, int indent) const; private: perm_string name_; + Expression*index_; }; class ExpUAbs : public ExpUnary { diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index 9555a0941..eb6154538 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -141,11 +141,17 @@ int ExpLogical::emit(ostream&out, Entity*ent, Architecture*arc) return errors; } -int ExpName::emit(ostream&out, Entity*, Architecture*) +int ExpName::emit(ostream&out, Entity*ent, Architecture*arc) { int errors = 0; out << name_; + if (index_) { + out << "["; + errors += index_->emit(out, ent, arc); + out << "]"; + } + return errors; } diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 5d0148e26..b9bd14f59 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -32,6 +32,7 @@ # include # include # include +# include inline void FILE_NAME(LineInfo*tmp, const struct yyltype&where) { @@ -129,7 +130,6 @@ static map block_components; %type direction -%type name %type interface_element interface_list entity_header %type port_clause port_clause_opt %type mode @@ -140,6 +140,7 @@ static map block_components; %type expression factor primary relation %type expression_logical expression_logical_and expression_logical_or %type expression_logical_xnor expression_logical_xor +%type name %type shift_expression simple_expression term waveform_element %type waveform waveform_elements @@ -345,16 +346,17 @@ configuration_declaration concurrent_signal_assignment_statement : name LEQ waveform ';' - { perm_string targ_name = lex_strings.make($1); - SignalAssignment*tmp = new SignalAssignment(targ_name, *$3); + { ExpName*name = dynamic_cast ($1); + assert(name); + SignalAssignment*tmp = new SignalAssignment(name, *$3); FILE_NAME(tmp, @1); $$ = tmp; - delete[]$1; delete $3; } | name LEQ error ';' { errormsg(@2, "Syntax error in signal assignment waveform.\n"); + delete $1; $$ = 0; yyerrok; } @@ -695,10 +697,16 @@ mode name : IDENTIFIER - { $$ = $1; } + { ExpName*tmp = new ExpName(lex_strings.make($1)); + FILE_NAME(tmp, @1); + delete[]$1; + $$ = tmp; + } | IDENTIFIER '(' expression ')' - { sorrymsg(@3, "Indexed names not supported yet.\n"); - $$ = $1; + { ExpName*tmp = new ExpName(lex_strings.make($1), $3); + FILE_NAME(tmp, @1); + delete[]$1; + $$ = tmp; } ; @@ -785,11 +793,7 @@ port_map_aspect_opt primary : name - { ExpName*tmp = new ExpName(lex_strings.make($1)); - FILE_NAME(tmp, @1); - delete[]$1; - $$ = tmp; - } + { $$ = $1; } | INT_LITERAL { ExpInteger*tmp = new ExpInteger($1); FILE_NAME(tmp, @1); diff --git a/vhdlpp/vsignal.cc b/vhdlpp/vsignal.cc index 0b869b398..b0c014884 100644 --- a/vhdlpp/vsignal.cc +++ b/vhdlpp/vsignal.cc @@ -18,6 +18,10 @@ */ # include "vsignal.h" +# include "vtype.h" +# include + +using namespace std; Signal::Signal(perm_string nam, const VType*typ) : name_(nam), type_(typ) @@ -27,3 +31,13 @@ Signal::Signal(perm_string nam, const VType*typ) Signal::~Signal() { } + +int Signal::emit(ostream&out, Entity*, Architecture*) +{ + int errors = 0; + + VType::decl_t decl; + type_->elaborate(decl); + errors += decl.emit(out, name_); + return errors; +} diff --git a/vhdlpp/vsignal.h b/vhdlpp/vsignal.h index dca6eca3d..32109e500 100644 --- a/vhdlpp/vsignal.h +++ b/vhdlpp/vsignal.h @@ -22,6 +22,8 @@ # include "StringHeap.h" # include "LineInfo.h" +class Architecture; +class Entity; class VType; class Signal : public LineInfo { @@ -30,6 +32,8 @@ class Signal : public LineInfo { Signal(perm_string name, const VType*type); ~Signal(); + int emit(ostream&out, Entity*ent, Architecture*arc); + void dump(ostream&out) const; private: diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 4a2984785..de000fb74 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -37,6 +37,19 @@ class VType { virtual ~VType() =0; virtual void show(std::ostream&) const; + + public: + enum vtype_t { VNONE, VBOOL, VLOGIC }; + struct decl_t { + public: + decl_t() : signed_flag(false), type(VNONE), msb(0), lsb(0) { } + int emit(std::ostream&out, perm_string name) const; + public: + bool signed_flag; + vtype_t type; + long msb, lsb; + }; + virtual void elaborate(decl_t&decl) const =0; }; inline std::ostream&operator << (std::ostream&out, const VType&item) @@ -71,6 +84,7 @@ class VTypePrimitive : public VType { ~VTypePrimitive(); void show(std::ostream&) const; + void elaborate(decl_t&decl) const; type_t type() const { return type_; } @@ -112,6 +126,7 @@ class VTypeArray : public VType { ~VTypeArray(); void show(std::ostream&) const; + void elaborate(decl_t&decl) const; size_t dimensions() const; const range_t&dimension(size_t idx) const diff --git a/vhdlpp/vtype_elaborate.cc b/vhdlpp/vtype_elaborate.cc new file mode 100644 index 000000000..b396cc034 --- /dev/null +++ b/vhdlpp/vtype_elaborate.cc @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 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 + */ + +# include "vtype.h" +# include +# include + +using namespace std; + +void VTypeArray::elaborate(VType::decl_t&decl) const +{ + const VTypePrimitive*base = dynamic_cast(etype_); + assert(base != 0); + + base->elaborate(decl); + //assert(decl.msb == decl.lsb == 0); + + decl.msb = dimension(0).msb(); + decl.lsb = dimension(0).lsb(); + decl.signed_flag = signed_flag_; +} + +void VTypePrimitive::elaborate(VType::decl_t&decl) const +{ + decl.type = VNONE; + decl.signed_flag = false; + decl.msb = 0; + decl.lsb = 0; + + switch (type_) { + case BOOLEAN: + case BIT: + decl.type = VBOOL; + break; + case STDLOGIC: + decl.type = VLOGIC; + break; + case INTEGER: + decl.type = VBOOL; + decl.msb = 31; + decl.lsb = 0; + break; + } +} diff --git a/vhdlpp/vtype_emit.cc b/vhdlpp/vtype_emit.cc new file mode 100644 index 000000000..981e08bdd --- /dev/null +++ b/vhdlpp/vtype_emit.cc @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 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 + */ + + +# include "vtype.h" +# include +# include +# include + +using namespace std; + +int VType::decl_t::emit(ostream&out, perm_string name) const +{ + switch (type) { + case VType::VNONE: + out << "// N type for " << name << endl; + break; + case VType::VLOGIC: + out << "wire logic "; + if (signed_flag) + out << "signed "; + if (msb != lsb) + out << "[" << msb << ":" << lsb << "] "; + out << name << ";" << endl; + break; + case VType::VBOOL: + out << "wire bool "; + if (signed_flag) + out << "signed "; + if (msb != lsb) + out << "[" << msb << ":" << lsb << "] "; + out << name << ";" << endl; + break; + } + + return 0; +} From 8a568055f6bfff9eca5c8ca3f909afb95310881b Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 29 Mar 2011 08:18:22 -0700 Subject: [PATCH 6/6] Spelling fixes All are in comments and .txt files except for one in the Architecture::Statement dump message. --- ivlpp/ivlpp.txt | 2 +- netlist.h | 2 +- pform.cc | 2 +- tgt-vhdl/stmt.cc | 4 ++-- vhdlpp/debug.cc | 2 +- vhdlpp/expression.h | 8 ++++---- vhdlpp/parse_api.h | 2 +- vvp/README.txt | 8 ++++---- vvp/vvp_net.cc | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ivlpp/ivlpp.txt b/ivlpp/ivlpp.txt index d8b7d7506..38a0b39f2 100644 --- a/ivlpp/ivlpp.txt +++ b/ivlpp/ivlpp.txt @@ -49,7 +49,7 @@ valid options include: -f Read ivlpp input files from a file list. There can be no - more then one file list. + more than one file list. -I Add a directory to the include path. Normally, only "." is diff --git a/netlist.h b/netlist.h index d10469d8c..042be10ae 100644 --- a/netlist.h +++ b/netlist.h @@ -1669,7 +1669,7 @@ class NetExpr : public LineInfo { // rise/fall/decay: Attach these delays to the driver for the // expression output. // - // drive0/drive1: Attach these strengths tp the driver for + // drive0/drive1: Attach these strengths to the driver for // the expression output. virtual NetNet*synthesize(Design*des, NetScope*scope, NetExpr*root); diff --git a/pform.cc b/pform.cc index e800e1de7..0a23a4647 100644 --- a/pform.cc +++ b/pform.cc @@ -116,7 +116,7 @@ void parm_to_defparam_list(const string¶m) if (*value == '"') { // string type char *buf = strdup (value); char *buf_ptr = buf+1; - // Parse untill another '"' or '\0' + // Parse until another '"' or '\0' while (*buf_ptr != '"' && *buf_ptr != '\0') { buf_ptr++; // Check for escape, especially '\"', which does not mean the diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index de27ac749..1053ed00f 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -116,7 +116,7 @@ static int draw_stask_display(vhdl_procedural *proc, switch (*p) { case 'm': - // TOOD: we can get the module name via attributes + // TODO: we can get the module name via attributes cerr << "Warning: no VHDL translation for %m format code" << endl; break; @@ -1603,7 +1603,7 @@ int draw_utask(vhdl_procedural *proc, stmt_container *container, // TODO: adding some comments to the output would be helpful - // TOOD: this completely ignores parameters! + // TODO: this completely ignores parameters! draw_stmt(proc, container, ivl_scope_def(tscope), false); return 0; diff --git a/vhdlpp/debug.cc b/vhdlpp/debug.cc index 5bcdb4cca..5357e8651 100644 --- a/vhdlpp/debug.cc +++ b/vhdlpp/debug.cc @@ -116,7 +116,7 @@ void Architecture::dump(ostream&out, perm_string of_entity) const void Architecture::Statement::dump(ostream&out) const { - out << " Architecutre::Statement at file=" << get_fileline() << endl; + out << " Architecture::Statement at file=" << get_fileline() << endl; } void Signal::dump(ostream&out) const diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index b62497c05..f58ec86ad 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -37,9 +37,9 @@ class Expression : public LineInfo { Expression(); virtual ~Expression() =0; - // The emit virtual method is called bu architecture emit to + // The emit virtual method is called by architecture emit to // output the generated code for the expression. The derived - // class fills in the details of what exactly happend. + // class fills in the details of what exactly happened. virtual int emit(ostream&out, Entity*ent, Architecture*arc) =0; // The evaluate virtual method tries to evaluate expressions @@ -49,9 +49,9 @@ class Expression : public LineInfo { virtual bool evaluate(int64_t&val) const; // This method returns true if the drawn Verilog for this - // expression is a primary. A containing expressin can use + // expression is a primary. A containing expression can use // this method to know if it needs to wrap parentheses. This - // is somewhile optional, so it is better to return false if + // is somewhat optional, so it is better to return false if // not certain. The default implementation does return false. virtual bool is_primary(void) const; diff --git a/vhdlpp/parse_api.h b/vhdlpp/parse_api.h index 73ce4201d..1193d8fb9 100644 --- a/vhdlpp/parse_api.h +++ b/vhdlpp/parse_api.h @@ -54,7 +54,7 @@ extern int yylex(void); extern int yyparse(void); /* - * Use this functio during parse to generate error messages. The "loc" + * Use this function during parse to generate error messages. The "loc" * is the location of the token that triggered the error, and the fmt * is printf-style format. */ diff --git a/vvp/README.txt b/vvp/README.txt index 7142941d8..a45854ded 100644 --- a/vvp/README.txt +++ b/vvp/README.txt @@ -282,7 +282,7 @@ general syntax of a variable is: