我正在尝试设计将产生以下序列的硬件,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
我做错了什么?
非常感谢您提前一段时间。
答案 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 site和Cummings Reset related Paper。