data/full_repos/permissive/150642927/VerilogSrc/Sources/universal_weight_comp_cell.v
1: b'%Warning-STMTDLY: data/full_repos/permissive/150642927/VerilogSrc/Sources/universal_weight_comp_cell.v:54: Unsupported: Ignoring delay on this delayed statement.\nalways @ (posedge clk) begin #1\n                             ^\n                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.\n%Error: data/full_repos/permissive/150642927/VerilogSrc/Sources/universal_weight_comp_cell.v:35: Cannot find file containing module: \'multiply_and_add\'\n        multiply_and_add #(\n        ^~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/150642927/VerilogSrc/Sources,data/full_repos/permissive/150642927/multiply_and_add\n             data/full_repos/permissive/150642927/VerilogSrc/Sources,data/full_repos/permissive/150642927/multiply_and_add.v\n             data/full_repos/permissive/150642927/VerilogSrc/Sources,data/full_repos/permissive/150642927/multiply_and_add.sv\n             multiply_and_add\n             multiply_and_add.v\n             multiply_and_add.sv\n             obj_dir/multiply_and_add\n             obj_dir/multiply_and_add.v\n             obj_dir/multiply_and_add.sv\n%Error: Exiting due to 1 error(s), 1 warning(s)\n        ... See the manual and https://verilator.org for more assistance.\n'
module universal_weight_comp_cell #(
        parameter DATA_WIDTH = 8,
        parameter RESULT_WIDTH = 16,
        parameter INDEX_WIDTH = 10,
        parameter WEIGHT_AMOUNT = 4,
        parameter [8*WEIGHT_AMOUNT-1:0] WEIGHTS = {8'd0, 8'd0, 8'd0, 8'd0},
        parameter WEIGHT_OFFSET = 0,
        parameter INPUT_OFFSET = 0,
        parameter INPUT_AMOUNT = 4
    ) (
        input wire clk,
        input wire [INDEX_WIDTH-1:0] input_index,
        input wire [INPUT_AMOUNT*DATA_WIDTH-1:0] input_value,
        input wire [RESULT_WIDTH:0] input_result,
        input wire input_enable,
        output reg [INDEX_WIDTH-1:0] output_index,
        output reg [INPUT_AMOUNT*DATA_WIDTH-1:0] output_value,
        output reg [RESULT_WIDTH:0] output_result,
        output reg output_enable
    );
    
reg [RESULT_WIDTH-1:0] accumulator;
reg [RESULT_WIDTH:0] result;
wire [(INPUT_AMOUNT+1)*RESULT_WIDTH-1:0] joint_accumulator; 

generate 
    genvar i;
    for (i = 0; i<INPUT_AMOUNT; i = i + 1) begin : mac_block 
        multiply_and_add #(
            .DATA_WIDTH(DATA_WIDTH),
            .RESULT_WIDTH(RESULT_WIDTH)
        ) mac (
            .add_value(joint_accumulator[RESULT_WIDTH*i +: RESULT_WIDTH]),
            .input_value(input_value[DATA_WIDTH*i +: DATA_WIDTH]),
            .weight_value(WEIGHTS[8*(input_index*INPUT_AMOUNT+i) +: 8]),
            .output_value(joint_accumulator[RESULT_WIDTH*(i+1) +: RESULT_WIDTH])
        );
    end
endgenerate

initial begin 
    result = 0; 
    accumulator = 0;
end

assign joint_accumulator[0 +: RESULT_WIDTH] = accumulator;

