!Rom Finite State Machine Simulator !RWT 1985 ! Input: ! Number of inputs ! Input Names ! Number of Outputs ! Output Names ! Number of state bits ! { state : { = clone-state } { Output = expression }* ! { next-state-number expression }* ; }* . ! Expressions involve input names, 0, 1, and )(+.\ and are ! terminated by a colon, thereby allowing them to extend ! over several lines. ! Output: ! A binary file for each byte the rom is wide. ! The state bits form the most significant part of both ! address and data, the input and output bits increase ! in significance, i.e. the first input bit is the least ! significant address bit, the last output bit is the most ! significant data bit (but less significant than the least ! significant state bit). %begin %include "inc:util.imp" %string(31)file = cliparam file = file.tostring('.') openinput(1,file."fsm"); selectinput(1) %integer line=1, pend=-1, i %integer inputs, outputs, statebits %integer inbits, outbits, max %integer errorcount=0 %routine error(%string(255)s) errorcount = errorcount+1 printstring(s." at line "); write(line,0); newline selectoutput(0) printstring(s." at line "); write(line,0); newline selectoutput(1) %end %routine wbsym(%integer x); !Write back symbol pend = x %end %integerfn rsym; !Read symbol, skip comments, count lines %integer x x = pend; pend = -1; %result = x %unless x<0 %cycle readsymbol(x); line = line+1 %if x=nl %if x='{' %start %cycle readsymbol(x); line = line+1 %if x=nl %repeatuntil x='}' %elseif x='|' readsymbol(x) %until x=nl line = line+1 %finishelseresult = x %repeat %end %integerfn sigsym; !Read significant symbol %integer x x = rsym %until ' '#x#nl %result = x %end %integerfn rdec; !Read decimal number %integer x=sigsym,n=0 %unless '0'<=x<='9' %start error("Warning: decimal number expected") %result = 0 %finish %cycle %exitunless '0'<=x<='9' n = n*10-'0'+x x = rsym %repeat wbsym(x); %result = n %end %routine rname(%string(15)%name s); !Read signal name or special symbol %integer x = sigsym s = tostring(x) %returnunless 'A'<=x&95<='Z' %cycle x = rsym %exitunless 'A'<=x&95<='Z' %or '0'<=x<='9' %or x='''' s = s.tostring(x) %repeat wbsym(x) %end inputs = rdec %string(15)%array in(0:inputs); !0 never used rname(in(i)) %for i=1,1,inputs outputs = rdec %begin %string(15)%array out(0:outputs); !0 never used rname(out(i)) %for i=1,1,outputs statebits = rdec inbits = statebits+inputs outbits = statebits+outputs %if outbits>32 %start error("Rom too wide"); %stop %finish max = 1<=0 %then printsymbol(op(x)) %else write(x,0); newline %returnif x=left error("Expression too complex") %if pd>=maxstack pd = pd+1; opd(pd) = x %end %integerfn tpop; !off operator stack {printstring("Tpop:") %result = 0 %if pt<=0 pt = pt-1; %result = opt(pt+1) %end %routine tpush(%integer x); !onto operator stack %integer y {printstring("Tpush "); %if x>=0 %then printsymbol(op(x)) %else write(x,0); newline %unless x=left %start %while pt>0 %and x<=opt(pt) %cycle; !flush high-prec ops y = tpop; %exitif x=right %and y=left dpush(y) %repeat %finish %returnif x=right error("Expression too complex") %if pt>=maxstack pt = pt+1; opt(pt) = x %end ! Part 1 of EXPR: read expression and build reverse polish list pd = 0; pt = 0; tpush(left); !Initial open bracket %cycle rname(s); k = charno(s,1) %if k='(' %start m(d,d); tpush(left) %elseif k=')' m(t,t); tpush(right) %if pt=0 %start error("Spurious ')'") k = rsym %until k=',' %or k=';'; %exit %finish %elseif k='+' m(t,d); tpush(or) %elseif k='.' m(t,d); tpush(and) %elseif k='\' m(d,d); tpush(not) %elseif k=',' %or k=';' wbsym(k) %unless k=',' m(t,0); tpush(right) %unless pt=0 %start error("Premature ','") %exit %finish %exit %elseif k='0' m(d,t); dpush(zero) %elseif k='1' m(d,t); dpush(one) %else m(d,t); k = inputs %while k>0 %cycle %exitif in(k)=s; k = k-1 %repeat %if k=0 %start error("Unknown operand ".s) k = 0 %finish dpush(-k) %finish %repeat ! Part 2 of EXPR: evaluate expression just built %integer p=0 %integer stackbit=1,nextbit,i %while p>1 p = p+1; k = opd(p) %if k=one %start e(i) = e(i)!stackbit %for i=low,1,high stackbit = stackbit<<1 %elseif k=zero e(i) = e(i)&\stackbit %for i=low,1,high stackbit = stackbit<<1 %elseif k=not e(i) = e(i)!!nextbit %for i=low,1,high %elseif k=and stackbit = nextbit; nextbit = nextbit>>1 %for i=low,1,high %cycle e(i) = e(i)&\nextbit %if e(i)&stackbit=0 %repeat %elseif k=or stackbit = nextbit; nextbit = nextbit>>1 %for i=low,1,high %cycle e(i) = e(i)!nextbit %if e(i)&stackbit#0 %repeat %else k = 1<<(-1-k) %for i=low,1,high %cycle %if i&k#0 %start e(i) = e(i)!stackbit %else e(i) = e(i)&\stackbit %finish %repeat stackbit = stackbit<<1 %finish %repeat error("Bit lost") %unless stackbit=2 e(i) = e(i)&1 %for i=low,1,high %end %routine equals %integer x = sigsym %returnif x='=' wbsym(x) error("Warning: '=' expected") %end %routine setoutput %string(15)o; rname(o) %integer k,i equals k = outputs %while k>0 %cycle %exitif out(k)=o k = k-1 %repeat error("Unknown output ".o) %if k=0 k = 1<<(k-1) expr %for i=low,1,high %cycle %if e(i)=0 %then a(i) = a(i)&\k %else a(i) = a(i)!k %repeat %end %routine nextstate %integer i,old,new,f=0 new = rdec; equals; expr %for i=low,1,high %cycle %if e(i)#0 %start old = a(i)>>outputs error("Ambiguous next state") %and f=1 %if old#state %and f=0 a(i) = a(i)!!(old!!new)<>outputs<0 %cycle %exitif in(i)=signal; i = i-1 %repeat %if i=0 %start printstring("Unknown signal ".signal); newline %else i = 1<<(i-1) %if mode=clear %start inbits = inbits&\i %elseif mode=set inbits = inbits!i %else inbits = inbits!!i %finish %finish %repeat %end %routine show state %integer i printstring("State:") i = inputs+statebits %cycle %exitif i=inputs i = i-1 space; printsymbol(inbits>>i&1+'0') %repeat newline printstring("Inputs:"); phex4(inbits) %while i>0 %cycle space; printstring(in(i)); printsymbol('=') i = i-1 printsymbol(inbits>>i&1+'0') %repeat newline printstring("Next state:") i = outputs+statebits %cycle %exitif i=outputs i = i-1 space; printsymbol(outbits>>i&1+'0') %repeat newline printstring("Outputs:"); phex(outbits) %while i>0 %cycle space; printstring(out(i)); printsymbol('=') i = i-1 printsymbol(outbits>>i&1+'0') %repeat newline %end selectinput(0); wbsym(-1) %cycle sym = rsym %if sym=nl %start {clock tick !!phex(inbits); space; phex(a(inbits)); space outbits = a(inbits) !!phex(outbits); newline show state feedback %elseif sym='0' list(clear) %elseif sym='1' list(set) %else wbsym(sym) list(complement) %finish %repeat %end %end %endofprogram