2007年8月20日 星期一

[EE_CSIE] 非同步電路設計Lab2. Aync 8 bit ALU

As we know, CPU includes 2 part.
One is CU (Control Unit), and the other is ALU (Arithmetics Logic Unit)
Let us design a 8-bit ALU by Belsa.

The ALU is as following :






----------------------------------------------------------
-- ALU8.balsa : 8-bit ALU
----------------------------------------------------------
-- 2007.07.29 by 9679505 Amzshar Liu ( AaA )
----------------------------------------------------------
--
-- 4 input ( aluop, src1, src2, PSW )
-- 2 output ( result, OPSW )
--
-- aluop is 3 bits ALU Operation Code
--
-- aluop : AND, OR, XOR, RLC, RRC, ADDC, SUBC, NONE
-- aluop = 0b000 -> AND
-- aluop = 0b001 -> OR
-- aluop = 0b010 -> XOR
-- aluop = 0b011 -> RLC (Rotate Left 1 bit with Carry)
-- aluop = 0b100 -> RRC (Rotate Right 1 bit with Carry)
-- aluop = 0b101 -> ADDC (src1 + src2 + PSW.CY)
-- aluop = 0b110 -> SUBC (src1 - src2 - PSW.CY)
-- aluop = 0b111 -> NONE
--
-- src1, src2 is 8 bits
-- result is 8 bits ALU Result
--
-- PSW, OPSW is 4 bits (P, OV, AC, CY)
-- P is 1 bit Parity Flag
-- OV is 1 bit Overflow Flag (1:overflow)
-- AC is 1 bit Auxilary Carry Flag
-- CY is 1 bit Carry Flag
--
-- All Op must update "PSW.P" according to "result"
-- ADDC : Update PSW.CY, PSW.AC, OV
-- SUBC : Update PSW.CY, PSW.AC, PV
--
----------------------------------------------------------

import [balsa.types.basic]

type OPType is 3 bits -- aluop OPType
type DataType is 8 bits -- src1, src2, result

type PswStatus is record -- PSW, OPSW
P, OV, AC, CY : bit
end

type InputType is record -- in_sigs
aluop : OPType;
src1 : DataType;
src2 : DataType;
PSW : PswStatus
end

type OutputType is record -- out_sigs
result : DataType;
OPSW : PswStatus
end

procedure ALU8(input in_sigs : InputType ; output out_sigs : OutputType) is
variable intmp : InputType
variable outtmp : OutputType
variable result : DataType -- outtmp.result
variable opsw : PswStatus -- outtmp.OPSW
-- variable P, OV, AC, CY : bit
variable src1tmp, src2tmp : DataType -- For ADDC, SUBC
variable CYtmp, Flag : bit -- For ADDC, SUBC
variable ADDSUB9 : 9 bits -- For ADDC, SUBC

---- Use shared add_sub to save cost
shared add_sub is
begin
ADDSUB9 := ( src1tmp + src2tmp + CYtmp as 9 bits ) ;

