#!/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 [invert] [high value] [low value] # # _______ _______ #___________________| |____________| |__________ # | | | # || | # |<----- 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 }