Extended fix for GitHub issue #99.

Most vvp functors need to support recv_vec4_pv. Any that are strength-aware
also need to support recv_vec8_pv. Note the simplifying assumption that is
documented in the base class recv_vec4_pv_ implementation.
This commit is contained in:
Martin Whitaker 2016-04-18 23:47:43 +01:00
parent b2f7d09f0d
commit 6e5ed73b09
16 changed files with 223 additions and 40 deletions

View File

@ -53,35 +53,11 @@ void vvp_arith_::dispatch_operand_(vvp_net_ptr_t ptr, vvp_vector4_t bit)
void vvp_arith_::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t)
vvp_context_t ctx)
{
unsigned port = ptr.port();
assert(bit.size() == wid);
assert(base + wid <= vwid);
vvp_vector4_t tmp;
switch (port) {
case 0:
tmp = op_a_;
break;
case 1:
tmp = op_b_;
break;
default:
fprintf(stderr, "Unsupported port type %u.\n", port);
assert(0);
}
// Set the part for the input. If nothing changes, then break.
bool flag = tmp.set_vec(base, bit);
if (flag == false)
return;
recv_vec4(ptr, tmp, 0);
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
vvp_arith_abs::vvp_arith_abs()
{
}
@ -112,6 +88,13 @@ void vvp_arith_abs::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
ptr.ptr()->send_vec4(out, 0);
}
void vvp_arith_abs::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
void vvp_arith_abs::recv_real(vvp_net_ptr_t ptr, double bit,
vvp_context_t)
{
@ -151,6 +134,13 @@ void vvp_arith_cast_real::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
ptr.ptr()->send_real(val, 0);
}
void vvp_arith_cast_real::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
vvp_arith_cast_vec2::vvp_arith_cast_vec2(unsigned wid)
: wid_(wid)
{
@ -173,6 +163,13 @@ void vvp_arith_cast_vec2::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
ptr.ptr()->send_vec4(vector2_to_vector4(tmp,wid_), 0);
}
void vvp_arith_cast_vec2::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
// Division
vvp_arith_div::vvp_arith_div(unsigned wid, bool signed_flag)

View File

@ -37,9 +37,9 @@ class vvp_arith_ : public vvp_net_fun_t {
public:
explicit vvp_arith_(unsigned wid);
void recv_vec4_pv(vvp_net_ptr_t p, const vvp_vector4_t&bit,
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t);
vvp_context_t ctx);
protected:
void dispatch_operand_(vvp_net_ptr_t ptr, vvp_vector4_t bit);
@ -63,6 +63,10 @@ class vvp_arith_abs : public vvp_net_fun_t {
void recv_real(vvp_net_ptr_t ptr, double bit,
vvp_context_t);
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx);
private:
};
@ -86,6 +90,10 @@ class vvp_arith_cast_real : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
vvp_context_t);
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx);
private:
bool signed_;
};
@ -100,6 +108,10 @@ class vvp_arith_cast_vec2 : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
vvp_context_t);
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx);
private:
unsigned wid_;
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2010 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
@ -81,3 +81,10 @@ void vvp_fun_bufif::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
ptr.ptr()->send_vec8(out);
}
void vvp_fun_bufif::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}

View File

