Version 2 (modified by nakasato, 14 years ago) (diff) |
---|
VHDLの生成
FP加算器のclass定義
class FPadd < FPop def initialize(nf = 32, nm = 23) super(nf, nm, 4) @narg = 3 @name = gen_name(:add) @nadder = nm + 1 + 3 + 1 @swap = addcomponent Swap.new(nf) @rshift = addcomponent Rshift.new(nm+1,@nexp+1) @sbit = addcomponent Extractsbit.new(nm+1, @nexp+1) @sadd = addcomponent INTsadder.new(@nadder+1) ## 2 @test = addcomponent FPaddtest.new(nf, nm, @nadder) ## 1 @uflow = addcomponent Underflow.new(@nman+1,@nexp) @delay1 = addcomponent(Delay.new(1,2)) @delay2 = addcomponent(Delay.new(@nexp,2)) @delay3 = addcomponent(Delay.new(1,3)) @delay4 = addcomponent(Delay.new(@nexp,3)) @delay5 = addcomponent(Delay.new(@nexp+1,3)) if @nexp == @nman then @delay6 = @delay5 else @delay6 = addcomponent(Delay.new(@nman+1,3)) end end def run super('float_add.vhd.erb') end end
FP加算器のソース
------------------------------------------------------------------------------- % defineIO :in, :x, @nfloat % defineIO :in, :y, @nfloat % defineIO :out, :z, @nfloat % defineIO :in, :clk, 1 ------------------------------------------------------------------------------- % nfloat = @nfloat % nman = @nman % nexp = @nexp % % width_nf = "#{nfloat-1} downto 0" % width_nm = "#{nman-1} downto 0" % width_ne = "#{nexp-1} downto 0" ------------------------------------------------------------------------------- <%= generate_header %> <%= generate_entity %> architecture source of <%= @name %> is <%= generate_components %> signal signz,sz : std_logic; signal manz,mz : std_logic_vector(<%= nman %> downto 0); signal expz,ez : std_logic_vector(<%= width_ne %>); signal ex0, ey0 : std_logic_vector(<%= nexp %> downto 0); signal xx, yy : std_logic_vector(<%= width_nf %>); signal sx, sy : std_logic; signal mx, my : std_logic_vector(<%= nman %> downto 0); signal ex, ey : std_logic_vector(<%= width_ne %>); signal dx : std_logic_vector(<%= nexp %> downto 0); signal dy : std_logic_vector(<%= nexp %> downto 0); signal diff : std_logic_vector(<%= nexp %> downto 0); -- signal res0 : std_logic_vector(<%= nman %> downto 0); signal expz0 : std_logic_vector(<%= width_ne %>); signal signz0 : std_logic; signal ulp0, rbit0, sbit0 : std_logic; signal res1 : std_logic_vector(<%= nman %> downto 0); signal expz1 : std_logic_vector(<%= width_ne %>); signal signz1 : std_logic; signal ulp1, rbit1, sbit1 : std_logic; -- signal o1 : std_logic_vector(<%= @nadder - 1 %> downto 0); signal o2 : std_logic_vector(<%= @nadder - 1 %> downto 0); signal r1, r2, r3 : std_logic; signal a0, a1 : std_logic_vector(<%= @nadder %> downto 0); signal b0, b1 : std_logic_vector(<%= @nadder %> downto 0); signal res : std_logic_vector(<%= @nadder %> downto 0); signal resn : std_logic_vector(<%= @nadder %> downto 0); signal zf : std_logic; -- signal dd : std_logic_vector(<%= nexp + 1 %> downto 0); signal d0 : std_logic_vector(<%= nexp + 1 %> downto 0); signal manzz : std_logic_vector(<%= nman %> downto 0); signal expzz : std_logic_vector(<%= width_ne %>); signal ulp, rbit, sbit : std_logic; signal zz : std_logic_vector(<%= width_nf %>); signal expz0_reg : std_logic_vector(<%= width_ne %>); signal expz0_regg : std_logic_vector(<%= width_ne %>); signal r1_reg, r2_reg, r3_reg : std_logic; signal diff_reg : std_logic_vector(<%= nexp %> downto 0); signal res0_reg : std_logic_vector(<%= nman %> downto 0); signal signz0_reg : std_logic; signal signz1_reg : std_logic; signal ulp0_reg, rbit0_reg, sbit0_reg : std_logic; signal zf_reg : std_logic; begin ex0 <= '0'&x(<%= nfloat - 2 %> downto <%= nman %>); ey0 <= '0'&y(<%= nfloat - 2 %> downto <%= nman %>); dx <= ex0 - ey0; dy <= ey0 - ex0; -- swap s0 : <%= @swap %> port map ( f => dx(<%= nexp %>), x => x, y => y, xs => xx, ys => yy); with dx(<%= nexp %>) select diff <= dy when '1', dx when others; e0 : <%= @fextract %> port map ( x => xx, s => sx, m => mx, e => ex); e1 : <%= @fextract %> port map ( x => yy, s => sy, m => my, e => ey); -------------------------------------------------------------------- -- if diff > <%= nman + 1 %> res0 <= mx; expz0 <= ex; signz0 <= sx; ulp0 <= res0(0); rbit0 <= '0'; sbit0 <= '1'; -- else -- o1 o1 <= "00"&mx&"00"; -- o2 shift0 : <%= @rshift %> port map (c => diff, i => my, o => o2); r1 <= o2(1); r2 <= o2(0); -- r3 sb0 : <%= @sbit %> port map (c => diff, i => my, s => r3); ---- a0 <= o1(<%= @nadder - 1 %> downto 0)&'0'; b0 <= o2(<%= @nadder - 1 %> downto 0)&r3; -- add: <%= @sadd %> port map (x => a0, sx => sx, y => b0, sy => sy, z => resn, sz => signz1, clk => clk); d1 : <%= @delay1 %> port map (i => r1, o => r1_reg, clk => clk); d2 : <%= @delay1 %> port map (i => r2, o => r2_reg, clk => clk); d3 : <%= @delay1 %> port map (i => r3, o => r3_reg, clk => clk); d4 : <%= @delay2 %> port map (i => expz0, o => expz0_reg, clk => clk); -- flag zf if res == 0 with resn select zf <= '1' when "<%= 0.to_b(@nadder+1) %>", '0' when others; ---- f0 : <%= @test %> port map ( tmp => resn(<%= @nadder - 1 %> downto 0), exp => expz0_reg, r1 => r1_reg, r2 => r2_reg, r3 => r3_reg, res => res1, expz => expz1, ulp => ulp1, rbit => rbit1, sbit => sbit1, clk => clk); process(clk) begin if(clk'event and clk='1') then signz1_reg <= signz1; zf_reg <= zf; end if; end process; --sadd 2 signz1, resn --test 3 res1, expz1, ulp1, rbit1, sbit1 d5 : <%= @delay3 %> port map (i => signz0, o => signz0_reg, clk => clk); d6 : <%= @delay3 %> port map (i => ulp0, o => ulp0_reg, clk => clk); d7 : <%= @delay3 %> port map (i => rbit0, o => rbit0_reg, clk => clk); d8 : <%= @delay3 %> port map (i => sbit0, o => sbit0_reg, clk => clk); d9 : <%= @delay4 %> port map (i => expz0, o => expz0_regg, clk => clk); d10 : <%= @delay5 %> port map (i => diff, o => diff_reg, clk => clk); d11 : <%= @delay6 %> port map (i => res0, o => res0_reg, clk => clk); -------------------------------------------------------------------- d0 <= '0'&diff_reg; dd <= "<%= (nman + 1).to_b(nexp+1) %>" - d0; uf : <%= @uflow %> port map (f => dd(<%= nexp %>), m1 => res0_reg, e1 => expz0_regg, u1 => ulp0_reg, r1 => rbit0_reg, s1 => sbit0_reg, m2 => res1, e2 => expz1, u2 => ulp1, r2 => rbit1, s2 => sbit1, m => manzz, e => expzz, u => ulp, r => rbit, s => sbit ); with dd(<%= nexp %>) select signz <= signz0_reg when '1', signz1_reg when others; r0 : <%= @frounding %> port map ( m => manzz, e => expzz, u => ulp, r => rbit, s => sbit, mout => manz, eout=> expz); with zf_reg select sz <= signz when '0', '0' when others; with zf_reg select mz <= manz when '0', "<%= 0.to_b(@nman+1) %>" when others; with zf_reg select ez <= expz when '0', "<%= 0.to_b(@nexp) %>" when others; c0 : <%= @fcompose %> port map (s => sz, m => mz, e => ez, z => z, clk => clk); end source; ------------------------------------------------------------------------------- <%= generate_components_body %> -------------------------------------------------------------------------------
エミュレーションコードの生成
そのうち載せる。