Add support for passing a real input to logic, mos and if gates
This commit is contained in:
parent
26c01e7f0a
commit
adcb9f4e0d
|
|
@ -0,0 +1,115 @@
|
|||
module top;
|
||||
reg passed;
|
||||
real inr;
|
||||
wire out_buf, out_not, out_and, out_nand, out_or, out_nor, out_xor, out_xnor;
|
||||
|
||||
buf(out_buf, inr);
|
||||
not(out_not, inr);
|
||||
and(out_and, inr, 1'b1);
|
||||
nand(out_nand, inr, 1'b1);
|
||||
or(out_or, inr, 1'b0);
|
||||
nor(out_nor, inr, 1'b0);
|
||||
xor(out_xor, inr, 1'b1);
|
||||
xnor(out_xnor, inr, 1'b1);
|
||||
|
||||
always @(out_not) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_not !== !inr_int[0]) begin
|
||||
$display("not of %f not equal to %b", inr, !inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_buf) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_buf !== inr_int[0]) begin
|
||||
$display("buf of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_and) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_and !== inr_int[0]) begin
|
||||
$display("and of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_nand) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_nand !== !inr_int[0]) begin
|
||||
$display("nand of %f not equal to %b", inr, !inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_or) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_or !== inr_int[0]) begin
|
||||
$display("or of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_nor) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_nor !== !inr_int[0]) begin
|
||||
$display("nor of %f not equal to %b", inr, !inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_xor) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_xor !== !inr_int[0]) begin
|
||||
$display("xor of %f not equal to %b", inr, !inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_xnor) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_xnor !== inr_int[0]) begin
|
||||
$display("xnor of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
$display("bf nt an na or no xo xn in");
|
||||
$monitor(out_buf,,,out_not,,,out_and,,,out_nand,,,out_or,,,out_nor,,,out_xor,,,out_xnor,,,inr);
|
||||
#1;
|
||||
if (passed === 1'bx) passed = 1'b1;
|
||||
|
||||
inr = 1.0;
|
||||
#1;
|
||||
inr = 0.0;
|
||||
#1
|
||||
inr = 3.0;
|
||||
#1;
|
||||
inr = 2.0;
|
||||
#1;
|
||||
inr = 4.0;
|
||||
#1;
|
||||
inr = 2.5;
|
||||
#1;
|
||||
inr = 2.49;
|
||||
#1;
|
||||
inr = -1.0;
|
||||
#1;
|
||||
inr = 1.0/0.0;
|
||||
#1;
|
||||
|
||||
if (passed) $display("PASSED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
module top;
|
||||
reg passed;
|
||||
real inr, ctrl;
|
||||
wire out_bf0, out_bf1, out_nt0, out_nt1;
|
||||
|
||||
bufif0(out_bf0, inr, ctrl);
|
||||
bufif1(out_bf1, inr, 1'b1);
|
||||
notif0(out_nt0, inr, ctrl);
|
||||
notif1(out_nt1, inr, 1'b1);
|
||||
|
||||
always @(out_bf0) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_bf0 !== inr_int[0]) begin
|
||||
$display("bufif0 of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_bf1) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_bf1 !== inr_int[0]) begin
|
||||
$display("bufif1 of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_nt0) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_nt0 !== !inr_int[0]) begin
|
||||
$display("bufif0 of %f not equal to %b", inr, !inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_nt1) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_nt1 !== !inr_int[0]) begin
|
||||
$display("bufif1 of %f not equal to %b", inr, !inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
$display("b0 b1 n0 n1 in");
|
||||
$monitor(out_bf0,,,out_bf1,,,out_nt0,,,out_nt1,,,inr);
|
||||
#1;
|
||||
if (passed === 1'bx) passed = 1'b1;
|
||||
|
||||
ctrl = 2.49;
|
||||
inr = 1.0;
|
||||
#1;
|
||||
inr = 0.0;
|
||||
#1
|
||||
inr = 3.0;
|
||||
#1;
|
||||
inr = 2.0;
|
||||
#1;
|
||||
inr = 4.0;
|
||||
#1;
|
||||
inr = 2.5;
|
||||
#1;
|
||||
inr = 2.49;
|
||||
#1;
|
||||
inr = -1.0;
|
||||
#1;
|
||||
inr = 1.0/0.0;
|
||||
#1;
|
||||
|
||||
if (passed) $display("PASSED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
module top;
|
||||
reg passed;
|
||||
real inr, ctrl;
|
||||
wire out_nm, out_rnm, out_pm, out_rpm;
|
||||
wire out_cm_n, out_cm_p, out_rcm_n, out_rcm_p;
|
||||
|
||||
pmos(out_pm, inr, ctrl);
|
||||
rpmos(out_rpm, inr, ctrl);
|
||||
nmos(out_nm, inr, 1'b1);
|
||||
rnmos(out_rnm, inr, 1'b1);
|
||||
|
||||
cmos(out_cm_n, inr, 1'b1, 1'b1);
|
||||
cmos(out_cm_p, inr, ctrl, ctrl);
|
||||
cmos(out_rcm_n, inr, 1'b1, 1'b1);
|
||||
cmos(out_rcm_p, inr, ctrl, ctrl);
|
||||
|
||||
always @(out_pm) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_pm !== inr_int[0]) begin
|
||||
$display("pmos of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_rpm) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_rpm !== inr_int[0]) begin
|
||||
$display("rpmos of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_nm) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_nm !== inr_int[0]) begin
|
||||
$display("nmos of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_rnm) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_rnm !== inr_int[0]) begin
|
||||
$display("rnmos of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_cm_n) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_cm_n !== inr_int[0]) begin
|
||||
$display("cmos(N) of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_cm_p) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_cm_p !== inr_int[0]) begin
|
||||
$display("cmos(P) of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_rcm_n) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_rcm_n !== inr_int[0]) begin
|
||||
$display("rcmos(N) of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(out_rcm_p) begin
|
||||
int inr_int;
|
||||
inr_int = inr;
|
||||
if (out_rcm_p !== inr_int[0]) begin
|
||||
$display("rcmos(P) of %f not equal to %b", inr, inr_int[0]);
|
||||
passed = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
$display("n rn p rp cn rcn cp rcp in");
|
||||
$monitor(out_nm,,,out_rnm,,,out_pm,,,out_rpm,,,out_cm_n,,,out_rcm_n,,,,out_cm_p,,,out_rcm_p,,,,inr);
|
||||
#1;
|
||||
if (passed === 1'bx) passed = 1'b1;
|
||||
|
||||
ctrl = 2.49;
|
||||
inr = 1.0;
|
||||
#1;
|
||||
inr = 0.0;
|
||||
#1
|
||||
inr = 3.0;
|
||||
#1;
|
||||
inr = 2.0;
|
||||
#1;
|
||||
inr = 4.0;
|
||||
#1;
|
||||
inr = 2.5;
|
||||
#1;
|
||||
inr = 2.49;
|
||||
#1;
|
||||
inr = -1.0;
|
||||
#1;
|
||||
inr = 1.0/0.0;
|
||||
#1;
|
||||
|
||||
if (passed) $display("PASSED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -364,6 +364,9 @@ br_gh1178a CE ivltests gold=br_gh1178a.gold
|
|||
br_gh1178b normal ivltests
|
||||
br_gh1178c normal ivltests
|
||||
br_gh1182 CE ivltests gold=br_gh1182.gold
|
||||
br_gh1223a normal,-g2009 ivltests
|
||||
br_gh1223b normal,-g2009 ivltests
|
||||
br_gh1223c normal,-g2009 ivltests
|
||||
br_ml20150315 normal ivltests gold=br_ml_20150315.gold
|
||||
br_ml20150321 CE ivltests
|
||||
br_mw20171108 normal ivltests
|
||||
|
|
|
|||
|
|
@ -859,6 +859,9 @@ br_gh386d normal,-g2009,-pallowsigned=1 ivltests
|
|||
br_gh477 normal,-g2009,-pallowsigned=1 ivltests
|
||||
br_gh540 normal,-g2009,-pallowsigned=1 ivltests
|
||||
br_gh793 normal,-pallowsigned=1 ivltests
|
||||
br_gh1223a normal,-g2009,-pallowsigned=1 ivltests
|
||||
br_gh1223b normal,-g2009,-pallowsigned=1 ivltests
|
||||
br_gh1223c normal,-g2009,-pallowsigned=1 ivltests
|
||||
ca_mult normal,-pallowsigned=1 ivltests gold=ca_mult.gold
|
||||
cast_int normal,-pallowsigned=1 ivltests
|
||||
cfunc_assign_op_vec normal,-g2009,-pallowsigned=1 ivltests
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2025 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
|
||||
|
|
@ -87,3 +87,9 @@ void vvp_fun_bufif::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
|||
{
|
||||
recv_vec4_pv_(ptr, bit, base, vwid, ctx);
|
||||
}
|
||||
|
||||
void vvp_fun_bufif::recv_real(vvp_net_ptr_t ptr, double real,
|
||||
vvp_context_t ctx)
|
||||
{
|
||||
recv_vec4(ptr, double_to_vector4_LSB(real), ctx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_bufif_H
|
||||
#define IVL_bufif_H
|
||||
/*
|
||||
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2025 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
|
||||
|
|
@ -39,9 +39,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 vwid, vvp_context_t ctx);
|
||||
void recv_real(vvp_net_ptr_t port, double real,
|
||||
vvp_context_t ctx);
|
||||
|
||||
private:
|
||||
vvp_vector4_t bit_;
|
||||
|
|
|
|||
133
vvp/logic.cc
133
vvp/logic.cc
|
|
@ -44,8 +44,7 @@ void vvp_fun_boolean_::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
|||
vvp_context_t)
|
||||
{
|
||||
unsigned port = ptr.port();
|
||||
if (input_[port] .eeq( bit ))
|
||||
return;
|
||||
if (input_[port] .eeq( bit )) return;
|
||||
|
||||
input_[port] = bit;
|
||||
if (net_ == 0) {
|
||||
|
|
@ -72,6 +71,12 @@ void vvp_fun_boolean_::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
|||
}
|
||||
}
|
||||
|
||||
void vvp_fun_boolean_::recv_real(vvp_net_ptr_t ptr, double real,
|
||||
vvp_context_t ctx)
|
||||
{
|
||||
recv_vec4(ptr, double_to_vector4_LSB(real), ctx);
|
||||
}
|
||||
|
||||
vvp_fun_and::vvp_fun_and(unsigned wid, bool invert)
|
||||
: vvp_fun_boolean_(wid), invert_(invert)
|
||||
{
|
||||
|
|
@ -156,10 +161,58 @@ void vvp_fun_impl::run_run()
|
|||
ptr->send_vec4(result, 0);
|
||||
}
|
||||
|
||||
vvp_fun_buf::vvp_fun_buf(unsigned wid)
|
||||
vvp_fun_buf_not_::vvp_fun_buf_not_(unsigned wid)
|
||||
: input_(wid, BIT4_Z)
|
||||
{
|
||||
net_ = 0;
|
||||
}
|
||||
|
||||
vvp_fun_buf_not_::~vvp_fun_buf_not_()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_fun_buf_not_::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||
vvp_context_t)
|
||||
{
|
||||
if (ptr.port() != 0) return;
|
||||
|
||||
if (input_ .eeq( bit )) return;
|
||||
|
||||
input_ = bit;
|
||||
if (net_ == 0) {
|
||||
net_ = ptr.ptr();
|
||||
schedule_functor(this);
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_fun_buf_not_::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||
unsigned base, unsigned vwid, vvp_context_t)
|
||||
{
|
||||
if (ptr.port() != 0) return;
|
||||
|
||||
assert(base + bit.size() <= vwid);
|
||||
|
||||
// Set the input part. If nothing changes, then break.
|
||||
bool flag = input_.set_vec(base, bit);
|
||||
if (flag == false) return;
|
||||
|
||||
if (net_ == 0) {
|
||||
net_ = ptr.ptr();
|
||||
schedule_functor(this);
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_fun_buf_not_::recv_real(vvp_net_ptr_t ptr, double real,
|
||||
vvp_context_t ctx)
|
||||
{
|
||||
if (ptr.port() != 0) return;
|
||||
|
||||
recv_vec4(ptr, double_to_vector4_LSB(real), ctx);
|
||||
}
|
||||
|
||||
vvp_fun_buf::vvp_fun_buf(unsigned wid)
|
||||
: vvp_fun_buf_not_(wid)
|
||||
{
|
||||
count_functors_logic += 1;
|
||||
}
|
||||
|
||||
|
|
@ -171,42 +224,6 @@ vvp_fun_buf::~vvp_fun_buf()
|
|||
* The buf functor is very simple--change the z bits to x bits in the
|
||||
* vector it passes, and propagate the result.
|
||||
*/
|
||||
void vvp_fun_buf::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||
vvp_context_t)
|
||||
{
|
||||
if (ptr.port() != 0)
|
||||
return;
|
||||
|
||||
if (input_ .eeq( bit ))
|
||||
return;
|
||||
|
||||
input_ = bit;
|
||||
|
||||
if (net_ == 0) {
|
||||
net_ = ptr.ptr();
|
||||
schedule_functor(this);
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_fun_buf::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||
unsigned base, unsigned vwid, vvp_context_t)
|
||||
{
|
||||
if (ptr.port() != 0)
|
||||
return;
|
||||
|
||||
assert(base + bit.size() <= vwid);
|
||||
|
||||
// Set the input part. If nothing changes, then break.
|
||||
bool flag = input_.set_vec(base, bit);
|
||||
if (flag == false)
|
||||
return;
|
||||
|
||||
if (net_ == 0) {
|
||||
net_ = ptr.ptr();
|
||||
schedule_functor(this);
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_fun_buf::run_run()
|
||||
{
|
||||
vvp_net_t*ptr = net_;
|
||||
|
|
@ -479,9 +496,8 @@ void vvp_fun_muxz::run_run()
|
|||
}
|
||||
|
||||
vvp_fun_not::vvp_fun_not(unsigned wid)
|
||||
: input_(wid, BIT4_Z)
|
||||
: vvp_fun_buf_not_(wid)
|
||||
{
|
||||
net_ = 0;
|
||||
count_functors_logic += 1;
|
||||
}
|
||||
|
||||
|
|
@ -493,41 +509,6 @@ vvp_fun_not::~vvp_fun_not()
|
|||
* The not functor is very simple--change the z bits to x bits in the
|
||||
* vector it passes, and propagate the inverted result.
|
||||
*/
|
||||
void vvp_fun_not::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||
vvp_context_t)
|
||||
{
|
||||
if (ptr.port() != 0)
|
||||
return;
|
||||
|
||||
if (input_ .eeq( bit ))
|
||||
return;
|
||||
|
||||
input_ = bit;
|
||||
if (net_ == 0) {
|
||||
net_ = ptr.ptr();
|
||||
schedule_functor(this);
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_fun_not::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||
unsigned base, unsigned vwid, vvp_context_t)
|
||||
{
|
||||
if (ptr.port() != 0)
|
||||
return;
|
||||
|
||||
assert(base + bit.size() <= vwid);
|
||||
|
||||
// Set the part value. If nothing changes, then break.
|
||||
bool flag = input_.set_vec(base, bit);
|
||||
if (flag == false)
|
||||
return;
|
||||
|
||||
if (net_ == 0) {
|
||||
net_ = ptr.ptr();
|
||||
schedule_functor(this);
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_fun_not::run_run()
|
||||
{
|
||||
vvp_net_t*ptr = net_;
|
||||
|
|
|
|||
49
vvp/logic.h
49
vvp/logic.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_logic_H
|
||||
#define IVL_logic_H
|
||||
/*
|
||||
* Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2025 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
|
||||
|
|
@ -36,6 +36,8 @@ class vvp_fun_boolean_ : public vvp_net_fun_t, protected vvp_gen_event_s {
|
|||
vvp_context_t);
|
||||
void recv_vec4_pv(vvp_net_ptr_t p, const vvp_vector4_t&bit,
|
||||
unsigned base, unsigned vwid, vvp_context_t);
|
||||
void recv_real(vvp_net_ptr_t p, double real,
|
||||
vvp_context_t);
|
||||
|
||||
protected:
|
||||
vvp_vector4_t input_[4];
|
||||
|
|
@ -74,28 +76,40 @@ class vvp_fun_impl : public vvp_fun_boolean_ {
|
|||
};
|
||||
|
||||
/*
|
||||
* The buffer functor is a very primitive functor that takes the input
|
||||
* from port-0 (and only port-0) and retransmits it as a vvp_vector4_t.
|
||||
* The retransmitted vector has all Z values changed to X, just like
|
||||
* the buf(Q,D) gate in Verilog.
|
||||
* vvp_fun_buf_not_ is just a common hook for holding operands.
|
||||
*/
|
||||
class vvp_fun_buf: public vvp_net_fun_t, private vvp_gen_event_s {
|
||||
class vvp_fun_buf_not_ : public vvp_net_fun_t, protected vvp_gen_event_s {
|
||||
|
||||
public:
|
||||
explicit vvp_fun_buf(unsigned wid);
|
||||
virtual ~vvp_fun_buf();
|
||||
explicit vvp_fun_buf_not_(unsigned wid);
|
||||
~vvp_fun_buf_not_();
|
||||
|
||||
void recv_vec4(vvp_net_ptr_t p, const vvp_vector4_t&bit,
|
||||
vvp_context_t);
|
||||
void recv_vec4_pv(vvp_net_ptr_t p, const vvp_vector4_t&bit,
|
||||
unsigned base, unsigned vwid, vvp_context_t);
|
||||
void recv_real(vvp_net_ptr_t p, double real,
|
||||
vvp_context_t ctx);
|
||||
|
||||
protected:
|
||||
vvp_vector4_t input_;
|
||||
vvp_net_t*net_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The buffer functor is a very primitive functor that takes the input
|
||||
* from port-0 (and only port-0) and retransmits it as a vvp_vector4_t.
|
||||
* The retransmitted vector has all Z values changed to X, just like
|
||||
* the buf(Q,D) gate in Verilog.
|
||||
*/
|
||||
class vvp_fun_buf: public vvp_fun_buf_not_ {
|
||||
|
||||
public:
|
||||
explicit vvp_fun_buf(unsigned wid);
|
||||
virtual ~vvp_fun_buf();
|
||||
|
||||
private:
|
||||
void run_run();
|
||||
|
||||
private:
|
||||
vvp_vector4_t input_;
|
||||
vvp_net_t*net_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -186,23 +200,14 @@ class vvp_fun_muxr : public vvp_net_fun_t, private vvp_gen_event_s {
|
|||
sel_type select_;
|
||||
};
|
||||
|
||||
class vvp_fun_not: public vvp_net_fun_t, private vvp_gen_event_s {
|
||||
class vvp_fun_not: public vvp_fun_buf_not_ {
|
||||
|
||||
public:
|
||||
explicit vvp_fun_not(unsigned wid);
|
||||
virtual ~vvp_fun_not();
|
||||
|
||||
void recv_vec4(vvp_net_ptr_t p, const vvp_vector4_t&bit,
|
||||
vvp_context_t);
|
||||
void recv_vec4_pv(vvp_net_ptr_t p, const vvp_vector4_t&bit,
|
||||
unsigned base, unsigned vwid, vvp_context_t);
|
||||
|
||||
private:
|
||||
void run_run();
|
||||
|
||||
private:
|
||||
vvp_vector4_t input_;
|
||||
vvp_net_t*net_;
|
||||
};
|
||||
|
||||
class vvp_fun_or : public vvp_fun_boolean_ {
|
||||
|
|
|
|||
14
vvp/npmos.cc
14
vvp/npmos.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2005-2025 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
|
||||
|
|
@ -56,6 +56,12 @@ void vvp_fun_pmos_::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
|
|||
recv_vec8_pv_(ptr, bit, base, vwid);
|
||||
}
|
||||
|
||||
void vvp_fun_pmos_::recv_real(vvp_net_ptr_t ptr, double real,
|
||||
vvp_context_t ctx)
|
||||
{
|
||||
recv_vec4(ptr, double_to_vector4_LSB(real), ctx);
|
||||
}
|
||||
|
||||
void vvp_fun_pmos_::generate_output_(vvp_net_ptr_t ptr)
|
||||
{
|
||||
const unsigned*strength_map = vvp_switch_strength_map[resistive_];
|
||||
|
|
@ -179,6 +185,12 @@ void vvp_fun_cmos_::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
|
|||
recv_vec8_pv_(ptr, bit, base, vwid);
|
||||
}
|
||||
|
||||
void vvp_fun_cmos_::recv_real(vvp_net_ptr_t ptr, double real,
|
||||
vvp_context_t ctx)
|
||||
{
|
||||
recv_vec4(ptr, double_to_vector4_LSB(real), ctx);
|
||||
}
|
||||
|
||||
void vvp_fun_cmos_::generate_output_(vvp_net_ptr_t ptr)
|
||||
{
|
||||
const unsigned*strength_map = vvp_switch_strength_map[resistive_];
|
||||
|
|
|
|||
10
vvp/npmos.h
10
vvp/npmos.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_npmos_H
|
||||
#define IVL_npmos_H
|
||||
/*
|
||||
* Copyright (c) 2005-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2005-2025 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
|
||||
|
|
@ -50,11 +50,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 vwid, vvp_context_t ctx);
|
||||
void recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
|
||||
unsigned base, unsigned vwid);
|
||||
void recv_real(vvp_net_ptr_t port, double real,
|
||||
vvp_context_t ctx);
|
||||
|
||||
protected:
|
||||
void generate_output_(vvp_net_ptr_t port);
|
||||
|
|
@ -110,13 +111,14 @@ class vvp_fun_cmos_ : public vvp_net_fun_t {
|
|||
public:
|
||||
explicit vvp_fun_cmos_(bool resistive);
|
||||
|
||||
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t &bit,
|
||||
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 vwid, vvp_context_t ctx);
|
||||
void recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
|
||||
unsigned base, unsigned vwid);
|
||||
void recv_real(vvp_net_ptr_t port, double real,
|
||||
vvp_context_t);
|
||||
|
||||
protected:
|
||||
void generate_output_(vvp_net_ptr_t port);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_vvp_net_H
|
||||
#define IVL_vvp_net_H
|
||||
/*
|
||||
* Copyright (c) 2004-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2004-2025 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
|
||||
|
|
@ -572,6 +572,15 @@ extern bool vector2_to_value(const vvp_vector2_t&a, int32_t&val, bool is_signed)
|
|||
|
||||
extern vvp_vector4_t vector4_from_text(const char*bits, unsigned wid);
|
||||
|
||||
inline vvp_vector4_t double_to_vector4_LSB(double real)
|
||||
{
|
||||
// Convert the double to a bit vector and then use the LSB.
|
||||
// You can use very large real values and break the 64-bit
|
||||
// size, but that's really horrible code so don't do that!
|
||||
vvp_vector4_t bit = vvp_vector4_t(64, real);
|
||||
bit.resize(1);
|
||||
return bit;
|
||||
}
|
||||
|
||||
/*
|
||||
* vvp_vector4array_t
|
||||
|
|
|
|||
Loading…
Reference in New Issue