├── PE阵列架构.pptx ├── README.md └── rtl ├── add.v ├── complete.v ├── conv_1.v ├── conv_2.v ├── fc_1.v ├── fc_2.v ├── lenet_top.v ├── max_pool.v ├── multi.v ├── pool_1.v ├── pool_2.v ├── u_PE.v ├── u_PE_array.v ├── u_PE_column.v └── u_PE_pass.v /PE阵列架构.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyu-ao/PE-array-for-LeNet-accelerator-based-on-FPGA/549f6aac3d21c6b0fe4ada73d0d06ae50fa38731/PE阵列架构.pptx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PE-array-for-LeNet-accelerator-based-on-FPGA 2 | ### This is a 4*5 PE array for LeNet accelerator based on FPGA. 3 | ### The code is improved based on zhan6841's verilog code for LeNet.(https://github.com/zhan6841/FPGA-Accelerator-for-AES-LeNet-VGG16) 4 | ### The speed of the accelerator is greatly increased by using PE array instead of single PE. 5 | -------------------------------------------------------------------------------- /rtl/add.v: -------------------------------------------------------------------------------- 1 | module add( 2 | input [15:0] A, 3 | input [15:0] B, 4 | output [15:0] out 5 | ); 6 | wire [15:0] x,y,sum; 7 | 8 | assign x=(A[15]==1)?(((A[14:0])==15'b0)?{16'b00000000}:{1'b1,~A[14:0]+1'b1}):({A[15:0]}); 9 | assign y=(B[15]==1)?(((B[14:0])==15'b0)?{16'b00000000}:{1'b1,~B[14:0]+1'b1}):({B[15:0]});//当输入是10000000时转换为00000000参与计算 10 | 11 | assign sum = x + y; 12 | 13 | assign out = (x[15] & y[15])? {1'b1,~sum[14:0]+1'b1}: //两个负数 14 | ( (x[15] || y[15])?(sum[15]?{1'b1,~sum[14:0]+1'b1}:{1'b0,sum[14:0]}): //一正一负 15 | {1'b0,sum[14:0]} ); // (两个正数) 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /rtl/complete.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 01/02/2018 02:18:44 AM 7 | // Design Name: 8 | // Module Name: complete 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | `define OUTPUT_NODE 10 23 | `define DATA_SIZE 8 24 | 25 | module complete( 26 | clk, rst, complete_en, result_bram_douta, 27 | result_bram_ena, result_bram_addra, 28 | result, 29 | complete_finish 30 | ); 31 | input clk; 32 | input rst; 33 | input complete_en; 34 | input [`DATA_SIZE-1:0] result_bram_douta; 35 | output reg result_bram_ena; 36 | output reg [14:0] result_bram_addra; 37 | output reg [`DATA_SIZE*`OUTPUT_NODE-1:0] result; 38 | output reg complete_finish; 39 | 40 | parameter fc2_result_base = 18900; 41 | 42 | integer count = 0, 43 | circle = 0, 44 | data_begin = 0; 45 | 46 | reg [2:0] state; 47 | //reg [`DATA_SIZE*`OUTPUT_NODE-1:0] tempresult; 48 | //assign result = tempresult; 49 | 50 | parameter S_IDLE = 3'b100, 51 | S_CHECK = 3'b010, 52 | S_LOAD = 3'b001; 53 | 54 | always@(posedge clk) 55 | begin 56 | if(rst == 1'b1) 57 | begin 58 | result_bram_ena <= 1'b0; 59 | circle <= 0; 60 | count <= 0; 61 | state <= S_IDLE; 62 | end 63 | else 64 | begin 65 | if(complete_en == 1'b1) 66 | begin 67 | case(state) 68 | S_IDLE: 69 | begin 70 | circle <= 0; 71 | count <= 0; 72 | complete_finish <= 1'b0; 73 | state <= S_CHECK; 74 | end 75 | S_CHECK: 76 | begin 77 | if(count == `OUTPUT_NODE) 78 | begin 79 | count <= 0; 80 | circle <= 0; 81 | complete_finish <= 1'b1; 82 | state <= S_IDLE; 83 | end 84 | else 85 | begin 86 | circle <= 0; 87 | state <= S_LOAD; 88 | end 89 | end 90 | S_LOAD: 91 | begin 92 | if(circle == 0) 93 | begin 94 | result_bram_ena <= 1'b1; 95 | result_bram_addra <= fc2_result_base + count; 96 | circle <= circle + 1; 97 | end 98 | else if(circle == 3) 99 | begin 100 | data_begin = `DATA_SIZE * (`OUTPUT_NODE - count) - 1; 101 | result[data_begin-:8] <= result_bram_douta; 102 | count <= count + 1; 103 | circle <= 0; 104 | result_bram_ena <= 1'b0; 105 | state <= S_CHECK; 106 | end 107 | else 108 | begin 109 | circle <= circle + 1; 110 | end 111 | end 112 | endcase 113 | end 114 | end 115 | end 116 | endmodule 117 | -------------------------------------------------------------------------------- /rtl/conv_1.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 12/30/2017 05:44:43 PM 7 | // Design Name: 8 | // Module Name: conv_1 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | `define INPUT_NODE 784 23 | `define IMAGE_SIZE 28 24 | `define NUM_CHANNELS 1 25 | `define CONV1_DEEP 20 26 | `define CONV1_SIZE 5 27 | `define CONV1_OUTPUT 24 28 | `define DATA_SIZE 8 29 | 30 | module conv_1( 31 | clk, rst, conv_1_en, bias_weights_bram_douta, input_bram_douta, graph, 32 | bias_weights_bram_ena, bias_weights_bram_addra, 33 | result_bram_ena, result_bram_wea, result_bram_addra, result_bram_dina, 34 | input_bram_ena, input_bram_addra, 35 | conv_1_finish 36 | ); 37 | input clk; 38 | input rst; 39 | input conv_1_en; 40 | input [`DATA_SIZE-1:0] bias_weights_bram_douta; 41 | input [`DATA_SIZE-1:0] input_bram_douta; 42 | input [4:0] graph; 43 | output reg bias_weights_bram_ena; 44 | output reg [18:0] bias_weights_bram_addra; 45 | output reg result_bram_ena; 46 | output reg result_bram_wea; 47 | output reg [14:0] result_bram_addra; 48 | output reg [`DATA_SIZE-1:0] result_bram_dina; 49 | output reg input_bram_ena; 50 | output reg [12:0] input_bram_addra; 51 | output reg conv_1_finish; 52 | 53 | 54 | integer filter = 0, 55 | channel = 0, 56 | row = 0, 57 | column = 0, 58 | count = 0; 59 | 60 | reg [`DATA_SIZE-1:0] IMap0,IMap1,IMap2,IMap3; 61 | reg [`DATA_SIZE-1:0] IWeight0,IWeight1,IWeight2,IWeight3,IWeight4; 62 | reg ImapVld0,ImapVld1,ImapVld2,ImapVld3; 63 | reg IweightVld0,IweightVld1,IweightVld2,IweightVld3,IweightVld4; 64 | reg [`DATA_SIZE-1:0] bias0,bias1,bias2,bias3,bias4; 65 | wire [`DATA_SIZE-1:0] dout0,dout1,dout2,dout3; 66 | reg dinVld; 67 | // reg [`DATA_SIZE-1:0] result0,result1,result2,result3; 68 | 69 | u_PE_array array_conv_1( 70 | .clk_cal (clk ), 71 | .rst_cal (rst ), 72 | .IWeight0 (IWeight0 ), 73 | .IWeight1 (IWeight1 ), 74 | .IWeight2 (IWeight2 ), 75 | .IWeight3 (IWeight3 ), 76 | .IWeight4 (IWeight4 ), 77 | .IweightVld0(IweightVld0), 78 | .IweightVld1(IweightVld1), 79 | .IweightVld2(IweightVld2), 80 | .IweightVld3(IweightVld3), 81 | .IweightVld4(IweightVld4), 82 | .IMap0 (IMap0 ), 83 | .IMap1 (IMap1 ), 84 | .IMap2 (IMap2 ), 85 | .IMap3 (IMap3 ), 86 | .ImapVld0 (ImapVld0 ), 87 | .ImapVld1 (ImapVld1 ), 88 | .ImapVld2 (ImapVld2 ), 89 | .ImapVld3 (ImapVld3 ), 90 | .dout0 (dout0 ), 91 | .dout1 (dout1 ), 92 | .dout2 (dout2 ), 93 | .dout3 (dout3 ), 94 | .bias0 (bias0 ), 95 | .bias1 (bias1 ), 96 | .bias2 (bias2 ), 97 | .bias3 (bias3 ), 98 | .bias4 (bias4 ), 99 | .dinVld (dinVld ) 100 | ); 101 | reg [4:0] state; 102 | 103 | parameter S_IDLE = 5'b10000, 104 | S_CHECK = 5'b01000, 105 | S_LOAD_BIAS = 5'b00100, 106 | S_CONVOLUTE = 5'b00010, 107 | S_STORE_RESULT = 5'b00001; 108 | 109 | integer circle = 0; 110 | integer PE_array_row = 0; 111 | integer PE_array_column = 0; 112 | integer PE_array_row_and_column = 0; 113 | 114 | parameter conv1_weights_base = 0, 115 | conv1_bias_base = 430500, 116 | conv1_result_base = 0; 117 | 118 | always@(posedge clk) 119 | begin 120 | if(rst == 1'b1) 121 | begin 122 | state <= S_IDLE; 123 | bias_weights_bram_ena <= 1'b0; 124 | result_bram_ena <= 1'b0; 125 | result_bram_wea <= 1'b0; 126 | input_bram_ena <= 1'b0; 127 | end 128 | else 129 | begin 130 | if(conv_1_en == 1'b1) 131 | begin 132 | case(state) 133 | S_IDLE: 134 | begin 135 | filter <= 0; 136 | channel <= 0; 137 | row <= 0; 138 | column <= 0; 139 | IMap0 <= 0; 140 | ImapVld0 <= 0; 141 | IMap1 <= 0; 142 | ImapVld1 <= 0; 143 | IMap2 <= 0; 144 | ImapVld2 <= 0; 145 | IMap3 <= 0; 146 | ImapVld3 <= 0; 147 | IWeight0 <= 0; 148 | IweightVld0 <= 0; 149 | bias0 <= 0; 150 | conv_1_finish <= 1'b0; 151 | state <= S_CHECK; 152 | end 153 | S_CHECK: 154 | begin 155 | if(filter == `CONV1_DEEP) 156 | begin 157 | bias_weights_bram_ena <= 1'b0; 158 | result_bram_ena <= 1'b0; 159 | result_bram_wea <= 1'b0; 160 | input_bram_ena <= 1'b0; 161 | conv_1_finish <= 1'b1; 162 | state <= S_IDLE; 163 | end 164 | else 165 | begin 166 | circle <= 0; 167 | PE_array_row <= 0; 168 | PE_array_column <= 0; 169 | PE_array_row_and_column <= 0; 170 | count <= 0; 171 | state <= S_LOAD_BIAS; 172 | end 173 | end 174 | S_LOAD_BIAS: 175 | begin 176 | if(PE_array_column == 0) 177 | begin 178 | if(circle == 0) 179 | begin 180 | bias_weights_bram_ena <= 1'b1; 181 | bias_weights_bram_addra <= conv1_bias_base + filter + 0; 182 | circle <= circle + 1; 183 | end 184 | else if(circle == 3) 185 | begin 186 | bias0 <= bias_weights_bram_douta; 187 | circle <= 0; 188 | bias_weights_bram_ena <= 1'b0; 189 | PE_array_column <= PE_array_column + 1; 190 | end 191 | else 192 | begin 193 | circle <= circle + 1; 194 | end 195 | end 196 | 197 | if(PE_array_column == 1) 198 | begin 199 | if(circle == 0) 200 | begin 201 | bias_weights_bram_ena <= 1'b1; 202 | bias_weights_bram_addra <= conv1_bias_base + filter + 1; 203 | circle <= circle + 1; 204 | end 205 | else if(circle == 3) 206 | begin 207 | bias1 <= bias_weights_bram_douta; 208 | circle <= 0; 209 | bias_weights_bram_ena <= 1'b0; 210 | PE_array_column <= PE_array_column + 1; 211 | end 212 | else 213 | begin 214 | circle <= circle + 1; 215 | end 216 | end 217 | 218 | if(PE_array_column == 2) 219 | begin 220 | if(circle == 0) 221 | begin 222 | bias_weights_bram_ena <= 1'b1; 223 | bias_weights_bram_addra <= conv1_bias_base + filter + 2; 224 | circle <= circle + 1; 225 | end 226 | else if(circle == 3) 227 | begin 228 | bias2 <= bias_weights_bram_douta; 229 | circle <= 0; 230 | bias_weights_bram_ena <= 1'b0; 231 | PE_array_column <= PE_array_column + 1; 232 | end 233 | else 234 | begin 235 | circle <= circle + 1; 236 | end 237 | end 238 | 239 | if(PE_array_column == 3) 240 | begin 241 | if(circle == 0) 242 | begin 243 | bias_weights_bram_ena <= 1'b1; 244 | bias_weights_bram_addra <= conv1_bias_base + filter + 3; 245 | circle <= circle + 1; 246 | end 247 | else if(circle == 3) 248 | begin 249 | bias3 <= bias_weights_bram_douta; 250 | circle <= 0; 251 | bias_weights_bram_ena <= 1'b0; 252 | PE_array_column <= PE_array_column + 1; 253 | end 254 | else 255 | begin 256 | circle <= circle + 1; 257 | end 258 | end 259 | 260 | if(PE_array_column == 4) 261 | begin 262 | if(circle == 0) 263 | begin 264 | bias_weights_bram_ena <= 1'b1; 265 | bias_weights_bram_addra <= conv1_bias_base + filter + 4; 266 | circle <= circle + 1; 267 | end 268 | else if(circle == 3) 269 | begin 270 | bias4 <= bias_weights_bram_douta; 271 | circle <= 0; 272 | bias_weights_bram_ena <= 1'b0; 273 | PE_array_column <= 0; 274 | state <= S_CONVOLUTE; 275 | end 276 | else 277 | begin 278 | circle <= circle + 1; 279 | end 280 | end 281 | 282 | end 283 | S_CONVOLUTE: 284 | begin 285 | if(count < `CONV1_SIZE * `CONV1_SIZE) 286 | begin 287 | if(PE_array_row_and_column == 0) 288 | begin 289 | if(circle == 0) 290 | begin 291 | bias_weights_bram_ena <= 1'b1; 292 | bias_weights_bram_addra <= conv1_weights_base + (filter + 0)*`CONV1_SIZE*`CONV1_SIZE + count; 293 | ImapVld3 <= 1'b0; 294 | IweightVld0 = 1'b0; 295 | circle <= circle + 1; 296 | end 297 | else if(circle == 3) 298 | begin 299 | IWeight0 <= bias_weights_bram_douta; 300 | IweightVld0 <= 1'b1; 301 | circle <= 0; 302 | PE_array_row_and_column <= PE_array_row_and_column + 1; 303 | end 304 | else 305 | begin 306 | circle <= circle + 1; 307 | end 308 | end 309 | 310 | if(PE_array_row_and_column == 1) 311 | begin 312 | if(circle == 0) 313 | begin 314 | bias_weights_bram_ena <= 1'b1; 315 | bias_weights_bram_addra <= conv1_weights_base + (filter + 1)*`CONV1_SIZE*`CONV1_SIZE + count; 316 | IweightVld1 = 1'b0; 317 | circle <= circle + 1; 318 | end 319 | else if(circle == 3) 320 | begin 321 | IWeight1 <= bias_weights_bram_douta; 322 | IweightVld1 <= 1'b1; 323 | circle <= 0; 324 | PE_array_row_and_column <= PE_array_row_and_column + 1; 325 | end 326 | else 327 | begin 328 | circle <= circle + 1; 329 | end 330 | end 331 | 332 | if(PE_array_row_and_column == 2) 333 | begin 334 | if(circle == 0) 335 | begin 336 | bias_weights_bram_ena <= 1'b1; 337 | bias_weights_bram_addra <= conv1_weights_base + (filter + 2)*`CONV1_SIZE*`CONV1_SIZE + count; 338 | IweightVld2 = 1'b0; 339 | circle <= circle + 1; 340 | end 341 | else if(circle == 3) 342 | begin 343 | IWeight2 <= bias_weights_bram_douta; 344 | IweightVld2 <= 1'b1; 345 | circle <= 0; 346 | PE_array_row_and_column <= PE_array_row_and_column + 1; 347 | end 348 | else 349 | begin 350 | circle <= circle + 1; 351 | end 352 | end 353 | 354 | if(PE_array_row_and_column == 3) 355 | begin 356 | if(circle == 0) 357 | begin 358 | bias_weights_bram_ena <= 1'b1; 359 | bias_weights_bram_addra <= conv1_weights_base + (filter + 3)*`CONV1_SIZE*`CONV1_SIZE + count; 360 | IweightVld3 = 1'b0; 361 | circle <= circle + 1; 362 | end 363 | else if(circle == 3) 364 | begin 365 | IWeight3 <= bias_weights_bram_douta; 366 | IweightVld3 <= 1'b1; 367 | circle <= 0; 368 | PE_array_row_and_column <= PE_array_row_and_column + 1; 369 | end 370 | else 371 | begin 372 | circle <= circle + 1; 373 | end 374 | end 375 | 376 | if(PE_array_row_and_column == 4) 377 | begin 378 | if(circle == 0) 379 | begin 380 | bias_weights_bram_ena <= 1'b1; 381 | bias_weights_bram_addra <= conv1_weights_base + (filter + 4)*`CONV1_SIZE*`CONV1_SIZE + count; 382 | IweightVld4 = 1'b0; 383 | circle <= circle + 1; 384 | end 385 | else if(circle == 3) 386 | begin 387 | IWeight4 <= bias_weights_bram_douta; 388 | IweightVld4 <= 1'b1; 389 | circle <= 0; 390 | PE_array_row_and_column <= PE_array_row_and_column + 1; 391 | end 392 | else 393 | begin 394 | circle <= circle + 1; 395 | end 396 | end 397 | 398 | if(PE_array_row_and_column == 5) 399 | begin 400 | if(circle == 0) 401 | begin 402 | input_bram_ena <= 1'b1; 403 | input_bram_addra <= graph * `INPUT_NODE + (row + count / `CONV1_SIZE) * `IMAGE_SIZE + column + 0 + count % `CONV1_SIZE; 404 | ImapVld0 <= 1'b0; 405 | circle <= circle + 1; 406 | end 407 | else if(circle == 3) 408 | begin 409 | IMap0 <= input_bram_douta; 410 | ImapVld0 <= 1'b1; 411 | circle <= 0; 412 | PE_array_row_and_column <= PE_array_row_and_column + 1; 413 | end 414 | else 415 | begin 416 | circle <= circle + 1; 417 | end 418 | end 419 | 420 | else if(PE_array_row_and_column == 6) 421 | begin 422 | if(circle == 0) 423 | begin 424 | input_bram_ena <= 1'b1; 425 | input_bram_addra <= graph * `INPUT_NODE + (row + count / `CONV1_SIZE) * `IMAGE_SIZE + column + 1 + count % `CONV1_SIZE; 426 | ImapVld0 <= 1'b0; 427 | ImapVld1 <= 1'b0; 428 | circle <= circle + 1; 429 | end 430 | else if(circle == 3) 431 | begin 432 | IMap1 <= input_bram_douta; 433 | ImapVld1 <= 1'b1; 434 | circle <= 0; 435 | PE_array_row_and_column <= PE_array_row_and_column + 1; 436 | end 437 | else 438 | begin 439 | circle <= circle + 1; 440 | end 441 | end 442 | 443 | else if(PE_array_row_and_column == 7) 444 | begin 445 | if(circle == 0) 446 | begin 447 | input_bram_ena <= 1'b1; 448 | input_bram_addra <= graph * `INPUT_NODE + (row + count / `CONV1_SIZE) * `IMAGE_SIZE + column + 2 + count % `CONV1_SIZE; 449 | ImapVld1 <= 1'b0; 450 | ImapVld2 <= 1'b0; 451 | circle <= circle + 1; 452 | end 453 | else if(circle == 3) 454 | begin 455 | IMap2 <= input_bram_douta; 456 | ImapVld2 <= 1'b1; 457 | circle <= 0; 458 | PE_array_row_and_column <= PE_array_row_and_column + 1; 459 | end 460 | else 461 | begin 462 | circle <= circle + 1; 463 | end 464 | end 465 | 466 | else if(PE_array_row_and_column == 8) 467 | begin 468 | if(circle == 0) 469 | begin 470 | input_bram_ena <= 1'b1; 471 | input_bram_addra <= graph * `INPUT_NODE + (row + count / `CONV1_SIZE) * `IMAGE_SIZE + column + 3 + count % `CONV1_SIZE; 472 | ImapVld2 <= 1'b0; 473 | ImapVld3 <= 1'b0; 474 | circle <= circle + 1; 475 | end 476 | else if(circle == 3) 477 | begin 478 | IMap3 <= input_bram_douta; 479 | ImapVld3 <= 1'b1; 480 | circle <= 0; 481 | PE_array_row_and_column <= 0; 482 | count <= count + 1; 483 | end 484 | else 485 | begin 486 | circle <= circle + 1; 487 | end 488 | end 489 | end 490 | else 491 | begin 492 | circle <= 0; 493 | PE_array_row_and_column <= 0; 494 | count <= 0; 495 | input_bram_ena <= 1'b0; 496 | bias_weights_bram_ena <= 1'b0; 497 | IMap0 <= 0; 498 | ImapVld0 <= 0; 499 | IMap1 <= 0; 500 | ImapVld1 <= 0; 501 | IMap2 <= 0; 502 | ImapVld2 <= 0; 503 | IMap3 <= 0; 504 | ImapVld3 <= 0; 505 | state <= S_STORE_RESULT; 506 | end 507 | end 508 | S_STORE_RESULT: 509 | begin 510 | if(PE_array_column < 5) 511 | begin 512 | if(PE_array_row == 0) 513 | begin 514 | if(circle == 0) 515 | begin 516 | result_bram_ena <= 1'b1; 517 | result_bram_wea <= 1'b1; 518 | result_bram_addra <= conv1_result_base + (filter + PE_array_column) * `CONV1_OUTPUT * `CONV1_OUTPUT + row * `CONV1_OUTPUT + column + 0; 519 | result_bram_dina <= dout0; 520 | circle <= circle + 1; 521 | end 522 | else if(circle == 3) 523 | begin 524 | result_bram_ena <= 1'b0; 525 | result_bram_wea <= 1'b0; 526 | PE_array_row <= PE_array_row + 1; 527 | circle <= 0; 528 | end 529 | else 530 | begin 531 | circle <= circle + 1; 532 | end 533 | end 534 | 535 | if(PE_array_row == 1) 536 | begin 537 | if(circle == 0) 538 | begin 539 | result_bram_ena <= 1'b1; 540 | result_bram_wea <= 1'b1; 541 | result_bram_addra <= conv1_result_base + (filter + PE_array_column) * `CONV1_OUTPUT * `CONV1_OUTPUT + row * `CONV1_OUTPUT + column + 1; 542 | result_bram_dina <= dout1; 543 | circle <= circle + 1; 544 | end 545 | else if(circle == 3) 546 | begin 547 | result_bram_ena <= 1'b0; 548 | result_bram_wea <= 1'b0; 549 | PE_array_row <= PE_array_row + 1; 550 | circle <= 0; 551 | end 552 | else 553 | begin 554 | circle <= circle + 1; 555 | end 556 | end 557 | 558 | if(PE_array_row == 2) 559 | begin 560 | if(circle == 0) 561 | begin 562 | result_bram_ena <= 1'b1; 563 | result_bram_wea <= 1'b1; 564 | result_bram_addra <= conv1_result_base + (filter + PE_array_column) * `CONV1_OUTPUT * `CONV1_OUTPUT + row * `CONV1_OUTPUT + column + 2; 565 | result_bram_dina <= dout2; 566 | circle <= circle + 1; 567 | end 568 | else if(circle == 3) 569 | begin 570 | result_bram_ena <= 1'b0; 571 | result_bram_wea <= 1'b0; 572 | PE_array_row <= PE_array_row + 1; 573 | circle <= 0; 574 | end 575 | else 576 | begin 577 | circle <= circle + 1; 578 | end 579 | end 580 | 581 | if(PE_array_row == 3) 582 | begin 583 | if(circle == 0) 584 | begin 585 | result_bram_ena <= 1'b1; 586 | result_bram_wea <= 1'b1; 587 | result_bram_addra <= conv1_result_base + (filter + PE_array_column) * `CONV1_OUTPUT * `CONV1_OUTPUT + row * `CONV1_OUTPUT + column + 3; 588 | result_bram_dina <= dout3; 589 | circle <= circle + 1; 590 | end 591 | else if(circle == 3) 592 | begin 593 | dinVld <= 1; 594 | circle <= circle + 1; 595 | end 596 | else if(circle == 4) 597 | begin 598 | dinVld <= 0; 599 | result_bram_ena <= 1'b0; 600 | result_bram_wea <= 1'b0; 601 | PE_array_row <= 0; 602 | PE_array_column <= PE_array_column + 1; 603 | circle <= 0; 604 | end 605 | else 606 | begin 607 | circle <= circle + 1; 608 | end 609 | end 610 | end 611 | else 612 | begin 613 | dinVld <= 0; 614 | PE_array_column <= 0; 615 | PE_array_row <= 0; 616 | 617 | if(column == `CONV1_OUTPUT - 4) 618 | begin 619 | if(row == `CONV1_OUTPUT - 1) 620 | begin 621 | if(channel == `NUM_CHANNELS - 1) 622 | begin 623 | filter <= filter + 5; 624 | end 625 | channel <= (channel + 1) % `NUM_CHANNELS; 626 | end 627 | row <= (row + 1) % `CONV1_OUTPUT; 628 | end 629 | column <= (column + 4) % `CONV1_OUTPUT; 630 | 631 | state <= S_CHECK; 632 | end 633 | end 634 | default 635 | begin 636 | state <= S_IDLE; 637 | bias_weights_bram_ena <= 1'b0; 638 | result_bram_ena <= 1'b0; 639 | result_bram_wea <= 1'b0; 640 | input_bram_ena <= 1'b0; 641 | end 642 | endcase 643 | end 644 | end 645 | end 646 | 647 | endmodule 648 | -------------------------------------------------------------------------------- /rtl/conv_2.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 01/01/2018 08:32:31 PM 7 | // Design Name: 8 | // Module Name: conv_2 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | `define CONV1_DEEP 20 23 | `define CONV2_DEEP 50 24 | `define CONV2_SIZE 5 25 | `define CONV2_INPUT 12 26 | `define CONV2_OUTPUT 8 27 | `define DATA_SIZE 8 28 | 29 | module conv_2( 30 | clk, rst, conv_2_en, bias_weights_bram_douta, result_bram_douta, 31 | bias_weights_bram_ena, bias_weights_bram_addra, 32 | result_bram_ena, result_bram_wea, result_bram_addra, result_bram_dina, 33 | conv_2_finish 34 | ); 35 | input clk; 36 | input rst; 37 | input conv_2_en; 38 | input [`DATA_SIZE-1:0] bias_weights_bram_douta; 39 | input [`DATA_SIZE-1:0] result_bram_douta; 40 | output reg bias_weights_bram_ena; 41 | output reg [18:0] bias_weights_bram_addra; 42 | output reg result_bram_ena; 43 | output reg result_bram_wea; 44 | output reg [14:0] result_bram_addra; 45 | output reg [`DATA_SIZE-1:0] result_bram_dina; 46 | output reg conv_2_finish; 47 | 48 | integer filter = 0, 49 | channel = 0, 50 | row = 0, 51 | column = 0, 52 | count = 0; 53 | 54 | reg [`DATA_SIZE-1:0] IMap0,IMap1,IMap2,IMap3; 55 | reg [`DATA_SIZE-1:0] IWeight0,IWeight1,IWeight2,IWeight3,IWeight4; 56 | reg ImapVld0,ImapVld1,ImapVld2,ImapVld3; 57 | reg IweightVld0,IweightVld1,IweightVld2,IweightVld3,IweightVld4; 58 | reg [`DATA_SIZE-1:0] bias0,bias1,bias2,bias3,bias4; 59 | wire [`DATA_SIZE-1:0] dout0,dout1,dout2,dout3; 60 | reg dinVld; 61 | 62 | defparam array_conv_2.column_0.u_PE_0.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 63 | defparam array_conv_2.column_0.u_PE_1.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 64 | defparam array_conv_2.column_0.u_PE_2.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 65 | defparam array_conv_2.column_0.u_PE_3.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 66 | defparam array_conv_2.column_1.u_PE_0.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 67 | defparam array_conv_2.column_1.u_PE_1.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 68 | defparam array_conv_2.column_1.u_PE_2.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 69 | defparam array_conv_2.column_1.u_PE_3.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 70 | defparam array_conv_2.column_2.u_PE_0.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 71 | defparam array_conv_2.column_2.u_PE_1.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 72 | defparam array_conv_2.column_2.u_PE_2.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 73 | defparam array_conv_2.column_2.u_PE_3.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 74 | defparam array_conv_2.column_3.u_PE_0.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 75 | defparam array_conv_2.column_3.u_PE_1.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 76 | defparam array_conv_2.column_3.u_PE_2.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 77 | defparam array_conv_2.column_3.u_PE_3.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 78 | defparam array_conv_2.column_4.u_PE_0.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 79 | defparam array_conv_2.column_4.u_PE_1.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 80 | defparam array_conv_2.column_4.u_PE_2.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 81 | defparam array_conv_2.column_4.u_PE_3.Calcycle = `CONV2_SIZE*`CONV2_SIZE*`CONV1_DEEP; 82 | u_PE_array array_conv_2( 83 | .clk_cal (clk ), 84 | .rst_cal (rst ), 85 | .IWeight0 (IWeight0 ), 86 | .IWeight1 (IWeight1 ), 87 | .IWeight2 (IWeight2 ), 88 | .IWeight3 (IWeight3 ), 89 | .IWeight4 (IWeight4 ), 90 | .IweightVld0(IweightVld0), 91 | .IweightVld1(IweightVld1), 92 | .IweightVld2(IweightVld2), 93 | .IweightVld3(IweightVld3), 94 | .IweightVld4(IweightVld4), 95 | .IMap0 (IMap0 ), 96 | .IMap1 (IMap1 ), 97 | .IMap2 (IMap2 ), 98 | .IMap3 (IMap3 ), 99 | .ImapVld0 (ImapVld0 ), 100 | .ImapVld1 (ImapVld1 ), 101 | .ImapVld2 (ImapVld2 ), 102 | .ImapVld3 (ImapVld3 ), 103 | .dout0 (dout0 ), 104 | .dout1 (dout1 ), 105 | .dout2 (dout2 ), 106 | .dout3 (dout3 ), 107 | .bias0 (bias0 ), 108 | .bias1 (bias1 ), 109 | .bias2 (bias2 ), 110 | .bias3 (bias3 ), 111 | .bias4 (bias4 ), 112 | .dinVld (dinVld ) 113 | ); 114 | reg [4:0] state; 115 | 116 | parameter S_IDLE = 5'b10000, 117 | S_CHECK = 5'b01000, 118 | S_LOAD_BIAS = 5'b00100, 119 | S_CONVOLUTE = 5'b00010, 120 | S_STORE_RESULT = 5'b00001; 121 | 122 | integer circle = 0; 123 | integer PE_array_row = 0; 124 | integer PE_array_column = 0; 125 | //integer count_channel = 0; 126 | integer PE_array_row_and_column = 0; 127 | 128 | parameter pool1_result_base = 11520, 129 | conv2_weights_base = 500, 130 | conv2_bias_base = 430520, 131 | conv2_result_base = 14400; 132 | 133 | always@(posedge clk) 134 | begin 135 | if(rst == 1'b1) 136 | begin 137 | state <= S_IDLE; 138 | bias_weights_bram_ena <= 1'b0; 139 | result_bram_ena <= 1'b0; 140 | result_bram_wea <= 1'b0; 141 | end 142 | else 143 | begin 144 | if(conv_2_en == 1'b1) 145 | begin 146 | case(state) 147 | S_IDLE: 148 | begin 149 | filter <= 0; 150 | channel <= 0; 151 | row <= 0; 152 | column <= 0; 153 | IMap0 <= 0; 154 | ImapVld0 <= 0; 155 | IMap1 <= 0; 156 | ImapVld1 <= 0; 157 | IMap2 <= 0; 158 | ImapVld2 <= 0; 159 | IMap3 <= 0; 160 | ImapVld3 <= 0; 161 | IWeight0 <= 0; 162 | IweightVld0 <= 0; 163 | IWeight1 <= 0; 164 | IweightVld1 <= 0; 165 | IWeight2 <= 0; 166 | IweightVld2 <= 0; 167 | IWeight3 <= 0; 168 | IweightVld3 <= 0; 169 | IWeight4 <= 0; 170 | IweightVld4 <= 0; 171 | bias0 <= 0; 172 | bias1 <= 0; 173 | bias2 <= 0; 174 | bias3 <= 0; 175 | bias4 <= 0; 176 | conv_2_finish <= 1'b0; 177 | state <= S_CHECK; 178 | end 179 | S_CHECK: 180 | begin 181 | if(filter == `CONV2_DEEP) 182 | begin 183 | bias_weights_bram_ena <= 1'b0; 184 | result_bram_ena <= 1'b0; 185 | result_bram_wea <= 1'b0; 186 | conv_2_finish <= 1'b1; 187 | state <= S_IDLE; 188 | end 189 | else 190 | begin 191 | circle <= 0; 192 | count <= 0; 193 | channel <= 0; 194 | PE_array_row <= 0; 195 | PE_array_column <= 0; 196 | PE_array_row_and_column <= 0; 197 | //count_channel <= 0; 198 | state <= S_LOAD_BIAS; 199 | end 200 | end 201 | S_LOAD_BIAS: 202 | begin 203 | if(PE_array_column == 0) 204 | begin 205 | if(circle == 0) 206 | begin 207 | bias_weights_bram_ena <= 1'b1; 208 | bias_weights_bram_addra <= conv2_bias_base + filter + 0; 209 | circle <= circle + 1; 210 | end 211 | else if(circle == 3) 212 | begin 213 | bias0 <= bias_weights_bram_douta; 214 | circle <= 0; 215 | bias_weights_bram_ena <= 1'b0; 216 | PE_array_column <= PE_array_column + 1; 217 | end 218 | else 219 | begin 220 | circle <= circle + 1; 221 | end 222 | end 223 | 224 | if(PE_array_column == 1) 225 | begin 226 | if(circle == 0) 227 | begin 228 | bias_weights_bram_ena <= 1'b1; 229 | bias_weights_bram_addra <= conv2_bias_base + filter + 1; 230 | circle <= circle + 1; 231 | end 232 | else if(circle == 3) 233 | begin 234 | bias1 <= bias_weights_bram_douta; 235 | circle <= 0; 236 | bias_weights_bram_ena <= 1'b0; 237 | PE_array_column <= PE_array_column + 1; 238 | end 239 | else 240 | begin 241 | circle <= circle + 1; 242 | end 243 | end 244 | 245 | if(PE_array_column == 2) 246 | begin 247 | if(circle == 0) 248 | begin 249 | bias_weights_bram_ena <= 1'b1; 250 | bias_weights_bram_addra <= conv2_bias_base + filter + 2; 251 | circle <= circle + 1; 252 | end 253 | else if(circle == 3) 254 | begin 255 | bias2 <= bias_weights_bram_douta; 256 | circle <= 0; 257 | bias_weights_bram_ena <= 1'b0; 258 | PE_array_column <= PE_array_column + 1; 259 | end 260 | else 261 | begin 262 | circle <= circle + 1; 263 | end 264 | end 265 | 266 | if(PE_array_column == 3) 267 | begin 268 | if(circle == 0) 269 | begin 270 | bias_weights_bram_ena <= 1'b1; 271 | bias_weights_bram_addra <= conv2_bias_base + filter + 3; 272 | circle <= circle + 1; 273 | end 274 | else if(circle == 3) 275 | begin 276 | bias3 <= bias_weights_bram_douta; 277 | circle <= 0; 278 | bias_weights_bram_ena <= 1'b0; 279 | PE_array_column <= PE_array_column + 1; 280 | end 281 | else 282 | begin 283 | circle <= circle + 1; 284 | end 285 | end 286 | 287 | if(PE_array_column == 4) 288 | begin 289 | if(circle == 0) 290 | begin 291 | bias_weights_bram_ena <= 1'b1; 292 | bias_weights_bram_addra <= conv2_bias_base + filter + 4; 293 | circle <= circle + 1; 294 | end 295 | else if(circle == 3) 296 | begin 297 | bias4 <= bias_weights_bram_douta; 298 | circle <= 0; 299 | bias_weights_bram_ena <= 1'b0; 300 | PE_array_column <= 0; 301 | state <= S_CONVOLUTE; 302 | end 303 | else 304 | begin 305 | circle <= circle + 1; 306 | end 307 | end 308 | 309 | end 310 | S_CONVOLUTE: 311 | begin 312 | if(channel < `CONV1_DEEP) 313 | begin 314 | if(count < `CONV2_SIZE * `CONV2_SIZE) 315 | begin 316 | if(PE_array_row_and_column == 0) 317 | begin 318 | if(circle == 0) 319 | begin 320 | bias_weights_bram_ena <= 1'b1; 321 | bias_weights_bram_addra <= conv2_weights_base + (filter + 0)*`CONV1_DEEP*`CONV2_SIZE*`CONV2_SIZE + channel*`CONV2_SIZE*`CONV2_SIZE + count; 322 | ImapVld3 <= 1'b0; 323 | IweightVld0 = 1'b0; 324 | circle <= circle + 1; 325 | end 326 | else if(circle == 3) 327 | begin 328 | IWeight0 <= bias_weights_bram_douta; 329 | IweightVld0 <= 1'b1; 330 | circle <= 0; 331 | PE_array_row_and_column <= PE_array_row_and_column + 1; 332 | end 333 | else 334 | begin 335 | circle <= circle + 1; 336 | end 337 | end 338 | 339 | if(PE_array_row_and_column == 1) 340 | begin 341 | if(circle == 0) 342 | begin 343 | bias_weights_bram_ena <= 1'b1; 344 | bias_weights_bram_addra <= conv2_weights_base + (filter + 1)*`CONV1_DEEP*`CONV2_SIZE*`CONV2_SIZE + channel*`CONV2_SIZE*`CONV2_SIZE + count; 345 | IweightVld1 = 1'b0; 346 | circle <= circle + 1; 347 | end 348 | else if(circle == 3) 349 | begin 350 | IWeight1 <= bias_weights_bram_douta; 351 | IweightVld1 <= 1'b1; 352 | circle <= 0; 353 | PE_array_row_and_column <= PE_array_row_and_column + 1; 354 | end 355 | else 356 | begin 357 | circle <= circle + 1; 358 | end 359 | end 360 | 361 | if(PE_array_row_and_column == 2) 362 | begin 363 | if(circle == 0) 364 | begin 365 | bias_weights_bram_ena <= 1'b1; 366 | bias_weights_bram_addra <= conv2_weights_base + (filter + 2)*`CONV1_DEEP*`CONV2_SIZE*`CONV2_SIZE + channel*`CONV2_SIZE*`CONV2_SIZE + count; 367 | IweightVld2 = 1'b0; 368 | circle <= circle + 1; 369 | end 370 | else if(circle == 3) 371 | begin 372 | IWeight2 <= bias_weights_bram_douta; 373 | IweightVld2 <= 1'b1; 374 | circle <= 0; 375 | PE_array_row_and_column <= PE_array_row_and_column + 1; 376 | end 377 | else 378 | begin 379 | circle <= circle + 1; 380 | end 381 | end 382 | 383 | if(PE_array_row_and_column == 3) 384 | begin 385 | if(circle == 0) 386 | begin 387 | bias_weights_bram_ena <= 1'b1; 388 | bias_weights_bram_addra <= conv2_weights_base + (filter + 3)*`CONV1_DEEP*`CONV2_SIZE*`CONV2_SIZE + channel*`CONV2_SIZE*`CONV2_SIZE + count; 389 | IweightVld3 = 1'b0; 390 | circle <= circle + 1; 391 | end 392 | else if(circle == 3) 393 | begin 394 | IWeight3 <= bias_weights_bram_douta; 395 | IweightVld3 <= 1'b1; 396 | circle <= 0; 397 | PE_array_row_and_column <= PE_array_row_and_column + 1; 398 | end 399 | else 400 | begin 401 | circle <= circle + 1; 402 | end 403 | end 404 | 405 | if(PE_array_row_and_column == 4) 406 | begin 407 | if(circle == 0) 408 | begin 409 | bias_weights_bram_ena <= 1'b1; 410 | bias_weights_bram_addra <= conv2_weights_base + (filter + 4)*`CONV1_DEEP*`CONV2_SIZE*`CONV2_SIZE + channel*`CONV2_SIZE*`CONV2_SIZE + count; 411 | IweightVld4 = 1'b0; 412 | circle <= circle + 1; 413 | end 414 | else if(circle == 3) 415 | begin 416 | IWeight4 <= bias_weights_bram_douta; 417 | IweightVld4 <= 1'b1; 418 | circle <= 0; 419 | PE_array_row_and_column <= PE_array_row_and_column + 1; 420 | end 421 | else 422 | begin 423 | circle <= circle + 1; 424 | end 425 | end 426 | 427 | if(PE_array_row_and_column == 5) 428 | begin 429 | if(circle == 0) 430 | begin 431 | result_bram_ena <= 1'b1; 432 | result_bram_addra <= pool1_result_base + channel * `CONV2_INPUT * `CONV2_INPUT + (row + count / `CONV2_SIZE) * `CONV2_INPUT + (column + 0) + count % `CONV2_SIZE; 433 | ImapVld0 <= 1'b0; 434 | circle <= circle + 1; 435 | end 436 | else if(circle == 3) 437 | begin 438 | IMap0 <= result_bram_douta; 439 | ImapVld0 <= 1'b1; 440 | circle <= 0; 441 | PE_array_row_and_column <= PE_array_row_and_column + 1; 442 | end 443 | else 444 | begin 445 | circle <= circle + 1; 446 | end 447 | end 448 | 449 | else if(PE_array_row_and_column == 6) 450 | begin 451 | if(circle == 0) 452 | begin 453 | result_bram_ena <= 1'b1; 454 | result_bram_addra <= pool1_result_base + channel * `CONV2_INPUT * `CONV2_INPUT + (row + count / `CONV2_SIZE) * `CONV2_INPUT + (column + 1) + count % `CONV2_SIZE; 455 | ImapVld0 <= 1'b0; 456 | ImapVld1 <= 1'b0; 457 | circle <= circle + 1; 458 | end 459 | else if(circle == 3) 460 | begin 461 | IMap1 <= result_bram_douta; 462 | ImapVld1 <= 1'b1; 463 | circle <= 0; 464 | PE_array_row_and_column <= PE_array_row_and_column + 1; 465 | end 466 | else 467 | begin 468 | circle <= circle + 1; 469 | end 470 | end 471 | 472 | else if(PE_array_row_and_column == 7) 473 | begin 474 | if(circle == 0) 475 | begin 476 | result_bram_ena <= 1'b1; 477 | result_bram_addra <= pool1_result_base + channel * `CONV2_INPUT * `CONV2_INPUT + (row + count / `CONV2_SIZE) * `CONV2_INPUT + (column + 2) + count % `CONV2_SIZE; 478 | ImapVld1 <= 1'b0; 479 | ImapVld2 <= 1'b0; 480 | circle <= circle + 1; 481 | end 482 | else if(circle == 3) 483 | begin 484 | IMap2 <= result_bram_douta; 485 | ImapVld2 <= 1'b1; 486 | circle <= 0; 487 | PE_array_row_and_column <= PE_array_row_and_column + 1; 488 | end 489 | else 490 | begin 491 | circle <= circle + 1; 492 | end 493 | end 494 | 495 | else if(PE_array_row_and_column == 8) 496 | begin 497 | if(circle == 0) 498 | begin 499 | result_bram_ena <= 1'b1; 500 | result_bram_addra <= pool1_result_base + channel * `CONV2_INPUT * `CONV2_INPUT + (row + count / `CONV2_SIZE) * `CONV2_INPUT + (column + 3) + count % `CONV2_SIZE; 501 | ImapVld2 <= 1'b0; 502 | ImapVld3 <= 1'b0; 503 | circle <= circle + 1; 504 | end 505 | else if(circle == 3) 506 | begin 507 | IMap3 <= result_bram_douta; 508 | ImapVld3 <= 1'b1; 509 | circle <= 0; 510 | PE_array_row_and_column <= 0; 511 | count <= count + 1; 512 | end 513 | else 514 | begin 515 | circle <= circle + 1; 516 | end 517 | end 518 | end 519 | else 520 | begin 521 | count <= 0; 522 | ImapVld3 <= 0; 523 | channel <= channel + 1; 524 | end 525 | end 526 | else 527 | begin 528 | circle <= 0; 529 | PE_array_row_and_column <= 0; 530 | count <= 0; 531 | result_bram_ena <= 1'b0; 532 | bias_weights_bram_ena <= 1'b0; 533 | IMap0 <= 0; 534 | ImapVld0 <= 0; 535 | IMap1 <= 0; 536 | ImapVld1 <= 0; 537 | IMap2 <= 0; 538 | ImapVld2 <= 0; 539 | IMap3 <= 0; 540 | ImapVld3 <= 0; 541 | channel <= 0; 542 | state <= S_STORE_RESULT; 543 | end 544 | end 545 | S_STORE_RESULT: 546 | begin 547 | if(PE_array_column < 5) 548 | begin 549 | if(PE_array_row == 0) 550 | begin 551 | if(circle == 0) 552 | begin 553 | result_bram_ena <= 1'b1; 554 | result_bram_wea <= 1'b1; 555 | result_bram_addra <= conv2_result_base + (filter + PE_array_column) * `CONV2_OUTPUT * `CONV2_OUTPUT + row * `CONV2_OUTPUT + column + 0; 556 | result_bram_dina <= dout0; 557 | circle <= circle + 1; 558 | end 559 | else if(circle == 3) 560 | begin 561 | result_bram_ena <= 1'b0; 562 | result_bram_wea <= 1'b0; 563 | PE_array_row <= PE_array_row + 1; 564 | circle <= 0; 565 | end 566 | else 567 | begin 568 | circle <= circle + 1; 569 | end 570 | end 571 | 572 | if(PE_array_row == 1) 573 | begin 574 | if(circle == 0) 575 | begin 576 | result_bram_ena <= 1'b1; 577 | result_bram_wea <= 1'b1; 578 | result_bram_addra <= conv2_result_base + (filter + PE_array_column) * `CONV2_OUTPUT * `CONV2_OUTPUT + row * `CONV2_OUTPUT + column + 1; 579 | result_bram_dina <= dout1; 580 | circle <= circle + 1; 581 | end 582 | else if(circle == 3) 583 | begin 584 | result_bram_ena <= 1'b0; 585 | result_bram_wea <= 1'b0; 586 | PE_array_row <= PE_array_row + 1; 587 | circle <= 0; 588 | end 589 | else 590 | begin 591 | circle <= circle + 1; 592 | end 593 | end 594 | 595 | if(PE_array_row == 2) 596 | begin 597 | if(circle == 0) 598 | begin 599 | result_bram_ena <= 1'b1; 600 | result_bram_wea <= 1'b1; 601 | result_bram_addra <= conv2_result_base + (filter + PE_array_column) * `CONV2_OUTPUT * `CONV2_OUTPUT + row * `CONV2_OUTPUT + column + 2; 602 | result_bram_dina <= dout2; 603 | circle <= circle + 1; 604 | end 605 | else if(circle == 3) 606 | begin 607 | result_bram_ena <= 1'b0; 608 | result_bram_wea <= 1'b0; 609 | PE_array_row <= PE_array_row + 1; 610 | circle <= 0; 611 | end 612 | else 613 | begin 614 | circle <= circle + 1; 615 | end 616 | end 617 | 618 | if(PE_array_row == 3) 619 | begin 620 | if(circle == 0) 621 | begin 622 | result_bram_ena <= 1'b1; 623 | result_bram_wea <= 1'b1; 624 | result_bram_addra <= conv2_result_base + (filter + PE_array_column) * `CONV2_OUTPUT * `CONV2_OUTPUT + row * `CONV2_OUTPUT + column + 3; 625 | result_bram_dina <= dout3; 626 | circle <= circle + 1; 627 | end 628 | else if(circle == 3) 629 | begin 630 | dinVld <= 1; 631 | circle <= circle + 1; 632 | end 633 | else if(circle == 4) 634 | begin 635 | dinVld <= 0; 636 | result_bram_ena <= 1'b0; 637 | result_bram_wea <= 1'b0; 638 | PE_array_row <= 0; 639 | PE_array_column <= PE_array_column + 1; 640 | circle <= 0; 641 | end 642 | else 643 | begin 644 | circle <= circle + 1; 645 | end 646 | end 647 | end 648 | else 649 | begin 650 | dinVld <= 0; 651 | PE_array_column <= 0; 652 | PE_array_row <= 0; 653 | 654 | if(column == `CONV2_OUTPUT - 4) 655 | begin 656 | if(row == `CONV2_OUTPUT - 1) 657 | begin 658 | filter <= filter + 5; 659 | end 660 | row <= (row + 1) % `CONV2_OUTPUT; 661 | end 662 | column <= (column + 4) % `CONV2_OUTPUT; 663 | 664 | state <= S_CHECK; 665 | end 666 | end 667 | default: 668 | begin 669 | state <= S_IDLE; 670 | bias_weights_bram_ena <= 1'b0; 671 | result_bram_ena <= 1'b0; 672 | result_bram_wea <= 1'b0; 673 | end 674 | endcase 675 | end 676 | end 677 | end 678 | 679 | endmodule 680 | -------------------------------------------------------------------------------- /rtl/fc_1.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 12/31/2017 08:00:24 AM 7 | // Design Name: 8 | // Module Name: fc_1 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | `define FC1_SIZE 500 23 | `define CONV2_DEEP 50 24 | `define POOL2_OUTPUT 4 25 | `define DATA_SIZE 8 26 | 27 | module fc_1( 28 | clk, rst, fc_1_en, bias_weights_bram_douta, result_bram_douta, 29 | bias_weights_bram_ena, bias_weights_bram_addra, 30 | result_bram_ena, result_bram_wea, result_bram_addra, result_bram_dina, 31 | fc_1_finish 32 | ); 33 | input clk; 34 | input rst; 35 | input fc_1_en; 36 | input [`DATA_SIZE-1:0] bias_weights_bram_douta; 37 | input [`DATA_SIZE-1:0] result_bram_douta; 38 | output reg bias_weights_bram_ena; 39 | output reg [18:0] bias_weights_bram_addra; 40 | output reg result_bram_ena; 41 | output reg result_bram_wea; 42 | output reg [14:0] result_bram_addra; 43 | output reg [`DATA_SIZE-1:0] result_bram_dina; 44 | output reg fc_1_finish; 45 | 46 | reg [`DATA_SIZE-1:0] matrix1; 47 | reg [`DATA_SIZE-1:0] matrix2; 48 | reg matrix1_vld; 49 | reg matrix2_vld; 50 | reg [`DATA_SIZE-1:0] bias; 51 | wire [`DATA_SIZE-1:0] dout; 52 | wire dout_vld; 53 | reg [`DATA_SIZE-1:0] result; 54 | 55 | u_PE #( 56 | .Calcycle(`POOL2_OUTPUT*`POOL2_OUTPUT*`CONV2_DEEP) 57 | ) fc_1_ma( 58 | .clk_cal(clk), 59 | .rst_cal(rst), 60 | .IMap(matrix1), 61 | .IWeight(matrix2), 62 | .ImapVld(matrix1_vld), 63 | .IweightVld(matrix2_vld), 64 | .bias(bias), 65 | .OMap(dout), 66 | .OMapVld(dout_vld) 67 | ); 68 | 69 | 70 | reg [4:0] state; 71 | 72 | parameter S_IDLE = 5'b10000, 73 | S_CHECK = 5'b01000, 74 | S_LOAD_BIAS = 5'b00100, 75 | S_MULTI_ADD = 5'b00010, 76 | S_STORE_RESULT = 5'b00001; 77 | 78 | integer row = 0, 79 | column = 0, 80 | circle = 0; 81 | 82 | parameter pool2_result_base = 17600, 83 | fc1_weights_base = 25500, 84 | fc1_bias_base = 430570, 85 | fc1_result_base = 18400; 86 | 87 | 88 | always@(posedge clk) 89 | begin 90 | if(rst == 1'b1) 91 | begin 92 | state <= S_IDLE; 93 | bias_weights_bram_ena <= 1'b0; 94 | result_bram_ena <= 1'b0; 95 | result_bram_wea <= 1'b0; 96 | end 97 | else 98 | begin 99 | if(fc_1_en == 1'b1) 100 | begin 101 | case(state) 102 | S_IDLE: 103 | begin 104 | row <= 0; 105 | column <= 0; 106 | matrix1 <= 0; 107 | matrix2 <= 0; 108 | matrix1_vld <= 0; 109 | matrix2_vld <= 0; 110 | bias <= 0; 111 | result <= 0; 112 | fc_1_finish <= 1'b0; 113 | state <= S_CHECK; 114 | end 115 | S_CHECK: 116 | begin 117 | if(row == `FC1_SIZE) 118 | begin 119 | bias_weights_bram_ena <= 1'b0; 120 | result_bram_ena <= 1'b0; 121 | result_bram_wea <= 1'b0; 122 | fc_1_finish <= 1'b1; 123 | state <= S_IDLE; 124 | end 125 | else 126 | begin 127 | circle <= 0; 128 | result <= 0; 129 | state <= S_LOAD_BIAS; 130 | end 131 | end 132 | S_LOAD_BIAS: 133 | begin 134 | if(circle == 0) 135 | begin 136 | bias_weights_bram_ena <= 1'b1; 137 | bias_weights_bram_addra <= fc1_bias_base + row; 138 | circle <= circle + 1; 139 | end 140 | else if(circle == 3) 141 | begin 142 | bias <= bias_weights_bram_douta; 143 | circle <= 0; 144 | bias_weights_bram_ena <= 1'b0; 145 | state <= S_MULTI_ADD; 146 | end 147 | else 148 | begin 149 | circle <= circle + 1; 150 | end 151 | end 152 | S_MULTI_ADD: 153 | begin 154 | if(column < `POOL2_OUTPUT*`POOL2_OUTPUT*`CONV2_DEEP) 155 | begin 156 | if(circle == 0) 157 | begin 158 | result_bram_ena <= 1'b1; 159 | result_bram_addra <= pool2_result_base + column; 160 | bias_weights_bram_ena <= 1'b1; 161 | bias_weights_bram_addra <= fc1_weights_base + row * `CONV2_DEEP * `POOL2_OUTPUT * `POOL2_OUTPUT + column; 162 | matrix1_vld <= 1'b0; 163 | matrix2_vld <= 1'b0; 164 | circle <= circle + 1; 165 | end 166 | else if(circle == 3) 167 | begin 168 | matrix1 <= result_bram_douta; 169 | matrix1_vld <= 1'b1; 170 | matrix2 <= bias_weights_bram_douta; 171 | matrix2_vld <= 1'b1; 172 | column <= column + 1; 173 | circle <= 0; 174 | end 175 | else 176 | begin 177 | matrix1_vld <= 1'b0; 178 | matrix2_vld <= 1'b0; 179 | circle <= circle + 1; 180 | end 181 | end 182 | else 183 | begin 184 | circle <= 0; 185 | result_bram_ena <= 1'b0; 186 | bias_weights_bram_ena <= 1'b0; 187 | matrix1 <= 0; 188 | matrix1_vld <= 1'b0; 189 | matrix2 <= 0; 190 | matrix2_vld <= 1'b0; 191 | result <= dout; 192 | state <= S_STORE_RESULT; 193 | end 194 | end 195 | S_STORE_RESULT: 196 | begin 197 | if(circle == 0) 198 | begin 199 | result_bram_ena <= 1'b1; 200 | result_bram_wea <= 1'b1; 201 | result_bram_addra <= fc1_result_base + row; 202 | result_bram_dina <= result; 203 | circle <= circle + 1; 204 | end 205 | else if(circle == 3) 206 | begin 207 | result_bram_ena <= 1'b0; 208 | result_bram_wea <= 1'b0; 209 | circle <= 0; 210 | column <= 0; 211 | row <= row + 1; 212 | state <= S_CHECK; 213 | end 214 | else 215 | begin 216 | circle <= circle + 1; 217 | end 218 | end 219 | default: 220 | begin 221 | state <= S_IDLE; 222 | bias_weights_bram_ena <= 1'b0; 223 | result_bram_ena <= 1'b0; 224 | result_bram_wea <= 1'b0; 225 | end 226 | endcase 227 | end 228 | end 229 | end 230 | 231 | endmodule 232 | -------------------------------------------------------------------------------- /rtl/fc_2.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 01/02/2018 12:22:35 AM 7 | // Design Name: 8 | // Module Name: fc_2 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | `define FC1_SIZE 500 23 | `define FC2_SIZE 10 24 | `define DATA_SIZE 8 25 | 26 | module fc_2( 27 | clk, rst, fc_2_en, bias_weights_bram_douta, result_bram_douta, 28 | bias_weights_bram_ena, bias_weights_bram_addra, 29 | result_bram_ena, result_bram_wea, result_bram_addra, result_bram_dina, 30 | fc_2_finish, 31 | out_result 32 | ); 33 | input clk; 34 | input rst; 35 | input fc_2_en; 36 | input [`DATA_SIZE-1:0] bias_weights_bram_douta; 37 | input [`DATA_SIZE-1:0] result_bram_douta; 38 | output reg bias_weights_bram_ena; 39 | output reg [18:0] bias_weights_bram_addra; 40 | output reg result_bram_ena; 41 | output reg result_bram_wea; 42 | output reg [14:0] result_bram_addra; 43 | output reg [`DATA_SIZE-1:0] result_bram_dina; 44 | output reg fc_2_finish; 45 | output reg [79:0] out_result; 46 | 47 | reg [`DATA_SIZE-1:0] matrix1; 48 | reg [`DATA_SIZE-1:0] matrix2; 49 | reg matrix1_vld; 50 | reg matrix2_vld; 51 | reg [`DATA_SIZE-1:0] bias; 52 | wire [`DATA_SIZE-1:0] dout; 53 | wire dout_vld; 54 | reg [`DATA_SIZE-1:0] result; 55 | 56 | u_PE #( 57 | .Calcycle(`FC1_SIZE) 58 | ) fc_2_ma( 59 | .clk_cal(clk), 60 | .rst_cal(rst), 61 | .IMap(matrix1), 62 | .IWeight(matrix2), 63 | .ImapVld(matrix1_vld), 64 | .IweightVld(matrix2_vld), 65 | .bias(bias), 66 | .OMap(dout), 67 | .OMapVld(dout_vld) 68 | ); 69 | 70 | 71 | reg [4:0] state; 72 | 73 | parameter S_IDLE = 5'b10000, 74 | S_CHECK = 5'b01000, 75 | S_LOAD_BIAS = 5'b00100, 76 | S_MULTI_ADD = 5'b00010, 77 | S_STORE_RESULT = 5'b00001; 78 | 79 | integer row = 0, 80 | column = 0, 81 | circle = 0, 82 | data_begin = 0; 83 | 84 | parameter fc1_result_base = 18400, 85 | fc2_weights_base = 425500, 86 | fc2_bias_base = 431070, 87 | fc2_result_base = 18900; 88 | 89 | always@(posedge clk) 90 | begin 91 | if(rst == 1'b1) 92 | begin 93 | state <= S_IDLE; 94 | bias_weights_bram_ena <= 1'b0; 95 | result_bram_ena <= 1'b0; 96 | result_bram_wea <= 1'b0; 97 | end 98 | else 99 | begin 100 | if(fc_2_en == 1'b1) 101 | begin 102 | case(state) 103 | S_IDLE: 104 | begin 105 | row <= 0; 106 | column <= 0; 107 | matrix1 <= 0; 108 | matrix2 <= 0; 109 | matrix1_vld <= 1'b0; 110 | matrix2_vld <= 1'b0; 111 | bias <= 0; 112 | result <= 0; 113 | //out_result <= 0; 114 | fc_2_finish <= 1'b0; 115 | state <= S_CHECK; 116 | end 117 | S_CHECK: 118 | begin 119 | if(row == `FC2_SIZE) 120 | begin 121 | bias_weights_bram_ena <= 1'b0; 122 | result_bram_ena <= 1'b0; 123 | result_bram_wea <= 1'b0; 124 | fc_2_finish <= 1'b1; 125 | state <= S_IDLE; 126 | end 127 | else 128 | begin 129 | circle <= 0; 130 | result <= 0; 131 | state <= S_LOAD_BIAS; 132 | end 133 | end 134 | S_LOAD_BIAS: 135 | begin 136 | if(circle == 0) 137 | begin 138 | bias_weights_bram_ena <= 1'b1; 139 | bias_weights_bram_addra <= fc2_bias_base + row; 140 | circle <= circle + 1; 141 | end 142 | else if(circle == 3) 143 | begin 144 | bias <= bias_weights_bram_douta; 145 | circle <= 0; 146 | bias_weights_bram_ena <= 1'b0; 147 | state <= S_MULTI_ADD; 148 | end 149 | else 150 | begin 151 | circle <= circle + 1; 152 | end 153 | end 154 | S_MULTI_ADD: 155 | begin 156 | if(column < `FC1_SIZE) 157 | begin 158 | if(circle == 0) 159 | begin 160 | result_bram_ena <= 1'b1; 161 | result_bram_addra <= fc1_result_base + column; 162 | bias_weights_bram_ena <= 1'b1; 163 | bias_weights_bram_addra <= fc2_weights_base + row * `FC1_SIZE + column; 164 | matrix1_vld <= 1'b0; 165 | matrix2_vld <= 1'b0; 166 | circle <= circle + 1; 167 | end 168 | else if(circle == 3) 169 | begin 170 | matrix1 <= result_bram_douta; 171 | matrix1_vld <= 1'b1; 172 | matrix2 <= bias_weights_bram_douta; 173 | matrix2_vld <= 1'b1; 174 | column <= column + 1; 175 | circle <= 0; 176 | end 177 | else 178 | begin 179 | matrix1_vld <= 1'b0; 180 | matrix2_vld <= 1'b0; 181 | circle <= circle + 1; 182 | end 183 | end 184 | else 185 | begin 186 | circle <= 0; 187 | result_bram_ena <= 1'b0; 188 | bias_weights_bram_ena <= 1'b0; 189 | matrix1 <= 0; 190 | matrix1_vld <= 1'b0; 191 | matrix2 <= 0; 192 | matrix2_vld <= 1'b0; 193 | result <= dout; 194 | state <= S_STORE_RESULT; 195 | end 196 | end 197 | S_STORE_RESULT: 198 | begin 199 | if(circle == 0) 200 | begin 201 | result_bram_ena <= 1'b1; 202 | result_bram_wea <= 1'b1; 203 | result_bram_addra <= fc1_result_base + row; 204 | result_bram_dina <= result; 205 | circle <= circle + 1; 206 | end 207 | else if(circle == 3) 208 | begin 209 | $display("result%d : %b\n", row,result); 210 | data_begin = 8 * (10 - row) - 1; 211 | out_result[data_begin-:8] <= result; 212 | result_bram_ena <= 1'b0; 213 | result_bram_wea <= 1'b0; 214 | circle <= 0; 215 | column <= 0; 216 | row <= row + 1; 217 | state <= S_CHECK; 218 | end 219 | else 220 | begin 221 | circle <= circle + 1; 222 | end 223 | end 224 | default: 225 | begin 226 | state <= S_IDLE; 227 | bias_weights_bram_ena <= 1'b0; 228 | result_bram_ena <= 1'b0; 229 | result_bram_wea <= 1'b0; 230 | end 231 | endcase 232 | end 233 | end 234 | end 235 | 236 | endmodule 237 | -------------------------------------------------------------------------------- /rtl/lenet_top.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 12/30/2017 01:39:54 AM 7 | // Design Name: 8 | // Module Name: lenet_top 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | // LeNet parameters 23 | `define INPUT_NODE 784 24 | `define OUTPUT_NODE 10 25 | `define LAYER1_NODE 500 26 | `define LAYER2_NODE 500 27 | `define IMAGE_SIZE 28 28 | `define NUM_CHANNELS 1 29 | `define NUM_LABELS 10 30 | 31 | // Conv1 32 | `define CONV1_DEEP 20 33 | `define CONV1_SIZE 5 34 | `define CONV1_OUTPUT 24 35 | 36 | // Conv2 37 | `define CONV2_DEEP 50 38 | `define CONV2_SIZE 5 39 | `define CONV2_OUTPUT 8 40 | 41 | // Fc 42 | `define FC1_SIZE 500 43 | 44 | // fixed point 45 | `define DATA_SIZE 8 46 | 47 | module lenet_top( 48 | clk, rst, start, graph, result, lenet_finish 49 | ); 50 | input clk; 51 | input rst; 52 | input start; 53 | input [4:0] graph; 54 | output [`DATA_SIZE*`OUTPUT_NODE-1:0] result; 55 | output lenet_finish; 56 | 57 | reg finish; 58 | assign lenet_finish = finish; 59 | 60 | reg bias_weights_bram_ena; 61 | reg [0:0] bias_weights_bram_wea; 62 | reg [18:0] bias_weights_bram_addra; 63 | reg [7:0] bias_weights_bram_dina = 8'b0; 64 | wire [7:0] bias_weights_bram_douta; 65 | 66 | reg result_bram_ena; 67 | reg [0:0] result_bram_wea; 68 | reg [14:0] result_bram_addra; 69 | reg [7:0] result_bram_dina; 70 | wire [7:0] result_bram_douta; 71 | 72 | reg input_bram_ena; 73 | reg [0:0] input_bram_wea; 74 | reg [12:0] input_bram_addra; 75 | reg [7:0] input_bram_dina = 8'b0; 76 | wire [7:0] input_bram_douta; 77 | 78 | blk_mem_gen_0 bias_weights_bram ( 79 | .clka(clk), // input wire clka 80 | .ena(bias_weights_bram_ena), // input wire ena 81 | .wea(bias_weights_bram_wea), // input wire [0 : 0] wea 82 | .addra(bias_weights_bram_addra), // input wire [18 : 0] addra 83 | .dina(bias_weights_bram_dina), // input wire [7 : 0] dina 84 | .douta(bias_weights_bram_douta) // output wire [7 : 0] douta 85 | ); 86 | 87 | blk_mem_gen_1 result_bram ( 88 | .clka(clk), // input wire clka 89 | .ena(result_bram_ena), // input wire ena 90 | .wea(result_bram_wea), // input wire [0 : 0] wea 91 | .addra(result_bram_addra), // input wire [14 : 0] addra 92 | .dina(result_bram_dina), // input wire [7 : 0] dina 93 | .douta(result_bram_douta) // output wire [7 : 0] douta 94 | ); 95 | 96 | blk_mem_gen_2 input_bram ( 97 | .clka(clk), // input wire clka 98 | .ena(input_bram_ena), // input wire ena 99 | .wea(input_bram_wea), // input wire [0 : 0] wea 100 | .addra(input_bram_addra), // input wire [12 : 0] addra 101 | .dina(input_bram_dina), // input wire [7 : 0] dina 102 | .douta(input_bram_douta) // output wire [7 : 0] douta 103 | ); 104 | 105 | reg conv_1_en; 106 | wire conv_1_finish; 107 | reg pool_1_en; 108 | wire pool_1_finish; 109 | reg conv_2_en; 110 | wire conv_2_finish; 111 | reg pool_2_en; 112 | wire pool_2_finish; 113 | reg fc_1_en; 114 | wire fc_1_finish; 115 | //reg relu_1_en; 116 | reg fc_2_en; 117 | wire fc_2_finish; 118 | reg complete_en; 119 | wire complete_finish; 120 | 121 | // conv1 122 | wire conv_1_bias_weights_bram_ena; 123 | //wire [0:0] conv_1_bias_weights_bram_wea; 124 | wire [18:0] conv_1_bias_weights_bram_addra; 125 | //wire [7:0] conv_1_bias_weights_bram_dina; 126 | reg [7:0] conv_1_bias_weights_bram_douta; 127 | wire conv_1_result_bram_ena; 128 | wire [0:0] conv_1_result_bram_wea; 129 | wire [14:0] conv_1_result_bram_addra; 130 | wire [7:0] conv_1_result_bram_dina; 131 | //reg [7:0] conv_1_result_bram_douta; 132 | wire conv_1_input_bram_ena; 133 | //wire [0:0] conv_1_input_bram_wea; 134 | wire [12:0] conv_1_input_bram_addra; 135 | //wire [7:0] conv_1_input_bram_dina; 136 | reg [7:0] conv_1_input_bram_douta; 137 | 138 | conv_1 u_conv_1( 139 | .clk(clk), 140 | .rst(rst), 141 | .conv_1_en(conv_1_en), 142 | .bias_weights_bram_douta(conv_1_bias_weights_bram_douta), 143 | .input_bram_douta(conv_1_input_bram_douta), 144 | .graph(graph), 145 | .bias_weights_bram_ena(conv_1_bias_weights_bram_ena), 146 | .bias_weights_bram_addra(conv_1_bias_weights_bram_addra), 147 | .result_bram_ena(conv_1_result_bram_ena), 148 | .result_bram_wea(conv_1_result_bram_wea), 149 | .result_bram_addra(conv_1_result_bram_addra), 150 | .result_bram_dina(conv_1_result_bram_dina), 151 | .input_bram_ena(conv_1_input_bram_ena), 152 | .input_bram_addra(conv_1_input_bram_addra), 153 | .conv_1_finish(conv_1_finish) 154 | ); 155 | 156 | // pool1 157 | //wire pool_1_bias_weights_bram_ena; 158 | //wire [0:0] pool_1_bias_weights_bram_wea; 159 | //wire [18:0] pool_1_bias_weights_bram_addra; 160 | //wire [7:0] pool_1_bias_weights_bram_dina; 161 | //wire [7:0] pool_1_bias_weights_bram_douta; 162 | wire pool_1_result_bram_ena; 163 | wire [0:0] pool_1_result_bram_wea; 164 | wire [14:0] pool_1_result_bram_addra; 165 | wire [7:0] pool_1_result_bram_dina; 166 | reg [7:0] pool_1_result_bram_douta; 167 | 168 | pool_1 u_pool_1( 169 | .clk(clk), 170 | .rst(rst), 171 | .pool_1_en(pool_1_en), 172 | .result_bram_douta(pool_1_result_bram_douta), 173 | .result_bram_ena(pool_1_result_bram_ena), 174 | .result_bram_wea(pool_1_result_bram_wea), 175 | .result_bram_addra(pool_1_result_bram_addra), 176 | .result_bram_dina(pool_1_result_bram_dina), 177 | .pool_1_finish(pool_1_finish) 178 | ); 179 | 180 | // conv2 181 | wire conv_2_bias_weights_bram_ena; 182 | //wire [0:0] conv_2_bias_weights_bram_wea; 183 | wire [18:0] conv_2_bias_weights_bram_addra; 184 | //wire [7:0] conv_2_bias_weights_bram_dina; 185 | reg [7:0] conv_2_bias_weights_bram_douta; 186 | wire conv_2_result_bram_ena; 187 | wire [0:0] conv_2_result_bram_wea; 188 | wire [14:0] conv_2_result_bram_addra; 189 | wire [7:0] conv_2_result_bram_dina; 190 | reg [7:0] conv_2_result_bram_douta; 191 | 192 | conv_2 u_conv_2( 193 | .clk(clk), 194 | .rst(rst), 195 | .conv_2_en(conv_2_en), 196 | .bias_weights_bram_douta(conv_2_bias_weights_bram_douta), 197 | .result_bram_douta(conv_2_result_bram_douta), 198 | .bias_weights_bram_ena(conv_2_bias_weights_bram_ena), 199 | .bias_weights_bram_addra(conv_2_bias_weights_bram_addra), 200 | .result_bram_ena(conv_2_result_bram_ena), 201 | .result_bram_wea(conv_2_result_bram_wea), 202 | .result_bram_addra(conv_2_result_bram_addra), 203 | .result_bram_dina(conv_2_result_bram_dina), 204 | .conv_2_finish(conv_2_finish) 205 | ); 206 | 207 | // pool2 208 | //wire pool_2_bias_weights_bram_ena; 209 | //wire [0:0] pool_2_bias_weights_bram_wea; 210 | //wire [18:0] pool_2_bias_weights_bram_addra; 211 | //wire [7:0] pool_2_bias_weights_bram_dina; 212 | //wire [7:0] pool_2_bias_weights_bram_douta; 213 | wire pool_2_result_bram_ena; 214 | wire [0:0] pool_2_result_bram_wea; 215 | wire [14:0] pool_2_result_bram_addra; 216 | wire [7:0] pool_2_result_bram_dina; 217 | reg [7:0] pool_2_result_bram_douta; 218 | 219 | pool_2 u_pool_2( 220 | .clk(clk), 221 | .rst(rst), 222 | .pool_2_en(pool_2_en), 223 | .result_bram_douta(pool_2_result_bram_douta), 224 | .result_bram_ena(pool_2_result_bram_ena), 225 | .result_bram_wea(pool_2_result_bram_wea), 226 | .result_bram_addra(pool_2_result_bram_addra), 227 | .result_bram_dina(pool_2_result_bram_dina), 228 | .pool_2_finish(pool_2_finish) 229 | ); 230 | 231 | // fc1 232 | wire fc_1_bias_weights_bram_ena; 233 | //wire [0:0] fc_1_bias_weights_bram_wea; 234 | wire [18:0] fc_1_bias_weights_bram_addra; 235 | //wire [7:0] fc_1_bias_weights_bram_dina; 236 | reg [7:0] fc_1_bias_weights_bram_douta; 237 | wire fc_1_result_bram_ena; 238 | wire [0:0] fc_1_result_bram_wea; 239 | wire [14:0] fc_1_result_bram_addra; 240 | wire [7:0] fc_1_result_bram_dina; 241 | reg [7:0] fc_1_result_bram_douta; 242 | 243 | fc_1 u_fc_1( 244 | .clk(clk), 245 | .rst(rst), 246 | .fc_1_en(fc_1_en), 247 | .bias_weights_bram_douta(fc_1_bias_weights_bram_douta), 248 | .result_bram_douta(fc_1_result_bram_douta), 249 | .bias_weights_bram_ena(fc_1_bias_weights_bram_ena), 250 | .bias_weights_bram_addra(fc_1_bias_weights_bram_addra), 251 | .result_bram_ena(fc_1_result_bram_ena), 252 | .result_bram_wea(fc_1_result_bram_wea), 253 | .result_bram_addra(fc_1_result_bram_addra), 254 | .result_bram_dina(fc_1_result_bram_dina), 255 | .fc_1_finish(fc_1_finish) 256 | ); 257 | 258 | // fc2 259 | wire fc_2_bias_weights_bram_ena; 260 | //wire [0:0] fc_2_bias_weights_bram_wea; 261 | wire [18:0] fc_2_bias_weights_bram_addra; 262 | //wire [7:0] fc_2_bias_weights_bram_dina; 263 | reg [7:0] fc_2_bias_weights_bram_douta; 264 | wire fc_2_result_bram_ena; 265 | wire [0:0] fc_2_result_bram_wea; 266 | wire [14:0] fc_2_result_bram_addra; 267 | wire [7:0] fc_2_result_bram_dina; 268 | reg [7:0] fc_2_result_bram_douta; 269 | 270 | fc_2 u_fc_2( 271 | .clk(clk), 272 | .rst(rst), 273 | .fc_2_en(fc_2_en), 274 | .bias_weights_bram_douta(fc_2_bias_weights_bram_douta), 275 | .result_bram_douta(fc_2_result_bram_douta), 276 | .bias_weights_bram_ena(fc_2_bias_weights_bram_ena), 277 | .bias_weights_bram_addra(fc_2_bias_weights_bram_addra), 278 | .result_bram_ena(fc_2_result_bram_ena), 279 | .result_bram_wea(fc_2_result_bram_wea), 280 | .result_bram_addra(fc_2_result_bram_addra), 281 | .result_bram_dina(fc_2_result_bram_dina), 282 | .fc_2_finish(fc_2_finish), 283 | .out_result(result) 284 | ); 285 | 286 | // complete 287 | wire complete_result_bram_ena; 288 | wire [14:0] complete_result_bram_addra; 289 | reg [7:0] complete_result_bram_douta; 290 | wire [`DATA_SIZE*`OUTPUT_NODE-1:0] tempresult; 291 | reg [`DATA_SIZE*`OUTPUT_NODE-1:0] result_1; 292 | 293 | //assign result = result_1; 294 | 295 | complete u_complete( 296 | .clk(clk), 297 | .rst(rst), 298 | .complete_en(complete_en), 299 | .result_bram_douta(complete_result_bram_douta), 300 | .result_bram_ena(complete_result_bram_ena), 301 | .result_bram_addra(complete_result_bram_addra), 302 | .result(tempresult), 303 | .complete_finish(complete_finish) 304 | ); 305 | 306 | // States 307 | reg [7:0] state; 308 | parameter S_IDLE = 8'b10000000, 309 | S_CONV_1 = 8'b01000000, 310 | S_POOL_1 = 8'b00100000, 311 | S_CONV_2 = 8'b00010000, 312 | S_POOL_2 = 8'b00001000, 313 | S_FC_1 = 8'b00000100, 314 | S_FC_2 = 8'b00000010, 315 | COMPLETE = 8'b00000001; 316 | 317 | always@(posedge clk) 318 | begin 319 | if(rst == 1'b1) 320 | begin 321 | state <= S_IDLE; 322 | //finish <= 1'b1; 323 | conv_1_en <= 1'b0; 324 | pool_1_en <= 1'b0; 325 | conv_2_en <= 1'b0; 326 | pool_2_en <= 1'b0; 327 | fc_1_en <= 1'b0; 328 | fc_2_en <= 1'b0; 329 | result_1 <= 0; 330 | complete_en <= 1'b0; 331 | end 332 | else 333 | begin 334 | case (state) 335 | S_IDLE: 336 | begin 337 | if(start == 1'b1) 338 | begin 339 | finish <= 1'b0; 340 | //result_1 <= 0; 341 | conv_1_en <= 1'b1; 342 | state <= S_CONV_1; 343 | end 344 | else 345 | begin 346 | state <= S_IDLE; 347 | end 348 | end 349 | S_CONV_1: 350 | begin 351 | if(conv_1_finish == 1'b1) 352 | begin 353 | //$writememb("conv1_output.txt",result_bram.register,0,11519); 354 | pool_1_en <= 1'b1; 355 | conv_1_en <= 1'b0; 356 | state <= S_POOL_1; 357 | end 358 | end 359 | S_POOL_1: 360 | begin 361 | if(pool_1_finish == 1'b1) 362 | begin 363 | //$writememb("pool1_output.txt",result_bram.register,11520,14399); 364 | conv_2_en <= 1'b1; 365 | pool_1_en <= 1'b0; 366 | state <= S_CONV_2; 367 | end 368 | end 369 | S_CONV_2: 370 | begin 371 | if(conv_2_finish == 1'b1) 372 | begin 373 | //$writememb("conv2_output.txt",result_bram.register,14400,17599); 374 | pool_2_en <= 1'b1; 375 | conv_2_en <= 1'b0; 376 | state <= S_POOL_2; 377 | end 378 | end 379 | S_POOL_2: 380 | begin 381 | if(pool_2_finish == 1'b1) 382 | begin 383 | //$writememb("pool2_output.txt",result_bram.register,17600,18399); 384 | fc_1_en <= 1'b1; 385 | pool_2_en <= 1'b0; 386 | state <= S_FC_1; 387 | end 388 | end 389 | S_FC_1: 390 | begin 391 | if(fc_1_finish == 1'b1) 392 | begin 393 | //$writememb("fc1_output.txt",result_bram.register,18400,18899); 394 | fc_2_en <= 1'b1; 395 | fc_1_en <= 1'b0; 396 | state <= S_FC_2; 397 | end 398 | end 399 | S_FC_2: 400 | begin 401 | if(fc_2_finish == 1'b1) 402 | begin 403 | //$writememb("fc2_output.txt",result_bram.register,18900,18909); 404 | complete_en <= 1'b1; 405 | fc_2_en <= 1'b0; 406 | state <= COMPLETE; 407 | end 408 | end 409 | COMPLETE: 410 | begin 411 | if(complete_finish == 1'b1) 412 | begin 413 | result_1 <= tempresult; 414 | state <= S_IDLE; 415 | complete_en <= 1'b0; 416 | finish <= 1'b1; 417 | end 418 | end 419 | default: 420 | begin 421 | state <= S_IDLE; 422 | conv_1_en <= 1'b0; 423 | pool_1_en <= 1'b0; 424 | conv_2_en <= 1'b0; 425 | pool_2_en <= 1'b0; 426 | fc_1_en <= 1'b0; 427 | fc_2_en <= 1'b0; 428 | complete_en <= 1'b0; 429 | end 430 | endcase 431 | end 432 | end 433 | 434 | // bias_weights_bram 435 | always@(*) 436 | begin 437 | if(rst == 1'b1) 438 | begin 439 | bias_weights_bram_ena = 1'b0; 440 | bias_weights_bram_wea = 1'b0; 441 | end 442 | else 443 | begin 444 | case (state) 445 | S_CONV_1: 446 | begin 447 | bias_weights_bram_ena = conv_1_bias_weights_bram_ena; 448 | bias_weights_bram_wea = 1'b0; 449 | bias_weights_bram_addra = conv_1_bias_weights_bram_addra; 450 | conv_1_bias_weights_bram_douta = bias_weights_bram_douta; 451 | end 452 | S_CONV_2: 453 | begin 454 | bias_weights_bram_ena = conv_2_bias_weights_bram_ena; 455 | bias_weights_bram_wea = 1'b0; 456 | bias_weights_bram_addra = conv_2_bias_weights_bram_addra; 457 | conv_2_bias_weights_bram_douta = bias_weights_bram_douta; 458 | end 459 | S_FC_1: 460 | begin 461 | bias_weights_bram_ena = fc_1_bias_weights_bram_ena; 462 | bias_weights_bram_wea = 1'b0; 463 | bias_weights_bram_addra = fc_1_bias_weights_bram_addra; 464 | fc_1_bias_weights_bram_douta = bias_weights_bram_douta; 465 | end 466 | S_FC_2: 467 | begin 468 | bias_weights_bram_ena = fc_2_bias_weights_bram_ena; 469 | bias_weights_bram_wea = 1'b0; 470 | bias_weights_bram_addra = fc_2_bias_weights_bram_addra; 471 | fc_2_bias_weights_bram_douta = bias_weights_bram_douta; 472 | end 473 | default: 474 | begin 475 | bias_weights_bram_ena = 1'b0; 476 | bias_weights_bram_wea = 1'b0; 477 | end 478 | endcase 479 | end 480 | end 481 | 482 | // result_bram 483 | always@(*) 484 | begin 485 | if(rst == 1'b1) 486 | begin 487 | result_bram_ena = 1'b0; 488 | result_bram_wea = 1'b0; 489 | end 490 | else 491 | begin 492 | case(state) 493 | S_CONV_1: 494 | begin 495 | result_bram_ena = conv_1_result_bram_ena; 496 | result_bram_wea = conv_1_result_bram_wea; 497 | result_bram_addra = conv_1_result_bram_addra; 498 | result_bram_dina = conv_1_result_bram_dina; 499 | end 500 | S_POOL_1: 501 | begin 502 | result_bram_ena = pool_1_result_bram_ena; 503 | result_bram_wea = pool_1_result_bram_wea; 504 | result_bram_addra = pool_1_result_bram_addra; 505 | result_bram_dina = pool_1_result_bram_dina; 506 | pool_1_result_bram_douta = result_bram_douta; 507 | end 508 | S_CONV_2: 509 | begin 510 | result_bram_ena = conv_2_result_bram_ena; 511 | result_bram_wea = conv_2_result_bram_wea; 512 | result_bram_addra = conv_2_result_bram_addra; 513 | result_bram_dina = conv_2_result_bram_dina; 514 | conv_2_result_bram_douta = result_bram_douta; 515 | end 516 | S_POOL_2: 517 | begin 518 | result_bram_ena = pool_2_result_bram_ena; 519 | result_bram_wea = pool_2_result_bram_wea; 520 | result_bram_addra = pool_2_result_bram_addra; 521 | result_bram_dina = pool_2_result_bram_dina; 522 | pool_2_result_bram_douta = result_bram_douta; 523 | end 524 | S_FC_1: 525 | begin 526 | result_bram_ena = fc_1_result_bram_ena; 527 | result_bram_wea = fc_1_result_bram_wea; 528 | result_bram_addra = fc_1_result_bram_addra; 529 | result_bram_dina = fc_1_result_bram_dina; 530 | fc_1_result_bram_douta = result_bram_douta; 531 | end 532 | S_FC_2: 533 | begin 534 | result_bram_ena = fc_2_result_bram_ena; 535 | result_bram_wea = fc_2_result_bram_wea; 536 | result_bram_addra = fc_2_result_bram_addra; 537 | result_bram_dina = fc_2_result_bram_dina; 538 | fc_2_result_bram_douta = result_bram_douta; 539 | end 540 | COMPLETE: 541 | begin 542 | result_bram_ena = complete_result_bram_ena; 543 | result_bram_addra = complete_result_bram_addra; 544 | complete_result_bram_douta = result_bram_douta; 545 | end 546 | default: 547 | begin 548 | result_bram_ena = 1'b0; 549 | result_bram_wea = 1'b0; 550 | end 551 | endcase 552 | end 553 | end 554 | 555 | // input_bram 556 | always@(*) 557 | begin 558 | if(rst == 1'b1) 559 | begin 560 | input_bram_ena = 1'b0; 561 | input_bram_wea = 1'b0; 562 | end 563 | else 564 | begin 565 | if(state == S_CONV_1) 566 | begin 567 | input_bram_ena = conv_1_input_bram_ena; 568 | input_bram_wea = 1'b0; 569 | input_bram_addra = conv_1_input_bram_addra; 570 | conv_1_input_bram_douta = input_bram_douta; 571 | end 572 | else 573 | begin 574 | input_bram_ena = 1'b0; 575 | input_bram_wea = 1'b0; 576 | end 577 | end 578 | end 579 | 580 | endmodule 581 | -------------------------------------------------------------------------------- /rtl/max_pool.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 12/31/2017 07:38:39 AM 7 | // Design Name: 8 | // Module Name: max_pool 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | `define DATA_SIZE 8 23 | 24 | module max_pool( 25 | din, dout 26 | ); 27 | input [4*`DATA_SIZE-1:0] din; 28 | output [`DATA_SIZE-1:0] dout; 29 | 30 | wire [`DATA_SIZE-1:0] max_1; 31 | wire [`DATA_SIZE-1:0] max_2; 32 | 33 | assign max_1 = ((din[4*`DATA_SIZE-1] == 1'b1) && (din[3*`DATA_SIZE-1] == 1'b0) || ((din[4*`DATA_SIZE-1] == din[3*`DATA_SIZE-1]) && (din[4*`DATA_SIZE-1:3*`DATA_SIZE] < din[3*`DATA_SIZE-1:2*`DATA_SIZE]))) ? din[3*`DATA_SIZE-1:2*`DATA_SIZE] : din[4*`DATA_SIZE-1:3*`DATA_SIZE]; 34 | 35 | assign max_2 = ((max_1[`DATA_SIZE-1] == 1'b1) && (din[2*`DATA_SIZE-1] == 1'b0) || ((max_1[`DATA_SIZE-1] == din[2*`DATA_SIZE-1]) && (max_1 < din[2*`DATA_SIZE-1:`DATA_SIZE]))) ? din[2*`DATA_SIZE-1:`DATA_SIZE] : max_1; 36 | 37 | assign dout = ((max_2[`DATA_SIZE-1] == 1'b1) && (din[`DATA_SIZE-1] == 1'b0) || ((max_2[`DATA_SIZE-1] == din[`DATA_SIZE-1]) && (max_2 < din[`DATA_SIZE-1:0]))) ? din[`DATA_SIZE-1:0] : max_2; 38 | 39 | endmodule 40 | -------------------------------------------------------------------------------- /rtl/multi.v: -------------------------------------------------------------------------------- 1 | module multi( 2 | a, 3 | b, 4 | data_out 5 | ); 6 | 7 | input [7:0]a,b; 8 | 9 | output [15:0]data_out; 10 | 11 | wire [14:0]ab; 12 | 13 | assign ab = a[6:0] * b[6:0]; 14 | assign data_out = {a[7]^b[7],ab}; 15 | 16 | 17 | endmodule 18 | 19 | -------------------------------------------------------------------------------- /rtl/pool_1.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 12/30/2017 01:09:48 AM 7 | // Design Name: 8 | // Module Name: pool_1 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | `define CONV1_DEEP 20 23 | `define POOL1_INPUT 24 24 | `define POOL1_OUTPUT 12 25 | `define POOL1_SIZE 2 26 | `define DATA_SIZE 8 27 | 28 | module pool_1( 29 | clk, rst, pool_1_en, result_bram_douta, 30 | result_bram_ena, result_bram_wea, result_bram_addra, result_bram_dina, 31 | pool_1_finish 32 | ); 33 | input clk; 34 | input rst; 35 | input pool_1_en; 36 | input [`DATA_SIZE-1:0] result_bram_douta; 37 | output reg result_bram_ena; 38 | output reg result_bram_wea; 39 | output reg [14:0] result_bram_addra; 40 | output reg [`DATA_SIZE-1:0] result_bram_dina; 41 | output reg pool_1_finish; 42 | 43 | reg [4*`DATA_SIZE-1:0] din; 44 | wire [`DATA_SIZE-1:0] dout; 45 | 46 | reg [`DATA_SIZE-1:0] result; 47 | 48 | max_pool pool_1_mp( 49 | .din(din), 50 | .dout(dout) 51 | ); 52 | 53 | reg [4:0] state; 54 | 55 | parameter S_IDLE = 5'b10000, 56 | S_CHECK = 5'b01000, 57 | S_LOAD_DATA = 5'b00100, 58 | S_POOLING = 5'b00010, 59 | S_STORE_RESULT = 5'b00001; 60 | 61 | integer count = 0, 62 | circle = 0, 63 | channel = 0, 64 | row = 0, 65 | row_in = 0, 66 | column = 0, 67 | column_in = 0, 68 | data_begin = 0; 69 | 70 | parameter conv1_result_base = 0, 71 | pool1_result_base = 11520; 72 | 73 | always@(posedge clk) 74 | begin 75 | if(rst == 1'b1) 76 | begin 77 | state <= S_IDLE; 78 | result_bram_ena <= 1'b0; 79 | result_bram_wea <= 1'b0; 80 | end 81 | else 82 | begin 83 | if(pool_1_en == 1'b1) 84 | begin 85 | case(state) 86 | S_IDLE: 87 | begin 88 | channel <= 0; 89 | circle <= 0; 90 | row <= 0; 91 | row_in <= 0; 92 | column <= 0; 93 | column_in <= 0; 94 | din <= 0; 95 | result <= 0; 96 | pool_1_finish <= 1'b0; 97 | state <= S_CHECK; 98 | end 99 | S_CHECK: 100 | begin 101 | if(channel == `CONV1_DEEP) 102 | begin 103 | result_bram_ena <= 1'b0; 104 | result_bram_wea <= 1'b0; 105 | pool_1_finish <= 1'b1; 106 | state <= S_IDLE; 107 | end 108 | else 109 | begin 110 | circle <= 0; 111 | count <= 0; 112 | state <= S_LOAD_DATA; 113 | end 114 | end 115 | S_LOAD_DATA: 116 | begin 117 | if(count < `POOL1_SIZE * `POOL1_SIZE) 118 | begin 119 | if(circle == 0) 120 | begin 121 | result_bram_ena <= 1'b1; 122 | result_bram_addra <= conv1_result_base + channel * `POOL1_INPUT * `POOL1_INPUT + (row_in + (count / `POOL1_SIZE)) * `POOL1_INPUT + column_in + count % `POOL1_SIZE; 123 | circle <= circle + 1; 124 | data_begin <= `DATA_SIZE * (`POOL1_SIZE * `POOL1_SIZE - count) - 1; 125 | end 126 | else if(circle == 3) 127 | begin 128 | din[data_begin-:`DATA_SIZE] <= result_bram_douta; 129 | count <= count + 1; 130 | circle <= 0; 131 | end 132 | else 133 | begin 134 | circle <= circle + 1; 135 | end 136 | end 137 | else 138 | begin 139 | circle <= 0; 140 | count <= 0; 141 | result_bram_ena <= 1'b0; 142 | state <= S_POOLING; 143 | end 144 | end 145 | S_POOLING: 146 | begin 147 | result <= dout; 148 | circle <= 0; 149 | state <= S_STORE_RESULT; 150 | end 151 | S_STORE_RESULT: 152 | begin 153 | if(circle == 0) 154 | begin 155 | result_bram_ena <= 1'b1; 156 | result_bram_wea <= 1'b1; 157 | result_bram_addra <= pool1_result_base + channel * `POOL1_OUTPUT * `POOL1_OUTPUT + row * `POOL1_OUTPUT + column; 158 | result_bram_dina <= result; 159 | circle <= circle + 1; 160 | end 161 | else if(circle == 3) 162 | begin 163 | result_bram_ena <= 1'b0; 164 | result_bram_wea <= 1'b0; 165 | circle <= 0; 166 | if(column == `POOL1_OUTPUT - 1) 167 | begin 168 | if(row == `POOL1_OUTPUT - 1) 169 | begin 170 | channel <= channel + 1; 171 | end 172 | row <= (row + 1) % `POOL1_OUTPUT; 173 | row_in <= (row_in + 2) % `POOL1_INPUT; 174 | end 175 | column <= (column + 1) % `POOL1_OUTPUT; 176 | column_in <= (column_in + 2) % `POOL1_INPUT; 177 | state <= S_CHECK; 178 | end 179 | else 180 | begin 181 | circle <= circle + 1; 182 | end 183 | end 184 | default: 185 | begin 186 | state <= S_IDLE; 187 | result_bram_ena <= 1'b0; 188 | result_bram_wea <= 1'b0; 189 | end 190 | endcase 191 | end 192 | end 193 | end 194 | 195 | endmodule 196 | -------------------------------------------------------------------------------- /rtl/pool_2.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 01/01/2018 09:13:10 PM 7 | // Design Name: 8 | // Module Name: pool_2 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | `define CONV2_DEEP 50 23 | `define POOL2_INPUT 8 24 | `define POOL2_OUTPUT 4 25 | `define POOL2_SIZE 2 26 | `define DATA_SIZE 8 27 | 28 | module pool_2( 29 | clk, rst, pool_2_en, result_bram_douta, 30 | result_bram_ena, result_bram_wea, result_bram_addra, result_bram_dina, 31 | pool_2_finish 32 | ); 33 | input clk; 34 | input rst; 35 | input pool_2_en; 36 | input [`DATA_SIZE-1:0] result_bram_douta; 37 | output reg result_bram_ena; 38 | output reg result_bram_wea; 39 | output reg [14:0] result_bram_addra; 40 | output reg [`DATA_SIZE-1:0] result_bram_dina; 41 | output reg pool_2_finish; 42 | 43 | reg [4*`DATA_SIZE-1:0] din; 44 | wire [`DATA_SIZE-1:0] dout; 45 | 46 | reg [`DATA_SIZE-1:0] result; 47 | 48 | max_pool pool_2_mp( 49 | .din(din), 50 | .dout(dout) 51 | ); 52 | 53 | reg [4:0] state; 54 | 55 | parameter S_IDLE = 5'b10000, 56 | S_CHECK = 5'b01000, 57 | S_LOAD_DATA = 5'b00100, 58 | S_POOLING = 5'b00010, 59 | S_STORE_RESULT = 5'b00001; 60 | 61 | integer count = 0, 62 | circle = 0, 63 | channel = 0, 64 | row = 0, 65 | row_in = 0, 66 | column = 0, 67 | column_in = 0, 68 | data_begin = 0; 69 | 70 | parameter conv2_result_base = 14400, 71 | pool2_result_base = 17600; 72 | 73 | always@(posedge clk) 74 | begin 75 | if(rst == 1'b1) 76 | begin 77 | state <= S_IDLE; 78 | result_bram_ena <= 1'b0; 79 | result_bram_wea <= 1'b0; 80 | end 81 | else 82 | begin 83 | if(pool_2_en == 1'b1) 84 | begin 85 | case(state) 86 | S_IDLE: 87 | begin 88 | channel <= 0; 89 | circle <= 0; 90 | row <= 0; 91 | column <= 0; 92 | din <= 0; 93 | result <= 0; 94 | pool_2_finish <= 1'b0; 95 | state <= S_CHECK; 96 | end 97 | S_CHECK: 98 | begin 99 | if(channel == `CONV2_DEEP) 100 | begin 101 | result_bram_ena <= 1'b0; 102 | result_bram_wea <= 1'b0; 103 | pool_2_finish <= 1'b1; 104 | state <= S_IDLE; 105 | end 106 | else 107 | begin 108 | circle <= 0; 109 | count <= 0; 110 | state <= S_LOAD_DATA; 111 | end 112 | end 113 | S_LOAD_DATA: 114 | begin 115 | if(count < `POOL2_SIZE * `POOL2_SIZE) 116 | begin 117 | if(circle == 0) 118 | begin 119 | result_bram_ena <= 1'b1; 120 | result_bram_addra <= conv2_result_base + channel * `POOL2_INPUT * `POOL2_INPUT + (row_in + (count / `POOL2_SIZE)) * `POOL2_INPUT + column_in + count % `POOL2_SIZE; 121 | circle <= circle + 1; 122 | end 123 | else if(circle == 3) 124 | begin 125 | data_begin = `DATA_SIZE * (`POOL2_SIZE * `POOL2_SIZE - count) - 1; 126 | din[data_begin-:`DATA_SIZE] <= result_bram_douta; 127 | count <= count + 1; 128 | circle <= 0; 129 | end 130 | else 131 | begin 132 | circle <= circle + 1; 133 | end 134 | end 135 | else 136 | begin 137 | circle <= 0; 138 | count <= 0; 139 | result_bram_ena <= 1'b0; 140 | state <= S_POOLING; 141 | end 142 | end 143 | S_POOLING: 144 | begin 145 | result <= dout; 146 | circle <= 0; 147 | state <= S_STORE_RESULT; 148 | end 149 | S_STORE_RESULT: 150 | begin 151 | if(circle == 0) 152 | begin 153 | result_bram_ena <= 1'b1; 154 | result_bram_wea <= 1'b1; 155 | result_bram_addra <= pool2_result_base + channel * `POOL2_OUTPUT * `POOL2_OUTPUT + row * `POOL2_OUTPUT + column; 156 | result_bram_dina <= result; 157 | circle <= circle + 1; 158 | end 159 | else if(circle == 3) 160 | begin 161 | result_bram_ena <= 1'b0; 162 | result_bram_wea <= 1'b0; 163 | circle <= 0; 164 | if(column == `POOL2_OUTPUT - 1) 165 | begin 166 | if(row == `POOL2_OUTPUT - 1) 167 | begin 168 | channel <= channel + 1; 169 | end 170 | row <= (row + 1) % `POOL2_OUTPUT; 171 | row_in <= (row_in + 2) % `POOL2_INPUT; 172 | end 173 | column <= (column + 1) % `POOL2_OUTPUT; 174 | column_in <= (column_in + 2) % `POOL2_INPUT; 175 | state <= S_CHECK; 176 | end 177 | else 178 | begin 179 | circle <= circle + 1; 180 | end 181 | end 182 | default: 183 | begin 184 | state <= S_IDLE; 185 | result_bram_ena <= 1'b0; 186 | result_bram_wea <= 1'b0; 187 | end 188 | endcase 189 | end 190 | end 191 | end 192 | 193 | endmodule 194 | -------------------------------------------------------------------------------- /rtl/u_PE.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | `define halfword_width 16 3 | `define DATA_SIZE 8 4 | 5 | 6 | module u_PE#( 7 | parameter Calcycle=25 8 | )( 9 | input clk_cal, 10 | input rst_cal, 11 | input [`DATA_SIZE-1:0] IWeight, IMap, 12 | input ImapVld,IweightVld, 13 | input [`DATA_SIZE-1:0] bias, 14 | output [`DATA_SIZE-1:0] OMap, 15 | output OMapVld 16 | ); 17 | //parameter Calcycle=25;// K*K*IChannel 18 | 19 | wire I_CalDataVld; 20 | reg [10:0] MultiCount; 21 | wire[`halfword_width-1:0] Multi,PEsum,data_B; 22 | wire[`halfword_width-1:0] Sum_a; 23 | wire[`halfword_width-1:0] Sum_m; 24 | reg [`halfword_width-1:0] data_B_R; 25 | 26 | //IMap * IWeight 27 | multi u_multi(.a(IMap),.b(IWeight),.data_out(Sum_m)); 28 | add u_add(.A(Multi),.B(data_B),.out(Sum_a)); 29 | 30 | assign data_B = (MultiCount == 0)? {bias[7],5'b0,bias[6:0],3'b0} : data_B_R; 31 | assign Multi = (I_CalDataVld == 1'b1)? Sum_m : 16'b0; 32 | assign PEsum = (I_CalDataVld == 1'b1)? Sum_a : 16'b0; 33 | assign I_CalDataVld = ImapVld & IweightVld; 34 | assign OMapVld = MultiCount == (Calcycle-1); 35 | assign OMap = (PEsum[15])? 8'b0 : (PEsum[2])?{PEsum[15],PEsum[9:3]+1'b1}:{PEsum[15],PEsum[9:3]}; 36 | 37 | 38 | always@(posedge rst_cal or posedge clk_cal ) 39 | begin 40 | if(rst_cal)begin 41 | MultiCount <= 0; 42 | data_B_R <= 0; 43 | end 44 | else begin 45 | if(I_CalDataVld)begin 46 | MultiCount <= MultiCount + 1; 47 | data_B_R <= PEsum; 48 | if(MultiCount == (Calcycle-1)) begin 49 | MultiCount <= 0; 50 | data_B_R <= 0; 51 | end 52 | end 53 | end 54 | end 55 | 56 | 57 | endmodule 58 | -------------------------------------------------------------------------------- /rtl/u_PE_array.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | `define halfword_width 16 3 | `define DATA_SIZE 8 4 | 5 | module u_PE_array( 6 | input clk_cal, 7 | input rst_cal, 8 | input dinVld, 9 | input [`DATA_SIZE-1:0] IWeight0,IWeight1,IWeight2,IWeight3,IWeight4,IMap0,IMap1,IMap2,IMap3, 10 | input IweightVld0,IweightVld1,IweightVld2,IweightVld3,IweightVld4,ImapVld0,ImapVld1,ImapVld2,ImapVld3, 11 | input [`DATA_SIZE-1:0] bias0,bias1,bias2,bias3,bias4, 12 | output [`DATA_SIZE-1:0] dout0,dout1,dout2,dout3 13 | ); 14 | 15 | wire [`DATA_SIZE-1:0] dout00,dout10,dout20,dout30,dout01,dout11,dout21,dout31,dout02,dout12,dout22,dout32,dout03,dout13,dout23,dout33,dout04,dout14,dout24,dout34,dout05,dout15,dout25,dout35; 16 | wire [`DATA_SIZE-1:0] IMap00,IMap10,IMap20,IMap30,IMap01,IMap11,IMap21,IMap31,IMap02,IMap12,IMap22,IMap32,IMap03,IMap13,IMap23,IMap33,IMap04,IMap14,IMap24,IMap34,IMap05,IMap15,IMap25,IMap35; 17 | wire ImapVld00,ImapVld10,ImapVld20,ImapVld30,ImapVld01,ImapVld11,ImapVld21,ImapVld31,ImapVld02,ImapVld12,ImapVld22,ImapVld32,ImapVld03,ImapVld13,ImapVld23,ImapVld33,ImapVld04,ImapVld14,ImapVld24,ImapVld34,ImapVld05,ImapVld15,ImapVld25,ImapVld35; 18 | 19 | assign dout0 = dout00; 20 | assign dout1 = dout10; 21 | assign dout2 = dout20; 22 | assign dout3 = dout30; 23 | assign IMap00 = IMap0; 24 | assign IMap10 = IMap1; 25 | assign IMap20 = IMap2; 26 | assign IMap30 = IMap3; 27 | assign ImapVld00 = ImapVld0; 28 | assign ImapVld10 = ImapVld1; 29 | assign ImapVld20 = ImapVld2; 30 | assign ImapVld30 = ImapVld3; 31 | 32 | u_PE_column column_0( 33 | .clk_cal (clk_cal ), 34 | .rst_cal (rst_cal ), 35 | .IMap_0 (IMap00 ), 36 | .IMap_1 (IMap10 ), 37 | .IMap_2 (IMap20 ), 38 | .IMap_3 (IMap30 ), 39 | .ImapVld_0 (ImapVld00 ), 40 | .ImapVld_1 (ImapVld10 ), 41 | .ImapVld_2 (ImapVld20 ), 42 | .ImapVld_3 (ImapVld30 ), 43 | .IWeight (IWeight0 ), 44 | .IweightVld (IweightVld0), 45 | .bias (bias0 ), 46 | .dout_0 (dout00 ), 47 | .dout_1 (dout10 ), 48 | .dout_2 (dout20 ), 49 | .dout_3 (dout30 ), 50 | .din_0 (dout01 ), 51 | .din_1 (dout11 ), 52 | .din_2 (dout21 ), 53 | .din_3 (dout31 ), 54 | .dinVld (dinVld ), 55 | .NMap_0 (IMap01 ), 56 | .NMap_1 (IMap11 ), 57 | .NMap_2 (IMap21 ), 58 | .NMap_3 (IMap31 ), 59 | .NMapVld_0 (ImapVld01 ), 60 | .NMapVld_1 (ImapVld11 ), 61 | .NMapVld_2 (ImapVld21 ), 62 | .NMapVld_3 (ImapVld31 ) 63 | ); 64 | 65 | u_PE_column column_1( 66 | .clk_cal (clk_cal ), 67 | .rst_cal (rst_cal ), 68 | .IMap_0 (IMap01 ), 69 | .IMap_1 (IMap11 ), 70 | .IMap_2 (IMap21 ), 71 | .IMap_3 (IMap31 ), 72 | .ImapVld_0 (ImapVld01 ), 73 | .ImapVld_1 (ImapVld11 ), 74 | .ImapVld_2 (ImapVld21 ), 75 | .ImapVld_3 (ImapVld31 ), 76 | .IWeight (IWeight1 ), 77 | .IweightVld (IweightVld1), 78 | .bias (bias1 ), 79 | .dout_0 (dout01 ), 80 | .dout_1 (dout11 ), 81 | .dout_2 (dout21 ), 82 | .dout_3 (dout31 ), 83 | .din_0 (dout02 ), 84 | .din_1 (dout12 ), 85 | .din_2 (dout22 ), 86 | .din_3 (dout32 ), 87 | .dinVld (dinVld ), 88 | .NMap_0 (IMap02 ), 89 | .NMap_1 (IMap12 ), 90 | .NMap_2 (IMap22 ), 91 | .NMap_3 (IMap32 ), 92 | .NMapVld_0 (ImapVld02 ), 93 | .NMapVld_1 (ImapVld12 ), 94 | .NMapVld_2 (ImapVld22 ), 95 | .NMapVld_3 (ImapVld32 ) 96 | ); 97 | 98 | u_PE_column column_2( 99 | .clk_cal (clk_cal ), 100 | .rst_cal (rst_cal ), 101 | .IMap_0 (IMap02 ), 102 | .IMap_1 (IMap12 ), 103 | .IMap_2 (IMap22 ), 104 | .IMap_3 (IMap32 ), 105 | .ImapVld_0 (ImapVld02 ), 106 | .ImapVld_1 (ImapVld12 ), 107 | .ImapVld_2 (ImapVld22 ), 108 | .ImapVld_3 (ImapVld32 ), 109 | .IWeight (IWeight2 ), 110 | .IweightVld (IweightVld2), 111 | .bias (bias2 ), 112 | .dout_0 (dout02 ), 113 | .dout_1 (dout12 ), 114 | .dout_2 (dout22 ), 115 | .dout_3 (dout32 ), 116 | .din_0 (dout03 ), 117 | .din_1 (dout13 ), 118 | .din_2 (dout23 ), 119 | .din_3 (dout33 ), 120 | .dinVld (dinVld ), 121 | .NMap_0 (IMap03 ), 122 | .NMap_1 (IMap13 ), 123 | .NMap_2 (IMap23 ), 124 | .NMap_3 (IMap33 ), 125 | .NMapVld_0 (ImapVld03 ), 126 | .NMapVld_1 (ImapVld13 ), 127 | .NMapVld_2 (ImapVld23 ), 128 | .NMapVld_3 (ImapVld33 ) 129 | ); 130 | 131 | u_PE_column column_3( 132 | .clk_cal (clk_cal ), 133 | .rst_cal (rst_cal ), 134 | .IMap_0 (IMap03 ), 135 | .IMap_1 (IMap13 ), 136 | .IMap_2 (IMap23 ), 137 | .IMap_3 (IMap33 ), 138 | .ImapVld_0 (ImapVld03 ), 139 | .ImapVld_1 (ImapVld13 ), 140 | .ImapVld_2 (ImapVld23 ), 141 | .ImapVld_3 (ImapVld33 ), 142 | .IWeight (IWeight3 ), 143 | .IweightVld (IweightVld3), 144 | .bias (bias3 ), 145 | .dout_0 (dout03 ), 146 | .dout_1 (dout13 ), 147 | .dout_2 (dout23 ), 148 | .dout_3 (dout33 ), 149 | .din_0 (dout04 ), 150 | .din_1 (dout14 ), 151 | .din_2 (dout24 ), 152 | .din_3 (dout34 ), 153 | .dinVld (dinVld ), 154 | .NMap_0 (IMap04 ), 155 | .NMap_1 (IMap14 ), 156 | .NMap_2 (IMap24 ), 157 | .NMap_3 (IMap34 ), 158 | .NMapVld_0 (ImapVld04 ), 159 | .NMapVld_1 (ImapVld14 ), 160 | .NMapVld_2 (ImapVld24 ), 161 | .NMapVld_3 (ImapVld34 ) 162 | ); 163 | 164 | u_PE_column column_4( 165 | .clk_cal (clk_cal ), 166 | .rst_cal (rst_cal ), 167 | .IMap_0 (IMap04 ), 168 | .IMap_1 (IMap14 ), 169 | .IMap_2 (IMap24 ), 170 | .IMap_3 (IMap34 ), 171 | .ImapVld_0 (ImapVld04 ), 172 | .ImapVld_1 (ImapVld14 ), 173 | .ImapVld_2 (ImapVld24 ), 174 | .ImapVld_3 (ImapVld34 ), 175 | .IWeight (IWeight4 ), 176 | .IweightVld (IweightVld4), 177 | .bias (bias4 ), 178 | .dout_0 (dout04 ), 179 | .dout_1 (dout14 ), 180 | .dout_2 (dout24 ), 181 | .dout_3 (dout34 ), 182 | .din_0 (dout05 ), 183 | .din_1 (dout15 ), 184 | .din_2 (dout25 ), 185 | .din_3 (dout35 ), 186 | .dinVld (dinVld ), 187 | .NMap_0 (IMap05 ), 188 | .NMap_1 (IMap15 ), 189 | .NMap_2 (IMap25 ), 190 | .NMap_3 (IMap35 ), 191 | .NMapVld_0 (ImapVld05 ), 192 | .NMapVld_1 (ImapVld15 ), 193 | .NMapVld_2 (ImapVld25 ), 194 | .NMapVld_3 (ImapVld35 ) 195 | ); 196 | 197 | endmodule 198 | -------------------------------------------------------------------------------- /rtl/u_PE_column.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | `define halfword_width 16 3 | `define DATA_SIZE 8 4 | 5 | module u_PE_column( 6 | input clk_cal, 7 | input rst_cal, 8 | input dinVld, 9 | input [`DATA_SIZE-1:0] IWeight,IMap_0,IMap_1,IMap_2,IMap_3, 10 | input IweightVld,ImapVld_0,ImapVld_1,ImapVld_2,ImapVld_3, 11 | input [`DATA_SIZE-1:0] din_0,din_1,din_2,din_3, 12 | input [`DATA_SIZE-1:0] bias, 13 | output [`DATA_SIZE-1:0] dout_0,dout_1,dout_2,dout_3, 14 | output [`DATA_SIZE-1:0] NMap_0,NMap_1,NMap_2,NMap_3, 15 | output NMapVld_0,NMapVld_1,NMapVld_2,NMapVld_3 16 | ); 17 | 18 | u_PE_pass u_PE_0( 19 | .clk_cal (clk_cal ), 20 | .rst_cal (rst_cal ), 21 | .IMap (IMap_0 ), 22 | .IWeight (IWeight ), 23 | .ImapVld (ImapVld_0 ), 24 | .IweightVld (IweightVld ), 25 | .bias (bias ), 26 | .dout (dout_0 ), 27 | .din (din_0 ), 28 | .dinVld (dinVld ), 29 | .NMap (NMap_0 ), 30 | .NMapVld (NMapVld_0 ) 31 | ); 32 | 33 | u_PE_pass u_PE_1( 34 | .clk_cal (clk_cal ), 35 | .rst_cal (rst_cal ), 36 | .IMap (IMap_1 ), 37 | .IWeight (IWeight ), 38 | .ImapVld (ImapVld_1 ), 39 | .IweightVld (IweightVld ), 40 | .bias (bias ), 41 | .dout (dout_1 ), 42 | .din (din_1 ), 43 | .dinVld (dinVld ), 44 | .NMap (NMap_1 ), 45 | .NMapVld (NMapVld_1 ) 46 | ); 47 | 48 | u_PE_pass u_PE_2( 49 | .clk_cal (clk_cal ), 50 | .rst_cal (rst_cal ), 51 | .IMap (IMap_2 ), 52 | .IWeight (IWeight ), 53 | .ImapVld (ImapVld_2 ), 54 | .IweightVld (IweightVld ), 55 | .bias (bias ), 56 | .dout (dout_2 ), 57 | .din (din_2 ), 58 | .dinVld (dinVld ), 59 | .NMap (NMap_2 ), 60 | .NMapVld (NMapVld_2 ) 61 | ); 62 | 63 | u_PE_pass u_PE_3( 64 | .clk_cal (clk_cal ), 65 | .rst_cal (rst_cal ), 66 | .IMap (IMap_3 ), 67 | .IWeight (IWeight ), 68 | .ImapVld (ImapVld_3 ), 69 | .IweightVld (IweightVld ), 70 | .bias (bias ), 71 | .dout (dout_3 ), 72 | .din (din_3 ), 73 | .dinVld (dinVld ), 74 | .NMap (NMap_3 ), 75 | .NMapVld (NMapVld_3 ) 76 | ); 77 | 78 | 79 | endmodule 80 | -------------------------------------------------------------------------------- /rtl/u_PE_pass.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | `define halfword_width 16 3 | `define DATA_SIZE 8 4 | 5 | 6 | module u_PE_pass 7 | ( 8 | input clk_cal, 9 | input rst_cal, 10 | input [`DATA_SIZE-1:0] IWeight,IMap,din, 11 | input IweightVld,ImapVld,dinVld, 12 | input [`DATA_SIZE-1:0] bias, 13 | output reg [`DATA_SIZE-1:0] dout, 14 | output reg NMapVld, 15 | output reg [`DATA_SIZE-1:0] NMap 16 | ); 17 | parameter Calcycle=25;// K*K*IChannel 18 | 19 | wire I_CalDataVld,OMapVld; 20 | wire [`DATA_SIZE-1:0] OMap; 21 | reg [9:0] MultiCount; 22 | wire[`halfword_width-1:0] Multi,PEsum,data_B; 23 | wire[`halfword_width-1:0] Sum_a; 24 | wire[`halfword_width-1:0] Sum_m; 25 | reg [`halfword_width-1:0] data_B_R; 26 | //IMap * IWeight 27 | multi u_multi(.a(IMap),.b(IWeight),.data_out(Sum_m)); 28 | add u_add(.A(Multi),.B(data_B),.out(Sum_a)); 29 | 30 | assign data_B = (MultiCount == 0)? {bias[7],5'b0,bias[6:0],3'b0} : data_B_R; 31 | assign Multi = (I_CalDataVld == 1'b1)? Sum_m : 16'b0; 32 | assign PEsum = (I_CalDataVld == 1'b1)? Sum_a : 16'b0; 33 | assign I_CalDataVld = ImapVld & IweightVld; 34 | assign OMapVld = MultiCount == (Calcycle-1); 35 | assign OMap = (PEsum[15])? 8'b0 : (PEsum[2])?{PEsum[15],PEsum[9:3]+1'b1}:{PEsum[15],PEsum[9:3]}; 36 | 37 | 38 | always@(posedge rst_cal or posedge clk_cal ) 39 | begin 40 | if(rst_cal)begin 41 | MultiCount <= 0; 42 | data_B_R <= 0; 43 | NMap <=0; 44 | end 45 | else begin 46 | if(I_CalDataVld)begin 47 | MultiCount <= MultiCount + 1; 48 | data_B_R <= PEsum; 49 | NMap <= IMap; 50 | NMapVld <= 1; 51 | if(MultiCount == (Calcycle-1)) begin 52 | MultiCount <= 0; 53 | data_B_R <= 0; 54 | end 55 | end 56 | 57 | else 58 | NMapVld <= 0; 59 | end 60 | end 61 | 62 | always@(posedge rst_cal or posedge clk_cal ) 63 | begin 64 | if(rst_cal)begin 65 | dout <= 0; 66 | end 67 | else begin 68 | if(dinVld)begin 69 | dout <= din; 70 | end 71 | 72 | else if(OMapVld) begin 73 | dout <= OMap; 74 | end 75 | end 76 | 77 | end 78 | 79 | endmodule 80 | --------------------------------------------------------------------------------