230 likes | 307 Views
WHYP Test Files. Lab 9. The WC16 WHYP Core Modifications for Multiplication and Division. y1. 7 different test programs. Used only for DIO2 Board. Code. Name. Function. 001D. mpp. multiply partial product (used for multiplication). 001E. shldc.
E N D
WHYP Test Files Lab 9
The WC16 WHYP Core Modifications for Multiplication and Division y1
7 different test programs Used only for DIO2 Board
Code Name Function 001D mpp multiply partial product (used for multiplication) 001E shldc shift left and decrement conditionally (used for division) Table 1 New Funit Instructions
opcodes.vhd -- Function Unit instructions constant plus: opcode := X"0010"; -- + constant minus: opcode := X"0011"; -- - constant plus1: opcode := X"0012"; -- 1+ constant minus1: opcode := X"0013"; -- 1- constant invert: opcode := X"0014"; -- INVERT constant andd: opcode := X"0015"; -- AND constant orr: opcode := X"0016"; -- OR constant xorr: opcode := X"0017"; -- XOR constant twotimes: opcode := X"0018"; -- 2* constant u2slash: opcode := X"0019"; -- U2/ constant twoslash: opcode := X"001A"; -- 2/ constant rshift: opcode := X"001B"; -- RSHIFT constant lshift: opcode := X"001C"; -- LSHIFT constant mpp: opcode := X"001D"; -- mpp constant shldc: opcode := X"001E"; -- shldc
mpp Multiply partial product when mpp => tload <= '1'; nload <= '1'; nsel <= "10"; fcode <= icode(5 downto 0);
variable AVector: STD_LOGIC_VECTOR (width downto 0); variable BVector: STD_LOGIC_VECTOR (width downto 0); variable CVector: STD_LOGIC_VECTOR (width downto 0); variable yVector: STD_LOGIC_VECTOR (width downto 0); variable y1_tmp: STD_LOGIC_VECTOR (width-1 downto 0); begin In Funit2 AVector := '0' & a; BVector := '0' & b; CVector := '0' & c; y1_tmp := false; yVector := '0' & false;
mpp (multiply partial product) if N(0) = 1 then adsh else sh end if; when "011101" => -- mpp if b(0) = '1' then yVector := AVector + CVector; else yVector := AVector; end if; y <= yVector(width downto 1); y1 <= yVector(0) & b(width-1 downto 1); T N N2
16 x 16 = 32 Multiplication : UM* ( u1 u2 - upL upH ) 0 mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp ROT_DROP ;
shldc Shift left and decrement conditionally when shldc=> tload <= '1'; nload <= '1'; nsel <= "10"; fcode <= icode(5 downto 0);
Division N2 N T : UM/MOD ( unumL unumH udenom -- urem uquot ) N2 N T -ROT \ udenom unumL unumH SHLDC SHLDC SHLDC SHLDC \ denom quot rem ROT_DROP_SWAP ; All other signed and unsigned division operations can be derived as WHYP words from UM/MOD
when "011110" => -- shldc yVector := a & b(width-1); y1_tmp := b(width-2 downto 0) & '0'; if yVector > CVector then yVector := yVector - CVector; y1_tmp(0) := '1'; end if; y <= yVector(width-1 downto 0); y1 <= y1_tmp; for I in 0 to 3 loop sll T & N; if T[8:4] > N2 then T := T - (0 & N2); N(0) := ‘1’; end if; end loop; T N sll 100001110 1101 N2
32 / 16 = 16:16 Division : UM/MOD ( unL unH ud -- ur uq ) -ROT shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc ROT_DROP_SWAP ;
WHYP Test Files sdigtest.whp -- tests the switches and 7-segment displays hex2asc.whp -- converts hex to ascii minmax.whp -- finds the min and max of two numbers mul.whp -- multiplies two 16-bit numbers div.whp -- divides a 32-bit number by a 16-bit number fact16.whp -- computes the factorial of a number leap.whp -- checks if a year is a leap year
SDigtest.whp \ Test of JB4HI, JB4LO, S@ and DIG! : main ( -- ) BEGIN waitB4 S@ DIG! AGAIN ;
Hex2asc.whp \ Convert hex to ASCII HEX : hex2asc ( n -- asc ) 0F AND \ mask upper nibble DUP 9 > \ if n > 9 IF 37 + \ add $37 ELSE 30 + \ else add $30 THEN ; : main ( -- ) BEGIN waitb4 S@ DUP DIG! waitb4 hex2asc DIG! AGAIN ;
\ MIN MAX : MIN ( n1 n2 -- min ) OVER OVER > \ n1 n2 f IF \ n1 n2 SWAP \ n2 n1 THEN DROP ; \ min : MAX ( n1 n2 -- max ) OVER OVER < \ n1 n2 f IF \ n1 n2 NIP \ n2 ELSE DROP \ n1 THEN ; Minmax.whp : main ( -- ) BEGIN waitB4 S@ DUP DIG! waitB4 S@ DUP DIG! waitB4 OVER OVER MIN DIG! waitB4 MAX DIG! AGAIN ;
: UM* ( u1 u2 - upL upH ) 0 mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp ROT_DROP ; : MAIN ( -- ) BEGIN waitB4 S@ \ get u1HI DUP DIG! 8 LSHIFT waitB4 S@ \ get u1LO OR DUP DIG! waitB4 S@ \ get u2HI DUP DIG! 8 LSHIFT waitB4 S@ \ get u2LO OR DUP DIG! waitB4 UM* \ multiply DIG! \ display upH waitB4 DIG! \ display upL AGAIN ; Mul.whp
: UM/MOD ( unL unH ud -- ur uq ) -ROT shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc shldc ROT_DROP_SWAP ; : MAIN ( -- ) BEGIN waitB4 S@ \ get unHHI DUP DIG! 8 LSHIFT waitB4 S@ \ get unHLO OR DUP DIG! waitB4 S@ \ get unLHI DUP DIG! 8 LSHIFT waitB4 S@ \ get unLLO OR DUP DIG! SWAP \ numerator waitB4 S@ \ get udHI DUP DIG! 8 LSHIFT waitB4 S@ \ get udLO OR \ denominator DUP DIG! waitB4 UM/MOD \ divide DIG! \ display uq waitB4 DIG! \ display ur AGAIN ; Div.whp
\ Example of BEGIN...WHILE...REPEAT : UM* ( u1 u2 - upL upH ) 0 mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp mpp ROT_DROP ; : * ( n1 n2 -- n3 ) UM* DROP ; : factorial ( n -- n! ) 1 2 ROT \ x i n BEGIN \ x i n OVER OVER <= \ x i n f WHILE \ x i n -ROT TUCK \ n i x i * SWAP \ n x' i 1+ ROT \ x' i' n REPEAT \ x i n DROP DROP ; \ x : main ( -- ) BEGIN waitB4 S@ DUP DIG! waitB4 factorial DIG! AGAIN ; Fact16.whp
Leap.whp \ leap year : UM/MOD ( unumL unumH udenom - urem uquot ) -ROT 16 FOR shldc NEXT ROT_DROP_SWAP ; : U/MOD ( n1 n2 -- urem uquot ) >R 0 R> UM/MOD ; : MOD ( n1 n2 -- urem ) U/MOD DROP ;
Leap.whp (cont.) : ?leap ( year -- flag ) DUP 400 MOD 0= IF DROP TRUE ELSE DUP 100 MOD 0= IF DROP FALSE ELSE 4 MOD 0= IF TRUE ELSE FALSE THEN THEN THEN ; : main ( -- ) BEGIN waitB4 S@ DUP DIG! 8 LSHIFT waitB4 S@ OR DUP DIG! waitB4 ?leap DIG! AGAIN ; Note: A year is a leap year if it is divisible by 4, but not by 100, or if it is divisible by 400.