Floating Point Unit - shifter block
prepared by P. Bakowski (designer G. Ramstein)
back
to main text
note : non synthetisable
The following model excecutes the shifter specification.
-- Data inputs :
-- ASX2F(39:0) x-operand input -- ASY2F(39:0) y-operand input -- ASZ2F(31:0)
z-operand input
-- -- PS_AV1F ALU overflow flag from ASTAT --
-- Data outputs :
-- -- SR2F(39:0) result operand
-- -- SH_STAT2F(2:0) status output bus -- 0: shifter zero flag -- 1:
shifter overflow flag -- 2: shifter sign flag
-- Control inputs :
-- -- RF_SHSD2F selects a shifter operation -- RF_ASOPD2F(7:0) ALU/shifter
op code -- PS_T6D1F selects an immediate shifter operation
-- -- CK processor clock -- HLDB processor hold -- RST processor reset
-- CEN bus driver enable
use work.DSP21020_pkg.all;
entity SFTR_Nty is port( ASX2F:in BV40_Typ; ASY2F:in BV40_Typ;
ASZ2F:in BV32_Typ; RF_SHSD2F:in BIT; RF_ASOPD2F:in BV8_Typ; PS_T6D1F:in
BIT; PS_AV1F:in BIT; CK:in BIT; HLDB:in BIT; RST:in BIT; CEN:in BIT; SR2F:out
BV40_Typ; SH_STAT2F:out BV3_Typ);
end SFTR_Nty;
architecture SFTR_a of SFTR_Nty is
- constant lshift : BV8_Typ := X"00";
- constant orlshift : BV8_Typ := X"20";
- constant ashift : BV8_Typ := X"04";
- constant orashift : BV8_Typ := X"24";
- constant rot : BV8_Typ := X"08";
- constant bclr : BV8_Typ := X"c4";
- constant bset : BV8_Typ := X"c0";
- constant btgl : BV8_Typ := X"c8";
- constant btst : BV8_Typ := X"cc";
- constant fdep : BV8_Typ := X"44";
- constant orfdep : BV8_Typ := X"64";
- constant fdepse : BV8_Typ := X"4c";
- constant orfdepse : BV8_Typ := X"6c";
- constant fext : BV8_Typ := X"40";
- constant fextse : BV8_Typ := X"48";
- constant exp : BV8_Typ := X"80";
- constant expex : BV8_Typ := X"84";
- constant leftz : BV8_Typ := X"88";
- constant lefto : BV8_Typ := X"8c";
begin
SFTR_process : process(Ck)
- use WORK.bitvector_pkg.ALL;
- use WORK.signvector_pkg.ALL;
- use WORK.Float40_Pkg.all;
- variable Op : BV8_Typ;
- variable Ry, yshf, ylen: Fix_Typ;
- variable exe, ovf, zero: BIT;
- variable ldrv, lav, lim: BIT;
- variable lstat: bit_vector(2 downto 0);
- variable xmnt, zmnt, res: BV32_Typ;
- variable i : integer;
begin
if Ck='1' then
-- op control
- if (exe='1') then
- lim :=PS_T6D1F; op := RF_ASOPD2F; xmnt:=Asx2f(39 downto 8); Ry:=Fix_Typ(Asy2f(39
downto 8)); zmnt:=Asy2f(31 downto 0);
- end if;
- if (RST='0') then
- ldrv := RF_SHSD2F;
- else ldrv :='0';
- end if;
- lav := PS_AV1F;
- --...........................................................................
- yshf:=X"00000000"; ylen:=X"00000000";
- if ((op = fext) or (op = fextse) or (op = fdep) or (op = orfdep)
or (op = fdepse) or (op = orfdepse)) then
- yshf(5 downto 0) := Ry(5 downto 0); ylen(5 downto 0) := Ry(11 downto
6);
- else
- else yshf:= sign_extend(Ry(7 downto 0),32);
- end if;
- end if;
-- logic shifts
- if ((op = lshift) or (op = orlshift)) then --...........................................................................
- if ((yshf <= X"0000001F") and (yshf >= X"00000000"))
then
- res := shl(xmnt,to_integer(yshf));
- end if;
- if ((yshf >=X"FFFFFFE1") and (yshf <X"0000001F")
or (yshf >X"00000000") then
- ovf :='1'; else ovf :='0';
- end if;
- end if;
-- arithmetic shifts
- if ((op = ashift) or (op = orashift)) then --...........................................................................
- if ((yshf <= X"0000001F") and (yshf >= X"00000000"))
then
- res := shl(xmnt,to_integer(yshf));
- end if;
- if ((yshf >= X"FFFFFFE1") and (yshf < X"00000000"))
then
- if (xmnt(31)='1') then
- res := shr(xmnt, -to_integer(yshf)); res := res or shl(X"ffffffff",
32 + to_integer(yshf));
- else res := shr(xmnt, -to_integer(yshf));
- end if;
- end if;
- if (yshf > X"0000001F") then
- end if;
- if (yshf < X"FFFFFFE1") then
- if (xmnt(31)='1') then
- else res := X"00000000";
- end if;
- end if; --...........................................................................
- if (op = orashift) then
- end if; --...........................................................................
- i := 1;
- while (xmnt(31 - i) = xmnt(31) and (i <= 31)) loop
- end loop;
- if ((to_integer(yshf) >= i) and (xmnt /= X"00000000"))
then
- else ovf:='0';
- end if;
- end if;
-- rotates
- if (op = rot) then --...........................................................................
- if (yshf >= X"00000000") then
- res := shl(xmnt, to_integer(yshf and X"1F")); res :=
res or shr(xmnt, 32 - to_integer(yshf and X"1F"));
- end if;
- if (yshf < X"00000000") then
- res := shr(xmnt, to_integer((X"00000000"-yshf) and X"1F"));
res := res or shl(xmnt,(32 - to_integer((X"00000000"-yshf) and
X"1F")));
- end if; --...........................................................................
- ovf := '0';
- end if;
-- bit operations
- if ((op = bclr) or (op = bset) or (op = btgl) or (op = btst)) then
--...........................................................................
- if ((yshf >=X"00000000") and (yshf <= X"0000001F"))
then
- res :=shl(X"00000001",to_integer(yshf));
- if (op = bclr) then
- end if;
- if (op = bset) then
- end if;
- if (op = btgl) then
- if (xmnt(to_integer(yshf))='1') then
- else res := xmnt or res;
- end if;
- end if;
- if (op = btst) then
- end if;
- end if;
- if ((yshf < X"00000000") or (yshf > X"0000001F"))
then
- if (op /= btst) then
- res := xmnt;
- else res := X"00000000";
- end if;
- end if; --...........................................................................
- if (yshf > X"0000001F") or (yshf < X"00000000")
then
- ovf:='1';
- else ovf:='0';
- end if;
- end if;
-- field operations
- if ((op = fext) or (op = fextse) or (op = fdep) or (op = fdepse)
or (op = orfdep) or (op = orfdepse)) then --...........................................................................
- if ((op = fdep) or (op = orfdep)) then
- if (yshf <= X"0000001F") then
- res := shl(xmnt, to_integer(yshf));
- end if;
- if (yshf > X"0000001F") then
- end if;
- if ((yshf + ylen) <= X"0000001F") then
- res := res and not shl(X"ffffffff", to_integer(yshf +
ylen));
- end if;
- end if; --...........................................................................
- if (op = fext) then
- if (yshf <= X"0000001F") then
- res := shr(xmnt, to_integer(yshf));
- end if;
- if (yshf > X"0000001F") then
- end if;
- if (ylen <= X"0000001F") then
- res := res and not shl(X"ffffffff", to_integer(ylen));
- end if;
- end if; --...........................................................................
- if ((op = fdepse) or (op = orfdepse)) then
- if (yshf <= X"0000001F") then
- res := shl(xmnt, to_integer(yshf));
- end if;
- if (yshf > X"0000001F") then
- end if;
- if ((yshf + ylen) <= X"0000001F") then
- if (ylen /= X"00000000") then
- if (xmnt(to_integer(ylen) - 1)='0') then
- res := res and not shl(X"ffffffff", to_integer(yshf +
ylen));
- else res := res or shl(X"ffffffff", to_integer(yshf +
ylen));
- end if;
- else res := X"00000000";
- end if;
- end if;
- end if; --...........................................................................
- if ((op = fextse)) then if (yshf <= X"0000001F") then
- res := shr(xmnt,to_integer(yshf));
- end if;
- if (yshf > X"0000001F") then
- end if;
- if ((to_integer(yshf + ylen) <= 32) and (ylen <= X"0000001F"))
then
- if (ylen /= X"00000000") then
- if (xmnt(to_integer(yshf + ylen) - 1)='0') then
- res := shr(xmnt,to_integer(yshf)) and not shl(X"ffffffff",
to_integer(ylen));
- else res := shr(xmnt,to_integer(yshf)) or shl(X"ffffffff",
to_integer(ylen));
- end if;
- else res := X"00000000";
- end if;
- end if;
- end if; --...........................................................................
- if ((op = orfdep) or (op = orfdepse)) then
- end if;
- if ((yshf + ylen) > X"00000020") then
- else ovf:='0';
- end if;
end if;
-- exponent extracts
- if ((op = exp) or (op = expex) or (op = leftz) or (op = lefto))
then --...........................................................................
- if ((op = exp) or (op = expex)) then
- i:= 1;
- while (xmnt(31 - i) = xmnt(31) and (i <= 31)) loop
- end loop;
- if (not ((op = expex) and lav='1')) then
- end if;
- if ((op = expex) and lav='1') then
- res := X"00000001";
- end if;
- ovf := '0';
- end if; --...........................................................................
- if (op = leftz) then
- i:= 0;
- while (xmnt(31 - i) ='0' and (i <= 31)) loop
- i:=i+1;
- end loop;
- res := IToBV(i,32); ovf := res(5);
- end if; --...........................................................................
- if (op = lefto) then
- i:= 0;
- while (xmnt(31 - i) ='1' and (i <= 31)) loop
- i:=i+1;
- end loop;
- res := IToBV(i,32); ovf := res(5);
- end if;
- end if;
-- output latches
- if (res =X"00000000") then
- else lstat(0):='0';
- end if;
- lstat(1) := ovf;
- if ((op /= exp) and (op /= expex)) then
- end if;
- if ((op =expex) and lav='1') then
- lstat(2) := xmnt(31) xor lav;
- end if;
- if (((op =expex) and lav='0') or (op =exp)) then
- end if;
-- output drivers
- if (CEN='1' and ldrv='1') then
- SR2F(7 downto 0) <= X"00"; SR2F(39 downto 8) <=
res;
- else
- SR2F(i) := RELEASE after RES_CEN_SPD;
- end if;
- SH_STAT2F <= lstat;
end if;
-- Ck=' '
end process;
end SFTR_a;
back
to text