Forum Discussion

JLee25's avatar
JLee25
Icon for Contributor rankContributor
2 years ago
Solved

Accumulator IP to Verilog

Hi support, I am trying porting an old desine on C3 to C10. Then I met a problem on the IP conversion. The accumulator is not supported on C10. I attached the IP file for your reference. ...
  • ShengN_altera's avatar
    2 years ago

    Hi @JLee25 ,

    I found out there's bug on overflow triggering for signed custom code posted before. I had fixed the problem. I found this link http://www.pldworld.com/_altera/html/_sw/q2help/source/mega/mega_file_altaccumulate.htm and had followed the altaccumulate megafunction truth table which shown in red circle of image below.

    Here is the updated code (highlighted bold are changes):

    module acc_19i_25o2 (

    clken,

    clock,

    data,

    sload,

    cin,

    result,

    overflow

    //result_prev_out,

    //data_prev_out

    );

    input clken;

    input clock;

    input signed [30:0] data;

    input sload;

    input cin;

    output signed [30:0] result;

    output overflow;

    //output signed [30:0] result_prev_out;

    //output signed [30:0] data_prev_out;

    wire signed [30:0] sub_wire0;

    wire signed [30:0] result = sub_wire0[30:0];

    reg signed [30:0] acc_data;

    reg signed [30:0] acc_data_reg;

    reg signed [30:0] result_prev;

    reg signed [30:0] data_prev;

    reg overflow_reg;

    always @(posedge clock) begin

    if (clken) begin

    if (result_prev != acc_data) begin // check if result has changed

    result_prev <= acc_data; //previous result

    end

    if (data_prev != data ) begin // check if data has changed

    data_prev <= data; //previous data

    end

    end

    if (sload && clken) begin

    acc_data <= data;

    acc_data_reg <= acc_data;

    if ((data_prev<0&result_prev<0&acc_data>=0) | (data_prev>=0&result_prev>=0&acc_data<0)) begin

    overflow_reg <= 1'b1;

    end else begin

    overflow_reg <= 1'b0;

    end

    end else if (clken) begin

    acc_data <= acc_data + data + cin;

    acc_data_reg <= acc_data;

    if ((data_prev<0&result_prev<0&acc_data>=0) | (data_prev>=0&result_prev>=0&acc_data<0)) begin

    overflow_reg <= 1'b1;

    end else begin

    overflow_reg <= 1'b0;

    end

    end else begin

    acc_data <= acc_data;

    acc_data_reg <= acc_data_reg;

    overflow_reg <= overflow_reg;

    end

    end

    assign sub_wire0 = acc_data_reg;

    assign overflow = overflow_reg;

    //assign result_prev_out = result_prev;

    //assign data_prev_out = data_prev;

    endmodule

    Note:

    a: data, data_prev

    previous result: result_prev

    result: acc_data

    I had tested the custom code and altaccumulate megafunction (SIGNED, 1 cycle latency, Width 31) for 3 simulations. Simulation results and folder are attached below. The results are all exactly the same. The altaccumulate megafunction that I used don't have add_sub port. You may further verify from your end and let me know if there's any further concern.

    Thanks,

    Best Regards,

    Sheng

    p/s: If any answer from the community or Intel Support are helpful, please feel free to give best answer.