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

by David   Last Updated September 11, 2019 13:25 PM The 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;

always @(posedge clk) begin
if (reset == 1'b0) begin
write_pointer <= 0;
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;

data[write_pointer] <= data_in;
end

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

endmodule
``````
#
``````// this define is only used for readability

`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.result_interconnect : 0;
assign remainder = output_valid ? interconnect_chain.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
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; data_in_delay <= 0; data_in_delay <= 0;
data_in_squared <= 0; data_in_squared <= 0; data_in_squared <= 0;
fifo_dout_delay <= 0; fifo_dout_delay <= 0; fifo_dout_delay <= 0;
fifo_dout_squared <= 0; fifo_dout_squared <= 0; fifo_dout_squared <= 0;

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

data_in_squared <= data_in*data_in;
data_in_squared <= data_in_squared;
data_in_squared <= data_in_squared; // pipeline DSP output

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

fifo_dout_squared <= fifo_dout*fifo_dout;
fifo_dout_squared <= fifo_dout_squared;
fifo_dout_squared <= fifo_dout_squared; // pipeline DSP output

rolling_sum <= rolling_sum + data_in_delay - fifo_dout_delay;
rolling_squares_sum <= rolling_squares_sum + data_in_squared - fifo_dout_squared;

mean_squared <= (rolling_sum >> WINDOW_WIDTH) * (rolling_sum >> WINDOW_WIDTH);
mean_squared <= mean_squared;
mean_squared <= mean_squared;

mean_of_squares <= (rolling_squares_sum >> WINDOW_WIDTH);
mean_of_squares <= mean_of_squares;
mean_of_squares <= mean_of_squares;

data_out <= mean_of_squares - mean_squared;
end else begin
// just load up the sums
rolling_sum <= rolling_sum + data_in_delay;
rolling_squares_sum <= rolling_squares_sum + data_in_squared;
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 :