-- Brian Doherty -- Nathan Morse -- Nathan Pritchard -- Elec 422 - Course Project -- Detailed Control Description (meg format) INPUTS : -- The RESTART signal allows the ALU to be returned to a clean initial -- state from any point. RESTART -- The PLA must be "told" what operation is being performed. The 6 bits -- stored in the opcode register do this. OP5 OP4 OP3 OP2 OP1 OP0 -- These signals are used to tell th ALU when the inputs are valid. -- 11 => opcode is ready. 01 => A input is ready. 10 => B input is ready. STROBE1 STROBE0; OUTPUTS : -- READY1 and READY0 are used by the ALU to indicate when outputs are -- valid. 11 indicates that the ALU is not performing any operation -- and it is ready for an opcode. The OUT register is only guaranteed -- to be valid as long as this is true. Of course, the -- output is not valid on RESTART. Perhaps it should be zeroed? -- 01 indicates that a valid opcode has been recognized and the ALU is -- waiting for the A input. 10 indicates that the current operation -- requires two operands, and the ALU is waiting for the B input. READY1 READY0 -- There are four internal registers which are controlled by the PLA: -- OP (the opcode register), A (the first operand register), B (the -- second operand register), and OUT (the output register). When -- the appropriate signal is asserted, the data on the input of the -- register will flow to the output of the appropriate latch. When -- the signal is deasserted, the new data will be latched. LATCHOP LATCHA LATCHB LATCHOUT -- The input register B is designed to implement a self- -- shifting mechanism for the multiplication algorithm described below. -- When the appropriate latching signal is asserted, the new register -- value will come from the input bus if the corresponding LOAD signal -- is asserted. If the LOAD signal is deasserted, the new value will -- be a shifted version of the previous value. LOADB -- Each functional unit inside the ALU is capable of driving the output -- bus. We must make sure at most one unit does this at a time. Each unit -- will have a block of transmission gates at the output that will be -- enabled when the appropriate signal is asserted. ADDOUT SHIFTOUT LOGICOUT -- Multiplication makes use of the adder and some internal logic to -- perform a shift-and-add algorithm. The details are described below. -- The only additional signal required is for resetting the output of -- the adder/multiplier to all zeroes before beginning the operation. MRESET -- For now, we have an error flag to tell us if something really -- bad is happening. ERROR; reset on RESTART to idle( READY1 READY0 LATCHOP LATCHA LATCHB LOADB ); -- Loop until the input STROBE signals are asserted. The READY flags -- are asserted while in this state. Latch the opcode on the transition. idle : CASE ( STROBE1 STROBE0 OP5 OP4 OP3 OP2 OP1 OP0 ) -- grab the opcode 1 1 ? ? ? ? ? ? => loada( READY0 LATCHOP ); -- else loop without error ENDCASE => idle( READY1 READY0 ); -- We have to wait until STROBE1 STROBE0 = 01 until we go on. -- Single-operand operations are done and will loop back to idle. -- For all others, we load the B latch and get ready to latch the output -- (or start multiplying). Opcode bits control the details of -- operations at the units themselves. Except for MRESET, which -- should be asserted so that it is high when B is finally latched. loada : CASE ( STROBE1 STROBE0 OP5 OP4 OP3 OP2 OP1 OP0 ) -- single-operand instructions 0 1 0 0 ? ? 0 0 => idle( LOGICOUT LATCHOUT READY1 READY0 LATCHA ); -- multiplication 0 1 1 0 0 0 0 0 => loadb( READY1 LATCHA ); -- other stuff 0 1 0 1 ? 0 0 ? => loadb( READY1 LATCHA ); 0 1 0 1 0 ? 1 0 => loadb( READY1 LATCHA ); 0 1 0 1 0 1 0 0 => loadb( READY1 LATCHA ); 0 1 0 0 ? ? 1 ? => loadb( READY1 LATCHA ); 0 1 0 0 ? ? 0 1 => loadb( READY1 LATCHA ); -- not ready yet 0 0 ? ? ? ? ? ? => loada( READY0 ); 1 ? ? ? ? ? ? ? => loada( READY0 ); -- invalid opcode ENDCASE => idle( READY1 READY0 ERROR); -- Many operations only take one cycle. The signals asserted in the -- transition take care of guiding the data flow. We need one more -- transtition to enable the appropriate output and latch the output data. -- On the transition back to the idle state, the next opcode can be -- latched. loadb : CASE ( STROBE1 STROBE0 OP5 OP4 OP3 OP2 OP1 OP0 ) -- start multiplying 1 0 1 ? ? ? ? ? => mult1( LOADB LATCHB MRESET ADDOUT LATCHOUT ); -- don't start multiplying yet 0 ? 1 ? ? ? ? ? => loadb( READY1 ); -- Use the output of the adder. 1 0 0 1 1 ? ? ? => idle( ADDOUT LATCHOUT READY1 READY0 LOADB LATCHB ); -- Use the output of the logic block. 1 0 0 0 ? ? ? ? => idle( LOGICOUT LATCHOUT READY1 READY0 LOADB LATCHB ); -- Use the output of the shifter. 1 0 0 1 0 ? ? ? => idle( SHIFTOUT LATCHOUT READY1 READY0 LOADB LATCHB ); -- keep waiting for input b ENDCASE => loadb( READY1 ); -- Multiplication is a 9-cycle shift-and-add operation (the ninth cycle -- completes the shifting of the output register and loads the final result -- into the upper 8 bits of the output register). The B and OUT register -- are shifted on every cycle, and cause either A or zeroes to be added to -- the previous output, depending on bit 0 of the B register. The first -- cycle is during the transition to "mult1," and the last cycle is the -- transition to "idle." mult1 : GOTO mult2( LATCHB ADDOUT LATCHOUT ); mult2 : GOTO mult3( LATCHB ADDOUT LATCHOUT ); mult3 : GOTO mult4( LATCHB ADDOUT LATCHOUT ); mult4 : GOTO mult5( LATCHB ADDOUT LATCHOUT ); mult5 : GOTO mult6( LATCHB ADDOUT LATCHOUT ); mult6 : GOTO mult7( LATCHB ADDOUT LATCHOUT ); mult7 : GOTO mult8( LATCHB ADDOUT LATCHOUT ); mult8 : GOTO idle( LATCHB ADDOUT LATCHOUT READY1 READY0 );