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.
This commit is contained in:
Cary R 2011-11-06 09:17:20 -08:00 committed by Stephen Williams
parent 5e4c0c9783
commit b1869f80ab
4 changed files with 33 additions and 3 deletions

12
PSpec.h
View File

@ -1,7 +1,7 @@
#ifndef __PSpec_H
#define __PSpec_H
/*
* Copyright (c) 2006 Stephen Williams <steve@icarus.com>
* Copyright (c) 2006-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
@ -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<perm_string> src;
// Ordered set of destination nodes of a path

View File

@ -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,

View File

@ -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<perm_string>::const_iterator cur;

View File

@ -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 << "(";