171 lines
3.9 KiB
Awk
Executable File
171 lines
3.9 KiB
Awk
Executable File
#!/usr/bin/awk -f
|
|
# File: clock.awk
|
|
#
|
|
# This file is part of XSCHEM,
|
|
# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
|
|
# simulation.
|
|
# Copyright (C) 1998-2023 Stefan Frederik Schippers
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
|
#
|
|
# plugin for clock expansion
|
|
#
|
|
# clock <signal> <pulse> <period> [invert] [high value] [low value]
|
|
#
|
|
# _______ _______
|
|
#___________________| |____________| |__________
|
|
# | | |
|
|
# |<pulse>| |
|
|
# |<----- period ----->|
|
|
# |
|
|
# clock_start
|
|
# Stefan, 04122001
|
|
|
|
|
|
|
|
BEGIN {
|
|
OFMT="%.14g" # better precision
|
|
CONVFMT="%.14g"
|
|
old_event=-1
|
|
}
|
|
|
|
## stefan fix 20100630: reset absolute time if multiple beginfile--endfile given
|
|
/^[ \t]*beginfile[ \t]+/{
|
|
time=0
|
|
}
|
|
|
|
/^[ \t]*clock[ \t]+/{
|
|
|
|
sub(/[ \t]*;.*/,"")
|
|
clock_name = $2
|
|
clock_start[clock_name]=time
|
|
clock_pulse[clock_name] = $3 + time
|
|
clock_period[clock_name] = $4
|
|
clock_state[clock_name] = ($5 == "invert") ? 0 : 1
|
|
if($5=="invert") {
|
|
if($6!="") clock_high[clock_name]=$6
|
|
else clock_high[clock_name]=1
|
|
if($7!="") clock_low[clock_name]=$7
|
|
else clock_low[clock_name]=0
|
|
} else {
|
|
if($5!="") clock_high[clock_name]=$5
|
|
else clock_high[clock_name]=1
|
|
if($6!="") clock_low[clock_name]=$6
|
|
else clock_low[clock_name]=0
|
|
}
|
|
|
|
print "set " clock_name " " value(clock_name, clock_state[clock_name])
|
|
next
|
|
}
|
|
|
|
/[ \t]*stop_clock[ \t]+/{
|
|
delete clock_start[$2]
|
|
delete clock_pulse[$2]
|
|
delete clock_period[$2]
|
|
delete clock_state[$2]
|
|
delete clock_high[$2]
|
|
delete clock_low[$2]
|
|
k=0; for(i in clock_start) {k=1}
|
|
if(!k) clock_name=""
|
|
next
|
|
}
|
|
|
|
|
|
|
|
|
|
/^[ \t]*s[ \t]+/{
|
|
go_to_time($2+time)
|
|
next
|
|
}
|
|
|
|
/^[ \t]*time[ \t]+/{
|
|
go_to_time($2)
|
|
next
|
|
}
|
|
|
|
{ print }
|
|
|
|
function go_to_time(to_time)
|
|
{
|
|
|
|
if(clock_name)
|
|
{
|
|
while((a=next_event()) <= to_time)
|
|
{
|
|
if(a>time) print "s " a - time " ;" a
|
|
m=split(current_clock, tmp)
|
|
for(i=1;i<=m;i++)
|
|
{
|
|
clock_state[tmp[i]]=!clock_state[tmp[i]]
|
|
print "set " tmp[i] " " value(tmp[i], clock_state[tmp[i]]) " ;" a
|
|
time =a
|
|
}
|
|
}
|
|
}
|
|
if(to_time > time)
|
|
{
|
|
print "s " to_time - time " ;" to_time
|
|
time=to_time
|
|
}
|
|
|
|
}
|
|
|
|
function next_event( k, i, clock_event1, clock_event2)
|
|
{
|
|
k=0
|
|
for(i in clock_start)
|
|
{
|
|
clock_event1 = int( (time-clock_start[i])/clock_period[i])*clock_period[i] + clock_start[i]
|
|
while(clock_event1 <= time) {
|
|
clock_event1+=clock_period[i]
|
|
}
|
|
clock_event2 = int( (time-clock_pulse[i])/clock_period[i])*clock_period[i] + clock_pulse[i]
|
|
while(clock_event2 <= time) {
|
|
clock_event2+=clock_period[i]
|
|
}
|
|
if(clock_event1 < clock_event2)
|
|
clock_event = clock_event1+0
|
|
else
|
|
clock_event = clock_event2+0
|
|
if(!k) { event=clock_event ; current_clock=i; k=1}
|
|
else if(clock_event < event)
|
|
{
|
|
event = clock_event
|
|
current_clock=i
|
|
}
|
|
else if( abs(clock_event - event)<1e-12 )
|
|
{
|
|
current_clock = current_clock " " i
|
|
}
|
|
|
|
print "; time= " time " next event = " clock_event " " i " event=" event
|
|
}
|
|
return event
|
|
|
|
}
|
|
|
|
function value(clock_name, i) {
|
|
if(i==1) return clock_high[clock_name]
|
|
else return clock_low[clock_name]
|
|
}
|
|
|
|
function abs(x)
|
|
{
|
|
return x<0? -x : x
|
|
}
|
|
|