How to connect a vip to a dut

So we have a vip that has built to run what we call a “connectivity test”. We have a mixed mode simulations with (A/D and D/A) and various power domains (no UPF flow in place). So in order to verify that all blocks are connected the way it’s supposed to be, we built an agent that forces one one side and samples on the other side, plain simple.

Now the problem comes when we want to make it generic and abstract away the connectivity to the dut. We decided that essentially we will have an array of “signals” to be injected and to be sampled, which are connected through interfaces to very basic BFMs (just wires to a hierarchical path). Since we do not want to have vip include any knowledge of the DUT we built macros to “register” the paths to be checked:



// BFM file, straight forward connectivity between interface and DUT

`include "a2d_targets.svh"

`define A2D_FSIG(SIG_NUM) \                                                                                                                                                                                                                                                 
    `ifdef A2D_FSIG_``SIG_NUM \                                                                                                                                                                                                                                             
        always @(*) begin: force_A2D_FSIG_``SIG_NUM \                                                                                                                                                                                                                       
            release `A2D_FSIG_``SIG_NUM; \                                                                                                                                                                                                                                  
            if (a2d_force_if_0.sig_forced[SIG_NUM]) begin \                                                                                                                                                                                                                 
                force `A2D_FSIG_``SIG_NUM = a2d_force_if_0.val_forced[SIG_NUM]; \                                                                                                                                                                                           
            end \                                                                                                                                                                                                                                                           
            a2d_force_if_0.val_read[SIG_NUM] = `A2D_FSIG_``SIG_NUM; \                                                                                                                                                                                                       
        end \                                                                                                                                                                                                                                                               
    `endif                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                            
`define A2D_RSIG(SIG_NUM) \                                                                                                                                                                                                                                                 
    `ifdef A2D_RSIG_``SIG_NUM \                                                                                                                                                                                                                                             
        assign a2d_read_if_0.val_read[SIG_NUM] = `A2D_RSIG_``SIG_NUM; \                                                                                                                                                                                                     
    `endif                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                            
`define A2D_SIG(SIG_NUM) \                                                                                                                                                                                                                                                  
    `A2D_FSIG(SIG_NUM) \                                                                                                                                                                                                                                                    
    `A2D_RSIG(SIG_NUM) \                                                                                                                                                                                                                                                    


so the A2D_RSIG will read the value while the A2D_FSIG will force it. We simply include a project specific file when compiling, that provides the paths in this way:



// "a2d_targets.svh" defines paths to be checked

    `define A2D_PATH(ID, SRC, DST) \                                                                                                                                                                                                                                   
        `define A2D_FSIG_``ID SRC \                                                                                                                                                                                                                                        
        `define A2D_RSIG_``ID DST \                                                                                                                                                                                                                                        
        `define A2D_NUMSIG (ID+1)                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                           
    `A2D_PATH(0 , `SUPPLYSYSTEM.OV_VDDA               , `DUT_DIG.ms_sup_ov_vdda)                                                                                                                                                                                           
    `A2D_PATH(1 , `SUPPLYSYSTEM.UV_VDDA               , `DUT_DIG.ms_sup_uv_vdda)                                                                                                                                                                                           
    `A2D_PATH(2 , `SUPPLYSYSTEM.OV_VS                 , `DUT_DIG.ms_sup_ov_vs)
    // ... etc                                                                                                                                                                                            
 

This mechanism works, albeit a bit clunky, but it does the job… to some extent. In some cases one single source ends up in two destinations and this is where things get messier. Unfortunately, since we cannot generate the list of paths differently, we will have, for the same source two A2D_FSIG_``ID which then will end up being released and forced by two different always(*) statements, ending up in an infinite loop.

I have the impression that are doing this wrongly and I believe there must be a simpler way to do this. Additionally I have the impression that forcing a slice in an array is not very well supported by tool vendors (Cadence here), so we have this extra problem to deal with.

A simple work-around is instead of creating the same source for two destinations, we can “daisy-chain” the connectivity and have the destination of one source being the source of the second destination… even though that is so unreadable.

We are open to radical changes and are pretty much interested in any reference.

P.S.: this connectivity test is a 0-level test that doesn’t check any functionality, just connectivity over hundreds of connections. We prefer to check low level connectivity before addressing functionality.

P.S.: I know that normally we would use binding to get the interfaces connected to the DUT, but unfortunately that wouldn’t work with our Verilog-AMS models for the analog domain.