| 1 | = VHDLの生成 = |
| 2 | == FP加算器のclass定義 == |
| 3 | {{{ |
| 4 | class FPadd < FPop |
| 5 | def initialize(nf = 32, nm = 23) |
| 6 | super(nf, nm, 4) |
| 7 | @narg = 3 |
| 8 | @name = gen_name(:add) |
| 9 | |
| 10 | @nadder = nm + 1 + 3 + 1 |
| 11 | @swap = addcomponent Swap.new(nf) |
| 12 | @rshift = addcomponent Rshift.new(nm+1,@nexp+1) |
| 13 | @sbit = addcomponent Extractsbit.new(nm+1, @nexp+1) |
| 14 | |
| 15 | @sadd = addcomponent INTsadder.new(@nadder+1) ## 2 |
| 16 | @test = addcomponent FPaddtest.new(nf, nm, @nadder) ## 1 |
| 17 | @uflow = addcomponent Underflow.new(@nman+1,@nexp) |
| 18 | |
| 19 | @delay1 = addcomponent(Delay.new(1,2)) |
| 20 | @delay2 = addcomponent(Delay.new(@nexp,2)) |
| 21 | |
| 22 | @delay3 = addcomponent(Delay.new(1,3)) |
| 23 | @delay4 = addcomponent(Delay.new(@nexp,3)) |
| 24 | @delay5 = addcomponent(Delay.new(@nexp+1,3)) |
| 25 | if @nexp == @nman then |
| 26 | @delay6 = @delay5 |
| 27 | else |
| 28 | @delay6 = addcomponent(Delay.new(@nman+1,3)) |
| 29 | end |
| 30 | end |
| 31 | |
| 32 | def run |
| 33 | super('float_add.vhd.erb') |
| 34 | end |
| 35 | end |
| 36 | }}} |
| 37 | |
| 38 | |
| 39 | == FP加算器のソース == |
| 40 | {{{ |
| 41 | ------------------------------------------------------------------------------- |
| 42 | % defineIO :in, :x, @nfloat |
| 43 | % defineIO :in, :y, @nfloat |
| 44 | % defineIO :out, :z, @nfloat |
| 45 | % defineIO :in, :clk, 1 |
| 46 | ------------------------------------------------------------------------------- |
| 47 | % nfloat = @nfloat |
| 48 | % nman = @nman |
| 49 | % nexp = @nexp |
| 50 | % |
| 51 | % width_nf = "#{nfloat-1} downto 0" |
| 52 | % width_nm = "#{nman-1} downto 0" |
| 53 | % width_ne = "#{nexp-1} downto 0" |
| 54 | ------------------------------------------------------------------------------- |
| 55 | <%= generate_header %> |
| 56 | |
| 57 | <%= generate_entity %> |
| 58 | |
| 59 | architecture source of <%= @name %> is |
| 60 | |
| 61 | <%= generate_components %> |
| 62 | |
| 63 | signal signz,sz : std_logic; |
| 64 | signal manz,mz : std_logic_vector(<%= nman %> downto 0); |
| 65 | signal expz,ez : std_logic_vector(<%= width_ne %>); |
| 66 | signal ex0, ey0 : std_logic_vector(<%= nexp %> downto 0); |
| 67 | |
| 68 | signal xx, yy : std_logic_vector(<%= width_nf %>); |
| 69 | signal sx, sy : std_logic; |
| 70 | signal mx, my : std_logic_vector(<%= nman %> downto 0); |
| 71 | signal ex, ey : std_logic_vector(<%= width_ne %>); |
| 72 | |
| 73 | signal dx : std_logic_vector(<%= nexp %> downto 0); |
| 74 | signal dy : std_logic_vector(<%= nexp %> downto 0); |
| 75 | signal diff : std_logic_vector(<%= nexp %> downto 0); |
| 76 | |
| 77 | -- |
| 78 | signal res0 : std_logic_vector(<%= nman %> downto 0); |
| 79 | signal expz0 : std_logic_vector(<%= width_ne %>); |
| 80 | signal signz0 : std_logic; |
| 81 | signal ulp0, rbit0, sbit0 : std_logic; |
| 82 | |
| 83 | signal res1 : std_logic_vector(<%= nman %> downto 0); |
| 84 | signal expz1 : std_logic_vector(<%= width_ne %>); |
| 85 | signal signz1 : std_logic; |
| 86 | signal ulp1, rbit1, sbit1 : std_logic; |
| 87 | |
| 88 | -- |
| 89 | signal o1 : std_logic_vector(<%= @nadder - 1 %> downto 0); |
| 90 | signal o2 : std_logic_vector(<%= @nadder - 1 %> downto 0); |
| 91 | signal r1, r2, r3 : std_logic; |
| 92 | |
| 93 | signal a0, a1 : std_logic_vector(<%= @nadder %> downto 0); |
| 94 | signal b0, b1 : std_logic_vector(<%= @nadder %> downto 0); |
| 95 | signal res : std_logic_vector(<%= @nadder %> downto 0); |
| 96 | signal resn : std_logic_vector(<%= @nadder %> downto 0); |
| 97 | |
| 98 | signal zf : std_logic; |
| 99 | |
| 100 | -- |
| 101 | signal dd : std_logic_vector(<%= nexp + 1 %> downto 0); |
| 102 | signal d0 : std_logic_vector(<%= nexp + 1 %> downto 0); |
| 103 | signal manzz : std_logic_vector(<%= nman %> downto 0); |
| 104 | signal expzz : std_logic_vector(<%= width_ne %>); |
| 105 | signal ulp, rbit, sbit : std_logic; |
| 106 | |
| 107 | signal zz : std_logic_vector(<%= width_nf %>); |
| 108 | |
| 109 | signal expz0_reg : std_logic_vector(<%= width_ne %>); |
| 110 | signal expz0_regg : std_logic_vector(<%= width_ne %>); |
| 111 | signal r1_reg, r2_reg, r3_reg : std_logic; |
| 112 | signal diff_reg : std_logic_vector(<%= nexp %> downto 0); |
| 113 | signal res0_reg : std_logic_vector(<%= nman %> downto 0); |
| 114 | signal signz0_reg : std_logic; |
| 115 | signal signz1_reg : std_logic; |
| 116 | signal ulp0_reg, rbit0_reg, sbit0_reg : std_logic; |
| 117 | signal zf_reg : std_logic; |
| 118 | |
| 119 | begin |
| 120 | ex0 <= '0'&x(<%= nfloat - 2 %> downto <%= nman %>); |
| 121 | ey0 <= '0'&y(<%= nfloat - 2 %> downto <%= nman %>); |
| 122 | |
| 123 | dx <= ex0 - ey0; |
| 124 | dy <= ey0 - ex0; |
| 125 | |
| 126 | -- swap |
| 127 | s0 : <%= @swap %> port map ( f => dx(<%= nexp %>), x => x, y => y, xs => xx, ys => yy); |
| 128 | |
| 129 | with dx(<%= nexp %>) select |
| 130 | diff <= dy when '1', |
| 131 | dx when others; |
| 132 | |
| 133 | e0 : <%= @fextract %> port map ( x => xx, s => sx, m => mx, e => ex); |
| 134 | e1 : <%= @fextract %> port map ( x => yy, s => sy, m => my, e => ey); |
| 135 | |
| 136 | -------------------------------------------------------------------- |
| 137 | -- if diff > <%= nman + 1 %> |
| 138 | res0 <= mx; |
| 139 | expz0 <= ex; |
| 140 | signz0 <= sx; |
| 141 | ulp0 <= res0(0); |
| 142 | rbit0 <= '0'; |
| 143 | sbit0 <= '1'; |
| 144 | -- else |
| 145 | -- o1 |
| 146 | o1 <= "00"&mx&"00"; |
| 147 | |
| 148 | -- o2 |
| 149 | shift0 : <%= @rshift %> port map (c => diff, i => my, o => o2); |
| 150 | |
| 151 | r1 <= o2(1); |
| 152 | r2 <= o2(0); |
| 153 | |
| 154 | -- r3 |
| 155 | sb0 : <%= @sbit %> port map (c => diff, i => my, s => r3); |
| 156 | |
| 157 | ---- |
| 158 | a0 <= o1(<%= @nadder - 1 %> downto 0)&'0'; |
| 159 | b0 <= o2(<%= @nadder - 1 %> downto 0)&r3; |
| 160 | |
| 161 | -- |
| 162 | add: <%= @sadd %> port map (x => a0, sx => sx, y => b0, sy => sy, |
| 163 | z => resn, sz => signz1, clk => clk); |
| 164 | |
| 165 | d1 : <%= @delay1 %> port map (i => r1, o => r1_reg, clk => clk); |
| 166 | d2 : <%= @delay1 %> port map (i => r2, o => r2_reg, clk => clk); |
| 167 | d3 : <%= @delay1 %> port map (i => r3, o => r3_reg, clk => clk); |
| 168 | d4 : <%= @delay2 %> port map (i => expz0, o => expz0_reg, clk => clk); |
| 169 | |
| 170 | -- flag zf if res == 0 |
| 171 | with resn select |
| 172 | zf <= '1' when "<%= 0.to_b(@nadder+1) %>", |
| 173 | '0' when others; |
| 174 | ---- |
| 175 | f0 : <%= @test %> port map ( tmp => resn(<%= @nadder - 1 %> downto 0), |
| 176 | exp => expz0_reg, r1 => r1_reg, r2 => r2_reg, r3 => r3_reg, |
| 177 | res => res1, expz => expz1, ulp => ulp1, rbit => rbit1, sbit => sbit1, clk => clk); |
| 178 | |
| 179 | process(clk) begin |
| 180 | if(clk'event and clk='1') then |
| 181 | signz1_reg <= signz1; |
| 182 | zf_reg <= zf; |
| 183 | end if; |
| 184 | end process; |
| 185 | |
| 186 | --sadd 2 signz1, resn |
| 187 | --test 3 res1, expz1, ulp1, rbit1, sbit1 |
| 188 | |
| 189 | d5 : <%= @delay3 %> port map (i => signz0, o => signz0_reg, clk => clk); |
| 190 | d6 : <%= @delay3 %> port map (i => ulp0, o => ulp0_reg, clk => clk); |
| 191 | d7 : <%= @delay3 %> port map (i => rbit0, o => rbit0_reg, clk => clk); |
| 192 | d8 : <%= @delay3 %> port map (i => sbit0, o => sbit0_reg, clk => clk); |
| 193 | d9 : <%= @delay4 %> port map (i => expz0, o => expz0_regg, clk => clk); |
| 194 | d10 : <%= @delay5 %> port map (i => diff, o => diff_reg, clk => clk); |
| 195 | d11 : <%= @delay6 %> port map (i => res0, o => res0_reg, clk => clk); |
| 196 | |
| 197 | -------------------------------------------------------------------- |
| 198 | d0 <= '0'&diff_reg; |
| 199 | dd <= "<%= (nman + 1).to_b(nexp+1) %>" - d0; |
| 200 | |
| 201 | uf : <%= @uflow %> port map (f => dd(<%= nexp %>), |
| 202 | m1 => res0_reg, e1 => expz0_regg, u1 => ulp0_reg, r1 => rbit0_reg, s1 => sbit0_reg, |
| 203 | m2 => res1, e2 => expz1, u2 => ulp1, r2 => rbit1, s2 => sbit1, |
| 204 | m => manzz, e => expzz, u => ulp, r => rbit, s => sbit ); |
| 205 | |
| 206 | with dd(<%= nexp %>) select |
| 207 | signz <= signz0_reg when '1', |
| 208 | signz1_reg when others; |
| 209 | |
| 210 | r0 : <%= @frounding %> port map ( m => manzz, e => expzz, u => ulp, r => rbit, s => sbit, |
| 211 | mout => manz, eout=> expz); |
| 212 | |
| 213 | with zf_reg select |
| 214 | sz <= signz when '0', |
| 215 | '0' when others; |
| 216 | |
| 217 | with zf_reg select |
| 218 | mz <= manz when '0', |
| 219 | "<%= 0.to_b(@nman+1) %>" when others; |
| 220 | |
| 221 | with zf_reg select |
| 222 | ez <= expz when '0', |
| 223 | "<%= 0.to_b(@nexp) %>" when others; |
| 224 | |
| 225 | c0 : <%= @fcompose %> port map (s => sz, m => mz, e => ez, z => z, clk => clk); |
| 226 | end source; |
| 227 | ------------------------------------------------------------------------------- |
| 228 | <%= generate_components_body %> |
| 229 | ------------------------------------------------------------------------------- |
| 230 | }}} |