Reputation: 11
Can you tell me why this simple verilog program doesn't print 4 as I want?
primitive confrontatore(output z, input x, input y);
table
0 0 : 1;
0 1 : 0;
1 0 : 0;
1 1 : 1;
endtable
endprimitive
comparatore :
module comparatore (r, x, y);
output wire r;
input wire [21:0]x;
input wire [21:0]y;
wire [21:0]z;
genvar i;
generate
for(i=0; i<22; i=i+1)
begin
confrontatore t(z[i],x[i],y[i]);
end
endgenerate
assign r = & z;
endmodule
commutatore :
module commutatore (uscita_commutatore, alpha);
output wire [2:0]uscita_commutatore;
input wire alpha;
reg [2:0]temp;
initial
begin
case (alpha)
1'b0 : assign temp = 3;
1'b1 : assign temp = 4;
endcase
end
assign uscita_commutatore = temp;
endmodule
prova:
module prova();
reg [21:0]in1;
reg [21:0]in2;
wire [2:0]uscita;
wire uscita_comparatore;
comparatore c(uscita_comparatore, in1, in2);
commutatore C(uscita, uscita_comparatore);
initial
begin
in1 = 14;
$dumpfile("prova.vcd");
$dumpvars;
$monitor("\n in1 %d in2 %d -> uscita %d uscita_comparatore %d \n", in1, in2, uscita, uscita_comparatore);
#25 in2 = 14;
#100 $finish;
end
endmodule
Upvotes: 0
Views: 336
Reputation: 19122
The issue is in commutatore
. You are using initial
, which means the procedural block is only executed at time 0. At time 0, the input alpha
is 1'bx
, meaning temp is not assigned to anything. Instead of initial
, use always @*
which will execute the procedural block every time alpha
changes.
Generally you should not assign statements in procedural blocks. It is legal Verilog however it is often the source of design bugs and synthesis support is limited.
always @*
begin
case (alpha)
1'b0 : temp = 3;
1'b1 : temp = 4;
default: temp = 3'bx; // <-- optional : to catch known to unknown transitions
endcase
end
Upvotes: 1
Reputation: 5108
The reason you are not getting 4 as you expect for an output is because your commutatore
uses an initial
block with assign
statements in it when you wanted an always @*
block to perform the combinational logic to get temp
. initial
blocks only fire once at the beginning of a simulation, while you want continuous assignment to act as combinational logic. Also, the assign
statements in the block are not needed, they only make the simulation behave improperly for your purposes (typically, you will never need to use assign
inside another block (initial
,always
,etc) as this has another meaning than simply set x to y.
For example, you really want something like this:
always @(*) begin
case (alpha)
1'b0: temp = 3'd3;
1'b1: temp = 3'd4;
endcase
end
Also, Verilog already has a build XNOR primative so your confrontatore
is not needed, you can use xnor
instead.
Upvotes: 0