always @ (posedge clk) begin #1
    if (input_enable) begin
        if (input_index*INPUT_AMOUNT == WEIGHT_AMOUNT-INPUT_AMOUNT && input_result[RESULT_WIDTH]) begin
            result <= {1'b1, joint_accumulator[RESULT_WIDTH*INPUT_AMOUNT +: RESULT_WIDTH]};
            accumulator <= 0; 
        end
        else accumulator <= joint_accumulator[RESULT_WIDTH*INPUT_AMOUNT +: RESULT_WIDTH]; 
        output_value <= input_value;
        output_index <= input_index;
        output_enable <= input_enable;
    end
    else begin
        output_value <= 0;
        output_index <= 0;
        output_enable <= 0;
    end
    
    if (input_result[RESULT_WIDTH]) output_result <= input_result;
    else begin
        if (result[RESULT_WIDTH]) begin 
            output_result <= result;
            result[RESULT_WIDTH] <= 1'b0;
        end
        else if (input_enable && input_index*INPUT_AMOUNT == WEIGHT_AMOUNT-INPUT_AMOUNT) begin
            output_result <= {1'b1, joint_accumulator[RESULT_WIDTH*INPUT_AMOUNT +: RESULT_WIDTH]};
            accumulator <= 0;
        end
        else output_result <= 0; 
    end
end

endmodule
module universal_weight_comp_cell #(
        parameter DATA_WIDTH = 8,
        parameter RESULT_WIDTH = 16,
        parameter INDEX_WIDTH = 10,
        parameter WEIGHT_AMOUNT = 4,
        parameter [8*WEIGHT_AMOUNT-1:0] WEIGHTS = {8'd0, 8'd0, 8'd0, 8'd0},
        parameter WEIGHT_OFFSET = 0,
        parameter INPUT_OFFSET = 0,
        parameter INPUT_AMOUNT = 4
    ) (
        input wire clk,
        input wire [INDEX_WIDTH-1:0] input_index,
        input wire [INPUT_AMOUNT*DATA_WIDTH-1:0] input_value,
        input wire [RESULT_WIDTH:0] input_result,
        input wire input_enable,
        output reg [INDEX_WIDTH-1:0] output_index,
        output reg [INPUT_AMOUNT*DATA_WIDTH-1:0] output_value,
        output reg [RESULT_WIDTH:0] output_result,
        output reg output_enable
    );

    
reg [RESULT_WIDTH-1:0] accumulator;
reg [RESULT_WIDTH:0] result;
wire [(INPUT_AMOUNT+1)*RESULT_WIDTH-1:0] joint_accumulator; 

generate 
    genvar i;
    for (i = 0; i<INPUT_AMOUNT; i = i + 1) begin : mac_block 
        multiply_and_add #(
            .DATA_WIDTH(DATA_WIDTH),
            .RESULT_WIDTH(RESULT_WIDTH)
        ) mac (
            .add_value(joint_accumulator[RESULT_WIDTH*i +: RESULT_WIDTH]),
            .input_value(input_value[DATA_WIDTH*i +: DATA_WIDTH]),
            .weight_value(WEIGHTS[8*(input_index*INPUT_AMOUNT+i) +: 8]),
            .output_value(joint_accumulator[RESULT_WIDTH*(i+1) +: RESULT_WIDTH])
        );
    end
endgenerate

initial begin 
    result = 0; 
    accumulator = 0;
end

assign joint_accumulator[0 +: RESULT_WIDTH] = accumulator;

always @ (posedge clk) begin #1
    if (input_enable) begin
        if (input_index*INPUT_AMOUNT == WEIGHT_AMOUNT-INPUT_AMOUNT && input_result[RESULT_WIDTH]) begin
            result <= {1'b1, joint_accumulator[RESULT_WIDTH*INPUT_AMOUNT +: RESULT_WIDTH]};
            accumulator <= 0; 
        end
        else accumulator <= joint_accumulator[RESULT_WIDTH*INPUT_AMOUNT +: RESULT_WIDTH]; 
        output_value <= input_value;
        output_index <= input_index;
        output_enable <= input_enable;
    end
    else begin
        output_value <= 0;
        output_index <= 0;
        output_enable <= 0;
    end
    
    if (input_result[RESULT_WIDTH]) output_result <= input_result;
    else begin
        if (result[RESULT_WIDTH]) begin 
            output_result <= result;
            result[RESULT_WIDTH] <= 1'b0;
        end
        else if (input_enable && input_index*INPUT_AMOUNT == WEIGHT_AMOUNT-INPUT_AMOUNT) begin
            output_result <= {1'b1, joint_accumulator[RESULT_WIDTH*INPUT_AMOUNT +: RESULT_WIDTH]};
            accumulator <= 0;
        end
        else output_result <= 0; 
    end
end

endmodule