[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [f-cpu] fadder forever




Michael Riepe a écrit :

Can't you just send the VHDL source code? I consider that more
readable.

so here is the first stage:


-- FLOATING POINT ADD/SUB UNIT STAGES :


r1_Fa <= Din_0(WIDTH-1 downto 0);
r1_Fb <= Din_1(WIDTH-1 downto 0);
Dout_0 <= Fout;

r1_Enable <= En;

r1_SuperMode(Super_Mode_IEEE) <= ieee_flag;
r1_SuperMode(Super_Mode_Sub) <= Substract;
r1_SuperMode(Super_Mode_SIMD) <= simd_flag;
r1_SuperMode(Super_Mode_OpSize0)<= SIMD(0);
r1_SuperMode(Super_Mode_OpSize1)<= SIMD(1);
r1_SuperMode(Super_Mode_RoundMode0) <= RoundMode(0);
r1_SuperMode(Super_Mode_RoundMode1) <= RoundMode(1);


-- stage 1 : start DE calculation and // trivial case checks
stage_1 : process (Clk, Rst)

-- first part of a integer adder
-- deliberately inspirated by M. Riepe's CSAdd function
-- estimated delay : d=3, t=4
procedure fasu_ExpAdder_PartOne(a, b : in std_ulogic_vector;
g, p, s, t : out std_ulogic_vector) is
constant L : natural := a'length; variable aa, bb : std_ulogic_vector(L-1 downto 0);
variable sv, tv : std_ulogic_vector(L-1 downto 0);
variable gm, pm : std_ulogic_vector(L-1 downto 0);
begin
assert a'length = L;
assert b'length = L;
assert g'length = L;
assert p'length = L;
assert s'length = L;
assert t'length = L;

-- normalize inputs
aa := A;
bb := B;

-- a row of 4-bit adders
-- (d=0)
gm := aa and bb; -- d=1, t=1
pm := aa xor bb; -- d=1, t=2
-- ( d=1 t=2 )

CSV(gm, pm, sv, tv); -- d=2, t=2
-- (d=3, t=4)

g := gm;
p := pm;
s := sv;
t := tv;

end;





-- input signals as single floats
variable Fa : std_ulogic_vector(CHUNK_SIZE-1 downto 0);
variable Fb : std_ulogic_vector(CHUNK_SIZE-1 downto 0);

variable gm00, gm01, pm00, pm01 : std_ulogic_vector(SGL_E_SIZE-1 downto 0);
variable sv00, sv01, tv00, tv01 : std_ulogic_vector(SGL_E_SIZE-1 downto 0);
variable gm10, gm11, pm10, pm11 : std_ulogic_vector(DBL_E_SIZE-1 downto 0);
variable sv10, sv11, tv10, tv11 : std_ulogic_vector(DBL_E_SIZE-1 downto 0);

variable Ea0, Eb0 : std_ulogic_vector(SGL_E_SIZE-1 downto 0);
variable Ea1, Eb1 : std_ulogic_vector(DBL_E_SIZE-1 downto 0);
variable EffSubDBL, EffSubSGL : std_ulogic;
variable Substract : std_ulogic;

-- only for representation detection, there is 3 datapaths:
-- see operands as DOUBLE
-- as 2 SINGLES
variable Fa_raE_DBL, Fa_roM_DBL, Fa_roE_DBL,
Fb_raE_DBL, Fb_roM_DBL, Fb_roE_DBL : std_ulogic;
variable Fa_raE_hSGL, Fa_roM_hSGL, Fa_roE_hSGL,
Fb_raE_hSGL, Fb_roM_hSGL, Fb_roE_hSGL : std_ulogic;
variable Fa_raE_lSGL, Fa_roM_lSGL, Fa_roE_lSGL,
Fb_raE_lSGL, Fb_roM_lSGL, Fb_roE_lSGL : std_ulogic;
variable OpSize : std_ulogic;

begin
if (Rst = '1') then
r2_Enable <= '0';
else
if (rising_edge(Clk)) then
if (r1_Enable = '1') then
for i in 0 to BLOCK64_NBR-1 loop -- for each 64bit chunk

Fa(CHUNK_SIZE-1 downto 0) := r1_Fa((i+1)*CHUNK_SIZE-1 downto i*CHUNK_SIZE);
Fb(CHUNK_SIZE-1 downto 0) := r1_Fb((i+1)*CHUNK_SIZE-1 downto i*CHUNK_SIZE);
OpSize := r1_SuperMode(Super_Mode_OpSize0);
-- note : r1_SuperMode(Super_Mode_OpSize1) = 0 assumed
Substract := r1_SuperMode(Super_Mode_Sub);
-- (d=0)
-- TODO : enable/disable chunk following SIMD_flag
-- (d=1)
if (OpSize = '1') then -- SIMD mode = SINGLE
-- First part Exponent Substraction
-- (d=2)
Ea0(SGL_E_SIZE-1 downto 0) := Fa(SGL_E_END downto SGL_E_START); -- d=1
Eb0(SGL_E_SIZE-1 downto 0) := not(Fb(SGL_E_END downto SGL_E_START)); -- d=2
-- (d=2)
Ea1(SGL_E_SIZE-1 downto 0) := Fa(SGL_E_END + SGL_SIZE downto SGL_E_START + SGL_SIZE); -- d=1
Ea1(SGL_E_SIZE-1 downto 0) := not (Fb(SGL_E_END + SGL_SIZE downto SGL_E_START + SGL_SIZE)); -- d=2
Ea1(DBL_SIZE-1 downto SGL_SIZE) := (others => '0'); -- d=0
Eb1(DBL_SIZE-1 downto SGL_SIZE) := (others => '0'); -- d=0
else -- SIMD mode = double
-- (d=1)
Ea0(SGL_E_SIZE-1 downto 0) := (others => '0'); -- d=0
Eb0(SGL_E_SIZE-1 downto 0) := (others => '0'); -- d=0
-- (d=2)
Ea1(DBL_E_SIZE-1 downto 0) := Fa(DBL_E_END downto DBL_E_START); -- d=1
Ea1(DBL_E_SIZE-1 downto 0) := not (Fb(DBL_E_END downto DBL_E_START)); -- d=2
end if;
-- (d=3)

-- First part 11-bits adders ('DOUBLE or highest single' datapath)
-- (d=3)
-- computing Ea-Eb
fasu_ExpAdder_PartOne(Ea1, Eb1, gm10, pm10, sv10, tv10); -- d=3
-- computing Eb-Ea
fasu_ExpAdder_PartOne(Eb1, Ea1, gm11, pm11, sv11, tv11); -- d=3
-- (d=6)
-- First part 8-bits adders ('lowest single' datapath)
-- (d=3)
-- computing Ea-Eb
fasu_ExpAdder_PartOne(Ea0, Eb0, gm00, pm00, sv00, tv00); -- d=3
-- computing Eb-Ea
fasu_ExpAdder_PartOne(Eb0, Ea0, gm01, pm01, sv01, tv01); -- d=3
-- (d=6)
-- First part 8-bits adders ('lowest single' datapath)
-- (d=3)
-- computing Ea-Eb
fasu_ExpAdder_PartOne(Ea1, Eb1, gm10, pm10, sv10, tv10); -- d=3
-- computing Eb-Ea
fasu_ExpAdder_PartOne(Eb1, Ea1, gm11, pm11, sv11, tv11); -- d=3
-- (d=6)


-- Special value detection, part one: DOUBLE datapath
-- (!!ONLY DOUBLE, NOT 'DOUBLE or highest SINGLE datapath !!)
--(d=1)
Fa_roE_DBL := reduce_or (Fa(DBL_E_End downto DBL_E_Start)); -- d=3 Fa_roM_DBL := reduce_or (Fa(DBL_M_End downto DBL_M_Start)); -- d=3 Fa_raE_DBL := reduce_and(Fa(DBL_E_End downto DBL_E_Start)); -- d=3
Fb_roE_DBL := reduce_or (Fb(DBL_E_End downto DBL_E_Start)); -- d=3 Fb_roM_DBL := reduce_or (Fb(DBL_M_End downto DBL_M_Start)); -- d=3 Fb_raE_DBL := reduce_and(Fb(DBL_E_End downto DBL_E_Start)); -- d=3
-- (d=4)
-- Special value detection, part one: highest SINGLE datapath
--(d=1)
Fa_roE_hSGL := reduce_or (Fa(32+SGL_E_End downto 32+SGL_E_Start)); -- d=3 Fa_roM_hSGL := reduce_or (Fa(32+SGL_M_End downto 32+SGL_M_Start)); -- d=3 Fa_raE_hSGL := reduce_and(Fa(32+SGL_E_End downto 32+SGL_E_Start)); -- d=3
Fb_roE_hSGL := reduce_or (Fb(32+SGL_E_End downto 32+SGL_E_Start)); -- d=3 Fb_roM_hSGL := reduce_or (Fb(32+SGL_M_End downto 32+SGL_M_Start)); -- d=3 Fb_raE_hSGL := reduce_and(Fb(32+SGL_E_End downto 32+SGL_E_Start)); -- d=3
-- (d=4)
-- Special value detection, part one: lowest SINGLE datapath
--(d=1)
Fa_roE_lSGL := reduce_or (Fa(SGL_E_End downto SGL_E_Start)); -- d=3 Fa_roM_lSGL := reduce_or (Fa(SGL_M_End downto SGL_M_Start)); -- d=3 Fa_raE_lSGL := reduce_and(Fa(SGL_E_End downto SGL_E_Start)); -- d=3
Fb_roE_lSGL := reduce_or (Fb(SGL_E_End downto SGL_E_Start)); -- d=3 Fb_roM_lSGL := reduce_or (Fb(SGL_M_End downto SGL_M_Start)); -- d=3 Fb_raE_lSGL := reduce_and(Fb(SGL_E_End downto SGL_E_Start)); -- d=3
-- (d=4)
-- Effective Subtraction detection for 'DOUBLE and highest SINGLE' datapath
-- (d=1)
EffSubDBL := Fa(DBL_S_POS) xor Fb(DBL_S_POS) xor Substract; -- d=2
-- rem: DBL_S_POS = SGL_S_POS + SGL_SIZE = 63
-- (d=3)
-- Effective Subtraction detection for 'lowest SINGLE' datapath
-- (d=1)
EffSubSGL := Fa(SGL_S_POS) xor Fb(SGL_S_POS) xor Substract; -- d=2
-- (d=3)
-- storing results to next stage registers
r2_gm00((i+1)*SGL_E_SIZE-1 downto i*SGL_E_SIZE) <= gm00;
r2_gm01((i+1)*SGL_E_SIZE-1 downto i*SGL_E_SIZE) <= gm01;
r2_pm00((i+1)*SGL_E_SIZE-1 downto i*SGL_E_SIZE) <= pm00;
r2_pm01((i+1)*SGL_E_SIZE-1 downto i*SGL_E_SIZE) <= pm01;
r2_sv00((i+1)*SGL_E_SIZE-1 downto i*SGL_E_SIZE) <= sv00;
r2_sv01((i+1)*SGL_E_SIZE-1 downto i*SGL_E_SIZE) <= sv01;
r2_tv00((i+1)*SGL_E_SIZE-1 downto i*SGL_E_SIZE) <= tv00;
r2_tv01((i+1)*SGL_E_SIZE-1 downto i*SGL_E_SIZE) <= tv01;
r2_gm10((i+1)*DBL_E_SIZE-1 downto i*DBL_E_SIZE) <= gm10;
r2_gm11((i+1)*DBL_E_SIZE-1 downto i*DBL_E_SIZE) <= gm11;
r2_pm10((i+1)*DBL_E_SIZE-1 downto i*DBL_E_SIZE) <= pm10;
r2_pm11((i+1)*DBL_E_SIZE-1 downto i*DBL_E_SIZE) <= pm11;
r2_sv10((i+1)*DBL_E_SIZE-1 downto i*DBL_E_SIZE) <= sv10;
r2_sv11((i+1)*DBL_E_SIZE-1 downto i*DBL_E_SIZE) <= sv11;
r2_tv10((i+1)*DBL_E_SIZE-1 downto i*DBL_E_SIZE) <= tv10;
r2_tv11((i+1)*DBL_E_SIZE-1 downto i*DBL_E_SIZE) <= tv11;
r2_Fa((i+1)*CHUNK_SIZE-1 downto i*CHUNK_SIZE) <= Fa;
r2_Fb((i+1)*CHUNK_SIZE-1 downto i*CHUNK_SIZE) <= Fb;

r2_EffSubDBL(i) <= EffSubDBL;
r2_EffSubSGL(i) <= EffSubSGL;

end loop;
-- enable stage 2
r2_Enable <= '1';
else
r2_Enable <= '0';
end if;
end if;
end if; end process;



--

~~ Gaetan ~~
http://www.xeberon.net


*************************************************************
To unsubscribe, send an e-mail to majordomo@seul.org with
unsubscribe f-cpu in the body. http://f-cpu.seul.org/