210 likes | 489 Views
One Compile to Rule them All: An elegant solution for OVM/UVM Testbench Topologies. and Steve Chappell Solutions Architect. by Galen Blake SMTS. System Verilog Topology. Hey, you got software in my hardware. No, you got hardware in my software.
E N D
One Compile to Rule them All:An elegant solution for OVM/UVM Testbench Topologies and Steve Chappell Solutions Architect by Galen Blake SMTS
System Verilog Topology • Hey, you got software in my hardware. • No, you got hardware in my software. • How are we going to mix all this stuff together and configure the topology? • If you never saw this advertisement, visithttp://www.youtube.com/watch?v=DJLDF6qZUX0
SystemVerilog Topology • Design • HW • Modules • Static • Fixed at Elab time • Testbench • SW • Classes • Dynamic • Created at Run time Software (HVL) Hardware (HDL)
SOC Topology Challenge • Traditional SOC Design: • Many peripherals. • Not enough pins. • Users must choose some combination of peripherals to keep. • Each combination is effectively a new DUT. • Each new DUT needs a new testbench. MPU Periph Periph Periph Periph Periph Periph Switch Fabric Periph Periph Periph Periph Periph Periph Periph Periph Periph Periph Memory Controller Periph Periph
OOP (SV) Topology Challenge • Polymorphic VIP’s create more topology options. • A polymorphic VIP could • Be held inactive • Monitor an internal bus • Drive an internal bus • The desired form of a polymorphic VIP must be selected. • Other topology controls are needed for driving an internal bus. MPU Driver Driver Switch Fabric Driver Driver Monitor or Driver Memory Controller
SOC on FPGA Topology Challenge • 1000s of nets added to 100s of pins. • Many more virtual pins connecting the SOC to the FPGA fabric. • Many more possible peripheral combinations. • Many more new DUTs and testbench topologies. Memory I-F CORE SOC Memory Controller
Testbench AcelerationChallenge • Testbench acceleration requires us to split up our OVM/UVM agents. • Time consuming tasks must be located in HDL context. • So we place our drivers and monitors into SV Interfaces. HVL HDL driver sequencer monitor analysis • Editorial: • SystemVerilog should not allow us to “mix our metaphors.” • We should not be putting hardware (HDL-TCTs) in our software (HVL-Classes). • Perhaps a topic for a future paper…
Invasion of SW Test Writers • Need to simplify view of HW and HW flows • One shared known-good pre-compiled database is crucial
Testbench Topology Development • Normal topology development strategy. • It evolves slowly. • Many different developers and their ideas all get mixed together. • A single cohesive strategy is often lacking.
Approach #1: “Many netlists” Pros: • Easy. Cons: • How many do we need? • Maintenance. • Copy-paste errors. • Re-use? module hdl_top_pci_tests(); wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); `include “dut_inst.svh” endmodule module hdl_top_nic_tests(); regtx = 0; wire rx; `include “dut_inst.svh” endmodule. module hdl_top_hat_tests(); wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); `include “dut_inst.svh” endmodule module hdl_top_nic_tests(); regtx = 0; wire rx; `include “dut_inst.svh” endmodule. module hdl_top_ddr_tests(); wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); `include “dut_inst.svh” endmodule module hdl_top_nic_tests(); regtx = 0; wire rx; `include “dut_inst.svh” endmodule. module hdl_top_foo_tests(); wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); `include “dut_inst.svh” endmodule module hdl_top_nic_tests(); regtx = 0; wire rx; `include “dut_inst.svh” endmodule. module hdl_top_uart_tests(); wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); `include “dut_inst.svh” endmodule module hdl_top_nic_tests(); regtx = 0; wire rx; `include “dut_inst.svh” endmodule. module hdl_top_usb_tests(); wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); `include “dut_inst.svh” endmodule module hdl_top_nic_tests(); regtx = 0; wire rx; `include “dut_inst.svh” endmodule. module hdl_top_emac_tests(); wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); `include “dut_inst.svh” endmodule module hdl_top_nic_tests(); regtx = 0; wire rx; `include “dut_inst.svh” endmodule.
Approach #2: Macros (`ifdefs) Pros: • Easy. Cons: • Expanded pre-compile • Scope? (Name collisions) • Debug • Nested readability module hdl_top_emac_tests(); wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); `include “dut_inst.svh” endmodule module hdl_top_nic_tests(); regtx = 0; wire rx; `include “dut_inst.svh” endmodule. module hdl_top (); `ifdef USE_EMAC0 wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); `else regtx = 0; wire rx; `endif dutdut(….); endmodule class my_env extends uvm_env; function void build_phase( uvm_phase phase); `ifdef USE_EMAC0 emac0_agent = new(…); // or create from factory `endif ….
Approach #3: Parameters Pros: • Set at elaboration time • Well-defined scope Cons: • Type specializations • UVM factory considerations HDL module hdl_top (); `ifdef USE_EMAC0 wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); `else regtx = 0; wire rx; `endif dutdut(….); endmodule class my_env extends uvm_env; function void build_phase( uvm_phase phase); `ifdef USE_EMAC0 emac0_agent = new(…); // or create from factory `endif …. module hdl_top (); parameter USE_EMAC0 = 1; if (USE_EMAC0 == 1) begin wire tx,rx,…; emac_vip_if emac_vip_if0(.tx(tx),.rx(rx),…); end else begin regtx = 0; wire rx; end dutdut(….); endmodule class my_env #(int USE_EMAC0=1) extends uvm_env; `uvm_component_param_utils(my_env); function void build_phase( uvm_phase phase); if (USE_EMAC0) emac0_agent = new(…); // or create from factory …. HVL
Approach #4: +plusargs Pros: • Runtime • UVM cmdline processor • Register encapsulation Cons: • Too late for HDL interface config_regs (); reg [`MAX_CFGS-1:0] tb_cfg; initial begin tb_cfg = `DEFAULT_TB_CFG; if ( $value$plusargs("USE_EMAC0=%d", use_e0 ) ) tb_cfg[`USE_EMAC0] = use_e0; end endinterface
The Elegant Topology Solution. • Any solution for dealing with the configuring the topology of the testbench must consider both contexts: • HDL (module) • HVL (class). • HVL topology must match HDL topology. • One set of controls is best. • Parameters are good in HDL. • But how do we configure HVL?
Parameter Transport • Parameters used to configure HDL are transported to HVL. • Parameters are tranported using a SV Interface to any HVL class object. • Hundreds of topology parameters are available without the burden of putting parameters in a class. Parameters Software (HVL) Hardware (HDL)
HDL Example FROM THE HDL CONTEXT: . . . parameter USE_L3_ACP_AXI_VIP = 0; . . . // This interface is used to store and distribute parameter settings // for which TB components and parameters to use. config_tb_ifcfg_tb(); assign cfg_tb.use_l3_acp_axi_vip = USE_L3_ACP_AXI_VIP; . . . //// AXI Tranactor (replaces peripheral connections for testing). generateif (USE_L3_ACP_AXI_VIP) begin : inst_acp_axi_vip_mst axi_monitor_module #( .ADDR_WIDTH (`ACP_ADDR_WIDTH), .RDATA_WIDTH (`ACP_RDATA_WIDTH), .WDATA_WIDTH (`ACP_WDATA_WIDTH), .ID_WIDTH (`ACP_ID_WIDTH), .LEN_WIDTH (4), .AXI_ID ( "acp_axi_monitor" ) ) acp_axi_monitor (.mif(acp_axi_vip_mst)); end endgenerate
HVL Example FROM THE HVL CONTEXT: . . . virtualconfig_tb_ifcfg_tb; . . . if ( cfg_tb.use_l3_acp_axi_vip) begin ovm_report_info("build: ", "ACP_AXI_VIP agent will be enabled ..."); l3_acp_axi_a = axi_agent #(ACP_axi_p)::type_id::create("l3_acp_axi_a", this); l3_acp_axi_a.set_config_id("master_acp", axi_pkg::MASTER_MONITOR); l3_acp_axi_a.register_agent(TBMB_PERIF_ACP_ID); end . . .
The Code (from paper) module hdl_top (); parameter USE_L3_ACP_AXI_VIP = 0; … generate if (USE_L3_ACP_AXI_VIP) begin : i_acp_axi_vipaxi_monitor_vip #( .ADDR_WIDTH (`ACP_ADDR_WIDTH), .RDATA_WIDTH (`ACP_RDATA_WIDTH), … .AXI_ID ( "acp_axi_monitor" ) ) acp_axi_monitor (.mif(acp_axi_vip_mst)); end endgenerate … endmodule class my_env extends uvm_env; `uvm_component_utils(my_env); virtual config_tb_ifcfg_tb; function void build_phase( uvm_phase phase); cfg_tb = uvm_config_db #( virtual config_tb_if )::get(.. ); if ( cfg_tb.use_l3_acp_axi_vip) begin l3_acp_axi_a = axi_agent #(ACP_axi_p)::type_id::create("l3_acp_axi_a", this); end . . . interface config_tb_if(); bit use_l3_acp_axi_vip; … endinterface module hdl_top (); parameter USE_L3_ACP_AXI_VIP = 0; … config_tb_ifcfg_tb(); assign cfg_tb.use_l3_acp_axi_vip = USE_L3_ACP_AXI_VIP; initial uvm_config_db #( virtual config_tb_if )::set( …); … endmodule
Conclusion • Sprawling complexity and inconsistent hybrid solutions for defining the testbench topology create serious maintenance issues making it difficult to develop or enhance tests for HVL and complex SOC designs. • Consolidating topology definition of both HDL net-lists and HVL object hierarchies to a single point source simplifies maintenance while preserving significant flexibility with a very large variety of topologies available.