How can I assign one interface to another interface without manually connecting all signals?

Hello,

I have a situation which I believe is very common. I have a module with an SV Interface. The interface is a typical AXI interface.

Depending on one of the module’s parameters I want to instantiate an IP (an AXI clock converter) which has two of those interfaces, one Slave port and one Master port. In that case the Interface port of the module is connected to the the slave port of the clock converter and the Master side is connected to a newly create interface (create inside my module itself).

However, when the HDL parameters indicate so I don’t wanna instantiate the clock converter, instead what I would like to do is connect the port interface to my internal interface, since no CDC is required, I want the internal interface to be a direct assignment of the input interface…

I tried with a simple assign but of course I got an error. Is there a clean way of doing this (hopefully a one-liner)? or do I have to go signal by signal to do this?

Thanks.

In reply to arquer:

Sorry, there is no way to tie two interfaces together.

In reply to dave_59:

Well… this is a pitty… seems like it would be a very usefull thing to do…

Just another quick question, are interfaces capable of having their internal signals initialized upon instantiation?? Inside my interface I have a bunch of logics, if I give them an initial valud then I can not assign them in clocked blocks, if I don’t then… well… I don’t have init values then.
If I give them init values and then I want to assign them with an “assign” I can’t… I have to use an “always_comb”, If I don’t and then I want to have one I am forced to use an auxiliary register with an init value and assign that register to the interface signal with an assign… The ideal thing would be to be able to choose upon instantiation… is there any way of doing this?

Thanks.

In reply to arquer:

SV LRM: “an interface can also contain processes (i.e., initial or always procedures) and continuous assignments, which are useful for system-level modeling and testbench applications.”

Please be clear about the signal in your interface is declared as “variable” or “net”.

A net can be written by one or more continuous assignments, by primitive outputs, or through module ports. The resultant value of multiple drivers is determined by the resolution function of the net type. A net cannot be procedurally assigned.

Variables can be written by one or more procedural statements, including procedural continuous assignments. The last write determines the value. Alternatively, variables can be written by one continuous assignment or one port.

You can have a continuous assignment to a variable. But when you do so,you can only have one continuous assignment and no other procedural assignments at the same time.

In reply to dave_59:

In reply to arquer:
Sorry, there is no way to tie two interfaces together.

For a module with an input interface port, can the interface wires be retimed
using a single assignment clocked process like this:

always_ff @(posedge clk)
  my_interface_port_q <= my_intrface_port;

Based on this thread, my guess is no.
Based on that if there is an interface port that needs to be retimed, all fields need to be broken out one at time like this:

always_ff @(posedge clk)
  begin
  first_sig_q <= my_inteface_port.first_sig;
  second_sig_q <= my_interface_port.second_sig;
  // ....
  end

Does that make sense that the signals have to be broken out to be retimed, or am I missing some easy way to retime all the signals in an interface?

A packed struct can be retimed, maybe this indicates a case where a packed struct port would be preferred over an interface.

In reply to mike_mentor:

Yes you can make procedural or continuous assignments from the signals inside one interface to another using hierarchical references. You would have to know the flow of data to know which direction to make the assignments.

If you were to use structures you would have to isolate the structures by direction. i.e. one structure for inputs and another for outputs.

In reply to dave_59:

ok.
Can you retime an interface input port like this?..

always_ff @(posedge clk)
  my_interface_port_q <= my_intrface_port;

The need is to simply retime all the signals that come into a module.
A best practice for timing closure.

In reply to mike_mentor:

Sorry, there is no way to assign one interface to another. If all the signals are going in the same direction, you might as well use a struct.

In reply to dave_59:

I still think an “interface alias” as I was brainstorming over here has potential.

https://verificationacademy.com/forums/systemverilog/multiple-interface-connections-multiple-dut

As this thread (again) shows, there’s certainly a need for this sort of construct in the SystemVerilog language.

Any chance something like this could be considered within the SystemVerilog working group?

In reply to Mark Curry:

We already have constructs in SystemVerilog that can handle these kinds of of requirements. They are called classes. Just by passing a handle, we can connect bundles of variables together. We know they can be synthesized as SystemC has shown us, but we’re still waiting for support in SystemVerilog. We’ve been waiting for synthesis and place&route tools to handle arrays of wires for 30 years.

In reply to dave_59:

Dave could you expand on how that requirement could be accomplished with classes?

In reply to miguel95:

class A;
  bit [3:0] x,y;
endclass

module top;
  bit clk;
  A w1,w2;
  
  classconnect cc(.clk,.in(w1),.out(w2));
  
  initial repeat(100) #5 clk=!clk;
  
  always @(negedge clk) begin
    w1 = new;
    assert (randomize(w1.x,w1.y));
    $display("%in %p out %p",w1,w2);
  end
endmodule

module classconnect(input bit clk, A in, output A out);
  always@(posedge clk)
    out <= in;
endmodule