├── README.md ├── fpu.v ├── test.v └── top.v /README.md: -------------------------------------------------------------------------------- 1 | # FPGA_networl -------------------------------------------------------------------------------- /fpu.v: -------------------------------------------------------------------------------- 1 | //32位浮点数乘法 2 | module FPU_MUL( 3 | input [31:0] Ai, 4 | input [31:0] Bi, 5 | output [31:0] Yo 6 | ); 7 | FLOAT_MUL f( 8 | .a_operand (Ai), 9 | .b_operand (Bi), 10 | .Exception (), 11 | .Overflow (), 12 | .Underflow (), 13 | .result (Yo)); 14 | endmodule 15 | 16 | //浮点数加法 17 | module FPU_ADD( 18 | input [31:0] Ai, 19 | input [31:0] Bi, 20 | output [31:0] Yo 21 | ); 22 | FLOAT_ADD_SUB add( 23 | .a_operand (Ai), 24 | .b_operand (Bi), 25 | .AddBar_Sub (1'b0), 26 | .Exception (), 27 | .result (Yo) 28 | ); 29 | endmodule 30 | 31 | //浮点数减法法 32 | module FPU_SUB( 33 | input [31:0] Ai, 34 | input [31:0] Bi, 35 | output [31:0] Yo 36 | ); 37 | FLOAT_ADD_SUB add( 38 | .a_operand (Ai), 39 | .b_operand (Bi), 40 | .AddBar_Sub (1'b1), 41 | .Exception (), 42 | .result (Yo) 43 | ); 44 | endmodule 45 | 46 | 47 | 48 | 49 | 50 | 51 | module FLOAT_ADD_SUB( 52 | input [31:0] a_operand,b_operand, 53 | input AddBar_Sub, 54 | output Exception, 55 | output [31:0] result 56 | ); 57 | 58 | wire operation_sub_addBar; 59 | wire Comp_enable; 60 | wire output_sign; 61 | 62 | wire [31:0] operand_a,operand_b; 63 | wire [23:0] significand_a,significand_b; 64 | wire [7:0] exponent_diff; 65 | 66 | 67 | wire [23:0] significand_b_add_sub; 68 | wire [7:0] exponent_b_add_sub; 69 | 70 | wire [24:0] significand_add; 71 | wire [30:0] add_sum; 72 | 73 | wire [23:0] significand_sub_complement; 74 | wire [24:0] significand_sub; 75 | wire [30:0] sub_diff; 76 | wire [24:0] subtraction_diff; 77 | wire [7:0] exponent_sub; 78 | 79 | assign {Comp_enable,operand_a,operand_b} = (a_operand[30:0] < b_operand[30:0]) ? {1'b1,b_operand,a_operand} : {1'b0,a_operand,b_operand}; 80 | 81 | assign exp_a = operand_a[30:23]; 82 | assign exp_b = operand_b[30:23]; 83 | 84 | 85 | assign Exception = (&operand_a[30:23]) | (&operand_b[30:23]); 86 | 87 | assign output_sign = AddBar_Sub ? Comp_enable ? !operand_a[31] : operand_a[31] : operand_a[31] ; 88 | 89 | assign operation_sub_addBar = AddBar_Sub ? operand_a[31] ^ operand_b[31] : ~(operand_a[31] ^ operand_b[31]); 90 | 91 | 92 | assign significand_a = (|operand_a[30:23]) ? {1'b1,operand_a[22:0]} : {1'b0,operand_a[22:0]}; 93 | assign significand_b = (|operand_b[30:23]) ? {1'b1,operand_b[22:0]} : {1'b0,operand_b[22:0]}; 94 | 95 | 96 | assign exponent_diff = operand_a[30:23] - operand_b[30:23]; 97 | 98 | 99 | assign significand_b_add_sub = significand_b >> exponent_diff; 100 | 101 | assign exponent_b_add_sub = operand_b[30:23] + exponent_diff; 102 | 103 | 104 | assign perform = (operand_a[30:23] == exponent_b_add_sub); 105 | 106 | 107 | assign significand_add = (perform & operation_sub_addBar) ? (significand_a + significand_b_add_sub) : 25'd0; 108 | 109 | 110 | assign add_sum[22:0] = significand_add[24] ? significand_add[23:1] : significand_add[22:0]; 111 | 112 | 113 | assign add_sum[30:23] = significand_add[24] ? (1'b1 + operand_a[30:23]) : operand_a[30:23]; 114 | 115 | 116 | assign significand_sub_complement = (perform & !operation_sub_addBar) ? ~(significand_b_add_sub) + 24'd1 : 24'd0 ; 117 | 118 | assign significand_sub = perform ? (significand_a + significand_sub_complement) : 25'd0; 119 | 120 | priority_encoder pe(significand_sub,operand_a[30:23],subtraction_diff,exponent_sub); 121 | 122 | assign sub_diff[30:23] = exponent_sub; 123 | 124 | assign sub_diff[22:0] = subtraction_diff[22:0]; 125 | 126 | assign result = Exception ? 32'b0 : ((!operation_sub_addBar) ? {output_sign,sub_diff} : {output_sign,add_sum}); 127 | 128 | endmodule 129 | 130 | 131 | 132 | 133 | module FLOAT_MUL( 134 | input [31:0] a_operand, 135 | input [31:0] b_operand, 136 | output Exception,Overflow,Underflow, 137 | output [31:0] result 138 | ); 139 | 140 | wire sign,product_round,normalised,zero; 141 | wire [8:0] exponent,sum_exponent; 142 | wire [22:0] product_mantissa; 143 | wire [23:0] operand_a,operand_b; 144 | wire [47:0] product,product_normalised; 145 | 146 | assign sign = a_operand[31] ^ b_operand[31]; 147 | 148 | assign Exception = (&a_operand[30:23]) | (&b_operand[30:23]); 149 | 150 | assign operand_a = (|a_operand[30:23]) ? {1'b1,a_operand[22:0]} : {1'b0,a_operand[22:0]}; 151 | 152 | assign operand_b = (|b_operand[30:23]) ? {1'b1,b_operand[22:0]} : {1'b0,b_operand[22:0]}; 153 | 154 | assign product = operand_a * operand_b; 155 | 156 | assign product_round = |product_normalised[22:0]; 157 | 158 | assign normalised = product[47] ? 1'b1 : 1'b0; 159 | 160 | assign product_normalised = normalised ? product : product << 1; 161 | 162 | 163 | assign product_mantissa = product_normalised[46:24] + (product_normalised[23] & product_round); 164 | 165 | assign zero = Exception ? 1'b0 : (product_mantissa == 23'd0) ? 1'b1 : 1'b0; 166 | 167 | assign sum_exponent = a_operand[30:23] + b_operand[30:23]; 168 | 169 | assign exponent = sum_exponent - 8'd127 + normalised; 170 | 171 | assign Overflow = ((exponent[8] & !exponent[7]) & !zero) ; 172 | 173 | assign Underflow = ((exponent[8] & exponent[7]) & !zero) ? 1'b1 : 1'b0; 174 | 175 | assign result = Exception ? 32'd0 : zero ? {sign,31'd0} : Overflow ? {sign,8'hFF,23'd0} : Underflow ? {sign,31'd0} : {sign,exponent[7:0],product_mantissa}; 176 | 177 | endmodule 178 | 179 | module priority_encoder( 180 | input [24:0] significand, 181 | input [7:0] Exponent_a, 182 | output reg [24:0] Significand, 183 | output [7:0] Exponent_sub 184 | ); 185 | 186 | reg [4:0] shift; 187 | 188 | always @(significand) 189 | begin 190 | casex (significand) 191 | 25'b1_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx : begin 192 | Significand = significand; 193 | shift = 5'd0; 194 | end 195 | 25'b1_01xx_xxxx_xxxx_xxxx_xxxx_xxxx : begin 196 | Significand = significand << 1; 197 | shift = 5'd1; 198 | end 199 | 200 | 25'b1_001x_xxxx_xxxx_xxxx_xxxx_xxxx : begin 201 | Significand = significand << 2; 202 | shift = 5'd2; 203 | end 204 | 205 | 25'b1_0001_xxxx_xxxx_xxxx_xxxx_xxxx : begin 206 | Significand = significand << 3; 207 | shift = 5'd3; 208 | end 209 | 210 | 25'b1_0000_1xxx_xxxx_xxxx_xxxx_xxxx : begin 211 | Significand = significand << 4; 212 | shift = 5'd4; 213 | end 214 | 215 | 25'b1_0000_01xx_xxxx_xxxx_xxxx_xxxx : begin 216 | Significand = significand << 5; 217 | shift = 5'd5; 218 | end 219 | 220 | 25'b1_0000_001x_xxxx_xxxx_xxxx_xxxx : begin // 24'h020000 221 | Significand = significand << 6; 222 | shift = 5'd6; 223 | end 224 | 225 | 25'b1_0000_0001_xxxx_xxxx_xxxx_xxxx : begin // 24'h010000 226 | Significand = significand << 7; 227 | shift = 5'd7; 228 | end 229 | 230 | 25'b1_0000_0000_1xxx_xxxx_xxxx_xxxx : begin // 24'h008000 231 | Significand = significand << 8; 232 | shift = 5'd8; 233 | end 234 | 235 | 25'b1_0000_0000_01xx_xxxx_xxxx_xxxx : begin // 24'h004000 236 | Significand = significand << 9; 237 | shift = 5'd9; 238 | end 239 | 240 | 25'b1_0000_0000_001x_xxxx_xxxx_xxxx : begin // 24'h002000 241 | Significand = significand << 10; 242 | shift = 5'd10; 243 | end 244 | 245 | 25'b1_0000_0000_0001_xxxx_xxxx_xxxx : begin // 24'h001000 246 | Significand = significand << 11; 247 | shift = 5'd11; 248 | end 249 | 250 | 25'b1_0000_0000_0000_1xxx_xxxx_xxxx : begin // 24'h000800 251 | Significand = significand << 12; 252 | shift = 5'd12; 253 | end 254 | 255 | 25'b1_0000_0000_0000_01xx_xxxx_xxxx : begin // 24'h000400 256 | Significand = significand << 13; 257 | shift = 5'd13; 258 | end 259 | 260 | 25'b1_0000_0000_0000_001x_xxxx_xxxx : begin // 24'h000200 261 | Significand = significand << 14; 262 | shift = 5'd14; 263 | end 264 | 265 | 25'b1_0000_0000_0000_0001_xxxx_xxxx : begin // 24'h000100 266 | Significand = significand << 15; 267 | shift = 5'd15; 268 | end 269 | 270 | 25'b1_0000_0000_0000_0000_1xxx_xxxx : begin // 24'h000080 271 | Significand = significand << 16; 272 | shift = 5'd16; 273 | end 274 | 275 | 25'b1_0000_0000_0000_0000_01xx_xxxx : begin // 24'h000040 276 | Significand = significand << 17; 277 | shift = 5'd17; 278 | end 279 | 280 | 25'b1_0000_0000_0000_0000_001x_xxxx : begin // 24'h000020 281 | Significand = significand << 18; 282 | shift = 5'd18; 283 | end 284 | 285 | 25'b1_0000_0000_0000_0000_0001_xxxx : begin // 24'h000010 286 | Significand = significand << 19; 287 | shift = 5'd19; 288 | end 289 | 290 | 25'b1_0000_0000_0000_0000_0000_1xxx : begin // 24'h000008 291 | Significand = significand << 20; 292 | shift = 5'd20; 293 | end 294 | 295 | 25'b1_0000_0000_0000_0000_0000_01xx : begin // 24'h000004 296 | Significand = significand << 21; 297 | shift = 5'd21; 298 | end 299 | 300 | 25'b1_0000_0000_0000_0000_0000_001x : begin // 24'h000002 301 | Significand = significand << 22; 302 | shift = 5'd22; 303 | end 304 | 305 | 25'b1_0000_0000_0000_0000_0000_0001 : begin // 24'h000001 306 | Significand = significand << 23; 307 | shift = 5'd23; 308 | end 309 | 310 | 25'b1_0000_0000_0000_0000_0000_0000 : begin // 24'h000000 311 | Significand = significand << 24; 312 | shift = 5'd24; 313 | end 314 | default : begin 315 | Significand = (~significand) + 1'b1; 316 | shift = 8'd0; 317 | end 318 | 319 | endcase 320 | end 321 | assign Exponent_sub = Exponent_a - shift; 322 | 323 | endmodule -------------------------------------------------------------------------------- /test.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | `include "top.v" 3 | module test( 4 | ); 5 | 6 | 7 | 8 | reg[31:0] x1=32'h3fa00000,x2=32'h3fa00000,x3=32'h3fa00000; 9 | 10 | 11 | 12 | 13 | wire[31:0] y1,y2,y3; 14 | 15 | 16 | NetWork net( 17 | .Xi ({x1,x2,x3}), 18 | .Yo ({y1,y2,y3}) 19 | ); 20 | 21 | 22 | 23 | endmodule 24 | -------------------------------------------------------------------------------- /top.v: -------------------------------------------------------------------------------- 1 | 2 | //3*3*3*3的神经网络 3 | module NetWork( 4 | input[3*32-1:0] Xi, 5 | output[3*32-1:0] Yo 6 | ); 7 | 8 | 9 | reg[3*3*3*32-1:0] ws = 10 | { 11 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC, 12 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC, 13 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC, 14 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC, 15 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC, 16 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC, 17 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC, 18 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC, 19 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC 20 | }; 21 | 22 | reg[3*3*32-1:0] bs = 23 | { 24 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC, 25 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC, 26 | 32'h3DCCCCCC,32'h3DCCCCCC,32'h3DCCCCCC 27 | }; 28 | 29 | 30 | wire[3*32-1:0] cen[1:0]; 31 | Layer l1(Xi,ws[0*3*3*32+3*3*32-1:0*3*3*32],bs[0*3*32+3*32-1:0*3*32],cen[0]); 32 | Layer l2(cen[0],ws[1*3*3*32+3*3*32-1:1*3*3*32],bs[1*3*32+3*32-1:1*3*32],cen[1]); 33 | Layer l3(cen[1],ws[2*3*3*32+3*3*32-1:2*3*3*32],bs[2*3*32+3*32-1:2*3*32],Yo); 34 | 35 | 36 | 37 | endmodule 38 | 39 | 40 | module Layer( 41 | input[3*32-1:0] Xi, 42 | input[3*3*32-1:0] Ws, 43 | input[3*32-1:0] Bs, 44 | output[3*32-1:0] Yo 45 | ); 46 | 47 | Neural n1(Xi,Ws[0*3*32+3*32-1:0*3*32],Bs[0*32+32-1:0*32],Yo[0*32+32-1:0*32]); 48 | Neural n2(Xi,Ws[1*3*32+3*32-1:1*3*32],Bs[1*32+32-1:1*32],Yo[1*32+32-1:1*32]); 49 | Neural n3(Xi,Ws[2*3*32+3*32-1:2*3*32],Bs[2*32+32-1:2*32],Yo[2*32+32-1:2*32]); 50 | 51 | endmodule 52 | 53 | 54 | module Neural( 55 | input[3*32-1:0] Xi, 56 | input[3*32-1:0] Ws,//权重 57 | input[31:0] B,//偏执 58 | output[31:0] Yo 59 | ); 60 | 61 | wire[31:0] o[2:0]; 62 | 63 | FPU_MUL f1(Xi[0*32+32-1:0*32],Ws[0*32+32-1:0*32],o[0]); 64 | FPU_MUL f2(Xi[1*32+32-1:1*32],Ws[1*32+32-1:1*32],o[1]); 65 | FPU_MUL f3(Xi[2*32+32-1:2*32],Ws[2*32+32-1:2*32],o[2]); 66 | 67 | 68 | wire[31:0] t[1:0],f; 69 | FPU_ADD f4(o[0],o[1],t[0]); 70 | FPU_ADD f5(o[2],t[0],t[1]); 71 | FPU_ADD f6(B,t[1],f); 72 | Act_Func act(f,Yo); 73 | endmodule 74 | 75 | 76 | //激活函数 77 | module Act_Func( 78 | input[31:0] Xi, 79 | output[31:0] Yo 80 | ); 81 | 82 | assign Yo = Xi[31] ? 32'd0 : Xi; 83 | 84 | endmodule --------------------------------------------------------------------------------