multi-base calculator cse378 final project
DESCRIPTION
Multi-Base Calculator CSE378 Final Project. By Matthew Lehn & Yanqing Zhu December 17, 2001 Professor Haskell. What About it?. It’s a calculator created from the original W8Y Microprocessor in Lab 9 Supports unsigned operands and results - PowerPoint PPT PresentationTRANSCRIPT
Multi-Base CalculatorMulti-Base CalculatorCSE378 Final ProjectCSE378 Final Project
By Matthew Lehn & Yanqing ZhuDecember 17, 2001
Professor Haskell
What About it?
It’s a calculator created from the original W8Y Microprocessor in Lab 9Supports unsigned operands and resultsCan accept operands in hexadecimal, decimal, or octal – Returns the result in the same baseAdds, subtracts, multiplies, & divides
Lab 9 Modifications
Our 7-segment display needs to show BASE and OPER, however, only the characters 0-F existed in seg7dec.vhd. We created a 1-bit register to store a “flag”. When the
flag is TRUE, P and R replace the characters 6 and 7.
We also need some place to store the user’s specified BASE. Since the data stack and return stack are inconvenient
spots and would require additional operations to retrieve, we decided to make the flag/status register to 5-bits.
ReturnStack
RmuxPmux
PCclrclk
pload
pinc
IRclrclkirload
W8Y_rom
W8Y_control
plus1
R
DS
Rin
R T
P
Pin
M
M P1
R
M
SW(1:8)
LDreg
LD(1:8)
T
ldloadclkclr
step_display
A(3:0) AtoG(6:0)
clk
clr
TN
BTN(1)
BTN(4)
clr
step
The W8YMicrocontroller
clkclr
rpop
rpush
psel rinsel
dssel(1:0)
rload
rdec
rsel
T
icode
E
BTN(1:4)
DataStack_ALUclkclr
dpop
dpush
ssel
nloadnsel
tload
tsel(1:0)
alusel(3:0)
T
0 11
1
0
0 2 3DSmux
T(4:0)
fload
M
StatusREG
●
F
clr
clk
●
●
clr clk
Lab 9 Mods cont’d - Schematic
M
Lab 9 Mods cont’d – Seg7Dec.vhdentity seg7dec is
port (q: in STD_LOGIC_VECTOR(3 downto 0);
flag: in STD_LOGIC_VECTOR(4 downto 0);
AtoG: out STD_LOGIC_VECTOR(6 downto 0));
end seg7dec;
architecture seg7dec_arch of seg7dec is
begin
process(q, flag)
begin
case q is
when "0000" =>
AtoG <= "0000001"; -- zero
. . .
when "0100" =>
AtoG <= "1001100"; -- 4
when "0101" =>
AtoG <= "0100100"; -- 5 or S
when "0110" =>
if flag = "11111" then
AtoG <= "0011000"; -- P
else
AtoG <= "0100000"; -- 6
end if;
when "0111" =>
if flag = "11111" then
AtoG <= "0011001"; -- r
else
AtoG <= "0001101"; -- 7
end if;
when "1000" =>
AtoG <= "0000000"; -- 8
. . .
when others =>
AtoG <= "1111110"; -- "dash"
end case;
end process;
end seg7dec_arch;
Lab 9 Mods – cont’dDue to space constraints, we removed several opcodes from w8y_codes.vhd and w8y_control.vhd. nop, over, nip, plus1, minus1, andd, orr, xorr,
twoslash, rfromdrop, j[n]btn1, j[n]btn2, j[n]btn4
Implemented the tof and ffetch commands tof -> Send T(4:0) to the 5-bit statusReg ffetch -> Fetch into T whatever is in the statusReg
Added a drop_swap command (1 clk cycle) Drop T, T <= N2, N is unchanged
Lab 9 Mods – w8y_control.vhdwhen drop_swap =>
tsel <= "10"; tload <= '1'; dpop <= '1';
when tof =>
-- Pop T and push it onto the flag register
tsel <= "11"; tload <= '1'; nsel <= "10"; nload <= '1';
dpop <= '1'; fload <= '1';
when ffetch =>
-- Copy F from status register to T and push data stack
tsel <= "01"; tload <= '1'; nload <= '1'; dpush <= '1';
dssel <= "11";
when jz =>
pload <= not z; pinc <= z; tsel <= "11"; tload <= '1';
nsel <= "10"; nload <= '1'; dpop <= '1';
Lab 9 Mods – cont’d
We expanded ALU4.vhd to include:Multiplication (mpp)
Nmux in the DS_ALU component changed to allow 4 inputs. A signal y2 was added into the MUX.
ALU can now accept T, N, AND N2 as inputs.Division (shldc)Addition w/ Carry (+C)
ALU4.VHD & W8Y_CONTROL.VHD
Note: The rest of ALU4.VHD resembles the lecture notes for MPP and SHLDC.
when "1111" => -- N + T (will display a carry)
yVector := AVector + BVector; -- 9 bits, 1 for the carry
y2_tmp(0) := yVector(width);
y2 <= yVector(width-1 downto 0); -- Store sum (minus carry) into N
y <= y2_tmp; -- Store carry bit into T
when plus_carry =>
-- Use when actually wanting to add two numbers as an
-- operation and NOT for intermediate steps requiring
-- addition. This function displays the carry, if it exists
tload <= '1'; nsel <= "00"; nload <= '1'; alusel <= "1111";
when mpp =>
tload <= '1'; nsel <= "00"; nload <= '1'; alusel <= "1101";
when shldc =>
tload <= '1'; nsel <= "00"; nload <= '1'; alusel <= "1110";
Convert_in Function
• Basic Idea
If entering “49” into the calculator: The input BCD number isn’t real 49 it’s only 2 digits 4 & 9 ! Represented as 0100 1001 The real 49 = 4 * 10 + 9
Convert_in Function
: CONVERT_IN ( BCD/BCO -- BIN )
DUP
4 FOR
U2/
NEXT \ get higher 4 bits
F@ \ fetch the base
UM* \ T*N return 16 bits
DROP_SWAP \ drop + swap
4 FOR
2*
NEXT \ shift out the lower 4 bits
4 FOR
U2/
NEXT \ get the higher 4 bits
+ ; \ Hbits+ Lbits
S N2 N T
49
49 49
49 4
49 4 A
49 28 00
28 49
28 90
28 9
31
Convert_out Function
• Basic Idea
The convert_out function is just the reverse of the convert_in function, i.e.
4 & 9 4*A+9 = (31)16 INPUT CONVERT_IN
4 & 9 (31)16 /A = 4…9 OUTPUT CONVERT_OUT
Convert_out_8 Function• Convert_out_8
Convert 8 bit number, used only for Subtraction & Division
Operation Quotient/Difference Remainder
Subtraction 0 ~ 99(Dec)
0 ~ 77(Oct)
0 ~ FF(Hex)
Division 0 ~ 99(Dec) 0 ~ 49 (Dec: 99/50)
0 ~ 77(Oct) 0 ~ 37 (Oct: 77/40)
0 ~ FF(Hex) 0 ~ 7F (Hex: FF/80)
Convert_out_8 Function
: CONVERT_OUT_8 ( Bin -- BCD/BCO )
0 \ Push higher 8 bits of result into T
F@ \ Get base from statusReg
UM/MOD \ Convert
4 FOR \ Shift & combine the answer
2*
NEXT
+ \ HBit + LBit
SWAP ;
Convert_out_16 Function
• Convert_out_16
Convert 16 bit number, used only for Addition & Multiplication
Operation Product/Sum
Addition 0 ~ 198(Dec)
0 ~ 176(Oct)
0 ~ 1FE(Hex)
Multiplication 0 ~ 9801(Dec)
0 ~ 7601(Oct)
0 ~ FE01(Hex)
Convert_out_16 Function : CONVERT_OUT_16 ( BinL BinL -- BCDL/BCOL BCDH/BCOH )
3 FOR
F@ MU/MOD \ Divide by base & return dbl quotient
NEXT
DROP \ Drop 00 in T
4 FOR \ T= bit 15-12 of the answer
2* \ Shift it to higher bits
NEXT
+ \ N= bit11-8 + bit15-12= bit15-8
-ROT \ N= bit7-4, put it in T
4 FOR
2* \ Shift bit7-4 to the higher positions
NEXT
+ \ N= bit3-0 + bit7-4= bit7-0 (in T)
SWAP ; \ Swap bit15-8 w/ bit7-0
WHYP it Up!HEX
: DELAY ( -- )
F5 FOR NEXT ;
: = ( n1 n2 -- f )
- 0= ;
: UM* ( u1 u2 -- ud )
0
8 FOR
mpp
NEXT
ROT_DROP ;
: UM/MOD ( unumL unumH udenom -- urem uquot )
-ROT
8 FOR
shldc
NEXT
ROT_DROP_SWAP ;
: MU/MOD ( ud un -- urem udquot )
>R 0 R@ \ udL udH 0 un
UM/MOD \ udl remH quotH
R> \ udL remH quotH un
SWAP >R \ udL remH un
UM/MOD \ remL quotL
R> ; \ remL quotL quotH
: CONVERT_IN ( fakebin -- realbin ) \ Convert BCD to real binary
DUP
4 FOR \ Get the higher bits (shift right)
U2/
NEXT
F@ \ Get the base from statusReg
UM* \ Convert the higher bits
DROP_SWAP \ Drop the 00 & load lower bits
4 FOR \ Get rid of the higher bits
2*
NEXT
4 FOR \ Shift back the lower bits
U2/
NEXT
+ ; \ HBit + LBit = real binary
: CONVERT_OUT_16 ( bin -- fakebin ) \ Convert binary to designated base -- Used for addition & multiplication
3 FOR
F@ MU/MOD \ Divide by base- return dbl quot
NEXT
DROP \ Drop 00 in T
WHYP it Up – Cont’d 4 FOR \ T= bit 15-12 of the answer
2* \ Shift it to higher bits
NEXT
+ \ N= bit11-8 + bit15-12= bit15-8
-ROT \ N= bit7-4, put it in T
4 FOR
2* \ Shift bit7-4 to the higher positions
NEXT
+ \ N= bit3-0 + bit7-4= bit7-0 (in T)
SWAP ; \ Swap bit15-8 w/ bit7-0
: CONVERT_OUT_8 \ Convert binary to designated base
\ Used for subtraction & division
0 \ Push higher 8 bits of result into T
F@ \ Get base from statusReg
UM/MOD \ Convert
4 FOR \ Shift & combine the answer as above
2*
NEXT
+ \ HBit + LBit
SWAP ;
: GET2_N_CONVERT ( -- u1 u2 ) \ Fetch & convertt
waitbtn3 SW@ DELAY CONVERT_IN \ to specified base
waitbtn3 SW@ DELAY CONVERT_IN
waitbtn3 ;
: main ( -- )
BEGIN
5E \ Display BASE
BA
waitbtn3
DROP DROP \ Get rid of BA5E in T & N regs
TRUE
>F \ Set flag to TRUE so OPER is displayed
SW@ \ Fetch the base (switches 4-8)
DUP \ Copy base to N for later use
E7 \ Display OPER
06
waitbtn3
DROP \ Drop 06 from T, put E7 in T
FALSE \ Overwrite E7 in T with zeros
>F \ Turn off P & R display mode
SW@ \ Fetch operation (switches 1-2)
TUCK + \ Place oper in N2 and add N & T
LD! \ Light LEDs to signify base and oper
SWAP \ Put base in T and oper in N
>F \ Save base in statusReg; put oper in T
DUP \ Duplicate oper into N
C0 = \ Division
IF
WHYP it Up – Cont’d
DROP \ Remove oper
GET2_N_CONVERT \ Get 2 operands & convert to base
0 SWAP \ Set high bits to 0 (8/8 div only)
UM/MOD \ Divide N2 by T (N is 0)
CONVERT_OUT_8 \ Convert quotient to base
CONVERT_OUT_8 \ Convert remainder to base
ELSE
DUP
80 = \ Multiplication
IF
DROP \ Remove OPER
GET2_N_CONVERT
UM* \ Multiply T & N
CONVERT_OUT_16
ELSE
40 = \ Subtraction
IF
GET2_N_CONVERT
- \ Subtract T from N
CONVERT_OUT_8
ELSE \ Addition
GET2_N_CONVERT
+C \ Add T & N; store carry in T
CONVERT_OUT_16
THEN
THEN
THEN
waitbtn3 \ Hold answer on display
AGAIN ;
Compiled w8y_rom (1/3)type rom_array is array (0 to 223) of STD_LOGIC_VECTOR (7 downto 0);constant rom: rom_array := (
JMP, --0X"83", --1LIT, -- :DELAYX"f5", --3tor, --4drjne, --5X"05", --6RET, --7minus, -- :=zeroequal, --9RET, --aLIT, -- :UM*X"00", --cLIT, --dX"08", --etor, --fmpp, --10drjne, --11X"10", --12ROT_DROP, --13RET, --14mrot, -- :UM/MODLIT, --16X"08", --17tor, --18shldc, --19
drjne, --1aX"19", --1bROT_DROP_SWAP, --1cRET, --1dtor, -- :MU/MODLIT, --1fX"00", --20rfetch, --21CALL, --22X"15", --23rfrom, --24swap, --25tor, --26CALL, --27X"15", --28rfrom, --29RET, --2adup, -- :convert_inLIT, --2cX"04", --2dtor, --2eu2slash, --2fdrjne, --30X"2f", --31ffetch, --32CALL, --33X"0b", --34drop_swap, --35LIT, --36
X"04", --37tor, --38twotimes, --39drjne, --3aX"39", --3bLIT, --3cX"04", --3dtor, --3eu2slash, --3fdrjne, --40X"3f", --41plus, --42RET, --43LIT, -- :conv_out_16X"03", --45tor, --46ffetch, --47CALL, --48X"1e", --49drjne, --4aX"47", --4bdrop, --4cLIT, --4dX"04", --4etor, --4ftwotimes, --50drjne, --51X"50", --52plus, --53
Compiled w8y_rom (2/3)mrot, --54LIT, --55X"04", --56tor, --57twotimes, --58drjne, --59X"58", --5aplus, --5bswap, --5cRET, --5dLIT, --5eX"00", -- :conv_out_8ffetch, --60CALL, --61X"15", --62LIT, --63X"04", --64tor, --65twotimes, --66drjne, --67X"66", --68plus, --69swap, --6aRET, --6bJBTN3, -- :get2_n_convX"6c", --6dJNBTN3, --6eX"6e", --6fswfetch, --70
CALL, --71X"02", --72CALL, --73X"2b", --74JBTN3, --75X"75", --76JNBTN3, --77X"77", --78swfetch, --79CALL, --7aX"02", --7bCALL, --7cX"2b", --7dJBTN3, --7eX"7e", --7fJNBTN3, --80X"80", --81RET, --82LIT, -- :MAINX"5e", --84LIT, --85X"ba", --86JBTN3, --87X"87", --88JNBTN3, --89X"89", --8adrop, --8bdrop, --8cones, --8dtof, --8eswfetch, --8fdup, --90
LIT, --91X"e7", --92LIT, --93X"06", --94JBTN3, --95X"95", --96JNBTN3, --97X"97", --98drop, --99zeros, --9atof, --9bswfetch, --9ctuck, --9dplus, --9eldstore, --9fswap, --a0tof, --a1dup, --a2LIT, --a3X"c0", -- DIVIDECALL, --a5X"08", --a6JZ, --a7X"b7", --a8drop, --a9CALL, --aaX"6c", --abLIT, --acX"00", --ad
Compiled w8y_rom (3/3)swap, --aeCALL, --afX"15", --b0CALL, --b1X"5e", --b2CALL, --b3X"5e", --b4JMP, --b5X"d9", --b6dup, --b7LIT, --b8X"80", -- MULTIPLYCALL, --baX"08", --bbJZ, --bcX"c7", --bddrop, --beCALL, --bfX"6c", --c0CALL, --c1X"0b", --c2CALL, --c3X"44", --c4JMP, --c5X"d9", --c6LIT, --c7X"40", --
SUBTRACTCALL, --c9X"08", --ca
JZ, --cb X"d4", --cc CALL, --cd X"6c", --ce minus, --cf CALL, --d0 X"5e", --d1 JMP, --d2 X"d9", --d3 CALL, -- ADD X"6c", --d5 plus_carry, --d6 CALL, --d7 X"44", --d8 JBTN3, --d9 X"d9", --da JNBTN3, --db X"db", --dc JMP, --dd X"83", --de X"00" --df);
INSTRUCTIONS FOR THE W8Y MULTI-BASE CALCULATOR
STEP 1: Enter the BASE using the SW 4-8 and press BTN3
BASE Switch Possibilities SW 1 2 3 4 5 6 7 8 - - - 1 0 0 0 0 Hexadecimal (Base-16) - - - 0 1 0 1 0 Decimal (Base-10) - - - 0 1 0 0 0 Octal (Base-8) STEP 2: Using SW 1-2, select the OPERation you want performed and push BTN3
OPERation Switch Possibilities SW 1 2 3 4 5 6 7 8 0 0 - - - - - - Addition 0 1 - - - - - - Subtraction 1 0 - - - - - - Multiplication 1 1 - - - - - - Division
STEP 3: If the operation requested is ADDITION -- Set switches, push btn3, set switches, push btn3 SUBTRACTION -- Set switches, push btn3, set switches, push btn3 The second number entered is subtracted from the first MULTIPLICATION -- Set switches, push btn3, set switches, push btn3 DIVISION -- Set switches, push btn3, set switches, push btn3 You can only divide 8 bits by 8 bits. The numerator is first. Notes:
After each BTN3 push, the number will be displayed in its original form for a few seconds. For decimal and octal, enter your numbers as BCD (binary coded decimal)
Example: For 15 in Decimal, SW1-8 should be 00010101 For 93 in Decimal, SW1-8 should be 10010011
For 17 in Octal, SW1-8 should be 00010111 For 77 in Octal, SW1-8 should be 01110111
The maximum value for decimal is 99. For octal, the maximum is 77. STEP 4: After you input the two operands, press BTN3 again to display the result. The displayed result will be in your designated base. STEP 5: Press BTN1 to start over.
Conclusion
Unfortunately, since each simulation waveform is extraordinarily long and would take 10+ slides to cover, they will not be shown here. The result is not shown until 12,400 ns!
Note that the calculator will only accept positive operands and only display positive results. For instance, it can’t perform (1 - F) or (-2 * 5).