Reputation: 41
I am having problem with this counter. The output is all xxxxxxxx. I know I should set the initial value of count
and overflow
to 0, but it gives an error that way.
module counter (in, start, count, clk, overflow);
input [3:0] in;
input clk;
input start;
output reg [7:0] count;
output reg overflow;
//reg count;
//count =0;
//overflow=0;
always @ (posedge clk)
begin
if (start) begin
count <= 8'b0;
overflow <= 1'b0;
end
else if (in == 4'b0101) begin
count <= count+1;
end
if (count == 4'b1111) begin
overflow <=1'b1;
end
end
endmodule
This is the testbench:
module tb();
reg [3:0] in;
reg clk,start;
wire [7:0] count;
reg overflow = 1'b0;
initial begin
$display ("time\t clk start in count overflow");
$monitor ("%g\t %b %b %b %b", $time, clk, start, in, count, overflow);
clk=0;
in=0;
start=0;
// overflow=0;
// count=0;
#5 in=4'd1;
#5 in=4'd5;
#5 in=4'd4;
#5 in=5'd5;
#5 in=4'd1;
#5 in=4'd5;
#5 in=4'd4;
#5 in=5'd5;
#5 in=4'd1;
#5 in=4'd5;
#5 in=4'd4;
#5 in=5'd5;
#5 in=4'd1;
#5 in=4'd5;
#5 in=4'd4;
#5 in=5'd5;
#50 $finish;
end
always #5 clk=~clk;
counter u0(.*);
endmodule
Upvotes: 1
Views: 12379
Reputation: 792
There are two issues that need to be fixed.
1) Coincidently in=5 is set only during the neg edge of clock. This is because clk cycle is #10 and the tb code changes "in" value every #5 .As the counter checks the value of in at posedge it misses the in = 5. The in time period needs to #10 or the TB can wait for a posedge of clk before setting signal "in".
2) the start needs to be set for the counter to reset , else the value of count = x (unknown) and count+1 => x+1 which equals x. Hence the counter will not increment and continue to remain x throughout.
Updated tb is below .
module tb();
reg [3:0] in;
reg clk,start;
wire [7:0] count;
reg overflow = 1'b0;
initial begin
$display ("time\t clk start in count overflow");
$monitor ("%g\t %b %b %b %b", $time, clk, start, in, count, overflow);
clk=0;
in=0;
start=0;
// overflow=0;
// count=0;
#10 start = 1'b1; // reset counter
#10 start = 1'b0;
#10 in=4'd1;
#10 in=4'd5;
#10 in=4'd4;
#10 in=5'd5;
#10 in=4'd1;
#10 in=4'd5;
#10 in=4'd4;
#10 in=5'd5;
#10 in=4'd1;
#10 in=4'd5;
#10 in=4'd4;
#10 in=5'd5;
#10 in=4'd1;
#10 in=4'd5;
#10 in=4'd4;
#10 in=5'd5;
#50 $finish;
end
always #5 clk=~clk;
counter u0(.*);
initial // Dump waveform for debug
$dumpvars;
endmodule
You can dump waveform using $dumpvars command to debug.
Alternative code ( using posedge event to drive data in test bench )
// Code your testbench here
// or browse Examples
module tb();
reg [3:0] in;
reg clk,start;
wire [7:0] count;
reg overflow = 1'b0;
initial begin
$display ("time\t clk start in count overflow");
$monitor ("%g\t %b %b %b %b", $time, clk, start, in, count, overflow);
clk=0;
in=0;
start=0;
// overflow=0;
// count=0;
@(posedge clk ) start = 1'b1;// reset counter
@(posedge clk ) start = 1'b0;
@(posedge clk ) in=4'd1;
@(posedge clk ) in=4'd5;
@(posedge clk ) in=4'd4;
@(posedge clk ) in=5'd5;
@(posedge clk ) in=4'd1;
@(posedge clk ) in=4'd5;
@(posedge clk ) in=4'd4;
@(posedge clk ) in=5'd5;
@(posedge clk ) in=4'd1;
@(posedge clk ) in=4'd5;
@(posedge clk ) in=4'd4;
@(posedge clk ) in=5'd5;
@(posedge clk ) in=4'd1;
@(posedge clk ) in=4'd5;
@(posedge clk ) in=4'd4;
@(posedge clk ) in=5'd5;
#50 $finish;
end
always #5 clk=~clk;
counter u0(.*);
initial
$dumpvars;
endmodule
Upvotes: 1