|
@@ -2,30 +2,142 @@
|
|
|
`timescale 1 ps / 1 ps
|
|
`timescale 1 ps / 1 ps
|
|
|
// synopsys translate_on
|
|
// synopsys translate_on
|
|
|
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ ______ _________
|
|
|
|
|
+ w[i] =>| MULT |==>| |
|
|
|
|
|
+ x[i] =>|______| | |
|
|
|
|
|
+ ______ | |
|
|
|
|
|
+ w[i+1] =>| MULT |==>| CASCADE | _____
|
|
|
|
|
+ x[i+1] =>|______| | | b =>| ADD |
|
|
|
|
|
+ . | ADDER |====>|_____|==> y
|
|
|
|
|
+ . | |
|
|
|
|
|
+ ______ | |
|
|
|
|
|
+ w[M-1] =>| MULT |==>| |
|
|
|
|
|
+ x[M-1] =>|______| |_________|
|
|
|
|
|
|
|
|
-module neuron#(parameter M, N=32)(x, y, w, b, stb, ack, clk, rst);
|
|
|
|
|
|
|
+*/
|
|
|
|
|
+
|
|
|
|
|
+module neuron#(parameter K, N=32)(x, y, w, b, left, right, clk, rst);
|
|
|
|
|
+ localparam M = 2**K;
|
|
|
input wire [N-1:0] x [M-1:0];
|
|
input wire [N-1:0] x [M-1:0];
|
|
|
- input wire [N-1:0] w;
|
|
|
|
|
- input wire [N-1:0] b [M-1:0];
|
|
|
|
|
- output logic stb;
|
|
|
|
|
- input logic ack;
|
|
|
|
|
- input logic clk;
|
|
|
|
|
- input logic rst;
|
|
|
|
|
|
|
+ input wire [N-1:0] w [M-1:0];
|
|
|
|
|
+ input wire [N-1:0] b;
|
|
|
output logic [N-1:0] y;
|
|
output logic [N-1:0] y;
|
|
|
|
|
|
|
|
- multiplier mult_array[M-1:0](
|
|
|
|
|
|
|
+ input wire clk;
|
|
|
|
|
+ input wire rst;
|
|
|
|
|
+
|
|
|
|
|
+ abus_io left[M-1:0];
|
|
|
|
|
+ abus_io inner_io0[M-1:0]();
|
|
|
|
|
+ abus_io inner_io1();
|
|
|
|
|
+ abus_io right;
|
|
|
|
|
+
|
|
|
|
|
+ wire [N-1:0] inner_w [M-1:0];
|
|
|
|
|
+ wire [N-1:0] casc_w;
|
|
|
|
|
+
|
|
|
|
|
+ genvar i;
|
|
|
|
|
+ generate
|
|
|
|
|
+ for(i=0;i<M;i++) begin: gen_mult_layer
|
|
|
|
|
+ multiplier mult(
|
|
|
|
|
+ .clk(clk),
|
|
|
|
|
+ .rst(rst),
|
|
|
|
|
+ .input_a(x[i]),
|
|
|
|
|
+ .input_b(w[i]),
|
|
|
|
|
+ .input_stb(left[i].stb),
|
|
|
|
|
+ .input_ack(left[i].ack),
|
|
|
|
|
+ .output_z(inner_w[i]),
|
|
|
|
|
+ .output_z_ack(inner_io0[i].ack),
|
|
|
|
|
+ .output_z_stb(inner_io0[i].stb)
|
|
|
|
|
+ );
|
|
|
|
|
+ end
|
|
|
|
|
+ endgenerate
|
|
|
|
|
+
|
|
|
|
|
+ adder_casc#(.K(K), .N(N)) adder0(
|
|
|
.clk(clk),
|
|
.clk(clk),
|
|
|
.rst(rst),
|
|
.rst(rst),
|
|
|
- .input_a(input_a),
|
|
|
|
|
- .input_b(input_b),
|
|
|
|
|
- .input_stb(mult_input_stb),
|
|
|
|
|
- .input_ack(mult_input_ack),
|
|
|
|
|
- .output_z(result_mult),
|
|
|
|
|
- .output_z_ack(mult_output_z_ack),
|
|
|
|
|
- .output_z_stb(mult_output_z_stb),
|
|
|
|
|
|
|
+ .x(inner_w),
|
|
|
|
|
+ .y(casc_w),
|
|
|
|
|
+ .left(inner_io0),
|
|
|
|
|
+ .right(inner_io1)
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ adder adder1 (
|
|
|
|
|
+ .clk(clk),
|
|
|
|
|
+ .rst(rst),
|
|
|
|
|
+ .input_a(b),
|
|
|
|
|
+ .input_b(casc_w),
|
|
|
|
|
+ .input_stb(inner_io1.stb),
|
|
|
|
|
+ .input_ack(inner_io1.ack),
|
|
|
|
|
+ .output_z(y),
|
|
|
|
|
+ .output_z_ack(right.ack),
|
|
|
|
|
+ .output_z_stb(right.stb)
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
endmodule : neuron
|
|
endmodule : neuron
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+module neuron_tb;
|
|
|
|
|
+ logic clk, rst;
|
|
|
|
|
+
|
|
|
|
|
+ logic [31:0] x [7:0];
|
|
|
|
|
+ logic [31:0] w [7:0];
|
|
|
|
|
+ logic [31:0] b;
|
|
|
|
|
+ logic [31:0] y;
|
|
|
|
|
+
|
|
|
|
|
+ logic ack [7:0];
|
|
|
|
|
+ logic stb [7:0];
|
|
|
|
|
+
|
|
|
|
|
+ abus_io left[7:0]();
|
|
|
|
|
+ abus_io right();
|
|
|
|
|
+
|
|
|
|
|
+ neuron#(.K(3)) neu0(
|
|
|
|
|
+ .clk(clk),
|
|
|
|
|
+ .rst(rst),
|
|
|
|
|
+ .x(x),
|
|
|
|
|
+ .y(y),
|
|
|
|
|
+ .w(w),
|
|
|
|
|
+ .b(b),
|
|
|
|
|
+ .left(left),
|
|
|
|
|
+ .right(right)
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ genvar k;
|
|
|
|
|
+ generate
|
|
|
|
|
+ for(k=0; k<8; k++) begin : io_mapper
|
|
|
|
|
+ assign left[k].stb = stb[k];
|
|
|
|
|
+ assign ack[k] = left[k].ack;
|
|
|
|
|
+ end
|
|
|
|
|
+ endgenerate
|
|
|
|
|
+
|
|
|
|
|
+ initial forever #5 clk = ~clk;
|
|
|
|
|
+ initial begin
|
|
|
|
|
+ clk = 0;
|
|
|
|
|
+ rst = 1;
|
|
|
|
|
+ foreach(stb[i]) stb[i] = 0;
|
|
|
|
|
+ right.ack = 0;
|
|
|
|
|
+ b = 'h3f000000;
|
|
|
|
|
+ w = {
|
|
|
|
|
+ 'h3fa00000, 'h3fa00000, 'h3fa00000, 'h3fa00000,
|
|
|
|
|
+ 'h3fa00000, 'h3fa00000, 'h3fa00000, 'h3fa00000
|
|
|
|
|
+ };
|
|
|
|
|
+ x = {
|
|
|
|
|
+ // 'h3fa00000, 'h3fa00000, 'h3fa00000, 'h3fa00000,
|
|
|
|
|
+ // 'h3fa00000, 'h3fa00000, 'h3fa00000, 'h3fa00000
|
|
|
|
|
+ 'h417a0000, 'h40fa0000, 'h41fa0000, 'h427a0000,
|
|
|
|
|
+ 'h407a0000, 'h40780000, 'h40440000, 'h40cc0000
|
|
|
|
|
+ };
|
|
|
|
|
+ #10;
|
|
|
|
|
+ rst = 0;
|
|
|
|
|
+ foreach(stb[i]) stb[i] = 1;
|
|
|
|
|
+ #20;
|
|
|
|
|
+ foreach(stb[i]) stb[i] = 0;
|
|
|
|
|
+ wait(right.stb == 1);
|
|
|
|
|
+ right.ack = 1;
|
|
|
|
|
+ #10
|
|
|
|
|
+ wait(right.stb == 0);
|
|
|
|
|
+ right.ack = 0;
|
|
|
|
|
+ end
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
+endmodule : neuron_tb
|