0

I have a fundamental understanding problem with System Verilog. I am working on a processor design, where some bus systems should be shared between several processing units (System Verilog modules). With an arbiter only one module at a time should be active, driving the bus, while all other are high impedance.

I got rid of the multidriven nets warnings in Vivado during synthesis and there are not anymore any bus conflicts, but the simulator gives a warning, that the bus signals 'might' be multidriven. I made a tiny example code and I would expect to get for 'data' '11', when 'select' is '10'?

While simulation stops at all in Vivado, it works with Cadence simulator, but with wrong results - screenshot simulation

testbench.sv

`timescale 1ns / 1ps
module testbench_top();

logic [1:0] select;
logic [1:0] data;

top top_inst(.*);

initial
begin
  select = 0;
  #2 select = 1;
  #2 select = 2;
  #2 select = 0;;
end
  initial
    begin
      $monitor("t=%3d s=%b,d=%b\n",$time,select,data);
    end
endmodule

design.sv

`timescale 1ns / 1ps
module top
(
 input logic [1:0] select,
 output logic [1:0] data 
);

driver_1 driver_1_inst(.*);
driver_2 driver_2_inst(.*);

endmodule



module driver_1
(
 input logic [1:0] select,
 output logic [1:0] data 
);
always_comb
begin
  if (select == 2'b10)
        data = 2'b11;
    else
        data = 'z;
end
endmodule



module driver_2
(
 input logic [1:0] select,
 output logic [1:0] data 
);
always_comb
begin
  if (select == 2'b01)
        data = 2'b01;
    else
        data = 'z;
end
endmodule
ES_major
  • 3
  • 1

1 Answers1

0

I'm assuming you expect the value of data signal the top module, which is driven by the two outputs of your driver modules, to be resolved (e.g. when one drive 'z, the other gets the bus.

This will happen if you declare the top.data signal as output wire logic [1:0] data.

Section 23.2.2.3 Rules for determining port kind, data type, and direction of the IEEE 1800-2012 standard states that

For output ports, the default port kind depends on how the data type is specified: — If the data type is omitted or declared with the implicit_data_type syntax, the port kind shall default to a net of default net type. — If the data type is declared with the explicit data_type syntax, the port kind shall default to variable.

In your case, the second clause applies, since you declared data as output logic[1:0], meaning that it was interpreted as a variable and not a net. Multiple values on variables aren't resolved (and in some tools are also illegal).

Tudor Timi
  • 7,453
  • 1
  • 24
  • 53
  • Thanks for the great answer! Would there be a solution, when data is assigned via a non-blocking assignment (each driver has its separate always_ff block and the non-active sets its value to 'z again), because then a wire can't be used or? – ES_major Aug 21 '18 at 20:08
  • @ES_major I think wires can only be driven by `assign` statements, so it won't be possible. – Tudor Timi Aug 22 '18 at 13:34