module perceptron (
    input [7:0] x0,
    input [7:0] x1,
    input [7:0] x2,
    input [7:0] x3,
    output y,
    output signed [11:0] z
);
    // Weights: w0=+3, w1=-2, w2=+4, w3=-1
    // Bias: b=-5
    
    // Extend inputs to 12 bits signed to prevent overflow and handle signed arithmetic
    wire signed [11:0] x0_s = {4'b0, x0};
    wire signed [11:0] x1_s = {4'b0, x1};
    wire signed [11:0] x2_s = {4'b0, x2};
    wire signed [11:0] x3_s = {4'b0, x3};
    
    // Constants
    localparam signed [11:0] W0 = 12'sd3;
    localparam signed [11:0] W1 = -12'sd2;
    localparam signed [11:0] W2 = 12'sd4;
    localparam signed [11:0] W3 = -12'sd1;
    localparam signed [11:0] BIAS = -12'sd5;
    
    // Compute weighted sum
    // z = 3*x0 - 2*x1 + 4*x2 - x3 - 5
    // Note: Intermediate products fit in 12 bits. 4*255 = 1020, which fits in 12 bits signed [-2048, 2047].
    
    // However, it's safer to let the synthesis tool handle width inference or be explicit.
    // 3*x0: max 765
    // 2*x1: max 510
    // 4*x2: max 1020
    // 1*x3: max 255
    // Max positive sum: 765 + 1020 = 1785
    // Max negative sum: -510 - 255 - 5 = -770
    // Both fit in 12-bit signed [-2048, 2047].
    
    assign z = (x0_s * W0) + (x1_s * W1) + (x2_s * W2) + (x3_s * W3) + BIAS;
    
    // Activation: y = 1 if z >= 0
    assign y = ~z[11]; // In 2's complement, MSB is sign bit. If 0, number is positive or zero.
                       // Wait, z=0 (0x000) -> MSB=0 -> y=1. Correct.
                       // z=-1 (0xFFF) -> MSB=1 -> y=0. Correct.
                       // z=MAX (0x6FA) -> MSB=0 -> y=1. Correct.
                       // z=MIN (0xCFD) -> MSB=1 -> y=0. Correct.

endmodule
