working with memory
This commit is contained in:
+93
-98
@@ -1,122 +1,117 @@
|
||||
module mac8 #(
|
||||
parameter DATA_WIDTH = 16,
|
||||
parameter ACC_WIDTH = 40
|
||||
parameter ACC_WIDTH = 40,
|
||||
parameter PARALLEL = 8
|
||||
)(
|
||||
input signed [DATA_WIDTH*8-1:0] x_bus,
|
||||
input signed [DATA_WIDTH*8-1:0] w_bus,
|
||||
input signed [DATA_WIDTH*PARALLEL-1:0] x_bus,
|
||||
input signed [DATA_WIDTH*PARALLEL-1:0] w_bus,
|
||||
input signed [ACC_WIDTH-1:0] acc_in,
|
||||
output signed [ACC_WIDTH-1:0] acc_out
|
||||
);
|
||||
|
||||
wire signed [ACC_WIDTH-1:0] m0;
|
||||
wire signed [ACC_WIDTH-1:0] m1;
|
||||
wire signed [ACC_WIDTH-1:0] m2;
|
||||
wire signed [ACC_WIDTH-1:0] m3;
|
||||
wire signed [ACC_WIDTH-1:0] m4;
|
||||
wire signed [ACC_WIDTH-1:0] m5;
|
||||
wire signed [ACC_WIDTH-1:0] m6;
|
||||
wire signed [ACC_WIDTH-1:0] m7;
|
||||
/*
|
||||
* Each MAC produces one sign-extended product.
|
||||
*/
|
||||
wire signed [ACC_WIDTH-1:0] products [0:PARALLEL-1];
|
||||
|
||||
wire signed [ACC_WIDTH-1:0] s0;
|
||||
wire signed [ACC_WIDTH-1:0] s1;
|
||||
wire signed [ACC_WIDTH-1:0] s2;
|
||||
wire signed [ACC_WIDTH-1:0] s3;
|
||||
genvar i;
|
||||
|
||||
wire signed [ACC_WIDTH-1:0] s4;
|
||||
wire signed [ACC_WIDTH-1:0] s5;
|
||||
generate
|
||||
for (i = 0; i < PARALLEL; i = i + 1) begin : GEN_MAC
|
||||
|
||||
wire signed [ACC_WIDTH-1:0] sum;
|
||||
mac_unit #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.ACC_WIDTH(ACC_WIDTH)
|
||||
) u_mac (
|
||||
.x(
|
||||
x_bus[
|
||||
i*DATA_WIDTH
|
||||
+:
|
||||
DATA_WIDTH
|
||||
]
|
||||
),
|
||||
.w(
|
||||
w_bus[
|
||||
i*DATA_WIDTH
|
||||
+:
|
||||
DATA_WIDTH
|
||||
]
|
||||
),
|
||||
.acc_in({ACC_WIDTH{1'b0}}),
|
||||
.acc_out(products[i])
|
||||
);
|
||||
|
||||
mac_unit #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.ACC_WIDTH(ACC_WIDTH)
|
||||
) mac0 (
|
||||
.x(x_bus[0*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.w(w_bus[0*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.acc_in({ACC_WIDTH{1'b0}}),
|
||||
.acc_out(m0)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
mac_unit #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.ACC_WIDTH(ACC_WIDTH)
|
||||
) mac1 (
|
||||
.x(x_bus[1*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.w(w_bus[1*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.acc_in({ACC_WIDTH{1'b0}}),
|
||||
.acc_out(m1)
|
||||
);
|
||||
|
||||
mac_unit #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.ACC_WIDTH(ACC_WIDTH)
|
||||
) mac2 (
|
||||
.x(x_bus[2*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.w(w_bus[2*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.acc_in({ACC_WIDTH{1'b0}}),
|
||||
.acc_out(m2)
|
||||
);
|
||||
/*
|
||||
* Balanced binary adder tree.
|
||||
*
|
||||
* PARALLEL is intended to be a power of two:
|
||||
* 8 -> 3 levels
|
||||
* 16 -> 4 levels
|
||||
* 32 -> 5 levels
|
||||
*
|
||||
* This replaces the previous linear accumulator:
|
||||
*
|
||||
* (((p0+p1)+p2)+p3)+...
|
||||
*
|
||||
* with:
|
||||
*
|
||||
* sum
|
||||
* / \
|
||||
* ... ...
|
||||
*
|
||||
* reducing the combinational depth from O(PARALLEL)
|
||||
* to O(log2(PARALLEL)).
|
||||
*/
|
||||
|
||||
mac_unit #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.ACC_WIDTH(ACC_WIDTH)
|
||||
) mac3 (
|
||||
.x(x_bus[3*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.w(w_bus[3*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.acc_in({ACC_WIDTH{1'b0}}),
|
||||
.acc_out(m3)
|
||||
);
|
||||
localparam TREE_LEVELS = $clog2(PARALLEL);
|
||||
|
||||
mac_unit #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.ACC_WIDTH(ACC_WIDTH)
|
||||
) mac4 (
|
||||
.x(x_bus[4*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.w(w_bus[4*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.acc_in({ACC_WIDTH{1'b0}}),
|
||||
.acc_out(m4)
|
||||
);
|
||||
wire signed [ACC_WIDTH-1:0]
|
||||
tree [0:TREE_LEVELS][0:PARALLEL-1];
|
||||
|
||||
mac_unit #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.ACC_WIDTH(ACC_WIDTH)
|
||||
) mac5 (
|
||||
.x(x_bus[5*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.w(w_bus[5*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.acc_in({ACC_WIDTH{1'b0}}),
|
||||
.acc_out(m5)
|
||||
);
|
||||
generate
|
||||
|
||||
mac_unit #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.ACC_WIDTH(ACC_WIDTH)
|
||||
) mac6 (
|
||||
.x(x_bus[6*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.w(w_bus[6*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.acc_in({ACC_WIDTH{1'b0}}),
|
||||
.acc_out(m6)
|
||||
);
|
||||
/*
|
||||
* Level 0 = individual products
|
||||
*/
|
||||
for (i = 0; i < PARALLEL; i = i + 1) begin : GEN_TREE_INPUT
|
||||
assign tree[0][i] = products[i];
|
||||
end
|
||||
|
||||
mac_unit #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.ACC_WIDTH(ACC_WIDTH)
|
||||
) mac7 (
|
||||
.x(x_bus[7*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.w(w_bus[7*DATA_WIDTH +: DATA_WIDTH]),
|
||||
.acc_in({ACC_WIDTH{1'b0}}),
|
||||
.acc_out(m7)
|
||||
);
|
||||
endgenerate
|
||||
|
||||
assign s0 = m0 + m1;
|
||||
assign s1 = m2 + m3;
|
||||
assign s2 = m4 + m5;
|
||||
assign s3 = m6 + m7;
|
||||
|
||||
assign s4 = s0 + s1;
|
||||
assign s5 = s2 + s3;
|
||||
genvar level;
|
||||
genvar node;
|
||||
|
||||
assign sum = s4 + s5;
|
||||
generate
|
||||
|
||||
assign acc_out = acc_in + sum;
|
||||
for (level = 0; level < TREE_LEVELS; level = level + 1) begin : GEN_TREE_LEVEL
|
||||
|
||||
for (
|
||||
node = 0;
|
||||
node < (PARALLEL >> (level + 1));
|
||||
node = node + 1
|
||||
) begin : GEN_TREE_NODE
|
||||
|
||||
assign tree[level + 1][node] =
|
||||
tree[level][2*node] +
|
||||
tree[level][2*node + 1];
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
|
||||
/*
|
||||
* Add the partial sum to the accumulator.
|
||||
*/
|
||||
assign acc_out =
|
||||
acc_in + tree[TREE_LEVELS][0];
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user