1 / 26

Function Unit

Function Unit. Lecture 8.3 A VHDL Forth Core for FPGAs: Sect. 4. FC16 Forth Core. Instructions for the FC16 Function Unit. case fcode is when "010000" => -- a + b y <= a + b; when "010001" => -- b - a y <= b - a; when "010010" => -- 1+

Download Presentation

Function Unit

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Function Unit Lecture 8.3 A VHDL Forth Core for FPGAs: Sect. 4

  2. FC16 Forth Core

  3. Instructions for the FC16 Function Unit

  4. case fcode is when "010000" => -- a + b y <= a + b; when "010001" => -- b - a y <= b - a; when "010010" => -- 1+ y <= a + 1; when "010011" => -- 1- y <= a - 1; when "010100" => -- invert y <= not a; when "010101" => -- a and b y <= a and b; when "010110" => -- a or b y <= a or b; when "010111" => -- a xor b y <= a xor b;

  5. when "011000" => -- 2* y <= a(width-2 downto 0) & '0'; when "011001" => -- U2/ y <= '0' & a(width-1 downto 1); when "011010" => -- 2/ y <= a(width-1) & a(width-1 downto 1); when "011011" => -- RSHIFT y <= SHR(b,a); when "011100" => -- LSHIFT y <= SHL(b,a);

  6. when "100000" => -- TRUE y <= true; when "100001" => -- FALSE y <= false; when "100010" => if (Z = '0') then -- 0= NOT y <= true; else y <= false; end if; when "100011" => if (a(width-1) = '1') then -- 0< y <= true; else y <= false; end if;

  7. when "100100" => if (b > a) then -- U> y <= true; else y <= false; end if; when "100101" => if (b < a) then -- U< y <= true; else y <= false; end if; when "100110" => if (a = b) then -- = y <= true; else y <= false; end if;

  8. when "100111" => if (b >= a) then -- U>= y <= true; else y <= false; end if; when "101000" => if (b <= a) then -- U<= y <= true; else y <= false; end if; when "101001" => if (a /= b) then -- <> y <= true; else y <= false; end if;

  9. when "101010" => if (bvs > avs) then -- > y <= true; else y <= false; end if; when "101011" => if (bvs < avs) then -- < y <= true; else y <= false; end if; when "101100" => if (bvs >= avs) then -- >= y <= true; else y <= false; end if;

  10. when "101101" => if (bvs <= avs) then -- <= y <= true; else y <= false; end if; when others => y <= false; y1 <= false; end case;

  11. Code Name Function 001D mpp multiply partial product (used for multiplication) 001E shldc shift left and decrement conditionally (used for division) Multiply and Divide Instructions

  12. 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

  13. mpp Multiply partial product when mpp => tload <= '1'; nload <= '1'; nsel <= "10"; fcode <= icode(5 downto 0);

  14. 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 Funit16 AVector := '0' & a; BVector := '0' & b; CVector := '0' & c; y1_tmp := false; yVector := '0' & false;

  15. 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. 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 ;

  17. shldc Shift left and decrement conditionally when shldc=> tload <= '1'; nload <= '1'; nsel <= "10"; fcode <= icode(5 downto 0);

  18. 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

  19. 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

  20. 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 ;

  21. WHYP Test Files 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

  22. : 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

  23. : 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

  24. \ 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

  25. 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 ;

  26. 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.

More Related