data/full_repos/permissive/493265923/04_DIFFERNTIATOR/DIFFERENTIATOR.v
data/verilator_xmls/43fe8bd7-f2d6-437f-a1af-0581e0bd716c.xml
module DIFFERENTIATOR(
    CLK_I,
    DATA_I,
    DATA_O,
    OFDET_O,
    UFDET_O
);

    parameter DATA_Bit_Length = 32;
    parameter Latch_Length = 3;

    input wire CLK_I;
    input wire signed [DATA_Bit_Length-1:0] DATA_I;

    output wire signed [DATA_Bit_Length-1:0] DATA_O;
    output wire OFDET_O;
    output wire UFDET_O;

    wire signed [DATA_Bit_Length:0] SUM_DATA;
    reg  signed [DATA_Bit_Length-1:0] DATA_REG[0:Latch_Length-1];
    reg  signed [DATA_Bit_Length-1:0] DATA_REG_NEG = {DATA_Bit_Length{1'b0}};

    assign SUM_DATA = DATA_I - DATA_REG_NEG;

    integer i = 0;

    always @ (posedge CLK_I) begin
        for (i = 0; i < Latch_Length; i = i + 1) begin
            if (i == 0) begin
                DATA_REG[i] <= DATA_I;
            end else begin
                DATA_REG[i] <= DATA_REG[i - 1];
            end
        end
    end

    always @ (negedge CLK_I) begin
        DATA_REG_NEG <= DATA_REG[Latch_Length-1];
    end

    assign {OFDET_O, UFDET_O, DATA_O} = assign_out(SUM_DATA);


    function [DATA_Bit_Length+1:0] assign_out;
        input [DATA_Bit_Length:0] SUM_DATA;
    begin
        case (SUM_DATA[DATA_Bit_Length:DATA_Bit_Length-1])
            2'b01: begin
                assign_out = {1'b1, 1'b0, 1'b0, {(DATA_Bit_Length-1){1'b1}}};
            end

            2'b10: begin
                assign_out = {1'b0, 1'b1, 1'b1, {(DATA_Bit_Length-1){1'b0}}};
            end

            default: begin
                assign_out = {1'b0, 1'b0, SUM_DATA[DATA_Bit_Length], SUM_DATA[DATA_Bit_Length-2:0]};
            end
        endcase
    end
    endfunction

endmodule
module DIFFERENTIATOR(
    CLK_I,
    DATA_I,
    DATA_O,
    OFDET_O,
    UFDET_O
);


    parameter DATA_Bit_Length = 32;
    parameter Latch_Length = 3;

    input wire CLK_I;
    input wire signed [DATA_Bit_Length-1:0] DATA_I;

    output wire signed [DATA_Bit_Length-1:0] DATA_O;
    output wire OFDET_O;
    output wire UFDET_O;

    wire signed [DATA_Bit_Length:0] SUM_DATA;
    reg  signed [DATA_Bit_Length-1:0] DATA_REG[0:Latch_Length-1];
    reg  signed [DATA_Bit_Length-1:0] DATA_REG_NEG = {DATA_Bit_Length{1'b0}};

    assign SUM_DATA = DATA_I - DATA_REG_NEG;

    integer i = 0;

    always @ (posedge CLK_I) begin
        for (i = 0; i < Latch_Length; i = i + 1) begin
            if (i == 0) begin
                DATA_REG[i] <= DATA_I;
            end else begin
                DATA_REG[i] <= DATA_REG[i - 1];
            end
        end
    end

    always @ (negedge CLK_I) begin
        DATA_REG_NEG <= DATA_REG[Latch_Length-1];
    end

    assign {OFDET_O, UFDET_O, DATA_O} = assign_out(SUM_DATA);


    function [DATA_Bit_Length+1:0] assign_out;
        input [DATA_Bit_Length:0] SUM_DATA;
    begin
        case (SUM_DATA[DATA_Bit_Length:DATA_Bit_Length-1])
            2'b01: begin
                assign_out = {1'b1, 1'b0, 1'b0, {(DATA_Bit_Length-1){1'b1}}};
            end

            2'b10: begin
                assign_out = {1'b0, 1'b1, 1'b1, {(DATA_Bit_Length-1){1'b0}}};
            end

            default: begin
                assign_out = {1'b0, 1'b0, SUM_DATA[DATA_Bit_Length], SUM_DATA[DATA_Bit_Length-2:0]};
            end
        endcase
    end
    endfunction

endmodule