在Verilog中实现最多N个整数的总和

时间:2017-10-22 00:19:02

标签: verilog

我正在尝试设计将产生以下序列的硬件,F =前N个整数的和,即1 + 2 ... + N. (例如,如果N = 3,则F = 1 + 2 + 3 = 6)。我正在实现一个模块,每当输入N改变时,它会在最近的N个时钟周期产生F. N将是任何4位数(意味着F必须是7位长)。在计算新的F时,N不会改变。这是我的尝试:

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

我的测试夹具是

// 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

模拟结果为F。

的XX
[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

我做错了什么?

非常感谢您提前一段时间。

1 个答案:

答案 0 :(得分:2)

问题似乎是由于重置。以下是对正在发生的事情的简单解释:

Fib模块中,您未在重置 上初始化变量。应用重置后,状态从“ X ”变为“ wait4newN ”。现在组合块在同一时钟被触发并且case语句被执行。因此, FMux 直接来自 X-> 1 。因此,等式“ Fib&lt; = Fib + count ”总是产生' X ',因为 Fib 从未初始化为零

除此之外,您从测试平台永远不会将重置置为零。所以FSM状态永远不会改变。

Fib 模块中,使用顺序块中的重置。

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

有关处理重置的更多信息,请访问this siteCummings Reset related Paper