361 lines
10 KiB
XML
361 lines
10 KiB
XML
v {xschem version=2.9.7 file_version=1.2}
|
|
G {}
|
|
V {// test}
|
|
S {* test}
|
|
E {}
|
|
T {rrreal type:
|
|
-----------
|
|
|
|
rreal is a record type containing voltage value, drive strength and
|
|
capacitive loading of an electrical node.
|
|
|
|
rrreal is a resolved subtype of rreal.
|
|
|
|
The resolution function invoked by the simulator updates
|
|
voltages, strengths and capacitive loading of all nodes.
|
|
|
|
this allows to simulate voltage transients, charge sharing,
|
|
floating conditions and more.
|
|
the example uses bidirectional analog switches
|
|
and simulates charge pumps which have a finite
|
|
driving capability (output impedance)} 10 -410 0 0 0.3 0.3 {}
|
|
T {VHDL DESIGN EXAMPLE} 140 -1290 0 0 1 1 {}
|
|
T {set netlist mode to VHDL
|
|
- create netlist
|
|
- simulate with ghdl
|
|
- view waveforms} 110 -1200 0 0 0.6 0.6 {}
|
|
N 830 -680 900 -680 {lab=VXS}
|
|
N 450 -680 510 -680 {lab=VX}
|
|
N 450 -680 450 -570 {lab=VX}
|
|
N 1230 -680 1240 -680 {lab=SP}
|
|
N 340 -680 450 -680 {lab=VX}
|
|
N 830 -680 830 -570 {lab=VXS}
|
|
N 1230 -680 1230 -570 {lab=SP}
|
|
N 470 -800 480 -800 {lab=VX2}
|
|
N 810 -800 810 -680 {lab=VXS}
|
|
N 780 -800 810 -800 {lab=VXS}
|
|
N 350 -910 470 -910 {lab=VX2}
|
|
N 470 -910 470 -800 {lab=VX2}
|
|
N 810 -680 830 -680 {lab=VXS}
|
|
N 1200 -680 1230 -680 {lab=SP}
|
|
N 340 -800 470 -800 {lab=VX2}
|
|
C {code.sym} 600 -200 0 0 {name=CODE
|
|
vhdl_ignore=false
|
|
value="
|
|
-- these assignments are done to have the voltage values available
|
|
-- in the waveform file
|
|
V_VX <= VX.value;
|
|
V_VX2 <= VX2.value;
|
|
V_VXS <= VXS.value;
|
|
V_SP <= SP.value;
|
|
|
|
|
|
process
|
|
begin
|
|
ING<='0';
|
|
ING1<='0';
|
|
SW <= '0';
|
|
SW1<='0';
|
|
SW2<='0';
|
|
--VX <= rreal'(4.5,10.0,0.0);
|
|
--VX2 <= rreal'(3.0, 5.0, 0.0);
|
|
wait for 200 ns;
|
|
ING1<='1';
|
|
wait for 200 ns;
|
|
ING<='1';
|
|
wait for 200 ns;
|
|
SW<='1';
|
|
wait for 200 ns;
|
|
SW2<='1';
|
|
wait for 200 ns;
|
|
SW1<='1';
|
|
wait for 200 ns;
|
|
SW1<='0';
|
|
wait for 200 ns;
|
|
SW2<='0';
|
|
wait for 200 ns;
|
|
SW1<='1';
|
|
wait for 200 ns;
|
|
SW<='1';
|
|
wait for 200 ns;
|
|
ING <='0';
|
|
wait for 200 ns;
|
|
SW1<= '0';
|
|
wait for 200 ns;
|
|
SW<='1';
|
|
wait for 200 ns;
|
|
ING<='1';
|
|
wait for 200 ns;
|
|
SW <= '0';
|
|
wait for 200 ns;
|
|
SW1<= '1';
|
|
wait for 200 ns;
|
|
ING<='1';
|
|
wait for 200 ns;
|
|
SW<='0';
|
|
wait for 200 ns;
|
|
SW1<='0';
|
|
wait for 200 ns;
|
|
SW<='1';
|
|
wait for 200 ns;
|
|
SW1<='1';
|
|
wait for 200 ns;
|
|
SW1<='0';
|
|
wait for 200 ns;
|
|
SW1<='1';
|
|
wait for 200 ns;
|
|
|
|
|
|
|
|
wait;
|
|
end process;
|
|
|
|
|
|
"
|
|
}
|
|
C {use.sym} 840 -220 0 0 {library ieee;
|
|
use std.TEXTIO.all;
|
|
use ieee.std_logic_1164.all;
|
|
|
|
library work;
|
|
use work.rrreal.all;
|
|
|
|
}
|
|
C {pump.sym} 250 -680 0 0 {name=x4 conduct="1.0/20000.0" val=4.5}
|
|
C {lab_pin.sym} 150 -680 0 0 {name=l4 lab=ING}
|
|
C {switch_rreal.sch} 660 -670 0 0 {name=x5 del="2 ns"}
|
|
C {lab_pin.sym} 510 -660 0 0 {name=l5 lab=SW}
|
|
C {real_capa.sym} 450 -540 0 0 {name=x3 cap=30.0}
|
|
C {real_capa.sym} 830 -540 0 0 {name=x1 cap=100.0}
|
|
C {switch_rreal.sch} 1050 -670 0 0 {name=x2 del="2 ns"}
|
|
C {lab_pin.sym} 900 -660 0 0 {name=l2 lab=SW1}
|
|
C {lab_pin.sym} 1240 -680 0 1 {name=l3 lab=SP sig_type=rrreal}
|
|
C {real_capa.sym} 1230 -540 0 0 {name=x6 cap=20.0}
|
|
C {lab_wire.sym} 860 -680 0 1 {name=l6 lab=VXS sig_type=rrreal
|
|
}
|
|
C {pump.sym} 250 -800 0 0 {name=x7 conduct="1.0/40000.0" val=3.0}
|
|
C {lab_pin.sym} 150 -800 0 0 {name=l7 lab=ING1}
|
|
C {switch_rreal.sym} 630 -790 0 0 {name=x8 del="2 ns"}
|
|
C {lab_pin.sym} 480 -780 0 0 {name=l0 lab=SW2}
|
|
C {lab_wire.sym} 400 -800 0 1 {name=l8 lab=VX2 sig_type=rrreal
|
|
}
|
|
C {real_capa.sym} 350 -880 0 0 {name=x9 cap=40.0}
|
|
C {package_not_shown.sym} 830 -340 0 0 {
|
|
library ieee, std;
|
|
use std.textio.all;
|
|
|
|
package rrreal is
|
|
|
|
|
|
|
|
type rreal is
|
|
record
|
|
value : real;
|
|
conduct : real;
|
|
cap : real;
|
|
end record;
|
|
|
|
|
|
|
|
type rreal_vector is array (natural range <>) of rreal;
|
|
function resolved_real( r: rreal_vector ) return rreal;
|
|
procedure print(s : in string);
|
|
subtype rrreal is resolved_real rreal;
|
|
type rrreal_vector is array (natural range <>) of rrreal;
|
|
|
|
CONSTANT RREAL_X : rreal := rreal'(value=> 0.0, cap=>0.0, conduct=>-1.0);
|
|
CONSTANT RREAL_Z : rreal := rreal'(value=> 0.0, cap=>0.0, conduct=>0.0);
|
|
CONSTANT RREAL_0 : rreal := rreal'(value=> 0.0, cap=>0.0, conduct=>10.0);
|
|
CONSTANT REAL_Z : real := 20.0;
|
|
CONSTANT REAL_X : real := 20.0;
|
|
|
|
|
|
procedure transition(
|
|
signal sig: INOUT rreal;
|
|
constant endval: IN real;
|
|
constant del: IN time
|
|
);
|
|
|
|
procedure glitch(
|
|
signal sig: INOUT rreal;
|
|
constant lowval: IN real;
|
|
constant endval: IN real;
|
|
constant del: IN time
|
|
);
|
|
|
|
end rrreal; -- end package declaration
|
|
|
|
|
|
package body rrreal is
|
|
|
|
procedure print(s : in string) is
|
|
variable outbuf: line;
|
|
begin
|
|
write(outbuf, s);
|
|
writeline(output, outbuf);
|
|
end procedure;
|
|
|
|
|
|
-- function resolved_real( r:rreal_vector) return rreal is
|
|
-- VARIABLE result : rreal := RREAL_Z;
|
|
-- begin
|
|
-- IF (r'LENGTH = 1) THEN RETURN r(r'LOW);
|
|
-- ELSE
|
|
-- FOR i IN r'RANGE LOOP
|
|
-- result.cap := result.cap + r(i).cap ;
|
|
-- IF r(i).value /=REAL_Z THEN
|
|
-- IF result.value /=REAL_Z THEN
|
|
-- result.value := REAL_X ;
|
|
-- ELSE
|
|
-- result.value := r(i).value ;
|
|
-- END IF;
|
|
-- END IF ;
|
|
-- END LOOP;
|
|
-- END IF;
|
|
-- RETURN result;
|
|
-- end resolved_real;
|
|
|
|
function resolved_real( r:rreal_vector) return rreal is
|
|
VARIABLE result : rreal := RREAL_Z;
|
|
variable vcapshare : real := 0.0;
|
|
begin
|
|
IF (r'LENGTH = 1) THEN RETURN r(r'LOW);
|
|
ELSE
|
|
FOR i IN r'RANGE LOOP
|
|
if r(i).conduct = -1.0 then
|
|
result := RREAL_X;
|
|
exit;
|
|
end if;
|
|
|
|
-- only process initialized (valid) data
|
|
if r(i).value > -30.0 and r(i).value < 30.0 then
|
|
if r(i).cap > -1.0e12 and r(i).cap < 1.0e12 then
|
|
if r(i).conduct > -1.0e12 and r(i).conduct < 1.0e12 then
|
|
vcapshare := vcapshare + r(i).value * r(i).cap;
|
|
result.value := result.value + r(i).value * r(i).conduct;
|
|
result.cap := result.cap + r(i).cap ;
|
|
if(r(i).conduct > 0.0 ) then
|
|
-- result.conduct := result.conduct + 1.0/r(i).conduct ;
|
|
result.conduct := result.conduct + r(i).conduct ;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
|
|
END LOOP;
|
|
END IF;
|
|
|
|
if result.conduct /= 0.0 then
|
|
result.value := result.value / result.conduct ; -- conductance
|
|
-- result.value := result.value * result.conduct ; -- resistance
|
|
-- result.conduct := 1.0 / result.conduct;
|
|
elsif result.cap >0.0 then
|
|
result.value := vcapshare / result.cap;
|
|
else
|
|
result.value:=0.0;
|
|
end if;
|
|
|
|
RETURN result;
|
|
end resolved_real;
|
|
|
|
procedure transition(
|
|
signal sig: INOUT rreal;
|
|
constant endval: IN real;
|
|
constant del: IN time) is
|
|
|
|
variable step: real;
|
|
variable startval: real;
|
|
variable del2: time;
|
|
begin
|
|
del2 := del;
|
|
if del2 = 0 fs then
|
|
del2 := 1 ns;
|
|
end if;
|
|
startval := sig.value;
|
|
step := (endval-startval);
|
|
if abs(endval-startval) < 0.01 then --do not propagate events if endval very close to startval
|
|
return;
|
|
end if;
|
|
-- sig.value <= endval after del;
|
|
sig.value <= startval,
|
|
startval+0.25*step after del2*0.1,
|
|
startval+0.45*step after del2*0.2,
|
|
startval+0.60*step after del2*0.3,
|
|
startval+0.72*step after del2*0.4,
|
|
startval+0.80*step after del2*0.5,
|
|
startval+0.86*step after del2*0.6,
|
|
startval+0.90*step after del2*0.7,
|
|
startval+0.94*step after del2*0.8,
|
|
startval+0.97*step after del2*0.9,
|
|
endval after del2;
|
|
end transition;
|
|
|
|
|
|
procedure glitch(
|
|
signal sig: INOUT rreal;
|
|
constant lowval: IN real;
|
|
constant endval: IN real;
|
|
constant del: IN time) is
|
|
|
|
variable step: real;
|
|
variable step2: real;
|
|
variable startval: real;
|
|
variable del2 : time;
|
|
begin
|
|
del2 := del;
|
|
if del2 = 0 fs then
|
|
del2 := 1 ns;
|
|
end if;
|
|
startval := sig.value;
|
|
step := (lowval-startval);
|
|
step2 := (lowval-endval);
|
|
if abs(lowval-startval) < 0.01 then --do not propagate events if endval very close to startval
|
|
return;
|
|
end if;
|
|
sig.value <=
|
|
-- startval,
|
|
-- startval+0.25*step after del*0.05,
|
|
-- startval+0.45*step after del*0.1,
|
|
-- startval+0.60*step after del*0.15,
|
|
-- startval+0.72*step after del*0.2,
|
|
-- startval+0.80*step after del*0.25,
|
|
-- startval+0.86*step after del*0.3,
|
|
-- startval+0.90*step after del*0.35,
|
|
-- startval+0.94*step after del*0.4,
|
|
-- startval+0.97*step after del*0.45,
|
|
-- lowval after del*0.5,
|
|
-- lowval-0.25*step2 after del*0.55,
|
|
-- lowval-0.45*step2 after del*0.6,
|
|
-- lowval-0.60*step2 after del*0.65,
|
|
-- lowval-0.72*step2 after del*0.7,
|
|
-- lowval-0.80*step2 after del*0.75,
|
|
-- lowval-0.86*step2 after del*0.8,
|
|
-- lowval-0.90*step2 after del*0.85,
|
|
-- lowval-0.94*step2 after del*0.9,
|
|
-- lowval-0.97*step2 after del*0.95,
|
|
-- endval after del;
|
|
lowval,
|
|
lowval-0.25*step2 after del2*0.1,
|
|
lowval-0.45*step2 after del2*0.2,
|
|
lowval-0.60*step2 after del2*0.3,
|
|
lowval-0.72*step2 after del2*0.4,
|
|
lowval-0.80*step2 after del2*0.5,
|
|
lowval-0.86*step2 after del2*0.6,
|
|
lowval-0.90*step2 after del2*0.7,
|
|
lowval-0.94*step2 after del2*0.8,
|
|
lowval-0.97*step2 after del2*0.9,
|
|
endval after del2;
|
|
|
|
|
|
end glitch;
|
|
|
|
|
|
end rrreal; -- end package body
|
|
}
|
|
C {title.sym} 160 -40 0 0 {name=l9 author="Stefan Schippers"}
|
|
C {arch_declarations.sym} 830 -280 0 0 {
|
|
signal V_VX, V_VX2, V_VXS, V_SP: real;
|
|
|
|
}
|
|
C {lab_wire.sym} 430 -680 0 1 {name=l1 lab=VX sig_type=rrreal }
|