Chapter 12: Virtual Platform Construction

Configurable Platforms (CCI)

Integrating IEEE 1666.1 CCI parameters into a complete Virtual Platform environment.

Configurable Platforms (CCI)

A truly reusable Virtual Platform must be highly configurable. A hardware vendor might sell an SoC with 256KB of RAM, while another SKU features 512KB. Rather than maintaining multiple C++ codebases, the Virtual Platform should expose parameters via the IEEE 1666.1 Configuration, Control, and Inspection (CCI) standard.

Integrating CCI in the Virtual Platform

In our completed Virtual Platform, the Router's memory map bounds and the RAM's size should be driven by cci_param. A top-level JSON or Python script can inject these parameters into the CCI Broker before elaboration, dynamically constructing the SoC.

Complete VP Configuration Example

This sc_main demonstrates injecting a custom RAM size into the Broker and observing the VP adapting to it during elaboration.

#include <systemc>
#include <cci_configuration>
 
// 1. Configurable Target (RAM)
class ConfigurableRAM : public sc_core::sc_module {
public:
    // CCI Parameter for Memory Size
    cci::cci_param<int> mem_size;
    unsigned char* memory;
 
    SC_HAS_PROCESS(ConfigurableRAM);
    
    ConfigurableRAM(sc_core::sc_module_name name) 
        : sc_core::sc_module(name), 
          // Default size is 1024 bytes if not overridden by the Broker
          mem_size("mem_size", 1024, "Size of the RAM in bytes") 
    {
        // Lock the parameter so it cannot change after elaboration
        mem_size.lock();
        
        // Allocate memory based on the CCI parameter!
        int size = mem_size.get_value();
        memory = new unsigned char[size];
        
        std::cout << "[ConfigurableRAM] Elaboration: RAM size configured to " 
                  << size << " bytes." << std::endl;
    }
 
    ~ConfigurableRAM() {
        delete[] memory;
    }
};
 
// 2. VP Top Level
SC_MODULE(VirtualPlatform) {
    ConfigurableRAM ram;
    
    SC_CTOR(VirtualPlatform) : ram("ram") {}
};
 
int sc_main(int argc, char* argv[]) {
    // 1. Acquire the Global CCI Broker BEFORE instantiating the VP
    cci::cci_broker_handle broker = cci::cci_get_broker();
 
    // 2. Set the Preset Configurations
    // In an industrial setting, these values are parsed from a JSON file.
    // The hierarchical name must perfectly match the elaboration tree.
    std::cout << "[System] Injecting custom CCI parameters..." << std::endl;
    broker.set_initial_preset_value("vp_top.ram.mem_size", cci::cci_value(4096)); // Override default 1024
 
    // 3. Elaborate the Virtual Platform
    // The ConfigurableRAM constructor will now fetch '4096' from the broker.
    VirtualPlatform vp_top("vp_top");
 
    // 4. Start Simulation
    sc_core::sc_start();
 
    return 0;
}

By conforming to the CCI standard, your IP blocks become plug-and-play components compatible with enterprise Virtual Platform environments like Synopsys Virtualizer or Cadence Virtual System Platform (VSP).

Comments and Corrections