chikitin
chikitin

Reputation: 781

Implementing sum of integers up to N in Verilog

I am trying to Design hardware that will produce the following sequence, F = sum of the first N whole number, that is, 1+2...+N. (e.g. If N=3, F=1+2+3=6). I am implementing a module that whenever its input N changes, it produces F, at latest N clock cycles later. N will be any 4-bit number (meaning that F has to be 7 bits long). N will not change while new a new F is being calculated. Here is my attempt:

module Fib (clock, reset, N, Fib);

input clock, reset;  input [3:0] N;  
output [6:0] Fib;

reg [6:0] Fib;  
// local vars  
reg [2:0] Nprev; 
reg [2:0] count;  
reg  state, next_state;

// control lines
reg [1:0] Fmux, Cmux;

//status line
wire zero, equal;

parameter wait4newN=1'b0,  
  wait4Zero=1'b1; 

// Datapath
always@(posedge clock)
  case(Fmux)
    2'h0 : Fib <= N;
    2'h1 : Fib <= Fib + count;
  endcase

always@(posedge clock)
 case (Cmux)
    2'h0 : count <= N-1;
    2'h1 : count <= count - 1;
  endcase

assign zero = (count == 0);
assign equal = (Nprev==N);

// Controller
always@(posedge clock)
  Nprev <= N;

always@(posedge clock)
  if (reset) state <= wait4newN;
    else 
      state <= next_state;

always@(*)
  begin
    Fmux = 0; Cmux = 0;
    case (state) // synopsys full_case parallel_case
      wait4newN : 
           if (!equal) 
             begin 
               Fmux = 0; Cmux = 0;
               next_state=wait4newN;
             end
           else 
              begin 
                Fmux = 1; Cmux = 1;
                next_state=wait4Zero;
              end
      wait4Zero : 
          if(!zero)
              begin
                  Fmux = 1; Cmux = 1;
                  next_state = wait4Zero;
              end
          else
            begin
                Fmux = 0; Cmux =0;
                next_state =wait4newN;
            end
      default:
         $display("why am I here?");
      endcase
  end
 endmodule

My test fixture is

// Testbench
module test;

reg  clk, reset;
reg [3:0] N;
reg [6:0] Fib; 

  // Instantiate device under test
Fib fibInstance(.clock(clk),.reset(reset), .N(N), .Fib(Fib));

  initial begin
    // Dump waves
    $dumpfile("dump.vcd");
    $dumpvars(1, test);

    clk = 0;
    reset = 1;
    N = 5;
    $display("wait4newN N: %0h, Fib: %0h",
      N, Fib);

    toggle_clk;
    $display("wait4Zero N: %0h, Fib: %0h",
      N, Fib);

    toggle_clk;
    $display("wait4Zero N: %0h, Fib: %0h",
      N, Fib);

    toggle_clk;
    $display("wait4Zero N: %0h, Fib: %0h",
      N, Fib);

    toggle_clk;
    $display("wait4Zero N: %0h, Fib: %0h",
      N, Fib);

    toggle_clk;
    $display("wait4Zero N: %0h, Fib: %0h",
      N, Fib);

    toggle_clk;
    $display("wait4newN N: %0h, Fib: %0h",
      N, Fib);
  end

  task toggle_clk;
    begin
      #5 clk = ~clk;
      #5 clk = ~clk;
    end
  endtask

endmodule

The result of simulation is XX for F.

[2017-10-21 20:17:23 EDT] iverilog '-Wall' '-g2012' design.sv testbench.sv  && unbuffer vvp a.out  
VCD info: dumpfile dump.vcd opened for output.
wait4newN N: 5, Fib: xx
wait4Zero N: 5, Fib: xx
wait4Zero N: 5, Fib: xx
wait4Zero N: 5, Fib: xx
wait4Zero N: 5, Fib: xx
wait4Zero N: 5, Fib: xx
wait4newN N: 5, Fib: xx
Done

What am I doing wrong please?

Thank you very much for you time in advance.

Upvotes: 1

Views: 2347

Answers (1)

sharvil111
sharvil111

Reputation: 4381

The problem seems due to reset. Here is a plain explanation for what is happening:

In your Fib module, you are not initializing variables on reset. When reset is applied, the state goes from 'X' to 'wait4newN'. Now the combinational block gets triggered on same clock and the case statement is executed. Thereby FMux goes from X->1 directly. As a result the equation "Fib <= Fib + count" always yields 'X' since Fib was never initialized to zero.

Apart from this, you are never deasserting reset to zero from your testbench. So the FSM state never changes.

In the Fib module, use the reset in sequential blocks.

always @(posedge clk) begin // Assuming synchronous reset
  if(reset) begin
    // Reset variables
  end else begin
    // other logic
  end
end

More information about handling resets is available at this site and Cummings Reset related Paper.

Upvotes: 2

Related Questions