Facing some error in verilog HDL coding of Standard deviation calculation?

by David   Last Updated September 11, 2019 13:25 PM

enter image description hereThe standard deviation (SD, also represented by the lower case Greek letter sigma σ for the population standard deviation or the Latin letter s for the sample standard deviation) is a measure that is used to quantify the amount of variation or dispersion of a set of data values.1 A low standard deviation indicates that the data points tend to be close to the mean (also called the expected value) of the set, while a high standard deviation indicates that the data points are spread out over a wider range of values.

I have a code for calculating standard deviation, everything in the codes looks ok, but when I am running the code I am getting some errors, I am using vivado 2017.4 for verilog HDL coding. The screen shot of the error is attatched. The code for the calculation of standard deviation is given below. please help me to solve the problem.

module fifo #(parameter WIDTH=8, parameter DEPTH=10) (
    input wire [WIDTH-1:0] data_in,
    output reg [WIDTH-1:0] data_out,

    output reg data_valid,

    input wire reset,
    input wire clk
    );

    function integer clog2(input reg [`MAXIMUM_FUNC_WIDTH-1:0] value); 
        begin 
            value = value-1;
            for (clog2=0; value>0; clog2=clog2+1)
                value = value>>1;
        end 
    endfunction

    reg [WIDTH-1:0] data [DEPTH-1:0];
    reg [clog2(DEPTH)-1:0] write_pointer;
    reg [clog2(DEPTH)-1:0] read_pointer;

    always @(posedge clk) begin
        if (reset == 1'b0) begin
            write_pointer <= 0;
            read_pointer <= 1;
            data_valid <= 0;
        end else begin
            if (write_pointer == DEPTH-1) write_pointer <= 0;
            else write_pointer <= write_pointer + 1;

            if (read_pointer == DEPTH-1) read_pointer <= 0;
            else read_pointer <= read_pointer + 1;

            data[write_pointer] <= data_in;
            data_out <= data[read_pointer];
        end

        if (read_pointer == 0) data_valid <= 1'b1;
    end

endmodule
#
// this define is only used for readability
`define NUMBER_OF_INTEGER_BITS_DISCARDED (2*(NUMBER_OF_BLOCKS-i))

`include "math.v"

// this module calculates the integer sqrt of an input in floor(N/2)+1 cycles, where N is the number of input bits
// it is also fully pipelined, capable of accepting a new integer every clock cycle
module sqrt #(parameter INTEGER_INPUT_WIDTH = 28) (
    input wire [INTEGER_INPUT_WIDTH-1:0] integer_input,
    output wire [(INTEGER_INPUT_WIDTH/2+1):0] remainder,
    output wire [(INTEGER_INPUT_WIDTH/2-1):0] result,

    input wire reset,
    input wire clk
  );

  localparam NUMBER_OF_BLOCKS = INTEGER_INPUT_WIDTH/2;

  // first, we generate an interconnect chain to connect together all of the sqrt_remainder modules
  // these need to have specific widths, or we will get lots of synthesis errors
  genvar i;
  generate
    for (i=NUMBER_OF_BLOCKS-1; i >= 0; i=i-1) begin : interconnect_chain
      wire [INTEGER_INPUT_WIDTH-1 - `NUMBER_OF_INTEGER_BITS_DISCARDED:0] integer_interconnect;
      wire [NUMBER_OF_BLOCKS-1+2 - i:0] remainder_interconnect ;
      wire [NUMBER_OF_BLOCKS-1 - i:0] result_interconnect;
    end : interconnect_chain
  endgenerate

  // now we simply attach the modules together, with the initial conditions specified for the first block only
  generate 
    for (i = NUMBER_OF_BLOCKS-1; i >= 0; i=i-1) begin : sqrt_chain
      if (i == (NUMBER_OF_BLOCKS-1)) begin // if this is the first block
        sqrt_remainder #(.RADICAND_WIDTH(INTEGER_INPUT_WIDTH), .STAGE_NUMBER(i)) inst (
            .reset(reset),
            .clk(clk),

            .integer_input(integer_input), // feed the initial conditions to the chain
            .remainder_previous(2'b00),
            .result_previous(1'b0), 

            .integer_output(interconnect_chain[i].integer_interconnect),
            .remainder(interconnect_chain[i].remainder_interconnect),
            .result(interconnect_chain[i].result_interconnect)
        );
      end else begin
        sqrt_remainder #(.RADICAND_WIDTH(INTEGER_INPUT_WIDTH), .STAGE_NUMBER(i)) inst (
            .reset(reset),
            .clk(clk),

            .integer_input(interconnect_chain[i+1].integer_interconnect),
            .remainder_previous(interconnect_chain[i+1].remainder_interconnect),
            .result_previous(interconnect_chain[i+1].result_interconnect),

            .integer_output(interconnect_chain[i].integer_interconnect),
            .remainder(interconnect_chain[i].remainder_interconnect),
            .result(interconnect_chain[i].result_interconnect)
        );
      end
    end : sqrt_chain
  endgenerate

  // delay the result so that we don't output garbage for the first two cycles
  reg [clog2(INTEGER_INPUT_WIDTH)-1:0] pipeline_fill_delay;

  // // attach the outputs
  wire output_valid = (pipeline_fill_delay == (INTEGER_INPUT_WIDTH-1));
  assign result = output_valid ? interconnect_chain[0].result_interconnect : 0;
  assign remainder = output_valid ? interconnect_chain[0].remainder_interconnect : 0;

  always @(posedge clk) begin
    if (reset == 1'b0) pipeline_fill_delay <= 0;
    else begin
      if (!output_valid) pipeline_fill_delay <= pipeline_fill_delay + 1;
    end
  end

endmodule
#
// these defines are only used for readability
`define INTEGER_INPUT_WIDTH ((STAGE_NUMBER+1) * 2)
`define INTEGER_OUTPUT_WIDTH `INTEGER_INPUT_WIDTH-2
`define REMAINDER_INPUT_WIDTH (((RADICAND_WIDTH/2) + 1) - STAGE_NUMBER)
`define RESULT_INPUT_WIDTH ((RADICAND_WIDTH/2) - STAGE_NUMBER - 1)
`define REMAINDER_OUTPUT_WIDTH (`REMAINDER_INPUT_WIDTH+1)
`define RESULT_OUTPUT_WIDTH `RESULT_INPUT_WIDTH+1

`define IS_FIRST_STAGE (STAGE_NUMBER == ((RADICAND_WIDTH/2) - 1))
`define IS_LAST_STAGE (STAGE_NUMBER == 0)

// this is the recursive sqrt remainder block
// you shouldn't have to do anything with this
module sqrt_remainder 
    #(
        parameter RADICAND_WIDTH = 8, 
        parameter STAGE_NUMBER = 3
    )
    ( 
        input wire [`INTEGER_INPUT_WIDTH-1:0] integer_input,
        input wire [`REMAINDER_INPUT_WIDTH-1:0] remainder_previous,
        input wire [(`RESULT_INPUT_WIDTH-1 + `IS_FIRST_STAGE):0] result_previous, // we need to force the first input to have a size of 1 for the first block

        output reg [`INTEGER_OUTPUT_WIDTH-1:0] integer_output,
        output reg signed [`REMAINDER_OUTPUT_WIDTH-1:0] remainder,
        output reg [`RESULT_OUTPUT_WIDTH-1:0] result,

        input wire reset,
        input wire clk
    );


    reg phase; // state variable

    // the following wires are used to force twos-complement arithmetic
    wire signed [`REMAINDER_OUTPUT_WIDTH-1:0] remainder_new_without_add;
    assign remainder_new_without_add = {
        remainder_previous[`REMAINDER_INPUT_WIDTH-2:0], // drop the sign bit
        integer_input[{STAGE_NUMBER, 1'b1}], // integer_input[2 * bit + 1]
        integer_input[{STAGE_NUMBER, 1'b0}] // integer_input[2 * bit]
    };

    wire signed [`REMAINDER_OUTPUT_WIDTH-1:0] remainder_greater_than_or_equal_to_0_subtractor;
    wire signed [`REMAINDER_OUTPUT_WIDTH-1:0] remainder_less_than_0_addition;
    assign remainder_greater_than_or_equal_to_0_subtractor = {result_previous, 2'b01};
    assign remainder_less_than_0_addition = {result_previous, 2'b11};

    reg signed [`REMAINDER_OUTPUT_WIDTH-1:0] remainder_delay;
    reg [`INTEGER_INPUT_WIDTH-1:0] integer_output_delay;
    reg [(`RESULT_INPUT_WIDTH-1 + `IS_FIRST_STAGE):0] result_previous_delay;

    always @(posedge clk) begin
        //if (reset == 1'b0) phase <= 0;
        //else begin
            //if (phase == 1'b0) begin
                // phase 1: calculate new remainder
                if (remainder_previous[`REMAINDER_INPUT_WIDTH-1] == 1'b0) begin // if sign bit indicates the number is positive
                    remainder_delay <= remainder_new_without_add - remainder_greater_than_or_equal_to_0_subtractor;
                end else begin
                    remainder_delay <= remainder_new_without_add + remainder_less_than_0_addition;
                end

                remainder <= remainder_delay;
                // save the integer into our local shift register, while dropping the top two bits
                // we need to force the output to have a size of 1 for the last block in the chain
                integer_output_delay <= integer_input[(`INTEGER_OUTPUT_WIDTH-1 + `IS_LAST_STAGE):0];
                integer_output <= integer_output_delay;
            //end else begin

                result_previous_delay <= result_previous;
                // phase 2: calculate new result
                if (remainder_delay[`REMAINDER_OUTPUT_WIDTH-1] != 1'b1) begin // if it is positive
                    result <= {result_previous_delay, 1'b1};
                end else begin
                    result <= {result_previous_delay, 1'b0};
                    if (`IS_LAST_STAGE) remainder <= remainder_delay + {result_previous_delay, 2'b01};
                end


            //end

            //phase <= ~phase;
        //end
    end

    // initial begin
    //  $display("sqrt_remainder block: RADICAND_WIDTH: %d, STAGE_NUMBER: %d (IS_FIRST_STAGE: %d, IS_LAST_STAGE: %d)", RADICAND_WIDTH, STAGE_NUMBER, `IS_FIRST_STAGE, `IS_LAST_STAGE);
    //  $display("\tINTEGER_INPUT_WIDTH: \t\t%d", `INTEGER_INPUT_WIDTH);
    //  $display("\tINTEGER_OUTPUT_WIDTH: \t\t%d", `INTEGER_OUTPUT_WIDTH);
    //  $display("\tREMAINDER_INPUT_WIDTH: \t\t%d", `REMAINDER_INPUT_WIDTH);
    //  $display("\tREMAINDER_OUTPUT_WIDTH: \t\t%d", `REMAINDER_OUTPUT_WIDTH);
    //  $display("\tRESULT_INPUT_WIDTH: \t\t%d", `RESULT_INPUT_WIDTH);
    //  $display("\tRESULT_OUTPUT_WIDTH: \t\t%d", `RESULT_OUTPUT_WIDTH);
    // end

endmodule
#
module standard_deviation_filter 
    #(parameter WIDTH=14, parameter WINDOW_WIDTH=7)
    (
        input wire [WIDTH-1:0] data_in,
        output wire [WIDTH-1:0] data_out,

        input wire reset,
        input wire clk

    );

    wire [WIDTH*2-1:0] variance_out;

    variance #(.WIDTH(WIDTH), .WINDOW_WIDTH(WINDOW_WIDTH)) variance_inst (
        .data_in(data_in),
        .data_out(variance_out),
        .reset(reset),
        .clk(clk)
    );

    sqrt #(.INTEGER_INPUT_WIDTH(28)) sqrt_inst (
        .integer_input(variance_out),
        .result(data_out),
        .reset(reset),
        .clk(clk)
    );

endmodule
#
`define WINDOW_SIZE ((2**WINDOW_WIDTH))

`define LARGE_CLOG2(x) clog2(x)

`define MAXIMUM_ROLLING_SUM ((2**WIDTH)-1)
`define MAXIMUM_ROLLING_SQUARES_SUM  (pow(2,(WIDTH*2))-1)

`include "math.v"

module variance #(
        parameter WIDTH=14, // data input width
        parameter WINDOW_WIDTH=7 // window size will be 2^WINDOW_WIDTH, so the default here is a size of 128
    )
    (
        input wire [WIDTH-1:0] data_in,
        output reg [WIDTH*2-1:0] data_out,

        input wire reset,
        input wire clk
    );

    reg [`LARGE_CLOG2(`MAXIMUM_ROLLING_SUM * `WINDOW_SIZE)-1:0] rolling_sum;
    reg [`LARGE_CLOG2(`MAXIMUM_ROLLING_SQUARES_SUM * `WINDOW_SIZE)-1:0] rolling_squares_sum;

    wire [WIDTH-1:0] fifo_dout;
    wire fifo_data_valid;

    fifo #(.WIDTH(WIDTH), .DEPTH(`WINDOW_SIZE)) fifo_inst (
        .data_in(data_in),
        .data_out(fifo_dout),
        .data_valid(fifo_data_valid),
        .reset(reset),
        .clk(clk)
    );

    reg [`LARGE_CLOG2(`MAXIMUM_ROLLING_SUM*`MAXIMUM_ROLLING_SUM * (`WINDOW_SIZE+1))-1:0] mean_squared [2:0];
    reg [`LARGE_CLOG2(`MAXIMUM_ROLLING_SQUARES_SUM * (`WINDOW_SIZE+1))-1:0] mean_of_squares [2:0];

    reg [WIDTH-1:0] data_in_delay [2:0];
    reg [WIDTH-1:0] fifo_dout_delay [2:0];
    reg [`LARGE_CLOG2(pow(2,WIDTH*2))-1:0] data_in_squared [2:0];
    reg [`LARGE_CLOG2(pow(2,WIDTH*2))-1:0] fifo_dout_squared [2:0];

    always @(posedge clk) begin
        if (reset == 1'b0) begin
            rolling_sum <= 0;
            rolling_squares_sum <= 0;

            data_in_delay[0] <= 0; data_in_delay[1] <= 0; data_in_delay[2] <= 0;
            data_in_squared[0] <= 0; data_in_squared[1] <= 0; data_in_squared[2] <= 0;
            fifo_dout_delay[0] <= 0; fifo_dout_delay[1] <= 0; fifo_dout_delay[2] <= 0;
            fifo_dout_squared[0] <= 0; fifo_dout_squared[1] <= 0; fifo_dout_squared[2] <= 0;

        end else begin
            data_in_delay[0] <= data_in;
            data_in_delay[1] <= data_in_delay[0];
            data_in_delay[2] <= data_in_delay[1]; // delay is required to keep data in sync with DSP output

            data_in_squared[0] <= data_in*data_in;
            data_in_squared[1] <= data_in_squared[0];
            data_in_squared[2] <= data_in_squared[1]; // pipeline DSP output

            if (fifo_data_valid) begin 
                fifo_dout_delay[0] <= fifo_dout;
                fifo_dout_delay[1] <= fifo_dout_delay[0];
                fifo_dout_delay[2] <= fifo_dout_delay[1]; // delay is required to keep data in sync with DSP output

                fifo_dout_squared[0] <= fifo_dout*fifo_dout;
                fifo_dout_squared[1] <= fifo_dout_squared[0];
                fifo_dout_squared[2] <= fifo_dout_squared[1]; // pipeline DSP output

                rolling_sum <= rolling_sum + data_in_delay[2] - fifo_dout_delay[2];
                rolling_squares_sum <= rolling_squares_sum + data_in_squared[2] - fifo_dout_squared[2];

                mean_squared[0] <= (rolling_sum >> WINDOW_WIDTH) * (rolling_sum >> WINDOW_WIDTH);
                mean_squared[1] <= mean_squared[0];
                mean_squared[2] <= mean_squared[1];

                mean_of_squares[0] <= (rolling_squares_sum >> WINDOW_WIDTH);
                mean_of_squares[1] <= mean_of_squares[0];
                mean_of_squares[2] <= mean_of_squares[1];

                data_out <= mean_of_squares[2] - mean_squared[2];
            end else begin
                // just load up the sums
                rolling_sum <= rolling_sum + data_in_delay[2];
                rolling_squares_sum <= rolling_squares_sum + data_in_squared[2];
            end
        end
    end

    initial begin
        $dumpfile("dump.vcd");
        $dumpvars(0, variance);
    end
endmodule
#
`ifndef _MATH_V_
`define _MATH_V_ 1

`define MAXIMUM_FUNC_WIDTH  64

function integer clog2(input reg [`MAXIMUM_FUNC_WIDTH-1:0] value); 
    begin 
        value = value-1;
        for (clog2=0; value>0; clog2=clog2+1)
            value = value>>1;
    end 
endfunction

function reg [`MAXIMUM_FUNC_WIDTH-1:0] pow(input integer base, input integer index); 
   begin
       for (pow=1; index>=0; pow=pow*base)
           index = index - 1;
   end
endfunction

`endif
Tags : fpga verilog hdl


Related Questions