250 likes | 333 Views
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
E N D
Multi-Base CalculatorCSE378 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 • Can accept operands in hexadecimal, decimal, or octal – Returns the result in the same base • Adds, 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.
● T(4:0) StatusREG clr clk fload ● ● F M clr clk Lab 9 Mods cont’d - Schematic M
Lab 9 Mods cont’d – Seg7Dec.vhd entity 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’d • Due 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.vhd when 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 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"; Note: The rest of ALU4.VHD resembles the lecture notes for MPP and SHLDC.
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 ( 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 Convert_in Function
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) X"04", --37 tor, --38 twotimes, --39 drjne, --3a X"39", --3b LIT, --3c X"04", --3d tor, --3e u2slash, --3f drjne, --40 X"3f", --41 plus, --42 RET, --43 LIT, -- :conv_out_16 X"03", --45 tor, --46 ffetch, --47 CALL, --48 X"1e", --49 drjne, --4a X"47", --4b drop, --4c LIT, --4d X"04", --4e tor, --4f twotimes, --50 drjne, --51 X"50", --52 plus, --53 drjne, --1a X"19", --1b ROT_DROP_SWAP, --1c RET, --1d tor, -- :MU/MOD LIT, --1f X"00", --20 rfetch, --21 CALL, --22 X"15", --23 rfrom, --24 swap, --25 tor, --26 CALL, --27 X"15", --28 rfrom, --29 RET, --2a dup, -- :convert_in LIT, --2c X"04", --2d tor, --2e u2slash, --2f drjne, --30 X"2f", --31 ffetch, --32 CALL, --33 X"0b", --34 drop_swap, --35 LIT, --36 type rom_array is array (0 to 223) of STD_LOGIC_VECTOR (7 downto 0); constant rom: rom_array := ( JMP, --0 X"83", --1 LIT, -- :DELAY X"f5", --3 tor, --4 drjne, --5 X"05", --6 RET, --7 minus, -- := zeroequal, --9 RET, --a LIT, -- :UM* X"00", --c LIT, --d X"08", --e tor, --f mpp, --10 drjne, --11 X"10", --12 ROT_DROP, --13 RET, --14 mrot, -- :UM/MOD LIT, --16 X"08", --17 tor, --18 shldc, --19
Compiled w8y_rom (2/3) CALL, --71 X"02", --72 CALL, --73 X"2b", --74 JBTN3, --75 X"75", --76 JNBTN3, --77 X"77", --78 swfetch, --79 CALL, --7a X"02", --7b CALL, --7c X"2b", --7d JBTN3, --7e X"7e", --7f JNBTN3, --80 X"80", --81 RET, --82 LIT, -- :MAIN X"5e", --84 LIT, --85 X"ba", --86 JBTN3, --87 X"87", --88 JNBTN3, --89 X"89", --8a drop, --8b drop, --8c ones, --8d tof, --8e swfetch, --8f dup, --90 LIT, --91 X"e7", --92 LIT, --93 X"06", --94 JBTN3, --95 X"95", --96 JNBTN3, --97 X"97", --98 drop, --99 zeros, --9a tof, --9b swfetch, --9c tuck, --9d plus, --9e ldstore, --9f swap, --a0 tof, --a1 dup, --a2 LIT, --a3 X"c0", -- DIVIDE CALL, --a5 X"08", --a6 JZ, --a7 X"b7", --a8 drop, --a9 CALL, --aa X"6c", --ab LIT, --ac X"00", --ad mrot, --54 LIT, --55 X"04", --56 tor, --57 twotimes, --58 drjne, --59 X"58", --5a plus, --5b swap, --5c RET, --5d LIT, --5e X"00", -- :conv_out_8 ffetch, --60 CALL, --61 X"15", --62 LIT, --63 X"04", --64 tor, --65 twotimes, --66 drjne, --67 X"66", --68 plus, --69 swap, --6a RET, --6b JBTN3, -- :get2_n_conv X"6c", --6d JNBTN3, --6e X"6e", --6f swfetch, --70
Compiled w8y_rom (3/3) 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 ); swap, --ae CALL, --af X"15", --b0 CALL, --b1 X"5e", --b2 CALL, --b3 X"5e", --b4 JMP, --b5 X"d9", --b6 dup, --b7 LIT, --b8 X"80", -- MULTIPLY CALL, --ba X"08", --bb JZ, --bc X"c7", --bd drop, --be CALL, --bf X"6c", --c0 CALL, --c1 X"0b", --c2 CALL, --c3 X"44", --c4 JMP, --c5 X"d9", --c6 LIT, --c7 X"40", -- SUBTRACT CALL, --c9 X"08", --ca
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).