The Cortex-M0 is one of ARM’s most popular microcontroller cores, known for its small size and low power consumption. It is commonly used in IoT and embedded devices where resources are limited. When developing for Cortex-M0, it is important to stay within the code size limits imposed by the core and target device. Exceeding these limits can lead to errors during compilation, flashing, or runtime crashes.
One challenge developers face is staying under code size restrictions when simulating their Cortex-M0 design in ModelSim Student Edition. ModelSim Student has a code size limit of 4K words for the free license. This is quite restrictive compared to the 32KB – 256KB flash available on most Cortex-M0 MCUs. It is easy to exceed the 4KB limit when compiling a full Cortex-M0 testbench, resulting in compilation errors in ModelSim.
Here are some tips to stay under the 4KB code size limit when simulating Cortex-M0 in ModelSim Student:
Minimize testbench size
The testbench usually takes up significant code space in a Cortex-M0 simulation. Try to remove any unnecessary stimulus generation logic, monitors, and assertions from the testbench. Stub out anything that is not required for basic functional verification of the current module under test.
For example, you may not need a full interrupt controller model if you are just testing the Cortex-M0 core at this stage. Or you may be able to get away with a simple memory model instead of full RAM and flash models.
Stub out peripherals and interfaces
The Cortex-M0 MCU connects to various peripherals over standard interfaces like SPI, I2C, UART, GPIO etc. Often the testbench will include models of these peripherals with the interface logic implemented. You can save code space by replacing peripheral models with simple stubs that just return dummy responses.
For example, an I2C EEPROM model can be replaced with a stub that returns 0xFF on every read. Similarly, stub out external interfaces by adding dummy drivers that sink data without any real protocol implementation.
Use precompiled IP where possible
Some third party IP vendors provide precompiled simulation libraries for their Cortex-M0 peripherals and subsystems. Using these precompiled models removes the need to include the IP RTL source in your simulation, saving code space.
For internally developed IP, consider compiling the simulation models into libraries and linking them at compile time rather than including all the RTL code directly in the testbench.
Compile only files needed for current test
ModelSim .do files allow you to compile selectively – compile only the RTL and testbench files needed for the particular test you are running. This avoids compiling unused modules and can significantly reduce code size.
Use multiple .do files, one for each test. Or use conditional compilation in a single .do file to compile only the needed files.
Use code coverage to identify unused logic
ModelSim’s code coverage feature can identify which parts of the design and testbench are actually exercised during a given simulation. Code that is not covered can potentially be removed or stubbed out to reduce size.
Make sure to have good coverage across multiple targeted test cases before optimizing though, or you may end up stubbing out important logic.
Use Verilog instead of VHDL
For equivalent functionality, Verilog code typically compiles to a smaller code size than VHDL code. Converting large VHDL files to Verilog can help squeezeTestbench code into the 4KB limit.
This doesn’t apply if you have opposite experience – use the HDL that gives you smaller code for your coding style.
Use ModelSim optimizations
ModelSim compiler has various optimizations that can reduce code size:
- -small: Generic optimization for code space
- -memcpr: Compress memory references
- -nolos: Eliminate lossless nets
Review the optimization manual section to identify tradeoffs and optimizations that can work for your design.
Leverage SDF timing annotations
Using SDF timing annotation avoids the need to model detailed gate-level timing in the testbench. SDF loading can result in significantly smaller code vs. explicit delays in testbench.
But be aware this also reduces visibility into timing details during debug.
Prototype in C/C++ before RTL coding
Developing and debugging algorithms in C/C++ allows finding functional issues early without requiring full Verilog/VHDL implementation initially. This avoids some trial-and-error timing/functional debug cycles at RTL.
Once the C model is stable, coding equivalent RTL should be more streamlined – allowing keeping RTL lean and focused only on implementing the verified C functionality.
Leverage available MCU development boards
Real silicon testing can complement simulation, allowing simulation models to be simpler while still achieving test coverage of key scenarios. Look for low cost development boards for your target Cortex-M0 MCU to enable this.
Example boards like STM32 Nucleo provide a cheap way to validate Cortex-M0 software and exercise corner cases difficult to simulate.
Evaluate code size early and often
Check code sizes regularly as the testbench evolves. This allows spotting growth trends and taking corrective actions early, instead of one big modification at the end.
ModelSim provides code size statistics for each compiled unit – monitor these unit sizes to keep growth in check.
Leverage available MCU SDKs/drivers
Many Cortex-M0 MCU vendors provide SDKs with pre-built and pre-verified device drivers and firmware libraries that execute on the Cortex-M0 cores. Using these instead of modeling everything in RTL can save simulation code size.
SDKs with production-qualified and compliance tested code can also improve confidence compared to custom Verilog/VHDL only testbenches.
The 4KB code size limit for ModelSim Student poses challenges for verifying full Cortex-M0 designs. With techniques like minimizing testbench logic, extensive stubbing, selective compilation, and leveraging available SDKs, it is possible to stay under this limit and achieve functional verification of key Cortex-M0 sub-systems.
A combination of smart simulation techniques together with prototyping on available Cortex-M0 development boards can enable comprehensive validation while staying within tool limitations.