@ -1,7 +1,7 @@
#ifndef IVL_bufif_H
#define IVL_bufif_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
@ -40,6 +40,10 @@ class vvp_fun_bufif : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
vvp_context_t);
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx);
private:
vvp_vector4_t bit_;
vvp_vector4_t en_;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005-2014 Stephen Williams <steve@icarus.com>
* Copyright (c) 2005-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
@ -332,6 +332,13 @@ void vvp_fun_delay::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
}
}
void vvp_fun_delay::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
/* See the recv_vec4 comment above. */
void vvp_fun_delay::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
{
@ -397,6 +404,12 @@ void vvp_fun_delay::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
}
}
void vvp_fun_delay::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
unsigned base, unsigned wid, unsigned vwid)
{
recv_vec8_pv_(ptr, bit, base, wid, vwid);
}
void vvp_fun_delay::recv_real(vvp_net_ptr_t port, double bit,
vvp_context_t)
{

View File

@ -1,7 +1,7 @@
#ifndef IVL_delay_H
#define IVL_delay_H
/*
* Copyright 2005-2014 Stephen Williams
* Copyright 2005-2016 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
@ -99,6 +99,12 @@ class vvp_fun_delay : public vvp_net_fun_t, private vvp_gen_event_s {
vvp_context_t);
//void recv_long(vvp_net_ptr_t port, long bit);
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx);
void recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
unsigned base, unsigned wid, unsigned vwid);
private:
virtual void run_run();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005-2015 Stephen Williams (steve@icarus.com)
* Copyright (c) 2005-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
@ -103,6 +103,13 @@ void vvp_dff::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
}
}
void vvp_dff::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
/*
* The recv_async functions respond to the asynchronous
* set/clear input by propagating the desired output.

View File

@ -1,7 +1,7 @@
#ifndef IVL_dff_H
#define IVL_dff_H
/*
* Copyright (c) 2005-2015 Stephen Williams (steve@icarus.com)
* Copyright (c) 2005-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
@ -44,6 +44,10 @@ class vvp_dff : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
vvp_context_t);
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx);
private:
virtual void recv_async(vvp_net_ptr_t port);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005-2010 Stephen Williams <steve@icarus.com>
* Copyright (c) 2005-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
@ -51,3 +51,10 @@ void vvp_fun_extend_signed::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bi
port.ptr()->send_vec4(res, 0);
}
void vvp_fun_extend_signed::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}

View File

@ -70,6 +70,13 @@ void vvp_latch::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
}
}
void vvp_latch::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
void compile_latch(char*label, unsigned width,
struct symb_s arg_d,
struct symb_s arg_e)

View File

@ -37,6 +37,10 @@ class vvp_latch : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
vvp_context_t);
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx);
private:
vvp_bit4_t en_;
vvp_vector4_t d_;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005 Stephen Williams (steve@icarus.com)
* Copyright (c) 2005-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
@ -43,6 +43,19 @@ void vvp_fun_pmos_::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
generate_output_(ptr);
}
void vvp_fun_pmos_::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
void vvp_fun_pmos_::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
unsigned base, unsigned wid, unsigned vwid)
{
recv_vec8_pv_(ptr, bit, base, wid, vwid);
}
void vvp_fun_pmos_::generate_output_(vvp_net_ptr_t ptr)
{
vvp_vector8_t out (bit_.size());
@ -147,7 +160,18 @@ void vvp_fun_cmos_::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t &bit,
generate_output_(ptr);
}
#include <iostream>
void vvp_fun_cmos_::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
void vvp_fun_cmos_::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
unsigned base, unsigned wid, unsigned vwid)
{
recv_vec8_pv_(ptr, bit, base, wid, vwid);
}
void vvp_fun_cmos_::generate_output_(vvp_net_ptr_t ptr)
{

View File

@ -1,7 +1,7 @@
#ifndef IVL_npmos_H
#define IVL_npmos_H
/*
* Copyright (c) 2005-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2005-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
@ -51,6 +51,12 @@ class vvp_fun_pmos_ : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
vvp_context_t);
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx);
void recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
unsigned base, unsigned wid, unsigned vwid);
protected:
void generate_output_(vvp_net_ptr_t port);
@ -108,6 +114,12 @@ class vvp_fun_cmos_ : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t &bit,
vvp_context_t);
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx);
void recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
unsigned base, unsigned wid, unsigned vwid);
protected:
void generate_output_(vvp_net_ptr_t port);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 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
@ -32,6 +32,10 @@ class vvp_fun_substitute : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit, vvp_context_t);
void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx);
private:
unsigned wid_;
unsigned soff_;
@ -77,6 +81,13 @@ void vvp_fun_substitute::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
port.ptr()->send_vec4(val_, 0);
}
void vvp_fun_substitute::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
void compile_substitute(char*label, unsigned width,
unsigned soff, unsigned swidth,
unsigned argc, struct symb_s*argv)

View File

@ -3249,6 +3249,31 @@ void vvp_net_fun_t::recv_vec4(vvp_net_ptr_t, const vvp_vector4_t&,
assert(0);
}
void vvp_net_fun_t::recv_vec4_pv_(vvp_net_ptr_t p, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t)
{
// The majority of functors don't normally expect to receive part
// values, because the primary operands of an expression will be
// extended to the expression width. But in the case that a primary
// operand is a wire that is only partly driven by a single driver,
// the part value driven onto the wire propagates directly to the
// inputs of any functors connected to that wire. In this case we
// know that the remaining bits are undriven, so can simply build
// the full width value from the part we have received.
//
// Note that this case is almost certainly a bug in the user's
// code, but we still need to handle it correctly. See GitHub
// issue #99 and br_gh99*.v in the test suite for examples.
assert(bit.size() == wid);
assert(base + wid <= vwid);
vvp_vector4_t tmp(vwid, BIT4_Z);
tmp.set_vec(base, bit);
recv_vec4(p, tmp, 0);
}
void vvp_net_fun_t::recv_vec4_pv(vvp_net_ptr_t, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t)
@ -3264,6 +3289,19 @@ void vvp_net_fun_t::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
recv_vec4(port, reduce4(bit), 0);
}
void vvp_net_fun_t::recv_vec8_pv_(vvp_net_ptr_t p, const vvp_vector8_t&bit,
unsigned base, unsigned wid, unsigned vwid)
{
// This is the strength-aware version of recv_vec4_pv_.
assert(bit.size() == wid);
assert(base + wid <= vwid);
vvp_vector8_t tmp(vwid);
tmp.set_vec(base, bit);
recv_vec8(p, tmp);
}
void vvp_net_fun_t::recv_vec8_pv(vvp_net_ptr_t port, const vvp_vector8_t&bit,
unsigned base, unsigned wid, unsigned vwid)
{
@ -3331,6 +3369,12 @@ void vvp_fun_drive::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
port.ptr()->send_vec8(vvp_vector8_t(bit, drive0_, drive1_));
}
void vvp_fun_drive::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
/* **** vvp_wide_fun_* methods **** */
@ -3426,6 +3470,13 @@ void vvp_wide_fun_t::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
core_->dispatch_vec4_from_input_(pidx, bit);
}
void vvp_wide_fun_t::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t ctx)
{
recv_vec4_pv_(ptr, bit, base, wid, vwid, ctx);
}
void vvp_wide_fun_t::recv_real(vvp_net_ptr_t port, double bit,
vvp_context_t)
{

View File

@ -1,7 +1,7 @@
#ifndef IVL_vvp_net_H
#define IVL_vvp_net_H
/*
* Copyright (c) 2004-2015 Stephen Williams (steve@icarus.com)
* Copyright (c) 2004-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
@ -1230,6 +1230,13 @@ class vvp_net_fun_t {
// do something about it.
virtual void force_flag(bool run_now);
protected:
void recv_vec4_pv_(vvp_net_ptr_t p, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t context);
void recv_vec8_pv_(vvp_net_ptr_t p, const vvp_vector8_t&bit,
unsigned base, unsigned wid, unsigned vwid);
public: // These objects are only permallocated.
static void* operator new(std::size_t size) { return heap_.alloc(size); }
static void operator delete(void*); // not implemented
@ -1470,6 +1477,9 @@ class vvp_fun_drive : public vvp_net_fun_t {
vvp_context_t context);
//void recv_long(vvp_net_ptr_t port, long bit);
void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t);
private:
unsigned char drive0_;
unsigned char drive1_;
@ -1490,6 +1500,9 @@ class vvp_fun_extend_signed : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
vvp_context_t context);
void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t);
private:
unsigned width_;
};
@ -1571,6 +1584,10 @@ class vvp_wide_fun_t : public vvp_net_fun_t {
void recv_real(vvp_net_ptr_t port, double bit,
vvp_context_t context);
void recv_vec4_pv(vvp_net_ptr_t p, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t context);
private:
vvp_wide_fun_core*core_;
unsigned port_base_;