cofiber-detection / circuit /person_small_synth.v
phanerozoic's picture
update repository
dbbceb8
Raw
History Blame Contribute Delete
3.09 kB
// Reduced person detector for synthesis — pure Verilog-2005
// FEAT_DIM=16, single MAC for classification
// Extrapolate: full 768-dim = 48x this gate count
module person_detector_small (
input wire [127:0] features, // 16 x 8-bit packed
output wire [23:0] person_score,
output wire detection
);
// Hardcoded INT8 weights (from analytical solution, first 16 dims)
wire signed [7:0] feat [0:15];
wire signed [7:0] w [0:15];
// Unpack features
assign feat[0] = features[7:0];
assign feat[1] = features[15:8];
assign feat[2] = features[23:16];
assign feat[3] = features[31:24];
assign feat[4] = features[39:32];
assign feat[5] = features[47:40];
assign feat[6] = features[55:48];
assign feat[7] = features[63:56];
assign feat[8] = features[71:64];
assign feat[9] = features[79:72];
assign feat[10] = features[87:80];
assign feat[11] = features[95:88];
assign feat[12] = features[103:96];
assign feat[13] = features[111:104];
assign feat[14] = features[119:112];
assign feat[15] = features[127:120];
// Weights as constants
assign w[0] = 8'sd10; assign w[1] = -8'sd5;
assign w[2] = 8'sd3; assign w[3] = 8'sd7;
assign w[4] = -8'sd2; assign w[5] = 8'sd12;
assign w[6] = 8'sd1; assign w[7] = -8'sd8;
assign w[8] = 8'sd4; assign w[9] = 8'sd6;
assign w[10] = -8'sd3; assign w[11] = 8'sd9;
assign w[12] = 8'sd2; assign w[13] = -8'sd1;
assign w[14] = 8'sd5; assign w[15] = 8'sd3;
// 16 parallel multiplies
wire signed [15:0] prod [0:15];
assign prod[0] = feat[0] * w[0];
assign prod[1] = feat[1] * w[1];
assign prod[2] = feat[2] * w[2];
assign prod[3] = feat[3] * w[3];
assign prod[4] = feat[4] * w[4];
assign prod[5] = feat[5] * w[5];
assign prod[6] = feat[6] * w[6];
assign prod[7] = feat[7] * w[7];
assign prod[8] = feat[8] * w[8];
assign prod[9] = feat[9] * w[9];
assign prod[10] = feat[10] * w[10];
assign prod[11] = feat[11] * w[11];
assign prod[12] = feat[12] * w[12];
assign prod[13] = feat[13] * w[13];
assign prod[14] = feat[14] * w[14];
assign prod[15] = feat[15] * w[15];
// Adder tree
wire signed [16:0] s0_0 = prod[0] + prod[1];
wire signed [16:0] s0_1 = prod[2] + prod[3];
wire signed [16:0] s0_2 = prod[4] + prod[5];
wire signed [16:0] s0_3 = prod[6] + prod[7];
wire signed [16:0] s0_4 = prod[8] + prod[9];
wire signed [16:0] s0_5 = prod[10] + prod[11];
wire signed [16:0] s0_6 = prod[12] + prod[13];
wire signed [16:0] s0_7 = prod[14] + prod[15];
wire signed [17:0] s1_0 = s0_0 + s0_1;
wire signed [17:0] s1_1 = s0_2 + s0_3;
wire signed [17:0] s1_2 = s0_4 + s0_5;
wire signed [17:0] s1_3 = s0_6 + s0_7;
wire signed [18:0] s2_0 = s1_0 + s1_1;
wire signed [18:0] s2_1 = s1_2 + s1_3;
wire signed [19:0] total = s2_0 + s2_1;
assign person_score = {{4{total[19]}}, total};
assign detection = ~total[19]; // positive = detection
endmodule