Cedar
ALUOpcode: TYPE = {Add, Sub, Or, And, Xor, PassLeft};
preShiftOpcode: TYPE = {ShNop, Sh1R};
postShiftOpcode: TYPE = {ShNop, Sh2R, Sh1R, Sh1L, PassLeft};
mqOpcode: TYPE = {NoOp, Read, Write, Sh2R, Sh1L};
carrySelChoice: TYPE = {Zero, PrevC, PrevCbar, Update, UpdateBar};
Returns a+b+carryIn and carryOut, where a and b are considered to be signed numbers
DoubleADD:
PROC[al, bl: Dragon.HexWord, carryIn:
BOOL]
RETURNS [sl: Dragon.HexWord, carryOut: BOOL] = {
Xor:
PROC[x, y:
BOOL]
RETURNS [z:
BOOL] =
{RETURN[(x AND NOT y) OR (y AND NOT x)]};
ai, bi: BOOL;
s: BOOL ← FALSE;
c: BOOL ← carryIn;
sum: BitOps.BitDWord ← [0,0];
FOR i:
INTEGER
IN [1..32]
DO
ai ← EBFL[al, 32-i];
bi ← EBFL[bl, 32-i];
s ← Xor[ai, Xor[bi, c]];
c ← Dragon.MoreThanOneOf[ai, bi, c]; -- c ← (ai AND bi) OR (bi AND c) OR (ai AND c);
sum ← BitOps.IBID[s, sum, 32, 32-i];
ENDLOOP;
RETURN[LFD[sum], c]};
Returns a-b-carryIn and carryOut, where a and b are considered to be signed numbers
Implemented as a+(~b)+1+(~carryIn)
DoubleSUB:
PROC[a, b: Dragon.HexWord, carryIn:
BOOL]
RETURNS [dif: Dragon.HexWord, carryOut:
BOOL] ={
[dif, carryOut] ← DoubleADD[a, WordOp[not,b], NOT carryIn]};
Shift1RDtoD:
PROC[i0:
BOOL, w: Dragon.HexWord]
RETURNS [sh: Dragon.HexWord, s31:
BOOL] =
BEGIN
s31 ← BitOps.EBFD[LTD[w], 32, 31];
sh ← LFD[BitOps.MDTD[LTD[w], 32, 0 , 31, LTD[sh], 32, 0, 31]];
sh ← BitOps.IBID[i0, LTD[sh], 32, 0];
END;
Shift2RDtoD:
PROC[i0, i1:
BOOL, w: Dragon.HexWord]
RETURNS [sh: Dragon.HexWord, s30, s31:
BOOL] =
BEGIN
sh ← LFD[BitOps.MDTD[LTD[w], 32, 0 , 30, LTD[sh], 32, 0, 30]];
sh ← BitOps.IBID[i0, LTD[sh], 32, 0];
sh ← BitOps.IBID[i1, LTD[sh], 32, 1];
s30 ← BitOps.EBFD[LTD[w], 32, 30];
s31 ← BitOps.EBFD[LTD[w], 32, 31];
END;
ALUOpcodeCtrl:
CELL [
Bits In and Out
EUAluOpAB< EnumType["Dragon.ALUOps"], -- sent on 2A, used during 2B. Not latched by EU.
mqAB30, mqAB31 < BOOL,
carryAB < BOOL,
LeftOpSign < BOOL,
preShiftOp > EnumType["preShiftOpcode"],
postShiftOp > EnumType["postShiftOpcode"],
ALURealOp > EnumType["ALUOpcode"],
mqOp > EnumType["mqOpcode"],
CarryIn > BOOL,
carryBASelect > EnumType["carrySelChoice"],
saveLeftOp > BOOL,
Timing and housekeeping interface
rejectBA < BOOL,
PhA, PhB<BOOL,
ResetAB<BOOL,
Vdd, Gnd, PadVdd, PadGnd<BOOL
]
State
prevSubBA: BOOL, -- Set iff EUAluOpAB=MulStep and ALURealOp=Sub
EvalSimple
IF PhA
AND
NOT rejectBA
THEN {
prevSubBA ← mqAB30; -- for next cycle
};
IF PhB
THEN {
-- control signals fired during PhB
The default values
preShiftOp ← ShNop;
postShiftOp ← ShNop;
ALURealOp ← PassLeft; -- safe, but in fact not such a common opcode
mqOp ← NoOp;
CarryIn ← FALSE; -- Depends on how OR, AND, ..., are implemented
carryBASelect ← PrevC; -- just recycle
SELECT EUAluOpAB
FROM
SAdd => {
ALURealOp ← Add;
CarryIn ← carryAB;
carryBASelect ← Zero;
};
SSub => {
ALURealOp ← Sub;
CarryIn ← carryAB;
carryBASelect ← Zero;
};
UAdd => {
ALURealOp ← Add;
CarryIn ← carryAB;
carryBASelect ← Update;
};
USub => {
ALURealOp ← Sub;
CarryIn ← carryAB;
carryBASelect ← UpdateBar;
};
VAdd => {
ALURealOp ← Add;
};
VSub => {
ALURealOp ← Sub;
};
LAdd => {
ALURealOp ← Add;
carryBASelect ← Zero;
};
LSub => {
ALURealOp ← Sub;
carryBASelect ← Zero;
};
FOP, FOPK => {
-- nothing to do, action in the Field Unit
};
And => {
ALURealOp ← And;
};
Or => {
ALURealOp ← Or;
};
Xor => {
ALURealOp ← Xor;
};
BndChk => {
-- BC ← NOT ( aluLeft IN [0..aluRight) ),
AluOut ←
aluLeftBus
postShiftOp ← PassLeft;
ALURealOp ← Sub; -- we throw away the result and pass the left op
};
LoadDouble => {
postShiftOp ← PassLeft; -- load Result2B with LeftOperand (=0 please)
mqOp ← Write; -- load mq with RightOperand
};
MulStep => {
zero:
BOOL ←
-- 000 or 111
mqAB30 AND mqAB31 AND prevSubBA OR
~mqAB30 AND ~mqAB31 AND ~prevSubBA;
two:
BOOL ←
-- 011 or 100
mqAB30 AND ~mqAB31 AND ~prevSubBA OR
~mqAB30 AND mqAB31 AND prevSubBA;
one: BOOL ← ~zero AND ~two; -- the other cases
SELECT
TRUE
FROM
zero => {
-- pass left, shift 2R [aluOut, mqAB] with sign extension
postShiftOp ← Sh2R; -- with sign extension
mqOp ← Sh2R; -- left bits from aluOut
};
one => {
-- either add or sub, then shift 2R with sign extension
carryBASelect ← Update;
ALURealOp ← IF mqAB30 THEN Sub ELSE Add;
postShiftOp ← Sh2R; -- with sign extension
mqOp ← Sh2R; -- left bits from aluOut
};
two => {
-- shift 1R aluLeft, then add or sub, then shift 1R aluOut
preShiftOp ← Sh1R;
carryBASelect ← Update;
ALURealOp ← IF mqAB30 THEN Sub ELSE Add;
postShiftOp ← Sh1R; -- sign extension
mqOp ← Sh2R; -- left bit: aluOut31, LeftOp31
ENDCASE => ERROR};
RdMQ => {
mqOp ← Read; -- we read mq, i.e. we put its value in Result2B
};
DivStep => {
postShiftOp ← Sh1L;
ALURealOp ← Sub;
carryBASelect ← Update;
mqOp ← Sh1L; -- left bit from AluOut
saveLeftOp ← ; -- depends on N, so see timing
};
LastDivStep => {
-- same, but shift only mq
};
ENDCASE => ERROR Stop["Invalid ALU Operation"];
};