program SimulaUla; { Nesse programa h  duas versoes da rotina PredizVai. A primeira foi totalmente codificada em Pascal enquanto que a segunda foi codificada em linguagem de montagem. A segunda versao eh muito mais rapida, porem so pode ser compilada empregando o Borland Pascal 7. Para compilar com versoes anteriores do turbo Pascal ‚ necessario utilizar a primeira versao ( totalmente em Pascal ) } type SinaisDeControle = ( Arit, GY, GXEY, GXEYI, PX, PY, PYINV, PSHR, VVEM, VVEMI, VN, VI ); Controles = array [ SinaisDeControle ] of byte; SaiUla = 0..$1FF; { Sa¡da da ula: 8 bits de dados + vai um } var Cnt : Controles; { Sinais de controle ( 12 ) } X, Y, CY, { Entradas da ULA } Vem, Gera, Propaga, { Vem um e Saidas da Geracao e Propagacao de vai } Vai : byte; { Sa¡da do preditor de vai um } procedure MontaContr ( A, B, C, D : byte ); { 1. monta os sinais de controle } var naoA, naoB, naoC, naoD : byte; begin { As expressoes foram extraidas dos mapas de Karnaugh } naoA := not A; naoB := not B; naoC := not C; naoD := not D; Cnt[Arit] := A or B; Cnt[GY] := ( A and naoB and D ) or ( A and B and naoC and naoD ); Cnt[GXEY] := ( naoA and naoB and naoD ) or ( naoA and B and D ); Cnt[GXEYI] := ( naoA and C and naoD ) or ( naoA and B and naoD ); Cnt[PX] := ( naoA and B ) or ( naoA and naoC and D ); Cnt[PY] := ( A and D ) or ( B and D ) or ( naoC and D ) or ( A and B and naoC ) or ( naoA and naoB and C and naoD ); Cnt[PYINV] := ( B and naoD ) or ( naoA and naoB and C and D ); Cnt[PSHR] := A and naoB and naoD; Cnt[VVEM] := ( A and naoB and C ) or ( naoA and B and naoC and naoD ) or ( naoA and B and C and D ) or ( A and C and naoD ) or ( A and B and naoC and D ); Cnt[VVEMI] := ( naoA and B and naoD ) or ( B and C and naoD ) or ( A and B and naoC and D ); Cnt[VN] := ( A and B ) or ( A and D ) or ( B and D ); Cnt[VI] := ( A and B ) or ( B and naoD ); end; (*Procedure PredizVai; { 2. Preditor de vai um } var G, P, OrG, Conta8 : byte; { emprega apenas and, or e shl } begin G := Gera; P := Propaga; OrG := 0; conta8 := $FF; Vai := Cnt[Arit] and Propaga; repeat orG := orG or G; { Esse Repeat implementa um "e" de 8 entradas } G := G shl 1; P := ( P shl 1 ) or 1; Vai := Vai and ( orG or P ); conta8 := conta8 shl 1; until ( Conta8 = 0 ) or ( Vai = 0 ); Vai := Vai and ( orG or Vem ); end;*) Procedure PredizVai; { 2. Essa rotina ‚ equivalente a anterior... } label Repete, FimRep; { mas usa apenas 7 instrucoes dentro do Loop } begin { porem exige o borland pascal 7 para compilar } asm mov bl,Gera; mov bh,Propaga; { G := Gera; P := Propaga; } xor DX,DX; mov cx,8; { Org := 0; Conta8 := 8; } mov AH,byte ptr Cnt[Arit]; and AH,BH; { V := Contr[Arit] and P; } jz FimRep; { if V <> 0 then Repeat } repete: or DL,BL; { OrG := OrG or G } shl BX,1; { G := G shl 1; P := P shl 1; } or BX,100H; { P := P or 1 } mov AL,DL; or AL,BH; and AH,AL; { V := V and ( orG or P ); } Loop Repete; { dec(conta8); until Conta8=0; } FimRep: or DL,Vem; and AH,DL; mov Vai,AH; { Vai := V and ( orG or Vem ); } end; { Numero m ximo de instru‡äes executadas: 66 } end; function ULA : SaiUla; { 3. emprega apenas and, or, xor, not e shl } begin Vem := not ( not ( Cnt[VVEMI] or CY ) or not ( Cnt[VVEM] or not CY ) or Cnt [PSHR] ); Gera := ( Cnt[GY] and Y ) or ( Cnt[GXEY] and X and Y ) or ( Cnt[GXEYI] and X and not Y ); Propaga := ( Cnt[PX] and X ) or ( Cnt[PY] and Y ) or ( Cnt[PYInv] and not Y ) or ( Cnt[PSHR] and ( ( Y shr 1 ) or ( ( Cnt[VVEM] and CY ) shl 7 ) ) ); PredizVai; ULA := ( ( Gera xor Propaga ) xor ( lo ( Vai shl 1 ) or ( Vem and 1 ) ) ) or ( ord ( ( ( Cnt[PSHR] and Y and 1 ) <> 0 ) or ( ( ( not Cnt[VI] ) and Cnt[VN] and Vai and $80 ) <> 0 ) or ( ( ( not Cnt[VI] ) or Cnt[VN] or ( Vai and $80 ) ) = 0 ) or ( ( Cnt[VI] and Cnt[VN] and CY ) <> 0 ) ) shl 8 ); end; type Operacoes = ( OpAnd, OpOr, OpXor, OpNot, OpSub, OpAdd, OpSbb, OpAdc, OpSHr, OpSHL, OpRR, OpRL, OpDec, OpInc, OpNeg, Nop ); var Op : Operacoes; { Operacao da ULA } Function OpLogicaseAritBin : SaiUla; { 4. } begin if Op < OpSub then case Op of OpAnd : OpLogicaseAritBin := X and Y; OpOr : OpLogicaseAritBin := X or Y; OpXor : OpLogicaseAritBin := X xor Y; OpNot : OpLogicaseAritBin := not Y; end else case Op of OpSub : OpLogicaseAritBin := ( X - Y ) and $1FF; OpAdd : OpLogicaseAritBin := X + Y; OpSbb : OpLogicaseAritBin := ( X - Y - ( Cy and 1 ) ) and $1FF; OpAdc : OpLogicaseAritBin := X + Y + ( Cy and 1 ); end; end; Function OpAritUnarias : SaiUla; { 5. } begin if Op < OpDec then case Op of OpSHR : OpAritUnarias := Y shr 1 or ( ( Y and 1 ) shl 8 ); OpSHL : OpAritUnarias := Y shl 1; OpRR : OpAritUnarias := ( Y shr 1 ) or ( Cy and $80 ) or ( ( Y and 1 ) shl 8 ); OPRL : OpAritUnarias := ( Y shl 1 ) or ( cy and 1 ); end else case Op of OPDEC : OpAritUnarias := ( ( Y - 1 ) and $FF ) or ( ( cy and 1 ) shl 8 ); OPINC : OpAritUnarias := ( ( Y + 1 ) and $FF ) or ( ( cy and 1 ) shl 8 ); OPNEG : OpAritUnarias := ( ( - Y ) and $FF ) or ( ( cy and 1 ) shl 8 ); Nop : OpAritUnarias := Y or ( ( cy and 1 ) shl 8 ); end; end; procedure EscBin ( V : byte ); { 6. } var i : byte; begin for i := 0 to 7 do begin if ( V and $80 ) = 0 then write ( '0' ) else write ( '1' ); inc ( V, V ); if i = 3 then write ( '.' ); end; end; var NumErros : longint; ResultUla, ResultCerto : SaiUla; procedure EscreveErro; { 7. } begin inc ( NumErros ); write ( 'Erro: X=' ); EscBin ( X ); write ( ', Y=' ); EscBin ( Y ); write ( ', V=', CY and 1, ':' ); write ( ' ULA=', hi ( ResultUla ), '/' ); EscBin ( ResultUla ); write ( ' Certo=', hi ( ResultCerto ), '/' ); EscBin ( ResultCerto ); writeln; write ( ' Gera=' ); EscBin ( Gera ); write ( ' Propaga=' ); EscBin ( Propaga ); write ( ' Vem=' ); EscBin ( Vem ); write ( ' Vai=' ); EscBin ( Vai ); readln; end; const NomeOp : array [ Operacoes ] of string [ 3 ] = ( 'AND', 'OR', 'XOR', 'NOT', 'SUB', 'ADD', 'SBB', 'ADC', 'SHR', 'SHL', 'RR', 'RL', 'DEC', 'INC', 'NEG', 'NOP' ); NomeSinal : array [ SinaisDeControle ] of string [ 5 ] = ( 'ARIT', 'GY', 'GXEY', 'GXEYI', 'PX', 'PY', 'PYINV', 'SHR', 'VVEM', 'VVEMI', 'VN', 'VI' ); var Sinal : SinaisDeControle; V : shortint; begin NumErros := 0; writeln ( 'In¡cio do teste completo da ULA.' ); for OP := OPAnd to Nop do begin MontaContr ( - ord ( ( ord ( Op ) and 8 ) <> 0 ), - ord ( ( ord ( Op ) and 4 ) <> 0 ), - ord ( ( ord ( Op ) and 2 ) <> 0 ), - ord ( ( ord ( Op ) and 1 ) <> 0 ) ); write ( 'Opera‡Æo ', NomeOp [ OP ] : 3, ', controles ativos: ' ); for Sinal := Arit to VI do if Cnt [ Sinal ] <> 0 then write ( NomeSinal [ Sinal ] : 5, ' ' ); writeln; for X := 0 to 255 do for Y := 0 to 255 do for V := 0 downto -1 do begin CY := V; ResultULA := ULA; if Op < OpSHR then ResultCerto := OpLogicaseAritBin else ResultCerto := OpAritUnarias; if ResultUla <> ResultCerto then EscreveErro; end; end; write ( 'Foram encontrados ', NumErros, ' erros. Tecle ' ); readln; end. O programa jah acabou!!! TabCnt : array [ Operacoes ] of set of SinaisDeControle = ( { And: } [ GXEY ], { OR: } [ PX, PY ], { Xor: } [ GXEY, GXEYI, PY ], { Not: } [ PYINV ], { SUB: } [ Arit, GXEYI, PX, PYINV, VVEM, VVEMI, VI ], { ADD: } [ Arit, GXEY, PX, PY, VN ], { SBB: } [ Arit, GXEYI, PX, PYINV, VVEMI, VI ], { ADC: } [ Arit, GXEY, PX, PY, VVEM, VN ], { SHR: } [ Arit, PSHR ], { SHL: } [ Arit, GY, PY, VN ], { RR: } [ Arit, PSHR, VVEM ], { RL: } [ Arit, GY, PY, VVEM, VN ], [ Arit, GY, PY, PYINV, VN, VI ], [ Arit, PY, VVEM, VVEMI, VN, VI ], [ Arit, PYINV, VVEM, VVEMI,VN, VI ], [ Arit, PY, VN, VI ] ); TabelaDeControles : array [ Operacoes ] of Controles = { Arit GY GXEY GXEYI PX PY PYINV PSHR VVEM VVEMI VN VI } ( ( 0, 0, Atv, 0, 0, 0, 0, 0, 0, 0, 0, 0 ), { AND } ( 0, 0, 0, 0, Atv, Atv, 0, 0, 0, 0, 0, 0 ), { OR } ( 0, 0, Atv, Atv, 0, Atv, 0, 0, 0, 0, 0, 0 ), { XOR } ( 0, 0, 0, 0, 0, 0, Atv, 0, 0, 0, 0, 0 ), { NOT } ( Atv, 0, 0, Atv, Atv, 0, Atv, 0, Atv, Atv, 0, Atv ), { SUB } ( Atv, 0, Atv, 0, Atv, Atv, 0, 0, 0, 0, Atv, 0 ), { ADD } ( Atv, 0, 0, Atv, Atv, 0, Atv, 0, 0, Atv, 0, Atv ), { SBB } ( Atv, 0, Atv, 0, Atv, Atv, 0, 0, Atv, 0, Atv, 0 ), { ADC } ( Atv, 0, 0, 0, 0, 0, 0, Atv, 0, 0, 0, 0 ), { SHR } ( Atv, Atv, 0, 0, 0, Atv, 0, 0, 0, 0, Atv, 0 ), { SHL } ( Atv, 0, 0, 0, 0, 0, 0, Atv, Atv, 0, 0, 0 ), { RR } ( Atv, Atv, 0, 0, 0, Atv, 0, 0, Atv, 0, Atv, 0 ), { RL } ( Atv, Atv, 0, 0, 0, Atv, Atv, 0, 0, 0, Atv, Atv ), { DEC } ( Atv, 0, 0, 0, 0, Atv, 0, 0, Atv, Atv, Atv, Atv ), { INC } ( Atv, 0, 0, 0, 0, 0, Atv, 0, Atv, Atv, Atv, Atv ), { NEG } ( Atv, 0, 0, 0, 0, Atv, 0, 0, 0, 0, Atv, Atv ) );