简体   繁体   中英

Verilog code does not print desired output

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

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  

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM