From aab491a7629c6e8d6322f0de06418df2f2c327db Mon Sep 17 00:00:00 2001 From: Cary R Date: Sun, 6 Nov 2011 09:23:20 -0800 Subject: [PATCH] V0.9: Add check that a parallel connection uses the same width input/output. This patch uses the full_flag to verify that the input and output have the same width for a parallel connection. Icarus always uses a full connection so this is just a portability issue with other simulators. The pform dump code was also modified to correctly display the polarity and full/parallel connection type. --- PSpec.h | 12 +++++++++++- elaborate.cc | 17 ++++++++++++++++- pform.cc | 2 ++ pform_dump.cc | 7 +++++-- 4 files changed, 34 insertions(+), 4 deletions(-) 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 1e28ea8bd..ddd341b33 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -4040,6 +4040,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) { @@ -4107,6 +4109,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; } @@ -4119,7 +4135,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 38e9bb8d0..a84ddff5a 100644 --- a/pform.cc +++ b/pform.cc @@ -1979,6 +1979,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 06a827be5..dc0c1dab6 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-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 @@ -951,7 +951,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 << "(";