I am writing a simple Control Unit in verilog. It goes something like this.
module controlUnit(
output reg wreg,
input wire [5:0] op, func
);
// wreg sub-handles. Beware: wreg is 0 if any of these s high
wire isBranch = (op[5:3] == 3'b0) & (|op[2:0]);
wire isStrWrd = op == 6'b101011;
wire isJumpReg = (op == 6'd0) & (func == 6'b001000);
// wreg handle
always @(*) begin
if(isBranch | isStrWrd | isJumpReg)
wreg <= op == 6'b000011;
else
wreg <= 1'b1;
end
endmodule
module testbench;
integer i;
wire out;
reg [11:0] in;
controlUnit CU0(
.wreg(out),
.op(in[11:6]), .func(in[5:0])
);
initial begin
$dumpfile("test.vcd");
$dumpvars(0, testbench);
#4 in = 0;
for(i=0; i<1024; i=i+1) begin
#1 in = i;
end
#1 in = 10'hXX; // Garbage input here
#1000;
end
endmodule
However in simulation, the wreg signal is a solid logical HIGH when the input becomes garbage. I have seen this behaviour with iverilog-10/GTKwave and Vivado 2019.1. Following is the waveform:
So, why?
You only set 10 of your 12 input bits to
x
; the 2 MSBs are 0. You should set all of your input signals tox
. This is probably unrelated to your problem, but I think it is what you intended. Change:to:
When the signals in
if(isBranch | isStrWrd | isJumpReg)
arex
, theif
is false, and theelse
is executed, which setswreg
to 1 (wreg <= 1'b1
), notx
. This answers the question of why the Verilog simulator assignswreg
to 1 when all the inputs arex
. This is the way the simulator is designed to work.Using the ternary operator equivalent code will set
wreg
tox
when the inputs arex
:Note that using a blocking assignment (
=
) is recommended for combinational logic.