SV bind in UVM where a parameter is used



 module flop
 #(parameter width = 1)
 (input wire [width-1:0] d,
 input wire clk,
 input wire rst_n,
 output wire [width-1:0] q
 );

 bind meta_flop meta_flop_metastability_injector_if i0 (
 .meta_ff_d (d),
 .dst_clk (clk),
 .dst_rst_n (rst_n),
 .meta_ff_q (q)
 ); 

 interface meta_flop_metastability_injector_if (
 input logic meta_ff_d, 
 input logic dst_clk,
 input logic dst_rst_n,
 output logic meta_ff_q
 );


In the code shown above, how do I pass the parameter width to the interface and bind declarations? Thank You!

When you use bind, all the identifiers you reference in the instantiation are from the target’s perspective, that includes the parameter override.


module flop
 #(parameter width = 1)
 (input wire [width-1:0] d,
 input wire clk,
 input wire rst_n,
 output wire [width-1:0] q
 );
endmodule : flop

module top;

   typedef logic [7:0]  uint8_t;
   typedef logic [15:0] uint16_t;
   logic 		clk, rst_n;
   uint8_t              d8,q8;
   uint16_t             d16, q16;
   
   flop #(8)  u8(.clk, .rst_n, .d(d8), .q(q8));
   flop #(16) u16(.clk, .rst_n, .d(d16), .q(q16));
   bind flop 
     meta_flop_metastability_injector_if #(.WIDTH(width)) i0 (
						      .meta_ff_d (d),
						      .dst_clk (clk),
						      .dst_rst_n (rst_n),
						      .meta_ff_q (q)
						      ); 
endmodule : top
		 
interface meta_flop_metastability_injector_if 
  #(parameter WIDTH = 1)(
			 input logic [WIDTH-1:0]  meta_ff_d, 
			 input logic 		  dst_clk,
			 input logic 		  dst_rst_n,
			 output logic [WIDTH-1:0] meta_ff_q
			 );
   initial $display("hello from %m WIDTH: %0d",WIDTH);

endinterface : meta_flop_metastability_injector_if

In reply to dave_59:

Thank You Dave!
I wish you a Merry Christmas and a Happy New Year!

In reply to dave_59:

When you use bind, all the identifiers you reference in the instantiation are from the target’s perspective, that includes the parameter override.


module flop
#(parameter width = 1)
(input wire [width-1:0] d,
input wire clk,
input wire rst_n,
output wire [width-1:0] q
);
endmodule : flop
module top;
typedef logic [7:0]  uint8_t;
typedef logic [15:0] uint16_t;
logic 		clk, rst_n;
uint8_t              d8,q8;
uint16_t             d16, q16;
flop #(8)  u8(.clk, .rst_n, .d(d8), .q(q8));
flop #(16) u16(.clk, .rst_n, .d(d16), .q(q16));
bind flop 
meta_flop_metastability_injector_if #(.WIDTH(width)) i0 (
.meta_ff_d (d),
.dst_clk (clk),
.dst_rst_n (rst_n),
.meta_ff_q (q)
); 
endmodule : top
interface meta_flop_metastability_injector_if 
#(parameter WIDTH = 1)(
input logic [WIDTH-1:0]  meta_ff_d, 
input logic 		  dst_clk,
input logic 		  dst_rst_n,
output logic [WIDTH-1:0] meta_ff_q
);
initial $display("hello from %m WIDTH: %0d",WIDTH);
endinterface : meta_flop_metastability_injector_if

Hey Dave,

I have few questions:

  1. What is the advantage of binding the Interface with the DUT?
  2. If I need to add any interface signal during the simulation, is it possible to do using this bind concept?

I’ll be looking forward to your humble response.

Thank you,

Regards,
Muneeb Ulla Shariff

In reply to muneebullashariff:

The bind construct is useful when inserting functionality inside your DUT without modifying your DUT when not practical. This is typically used by monitors and checkers as part of your testbench.

I don’t understood your second question. The bind construct connects to existing signals in your design. You can add whatever signals you want inside the interface.

In reply to dave_59:

In reply to muneebullashariff:
The bind construct is useful when inserting functionality inside your DUT without modifying your DUT when not practical. This is typically used by monitors and checkers as part of your testbench.
I don’t understood your second question. The bind construct connects to existing signals in your design. You can add whatever signals you want inside the interface.

Hey Dave,

Many thanks for your reply.

Let me explain my question: “If I need to add any interface signal during the simulation, is it possible to do using this bind concept?”

What I mean is, if my interface is as below before simulation starts:

interface int_if ( input logic clk,
input logic data_in,
input logic rst,
output logic data_o
);

endinterface : int_if

Can I add another input signal, say, logic a_in to the interface in any of the uvm_phases, is it possible to do it?

Thank you,

Regards,
Muneeb Ulla Shariff

In reply to muneebullashariff:

No.

In reply to dave_59:

When you use bind, all the identifiers you reference in the instantiation are from the target’s perspective, that includes the parameter override.


module flop
#(parameter width = 1)
(input wire [width-1:0] d,
input wire clk,
input wire rst_n,
output wire [width-1:0] q
);
endmodule : flop
module top;
typedef logic [7:0]  uint8_t;
typedef logic [15:0] uint16_t;
logic 		clk, rst_n;
uint8_t              d8,q8;
uint16_t             d16, q16;
flop #(8)  u8(.clk, .rst_n, .d(d8), .q(q8));
flop #(16) u16(.clk, .rst_n, .d(d16), .q(q16));
bind flop 
meta_flop_metastability_injector_if #(.WIDTH(width)) i0 (
.meta_ff_d (d),
.dst_clk (clk),
.dst_rst_n (rst_n),
.meta_ff_q (q)
); 
endmodule : top
interface meta_flop_metastability_injector_if 
#(parameter WIDTH = 1)(
input logic [WIDTH-1:0]  meta_ff_d, 
input logic 		  dst_clk,
input logic 		  dst_rst_n,
output logic [WIDTH-1:0] meta_ff_q
);
initial $display("hello from %m WIDTH: %0d",WIDTH);
endinterface : meta_flop_metastability_injector_if

Hi Dave,
Bind of the interface does not work when input/output is declared within clocking blocks of interface, like the one below(Thats how my 3rd Party VIP is), How do we then bind?


interface meta_flop_metastability_injector_if 
  #(parameter WIDTH = 1)(
			 logic [WIDTH-1:0]  meta_ff_d, 
			 logic 		  dst_clk,
			 logic 		  dst_rst_n,
			 logic [WIDTH-1:0] meta_ff_q
			 );
   initial $display("hello from %m WIDTH: %0d",WIDTH);
 clocking master_synch @(posedge sys_clk);   
                         input [WIDTH-1:0]  meta_ff_d, 
			 input 		  dst_clk,
			 input 		  dst_rst_n,
			 output [WIDTH-1:0] meta_ff_q
 endclocking
endinterface : meta_flop_metastability_injector_if

In reply to rsguptaji:

Please explain what “does not work” means. I’m guessing you need to declare meta_ff_q as an output wire instead of the default input.

In reply to dave_59:

Created the same code in eda playground for the error I am facing.

Please suggest when input/output is declared within clocking blocks of interface, then how do we then bind?

In reply to rsguptaji:

You need to declare directions for your interface ports. They default to inout, which is incompatible with variables. You could also change the ports to wires.

Clocking block directions are not the same as port directions and do not necessarily match. A clocking block input says to sample a signal, yet that signal could still be an output of the interface.