Reputation: 45
Below code is of up counter. The code has no errors, but the graph has some errors like the count should be at only posedge but the count is counting even at the negedge of clk.
module countergate (clk,rst,current,next);
input clk,rst;
input [2:0] current;
output reg [2:0] next;
always@(*)
begin
if (rst==1)
{next[2],next[1],next[0]} <= 3'b000;
else
begin
next[2] <= ((~current[2])&(current[1])&(current[0]) | (current[2])&(~current[0]) | (current[2])&(~current[1]));
next[1] <= ((~current[1])&(current[0]) | (current[1])&(~current[0]));
next[0] <= (~current[0]);
end
end
endmodule
TEST BENCH
`include "countergate.v"
module tb1();
reg clk,rst;
reg [2:0] current;
wire [2:0] next;
countergate DUT (clk,rst,current,next);
initial
begin
clk = 1;
forever #1 clk = ~clk;
end
initial
begin
rst = 1;
repeat (2) @(posedge clk);
rst = 0;
end
initial
begin
#4;
{current[2],current[1],current[0]} = 3'b000;
#1;
{current[2],current[1],current[0]} = 3'b001;
#1;
{current[2],current[1],current[0]} = 3'b010;
#1;
{current[2],current[1],current[0]} = 3'b011;
#1;
{current[2],current[1],current[0]} = 3'b100;
#1;
{current[2],current[1],current[0]} = 3'b101;
#1;
{current[2],current[1],current[0]} = 3'b110;
#1;
{current[2],current[1],current[0]} = 3'b111;
#1;
$finish;
end
initial
begin
$monitor("%t :clk = %b , rst = %b , current = %b, next = %b", $time,clk,rst,current,next);
end
endmodule
Upvotes: 1
Views: 746
Reputation: 354
You have to explicitly indicate that you want the always block to be evaluated at posedge of the clock:
always @ (posedge clk)...
If you also want to include an "asynchronous" reset, this means a reset that doesn't care about the clock cycle, you should also include it in the sensitivity list:
always @ (posedge clk, posedge rst)...
As this, the always block would trigger in both cases, in posedge clk or in posedge rst.
Upvotes: 0
Reputation: 62083
As mentioned in a Comment, if you want the count value to only change on the posedge of the clock instead of on both edges of the clock, you should use a sequential always
block. Change:
always@(*)
to:
always @(posedge clk or posedge rst)
You also need to change the testbench since it is driving the current
input on both edges of the clock as well. You should drive it only on the posedge of the clock. Since you are incrementing the input, you can greatly simplify the code using a for
loop. Also, instead of using #
delays, you can align it to the clock as you did with the rst
signal.
integer i;
initial
begin
repeat (2) @(posedge clk);
for (i=0; i<8; i=i+1) begin
current = i;
@(posedge clk);
end
$finish;
end
Upvotes: 0