| | 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 | }}} |