result := ( #ADDSUB9[0..7] as DataType ) ;

---- Overflow Detection Logic : Overflow = CarryIn[N-1] XOR CarryOut[N-1]
opsw.OV := #ADDSUB9[8] xor #src1tmp[7] xor #src2tmp[7] xor #ADDSUB9[7] ;

---- Flag=0 => ADDC => AC = 1, when there is a carry-out from bit 3
if( Flag = 0 ) then
opsw.AC :=( ( (not #src1tmp[4]) and (not #src2tmp[4]) and #result[4] ) or
( (not #src1tmp[4]) and #src2tmp[4] and (not #result[4]) ) or
( #src1tmp[4] and (not #src2tmp[4]) and (not #result[4]) ) or
( #src1tmp[4] and #src2tmp[4] and #result[4] ) ) ;

---- Flag=0 => ADDC => CY = 1 when there is a carry-out from bit 7
opsw.CY := #ADDSUB9[8]

else

---- Flag=1 => SUBC => AC = 1, if a borrow is needed for bit3
---- Because src2tmp = 1's complement of intmp.src2
opsw.AC :=( ( (not #src1tmp[4]) and (not #src2tmp[4]) and (not #result[4]) ) or
( (not #src1tmp[4]) and #src2tmp[4] and #result[4] ) or
( #src1tmp[4] and (not #src2tmp[4]) and #result[4] ) or
( #src1tmp[4] and #src2tmp[4] and (not #result[4]) ) ) ;

---- Flag=1 => SUBC => CY = 1 if a borrow is needed for bit7
opsw.CY := not #ADDSUB9[8]

end -- end if
end -- end begin

---- Update for outtmp.OPSW.P
shared ParityCheck is
begin
opsw.P := #result[0] xor #result[1] xor #result[2] xor #result[3] xor
#result[4] xor #result[5] xor #result[6] xor #result[7]
end -- end begin

---- Procedure BODY
begin
loop
in_sigs -> intmp ;
-- P := intmp.PSW.P
-- OV := intmp.PSW.OV
-- AC := intmp.PSW.AC
-- CY := intmp.PSW.CY ;
opsw := intmp.PSW ;

print "---> PSW (P, OV, AC, CY) => ", intmp.PSW.P , intmp.PSW.OV,
intmp.PSW.AC, intmp.PSW.CY ;

case intmp.aluop of
0b000 then ---- AND
result := intmp.src1 and intmp.src2 ;
print "aluop=000 : ", #intmp.src1, " AND ", #intmp.src2, " => ", #result

0b001 then ---- OR
result := intmp.src1 or intmp.src2 ;
print "aluop=001 : ", #intmp.src1, " OR ", #intmp.src2, " => ", #result

0b010 then ---- XOR
result := intmp.src1 xor intmp.src2 ;
print "aluop=010 : ", #intmp.src1, " XOR ", #intmp.src2, " => ", #result

0b011 then ---- RLC : (Rotate Left 1 bit with Cary)
result := ( #intmp.PSW.CY @ #intmp.src1[0..6] as DataType ) ;
opsw.CY := #intmp.src1[7] ;
print "aluop=011 : ", #intmp.src1, " RLC => ", #result

0b100 then ---- RRC : (Rotate right 1 bit with Cary)
result := ( #intmp.src1[1..7] @ #intmp.PSW.CY as DataType) ;
opsw.CY := #intmp.src1[0] ;
print "aluop=100 : ", #intmp.src1, " RRC => ", #result

0b101 then ---- ADDC is " result := src1 + src2 + CY " and Updated PSW
---- => result := src1tmp + src2tmp + CYtmp
src1tmp := intmp.src1 ;
src2tmp := intmp.src2 ;
CYtmp := intmp.PSW.CY ;
Flag := 0 ;
add_sub() ;
print "aluop=101 : ", #intmp.src1, " ADDC ", #intmp.src2, " => ", #result

0b110 then ---- SUBC is " result := src1 - src2 - CY " and Updated PSW
---- => result := src1 + ( (not src2) + 1 ) - CY
---- => result := src1 + ( not src2) + ( 1 - CY )
---- => result := src1tmp + src2tmp + CYtmp
src1tmp := intmp.src1 ;
---- Here for src2 1's complement
src2tmp := ( not intmp.src2 + 1 as DataType ) ;
---- Here (+1 - CY) for src2 2's complement
CYtmp := ( not intmp.PSW.CY as bit ) ;
Flag := 1 ;
add_sub() ;
print "aluop=110 : ", #intmp.src1, " SUBC ", #intmp.src2, " => ", #result

0b111 then ---- NONE
print "alop=111 : NONE ! " ;
continue
end; -- end case intmp.aluop

ParityCheck();

print "==> OPSW (P, OV, AC, CY) => ", opsw.P, opsw.OV, opsw.AC, opsw.CY ;

outtmp.result := result outtmp.OPSW := opsw ;
out_sigs <- outtmp ;

print ">>>=====================================================>>>"
end -- end loop
end -- end begin

沒有留言:

張貼留言