I want to test a simple Verilog module that outputs 1
if the minterms 2
, 3
, 5
or 7
are found in a 3-variable input.
The module looks like this:
module modified_prime_detector(
input [2:0] in,
input clk,
output reg out
);
always @ (posedge clk)
begin
out <= (~in[2] && in[1] && ~in[0]) || (~in[2] && in[1] && in[0]) || (in[2] && ~in[1] && in[0]) || (in[2] && in[1] && in[0]);
end
endmodule
I have also developed a testbench in order to run my simulation using EDA Playground:
module modified_prime_detector_tb();
reg [2:0] in;
reg clk;
wire out;
modified_prime_detector uut (
.clk(clk),
.in(in),
.out(out)
);
always #5 clk = ~clk;
always @(posedge clk) begin
if (in == 3'b111)
in <= 3'b000;
else
in <= in + 1'b1;
end
always @ (posedge clk) begin
$display("Time: %t, in: %b, out: %b", $time, in, out);
end
initial begin
$dumpfile("dump.vcd");
$dumpvars(1, modified_prime_detector_tb);
clk = 0;
in = 0;
#5;
#100;
$finish;
end
endmodule
Basically, I'm increasing the 3-bit value of in
on each clock cycle. I then expect to see the out
's value set to 1
for the values: 010
, 011
, 101
and 111
.
However, I see that the module outputs 1
for these values: 011
, 100
, 110
and 000
? I'm not sure why it works like that. I think it might have to do with the simulation, because this is how the waveforms look like:
It seems that the output is "right-shifted" by one, at it also seems like my module gives no output for the input 000
. Unfortunately, I'm not sure why this happens and how to further investigate this issue.
What might be the problem?
There is no issue in the output, it is correct but your intuition is wrong. In your module you are using the non-blocking statement <=
and that is the standard behavior of the non-blocking statement that the output occurs after one clock cycle. This is the same reason as to why you cannot see output at 000
condition because output will arrive one cycle later.
If you want your output to occur upon arrival of input then you should use the combinational logic by replacing the posedge clk
in the sensitivity list with in
and use =
.
always @ (in) begin
out = (~in[2] && in[1] && ~in[0]) || (~in[2] && in[1] && in[0]) || (in[2] && ~in[1] && in[0]) || (in[2] && in[1] && in[0]);
end
Now if you do this, the your logic is no longer depends on the clock. Secondly I have noticed that your input is 3-bit and in the test bench you are checking if in == 3'b111
and then you reset it to in <= 3'b000
, but there is no need to check this. Because if you add 1
in 3'b111, it will automatically become '0'. So you can simply write this in your test bench:
always @(posedge clk) begin
in <= in + 1'b1;
end