module stat_abl



title 'State machine for Calc design'

"This state machine has 3 states which control the functions 

"of the ALU and the stack.  The states are as follows:

"      SPUSH  -- increment stack pointer

"      SWE    -- write value into stack

"      SOTHER -- do neither (initial state)



"This is a one-hot state machine, which means that only 

" one of the states is active at any given time.  This method 

"is particularly suited for use with Xilinx ABEL and Xilinx 

"FPGAs, which are rich in flip-flop resources.

"This file also generates control signals from equations.

"For an equivalent schematic, see statmach.1.



declarations



"inputs

          OP5, OP4, OP3, OP2, OP1, OP0, EXC        pin;



"clock

          CLK                                      pin;



"outputs

          CTL3, CTL2, CTL1, CTL0                   pin;

          UP_DN, WE, RST, ADD_SUB, CE_ALU, CE_ADDR pin;



"state diagram declarations and assignments

          XABELSM        state_register istype 'reg_d';

          SPUSH, SWE, SOTHER                     state;



"vector definitions

          OP  = [OP5,OP4,OP3,OP2,OP1,OP0];

          HOP = [OP5,OP4,OP3];

          CTL = [CTL3,CTL2,CTL1,CTL0];



"declare internal nodes

          SEL_OP, OP_CTL2, OP_CTL1, OP_CTL0       node;



"node declarations for simulation only, can't use state names 

"in simulation vectors

          PUSH, OTHER                             node;



"define clock & don't-care values for test vectors

          C, X = .C., .X.;



Xilinx property 'initialstate SOTHER';



equations

          XABELSM.CLK  = CLK;

          RST          = (HOP == ^b101) & EXC;

          ADD_SUB      = !OP_CTL2; 

          SEL_OP       = (HOP == ^b111);

          CE_ALU       = !(SEL_OP & OP2 & OP0) & SOTHER & EXC;

          CE_ADDR      = !(OP2 & OP1 & OP0) & SEL_OP & EXC;

          OP_CTL2      = (OP5 & !SEL_OP) # (OP2 & SEL_OP);

          OP_CTL1      = (OP4 & !SEL_OP) # (OP1 & SEL_OP);

          OP_CTL0      = (OP3 & !SEL_OP) # (OP0 & SEL_OP);

          CTL3         = SEL_OP;

          CTL2         = OP_CTL2 & OP_CTL1;

          CTL1         = OP_CTL1 & !OP_CTL2;

          CTL0         = !OP_CTL2 & OP_CTL0;

          UP_DN        = OP2 & !OP1 & OP0 & SEL_OP & EXC;

          PUSH         = SPUSH;

          WE           = SWE;

          OTHER        = SOTHER;



"always optimize out don't-cares

@DCSET



state_diagram XABELSM

          state SPUSH:  goto                               SWE;

          state SWE:    goto                            SOTHER;

          state SOTHER: if                   (UP_DN) then SPUSH

                        else                            SOTHER;



test_vectors

"begin in initial state, each line is one clock cycle



([CLK,EXC,OP]->[PUSH,WE,OTHER,ADD_SUB,RST,CE_ALU,CE_ADDR,CTL])



"quick check to test the state machine

[ C, 0,   X ]->[  0,  0,  1,    X,     X,    X,     X,    X  ];

[ C, 1, ^h3F]->[  0,  0,  1,    X,     X,    X,     X,    X  ];

[ C, 0,   X ]->[  0,  0,  1,    X,     X,    X,     X,    X  ];

[ C, 1, ^h3D]->[  1,  0,  0,    X,     X,    X,     X,    X  ];

[ C, 0,   X ]->[  0,  1,  0,    X,     X,    X,     X,    X  ];

[ C, 0,   X ]->[  0,  0,  1,    X,     X,    X,     X,    X  ];

[ C, 1, ^h38]->[  0,  0,  1,    X,     X,    X,     X,    X  ];



"test the control logic, EXC low

[ C, 0, ^h0 ]->[  0,  0,  1,    1,     0,    0,     0,   ^h0 ];

[ C, 0, ^h8 ]->[  0,  0,  1,    1,     0,    0,     0,   ^h1 ];

[ C, 0, ^h10]->[  0,  0,  1,    1,     0,    0,     0,   ^h2 ];

[ C, 0, ^h18]->[  0,  0,  1,    1,     0,    0,     0,   ^h3 ];

[ C, 0, ^h20]->[  0,  0,  1,    0,     0,    0,     0,   ^h0 ];

[ C, 0, ^h28]->[  0,  0,  1,    0,     0,    0,     0,   ^h0 ];

[ C, 0, ^h30]->[  0,  0,  1,    0,     0,    0,     0,   ^h4 ];

"extended instruction set

[ C, 0, ^h38]->[  0,  0,  1,    1,     0,    0,     0,   ^h8 ];

[ C, 0, ^h39]->[  0,  0,  1,    1,     0,    0,     0,   ^h9 ];

[ C, 0, ^h3A]->[  0,  0,  1,    1,     0,    0,     0,   ^hA ];

[ C, 0, ^h3B]->[  0,  0,  1,    1,     0,    0,     0,   ^hB ];

[ C, 0, ^h3C]->[  0,  0,  1,    0,     0,    0,     0,   ^h8 ];

[ C, 0, ^h3D]->[  0,  0,  1,    0,     0,    0,     0,   ^h8 ];

[ C, 0, ^h3E]->[  0,  0,  1,    0,     0,    0,     0,   ^hC ];

[ C, 0, ^h3F]->[  0,  0,  1,    0,     0,    0,     0,   ^hC ];



"test the control logic, EXC high

[ C, 1, ^h0 ]->[  0,  0,  1,    1,     0,    1,     0,   ^h0 ];

[ C, 1, ^h8 ]->[  0,  0,  1,    1,     0,    1,     0,   ^h1 ];

[ C, 1, ^h10]->[  0,  0,  1,    1,     0,    1,     0,   ^h2 ];

[ C, 1, ^h18]->[  0,  0,  1,    1,     0,    1,     0,   ^h3 ];

[ C, 1, ^h20]->[  0,  0,  1,    0,     0,    1,     0,   ^h0 ];

[ C, 1, ^h28]->[  0,  0,  1,    0,     1,    1,     0,   ^h0 ];

[ C, 1, ^h30]->[  0,  0,  1,    0,     0,    1,     0,   ^h4 ];

"extended instruction set

[ C, 1, ^h38]->[  0,  0, 1,    1,      0,    1,     1,   ^h8 ];

[ C, 1, ^h39]->[  0,  0, 1,    1,      0,    1,     1,   ^h9 ];

[ C, 1, ^h3A]->[  0,  0, 1,    1,      0,    1,     1,   ^hA ];

[ C, 1, ^h3B]->[  0,  0, 1,    1,      0,    1,     1,   ^hB ];

[ C, 1, ^h3C]->[  0,  0, 1,    0,      0,    1,     1,   ^h8 ];

[ C, 1, ^h3D]->[  1,  0, 0,    0,      0,    0,     1,   ^h8 ];



"insert two clocks to return to initial state

[ C, 0, ^h3D]->[  0,  1, 0,    0,      0,    0,     0,   ^h8 ];

[ C, 0, ^h3D]->[  0,  0, 1,    0,      0,    0,     0,   ^h8 ];

[ C, 1, ^h3E]->[  0,  0, 1,    0,      0,    1,     1,   ^hC ];

[ C, 1, ^h3F]->[  0,  0, 1,    0,      0,    0,     0,   ^hC ];



end stat_abl

