diff --git a/PSpec.h b/PSpec.h index dd75c33a0..3b65ba283 100644 --- a/PSpec.h +++ b/PSpec.h @@ -1,7 +1,7 @@ #ifndef __PSpec_H #define __PSpec_H /* - * Copyright (c) 2006 Stephen Williams + * Copyright (c) 2006-2011 Stephen Williams * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -46,6 +46,12 @@ class PExpr; * * If data_source_expression != nil, then the path is edge sensitive * and the edge might not be 0. +* +* The full flag is used to verify that only vectors of the same size +* are used in a parallel connection. Icarus always creates a full +* connection between the source and destination. The polarity is for +* informational (display) purposes only. The polarity is either '+', +* '-' or 0. */ class PSpecPath : public LineInfo { @@ -63,6 +69,10 @@ class PSpecPath : public LineInfo { class PExpr* condition; // Edge specification (-1==negedge, 0 = no edge, 1==posedge) int edge; + // Is this a full connection. + bool full_flag; + // What is the polarity of the connection. + char polarity; // Ordered set of source nodes of a path std::vector src; // Ordered set of destination nodes of a path diff --git a/elaborate.cc b/elaborate.cc index 42acbea88..e8de6539b 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -4216,6 +4216,8 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const continue; } + unsigned long dst_wid = dst_sig->vector_width(); + if (dst_sig->port_type() != NetNet::POUTPUT && dst_sig->port_type() != NetNet::PINOUT) { @@ -4283,6 +4285,20 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const des->errors += 1; } + // For a parallel connection the source and destination + // must be the same width. + if (! full_flag) { + unsigned long src_wid = src_sig->vector_width(); + if (src_wid != dst_wid) { + cerr << get_fileline() << ": error: For a " + "parallel connection the " + "source/destination width must match " + "found (" << src_wid << "/" << dst_wid + << ")." << endl; + des->errors += 1; + } + } + connect(src_sig->pin(0), path->pin(idx)); idx += 1; } @@ -4295,7 +4311,6 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const dst_sig->add_delay_path(path); } - } static void elaborate_functions(Design*des, NetScope*scope, diff --git a/pform.cc b/pform.cc index 82bb894ce..476830b28 100644 --- a/pform.cc +++ b/pform.cc @@ -2346,6 +2346,8 @@ extern PSpecPath* pform_make_specify_path(const struct vlltype&li, { PSpecPath*path = new PSpecPath(src->size(), dst->size()); FILE_NAME(path, li.text, li.first_line); + path->polarity = pol; + path->full_flag = full_flag; unsigned idx; list::const_iterator cur; diff --git a/pform_dump.cc b/pform_dump.cc index 4455fa7e9..ccb74830f 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -944,7 +944,10 @@ void PSpecPath::dump(std::ostream&out, unsigned ind) const out << src[idx]; } - out << " => "; + out << " "; + if (polarity) out << polarity; + if (full_flag) out << "*> "; + else out << "=> "; if (data_source_expression) out << "(";