xschem/xschem_library/examples/loading.vhdl

641 lines
14 KiB
VHDL
Raw Normal View History

2020-08-08 15:47:34 +02:00
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
library ieee;
use std.TEXTIO.all;
use ieee.std_logic_1164.all;
library work;
use work.rrreal.all;
entity loading is
end loading ;
architecture arch_loading of loading is
component pump
generic (
val : real := 4.5 ;
conduct : real := 10.0
);
port (
USC : inout rreal ;
ING : in std_logic
);
end component ;
component switch_rreal
generic (
del : time := 2 ns
);
port (
ENAB : in std_logic ;
B : inout rreal ;
A : inout rreal
);
end component ;
component real_capa
generic (
cap : real := 10.0
);
port (
USC : inout rreal
);
end component ;
signal SW : std_logic ;
signal VXS : rrreal ;
signal SW1 : std_logic ;
signal VX : rrreal ;
signal SW2 : std_logic ;
signal ING1 : std_logic ;
signal ING : std_logic ;
signal SP : rrreal ;
signal VX2 : rrreal ;
begin
x4 : pump
generic map (
conduct => 1.0/20000.0 ,
val => 4.5
)
port map (
USC => VX ,
ING => ING
);
x5 : switch_rreal
generic map (
del => 2 ns
)
port map (
ENAB => SW ,
B => VXS ,
A => VX
);
x3 : real_capa
generic map (
cap => 30.0
)
port map (
USC => VX
);
x1 : real_capa
generic map (
cap => 100.0
)
port map (
USC => VXS
);
x2 : switch_rreal
generic map (
del => 2 ns
)
port map (
ENAB => SW1 ,
B => SP ,
A => VXS
);
x6 : real_capa
generic map (
cap => 20.0
)
port map (
USC => SP
);
x7 : pump
generic map (
conduct => 1.0/40000.0 ,
val => 3.0
)
port map (
USC => VX2 ,
ING => ING1
);
x8 : switch_rreal
generic map (
del => 2 ns
)
port map (
ENAB => SW2 ,
B => VXS ,
A => VX2
);
x9 : real_capa
generic map (
cap => 40.0
)
port map (
USC => VX2
);
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;
end arch_loading ;
-- expanding symbol: templates/pump # of pins=2
library ieee;
use std.TEXTIO.all;
use ieee.std_logic_1164.all;
use work.rrreal.all;
library work;
use work.rrreal.all;
entity pump is
generic (
val : real := 4.5 ;
conduct : real := 10.0
);
port (
USC : inout rreal ;
ING : in std_logic
);
end pump ;
architecture arch_pump of pump is
begin
process
variable del: time := 0.4 ns;
variable delay: time;
variable last : time;
variable lowvalue: real;
begin
wait on ING , USC.cap;
last := now;
delay := del * USC.cap;
print("start pump process: " & pump'PATH_NAME & " " & time'image(now) );
if(now=0 ns) then
USC <= RREAL_0;
elsif ING'event and ING='1' then
USC.conduct<=conduct;
transition(USC,val,delay);
elsif ING'event and ING='0' then
USC.conduct<=conduct;
transition(USC,0.0,delay);
elsif USC.cap'event and USC.cap > USC.cap'last_value and ING='1' then
lowvalue := USC.value * USC.cap'last_value / USC.cap;
glitch(USC, lowvalue, val, delay);
end if;
end process;
end arch_pump ;
-- expanding symbol: templates/switch_rreal # of pins=3
library ieee,work;
use ieee.std_logic_1164.all;
use work.rrreal.all;
use std.textio.all;
entity switch_rreal is
generic (
del : time := 2 ns
);
port (
ENAB : in std_logic ;
B : inout rreal ;
A : inout rreal
);
end switch_rreal ;
architecture arch_switch_rreal of switch_rreal is
signal SCHEDULE : integer ;
procedure print2( signal x : in rreal) is
begin
print(" " & x'SIMPLE_NAME & ".value=" & real'image(x.value)& " t= " & time'image(now) );
print(" " & x'SIMPLE_NAME & ".cap=" & real'image(x.cap) & " t= " & time'image(now));
print(" " & x'SIMPLE_NAME & ".conduct=" & real'image(x.conduct) & " t= " & time'image(now));
end print2;
begin
process
variable last : time;
variable aa,bb : rreal;
begin
wait until ( SCHEDULE'transaction'event or A'event or B'event or ENAB'event ) and now>last;
last := now;
print(switch_rreal'PATH_NAME & " start switch process: " & time'image(now) );
if now= 0 ns then
aa:=rreal'(0.0,0.0,0.0);
bb:=rreal'(0.0,0.0,0.0);
A <= aa ;
B <= bb ;
elsif ENAB'event and ENAB='1' then SCHEDULE <= 4 after del;
elsif ENAB'event and ENAB='0' then SCHEDULE <= 3 after del;
elsif B'event and ENAB='1' then SCHEDULE <= 2 after del;
elsif A'event and ENAB='1' then SCHEDULE <= 1 after del;
elsif SCHEDULE'transaction'event and SCHEDULE=3 then -- ENAB=0 event
print(switch_rreal'PATH_NAME & " release outputs: " & time'image(now) );
aa:=rreal'(0.0,0.0,0.0);
bb:=rreal'(0.0,0.0,0.0);
A <= aa ;
B <= bb ;
elsif SCHEDULE'transaction'event and SCHEDULE=4 then -- ENAB=1 event
aa := B;
bb := A;
A <= aa ;
print(switch_rreal'PATH_NAME & " enab forcing A, done: " & time'image(now) );
print2(A);
B <= bb ;
print(switch_rreal'PATH_NAME & " enab forcing B, done: " & time'image(now) );
print2(B);
elsif SCHEDULE'transaction'event and SCHEDULE=2 then -- B event
print(switch_rreal'PATH_NAME & " B'event: " & time'image(now) );
aa.conduct := B.conduct - bb.conduct;
aa.cap := B.cap - bb.cap;
if aa.conduct /= 0.0 then
aa.value := ( B.value * B.conduct - bb.value * bb.conduct) / aa.conduct;
else
aa.value := B.value;
end if;
A <= aa ;
elsif SCHEDULE'transaction'event and SCHEDULE=1 then -- A event
print(switch_rreal'PATH_NAME & " A'event: " & time'image(now) );
bb.conduct := A.conduct - aa.conduct;
bb.cap := A.cap - aa.cap;
if bb.conduct /= 0.0 then
bb.value := ( A.value * A.conduct - aa.value * aa.conduct) / bb.conduct;
else
bb.value := A.value;
end if;
B <= bb ;
end if; -- now = 0
end process;
end arch_switch_rreal ;
-- expanding symbol: templates/real_capa # of pins=1
library ieee;
use std.TEXTIO.all;
use ieee.std_logic_1164.all;
use work.rrreal.all;
library work;
use work.rrreal.all;
entity real_capa is
generic (
cap : real := 10.0
);
port (
USC : inout rreal
);
end real_capa ;
architecture arch_real_capa of real_capa is
begin
process
variable buf: LINE;
variable last : time;
variable val : real;
begin
if now = 0 ns then
last := now;
USC.cap <=cap;
USC.conduct <=0.0;
USC.value <= 0.0;
end if;
wait on USC until last /=now;
last := now;
WRITE(buf,string'("start real_capa process"));
WRITELINE(output,buf);
USC.conduct <= 0.0;
USC.cap <= cap ;
val := USC'LAST_VALUE.value;
if now = 0 ns then
USC.value <= 0.0;
else
USC.value <= val;
end if;
end process;
end arch_real_capa ;