Code coverage statistics method, electronic device and storage medium

By generating intermediate code and performing distributed compilation during large-scale code verification, the inefficiency of traditional single-node tools is solved, achieving efficient code coverage statistics and scalable verification capabilities.

CN122309373APending Publication Date: 2026-06-30XINHUAZHANG TECH CO LTD
View PDF 0 Cites 0 Cited by

Patent Information

Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
XINHUAZHANG TECH CO LTD
Filing Date
2026-03-31
Publication Date
2026-06-30

AI Technical Summary

Technical Problem

Traditional single-node coverage verification tools are inefficient when dealing with large-scale code and complex verification scenarios. They cannot meet the verification needs of massive prototype designs. Storage and electronic devices cannot be expanded, compilation capabilities are limited, and distributed deployment and parallel compilation cannot be achieved.

Method used

Intermediate code is generated by compiling source code containing coverage statistics code, performing global syntax analysis to build a node tree framework, splitting it into multiple local subtree frameworks and distributing them to multiple distributed computing nodes for local compilation, and aggregating the local coverage node trees to generate code coverage statistics results.

Benefits of technology

It significantly improves the efficiency and speed of code coverage statistics, can efficiently handle large-scale code, meet the needs of complex projects for code testing adequacy assessment, and supports verification of millions of lines of code.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN122309373A_ABST
    Figure CN122309373A_ABST
Patent Text Reader

Abstract

This application provides a code coverage statistics method, electronic device, and storage medium. The method includes: compiling source code to generate intermediate code; the source code includes coverage statistics code; performing global syntax analysis on the intermediate code to generate a node tree framework; the node tree framework includes hierarchical nodes, and the hierarchical nodes are associated with the code structure of the intermediate code; splitting the node tree framework based on the hierarchical nodes to obtain multiple local subtree frameworks; sending the multiple local subtree frameworks to multiple distributed computing nodes for local compilation; receiving the local coverage node tree generated by the local compilation; the local coverage node tree includes coverage nodes, and the coverage nodes include coverage data corresponding to the coverage statistics code in the local subtree framework; aggregating the coverage data of multiple local coverage node trees to generate code coverage statistics results.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This application relates to the field of computer software technology, and in particular to a code coverage statistics method, electronic device, and storage medium. Background Technology

[0002] Traditional single-node coverage verification tools typically run on a single compute node, compiling the target code and inserting coverage statistics code during the compilation process to collect coverage information. Subsequently, the compiled program is run, and during execution, this coverage statistics code records the code execution details, such as which statements, branches, or conditions are covered. Finally, the tool analyzes and processes the recorded data to generate a coverage report, thereby assessing the adequacy of the code's tests. However, limited by single-node resources, it is inefficient when handling large-scale code and complex verification scenarios. Summary of the Invention

[0003] A first aspect of this application provides a method for code coverage statistics, the method comprising: Compile the source code to generate intermediate code; the source code includes coverage statistics code. A global syntax analysis is performed on the intermediate code to generate a node tree framework; the node tree framework includes hierarchical nodes, which are associated with the code structure of the intermediate code; Based on the hierarchical nodes, the node tree framework is split to obtain multiple local subtree frameworks; The multiple local subtree frameworks are sent to multiple distributed computing nodes for local compilation. Receive the local coverage node tree generated by the local compilation; the local coverage node tree includes coverage nodes, and the coverage nodes include coverage data corresponding to the coverage statistics code in the local subtree framework; The coverage data from multiple local coverage node trees are aggregated to generate code coverage statistics.

[0004] A second aspect of this application provides an electronic device, comprising: a memory for storing a set of instructions; and at least one processor configured to execute the set of instructions to cause the electronic device to perform the method as described in the first aspect.

[0005] A third aspect of this application provides a non-transitory computer-readable storage medium storing a set of instructions for a computer, which, when executed, causes the computer to perform the method described in the first aspect.

[0006] This application provides a code coverage statistics method, electronic device, and storage medium. The method involves compiling source code containing coverage statistics code to generate intermediate code, then performing global syntax analysis on the intermediate code to construct a node tree framework associated with the code structure. Next, this framework is split based on hierarchical nodes to obtain multiple local subtree frameworks, which are then distributed to multiple distributed computing nodes for local compilation. The system then receives the local coverage node trees containing coverage data generated from the local compilation and finally aggregates this data to generate the code coverage statistics result. This approach can efficiently handle large-scale code, significantly improving the efficiency and speed of code coverage statistics and meeting the needs of complex projects for evaluating the adequacy of code testing. Attached Figure Description

[0007] To more clearly illustrate the technical solutions in this application or related technologies, the drawings used in the description of the embodiments or related technologies will be briefly introduced below. Obviously, the drawings described below are only embodiments of this application. For those skilled in the art, other drawings can be obtained based on these drawings without creative effort.

[0008] Figure 1 A schematic diagram of the structure of an exemplary electronic device according to an embodiment of this application is shown.

[0009] Figure 2A A schematic diagram of an exemplary simulation system according to an embodiment of this application is shown.

[0010] Figure 2B A schematic diagram of an exemplary compiler according to an embodiment of this application is shown.

[0011] Figure 3 A flowchart illustrating a code coverage statistics method according to an embodiment of this application is shown. Detailed Implementation

[0012] To make the objectives, technical solutions, and advantages of this application clearer, the following detailed description is provided in conjunction with specific embodiments and the accompanying drawings.

[0013] It should be noted that, unless otherwise defined, the technical or scientific terms used in this application should have the ordinary meaning understood by one of ordinary skill in the art to which this application pertains. The terms "first," "second," and similar terms used in this application do not indicate any order, quantity, or importance, but are merely used to distinguish different components. Terms such as "comprising" mean that the element or object preceding the word encompasses the elements or objects listed following the word and their equivalents, without excluding other elements or objects. Terms such as "connection" are not limited to physical or mechanical connections, but can include electrical connections, whether direct or indirect.

[0014] As mentioned above, traditional single-node coverage verification tools operate on a single-node architecture, binding only one storage device for data storage and relying on a single electronic device to perform compilation tasks. The entire process is serial, lacking parallel compilation and distributed capabilities, and all coverage verification operations are completed through a single node. However, existing single-node coverage verification tools cannot adapt to the needs of large-scale prototype design verification. Storage devices are not scalable, with limited storage capacity and performance, failing to meet the massive data storage demands generated during large-scale prototype design verification. Electronic devices are also not scalable or capable of distributed deployment, and the limited compilation capabilities of a single device make it difficult to handle large-scale prototype design verification tasks. Furthermore, the lack of a parallel compilation mechanism, relying solely on serial compilation on a single node, results in a cumbersome, time-consuming, and inefficient compilation process, failing to meet the requirements for high-efficiency verification.

[0015] To address at least the aforementioned issues, this approach generates intermediate code by compiling source code containing coverage statistics. Global syntax analysis is then performed on this intermediate code to construct a node tree framework associated with the code structure. This framework is then split into multiple local subtree frameworks based on hierarchical nodes and distributed to multiple distributed computing nodes for local compilation. The system then receives the local coverage node trees containing coverage data generated from these local compilations and finally aggregates this data to generate the code coverage statistics. This method efficiently handles large-scale code, significantly improving the efficiency and speed of code coverage statistics and meeting the needs of complex projects for evaluating the adequacy of code testing.

[0016] Figure 1 A schematic diagram of an electronic device 100 according to an embodiment of this application is shown. The electronic device 100 may be an electronic device running a simulation system. For example... Figure 1 As shown, the electronic device 100 may include: a processor 102, a memory 104, a network interface 106, a peripheral interface 108, and a bus 110. The processor 102, memory 104, network interface 106, and peripheral interface 108 are interconnected within the electronic device via the bus 110.

[0017] Processor 102 may be a Central Processing Unit (CPU), a graphics processor, a neural network processor (NPU), a microcontroller (MCU), a programmable logic device, a digital signal processor (DSP), an application-specific integrated circuit (ASIC), or one or more integrated circuits. Processor 102 can be used to perform functions related to the techniques described in this application. In some embodiments, processor 102 may also include multiple processors integrated into a single logic component. Figure 1 As shown, processor 102 may include multiple processors 102a, 102b and 102c.

[0018] Memory 104 can be configured to store data (e.g., instruction sets, computer code, intermediate data, etc.). In some embodiments, a simulation test system for simulation test design can be a computer program stored in memory 104. Figure 1 As shown, the data stored in the memory may include program instructions (e.g., program instructions for implementing the code coverage statistics method of this application) and data to be processed (e.g., the memory may store temporary code generated during the compilation process). The processor 102 may also access the program instructions and data stored in the memory and execute the program instructions to operate on the data to be processed. The memory 104 may include a volatile storage device or a non-volatile storage device. In some embodiments, the memory 104 may include random access memory (RAM), read-only memory (ROM), optical disk, magnetic disk, hard disk, solid-state drive (SSD), flash memory, memory stick, etc.

[0019] Network interface 106 can be configured to provide communication with other external devices to electronic device 100 via a network. This network can be any wired or wireless network capable of transmitting and receiving data. For example, the network can be a wired network, a local wireless network (e.g., Bluetooth, WiFi, Near Field Communication (NFC), etc.), a cellular network, the Internet, or a combination thereof. It is understood that the type of network is not limited to the specific examples described above. In some embodiments, network interface 106 may include any combination of any number of network interface controllers (NICs), radio frequency modules, transceivers, modems, routers, gateways, adapters, cellular network chips, etc.

[0020] The peripheral interface 108 can be configured to connect the electronic device 100 to one or more peripheral devices to enable information input and output. For example, peripheral devices may include input devices such as keyboards, mice, touchpads, touch screens, microphones, and various sensors, as well as output devices such as displays, speakers, vibrators, and indicator lights.

[0021] Bus 110 can be configured to transfer information between various components of electronic device 100 (e.g., processor 102, memory 104, network interface 106, and peripheral interface 108), such as internal buses (e.g., processor-memory bus), external buses (USB port, PCI-E bus), etc.

[0022] It should be noted that although the above electronic device architecture only shows the processor 102, memory 104, network interface 106, peripheral interface 108, and bus 110, in specific implementations, this electronic device architecture may also include other components necessary for normal operation. Furthermore, those skilled in the art will understand that the above electronic device architecture may only include the components necessary for implementing the embodiments of this application, and does not necessarily include all the components shown in the figures.

[0023] Figure 2A A schematic diagram of an exemplary simulation tool 200 according to an embodiment of the present disclosure is shown. The simulation tool 200 may be a computer program running on an electronic device 100.

[0024] In the field of chip design, simulation tools are typically used to simulate a design. One example of such a tool is GalaxSim, produced by Chipown Technology Co., Ltd. Figure 2A The exemplary simulation tool 200 shown may include a compiler 210 and a simulator 220. The compiler 210 may receive source code 204 (e.g., a hardware description language such as VHDL, Verilog, SystemVerilog, etc.) and compile it into executable code 206 (e.g., machine code, assembly code, software code, etc.). It is understood that the description of the logic system design may be in a hardware description language (HDL), register transfer level (RTL) language, binary code, assembly code, or machine code, etc. The simulator 220 may perform simulation based on the executable code 206 and output the simulation result 208. For example, the simulation tool 200 may transmit the simulation result 208 via... Figure 1 The peripheral interface 108 outputs to an output device (e.g., displayed on a monitor).

[0025] Figure 2B This is a schematic diagram of an exemplary compiler 210 according to an embodiment of this application. Figure 2B As shown, compiler 210 may include front-end 212, middle-end 214 and back-end 216.

[0026] Frontend212 can be used to analyze the lexical, syntactic, and semantic aspects of source code based on the specific source language.

[0027] After lexical, syntactic, and semantic analysis of the source code, the intermediate stage 214 can convert the source code into an intermediate representation (or intermediate code) and optimize this intermediate representation. Intermediate language (intermediate code) is a syntax-oriented code that is an equivalent internal representation of the source code, easily translated into the target program's source code. Its understandability and ease of generating executable code fall between that of the source code and the executable code. Commonly used intermediate codes include Reverse Polish Notation, quadruples, triples, and tree representations. For example, the intermediate stage 214 can remove useless code, inaccessible code, and unused variables. Optimization can include machine-dependent and machine-independent optimizations. Machine-dependent optimizations, for example, can be optimizations of the testbench (TB) and can utilize some of the testbench's features to aid in optimization. Machine-independent optimizations, for example, can be optimizations of the Design Under Test (DUT). The optimized intermediate representation can then be passed to the backend 126 for further processing.

[0028] Backend 216 can be based on the target processor (e.g., Figure 1 The processor (102) architecture is used to further optimize the intermediate representation and generate executable code. Typically, the executable code is machine code.

[0029] Understandably, the structure of a compiler is not limited to... Figure 2B Examples. For instance, frontend 212 and middleend 214 can be collectively referred to as the compiler's frontend.

[0030] The compiler 210 can generate executable code based on the computer code to be compiled. The computer code to be compiled can also be called source code, such as a written logic system design. Typically, the source language used to write the source code is a high-level programming language. High-level programming languages ​​can be the aforementioned software programming languages ​​or hardware programming languages. The executable code can be, for example, assembly code, machine code, etc. Typically, the compiler 210 can store... Figure 1 The logic system design is stored in memory 104 and executed by processor 102 to compile it into executable code. Compiler 210 can translate the description of the logic system design from a high-level language description (e.g., HDL language) into a lower-level description (e.g., RTL language or binary code), thereby enabling the underlying hardware to run the logic system design.

[0031] In related technologies, code coverage testing can be categorized into different types based on the monitoring targets: function coverage testing, line coverage testing, branch coverage testing, and condition coverage testing. It's understandable that the monitoring targets here refer to the software design, program design, and logical system design to be tested.

[0032] In some embodiments, a logic system design can be a system-on-a-chip (SoC) design. Once a logic system design comprising one or more modules is described using a hardware language (e.g., VHDL, Verilog, etc.), it can be debugged using a simulator. The logic system design can be, for example, an application-specific integrated circuit (ASIC) or a system-on-a-chip (SoC) design. Therefore, a logic system design being tested in a simulator can also be called a design under test (DUT). The simulator can simulate the DUT using one or more configurable components (e.g., a field-programmable gate array (FPGA), including performing various operations of the DUT, thereby testing and verifying the functionality of the individual modules of the DUT before manufacturing.

[0033] In code coverage testing, for different monitored objects, code coverage testing is generally achieved by inserting relevant coverage statistics code into the code to be monitored within the source code of the logical system design. This coverage statistics code is typically inserted directly into the source code of the logical system design before compilation. When a user needs to perform coverage statistics on the source code, they can first insert the coverage statistics code into the source code. After all the coverage statistics code has been inserted to form intermediate code, the intermediate code is then compiled and optimized to generate the executable target code.

[0034] Figure 3 A flowchart illustrating an exemplary method for code coverage statistics according to an embodiment of this application is shown. Method 5300 may be derived from... Figure 1 The illustrated electronic device 100 is implemented, more specifically, by a compiler / emulation system (e.g., running on the electronic device 100) Figure 2A or Figure 2B Compiler 210 / Figure 2A The simulation system in the simulation is implemented. Method 300 may include the following steps.

[0035] In step S310, the source code is compiled to generate intermediate code; the source code includes coverage statistics code.

[0036] The source code can be the original program code (such as if(a>0){...} in C++), the intermediate code is the platform-independent intermediate representation generated during compilation (such as the three-address code %cond = icmp sgt i32 %a, 0 in LLVM IR), and the coverage statistics code is the special code inserted to trace the execution path (such as adding the __coverage_hit(1) counter before and after conditional branches). This scheme uses a distributed split intermediate code node tree framework to compile multiple nodes in parallel, and generates global statistical results after aggregating local coverage node tree data. It can efficiently handle large-scale code (such as projects with millions of lines) and accurately count the coverage of branches, statements, etc., significantly improving verification efficiency and scalability.

[0037] In step S320, a global syntax analysis is performed on the intermediate code to generate a node tree framework; the node tree framework includes hierarchical nodes, and the hierarchical nodes are associated with the code structure of the intermediate code.

[0038] The node tree framework can be an Abstract Syntax Tree (AST) structure generated through global syntax analysis. Hierarchical nodes can be nodes reflecting code hierarchy (such as function nodes, loop nodes, and conditional nodes), and the code structure can correspond to the syntactic organization of the source code (such as function definitions and control flow blocks). For example, after parsing C code containing a `main()` function and its inner `if` and `for` loops, the node tree framework will have `main` as the root node, with its lower-level nodes corresponding to the `if` conditional branches and the `for` loop bodies, forming a tree-like framework strictly associated with the code structure. By splitting the code structure into distributed nodes for parallel processing using this framework, coverage statistics code can be accurately mapped to corresponding hierarchical nodes, enabling efficient coverage statistics and scalable verification for large-scale code.

[0039] In some embodiments, global syntax analysis is performed on the intermediate code to generate a node tree framework, including: Perform global syntax analysis on the intermediate code to generate an abstract syntax tree; The hierarchical nodes are generated based on the intermediate nodes and corresponding global identifiers in the abstract syntax tree; The node tree framework is obtained based on the parent-child node information of the hierarchical nodes.

[0040] The global identifier is a unique identifier assigned to intermediate nodes in the abstract syntax tree (e.g., a function node ID of "func_001"), used to ensure the accuracy of node associations in a distributed environment. For example, when splitting a code structure containing a main() function and its internal if branches, the main function node carries a global ID, and its child nodes (such as if conditional branches) also inherit the parent node ID and generate their own unique IDs, forming a parent-child node association chain. The global identifier enables precise splicing of the distributed node tree and aggregation of coverage data, avoiding node confusion or data loss, effectively supporting distributed coverage statistics for large-scale code, and improving verification efficiency and result reliability.

[0041] Specifically, hierarchical nodes can be of type Scope, representing the code structure hierarchy within a node tree. They are associated with intermediate nodes in the syntax tree (such as functions, loops, conditional statements, etc.) and maintain the nested structure of the code through parent-child pointers. For example, using child and parent pointers, flat code can be transformed into a tree structure, supporting the representation of complex nested logic. Scope nodes themselves do not store coverage data; instead, they explicitly maintain hierarchical scope relationships (such as a function's scope containing its internal block scope) through child and parent information. In distributed compilation, this allows for precise mapping of the code structure hierarchy, ensuring that coverage data maintains contextual consistency during node splitting and aggregation, thereby improving the accuracy of large-scale code coverage statistics and the efficiency of parallel processing.

[0042] In some embodiments, the coverage data of multiple local coverage node trees are aggregated to generate code coverage statistics, including: By aggregating multiple local coverage node trees, a global coverage node tree is obtained; Based on the coverage data in the global coverage node tree, code coverage statistics are generated.

[0043] Coverage data can be records of the coverage status of each syntactic unit (such as statements, branches, and conditions) during code execution, such as the number of times a conditional branch is executed or whether it is accessed. In the distributed scheme, each node independently collects local coverage data (e.g., node A records that the "if(a>0)" branch was executed 3 times, and node B records that the "else" branch was executed 2 times). During aggregation, a global coverage node tree is constructed by concatenating global identifiers and parent-child relationships, ultimately generating statistical results that include dimensions such as overall statement coverage and branch coverage. This scheme improves efficiency through parallel processing, supports verification of millions of lines of code, ensures accurate and complete data correlation, and effectively enhances the reliability and scalability of coverage statistics.

[0044] In some embodiments, aggregating multiple local coverage node trees to obtain a global coverage node tree includes: The local coverage node tree is aggregated based on the global identifier of the hierarchical nodes and the parent-child node information to obtain the global coverage node tree.

[0045] This method precisely assembles local coverage node trees scattered across multiple distributed computing nodes by using globally unique identifiers (such as unique IDs for functions or code blocks) and the association information between parent and child nodes. For example, if local tree A contains branch coverage data for the function `foo()`, and local tree B contains coverage data for the loop within `foo()`, the aggregation process identifies them as belonging to the same scope of `foo()` based on their global identifiers. Then, it attaches the loop node to the corresponding position of the function node based on the parent-child relationship, ultimately forming a complete global tree that reflects the code structure and coverage status. This ensures the integrity and structure of coverage data in a distributed environment, avoids node misalignment or data loss, and significantly improves the accuracy and efficiency of large-scale code coverage statistics.

[0046] In some embodiments, method 300 further includes: The node tree framework is serialized to obtain a serialized node tree framework, and then stored in a storage medium.

[0047] Serializing the node tree framework involves converting it from a memory-based tree-like data structure into a persistent binary or text format (such as JSON or Protocol Buffers), and then storing it on disk or a distributed file system. For example, depth-first traversal encodes the nodes of the abstract syntax tree, their parent-child relationships, global identifiers, and other information into a byte stream, which is then written to a file or database. This not only ensures the recoverability of the node tree framework in the event of distributed task restarts or node failures, avoiding the overhead of repeatedly analyzing intermediate code, but also enables cross-node sharing through storage media. This provides a reliable foundation for subsequent coverage data aggregation and result reuse, significantly improving system stability and resource utilization.

[0048] In step S330, the node tree framework is split based on the hierarchical nodes to obtain multiple local subtree frameworks.

[0049] Based on the global identifiers and scope relationships (such as function and loop boundaries) of hierarchical nodes in the node tree framework, the complete syntax tree structure is logically divided into multiple independent local subtree frameworks. For example, if the source code contains a main function and two independent methods, three subtrees will be generated based on the method scope boundaries during the split. Each subtree retains its complete parent-child node relationships and coverage statistics markers. By decomposing a large-scale syntax tree into parallelizable subtrees, distributed computing resources are effectively utilized, avoiding memory bottlenecks in single-node processing. Simultaneously, data isolation between subtrees and subsequent accurate aggregation are ensured, significantly improving the efficiency and scalability of code coverage statistics.

[0050] In step S340, the multiple local subtree frameworks are sent to multiple distributed computing nodes for local compilation.

[0051] The process involves distributing the split, multi-part subtree framework to different distributed computing nodes via a task scheduling system. Each node only needs to process its associated subtree (such as a specific function or code block), independently performing local compilation and collecting coverage data. For example, node A processes the main function subtree, while node B processes the class method subtree; both run in parallel without interfering with each other. By fully utilizing the cluster's computing power through task parallelization, the compilation and coverage statistics time for large-scale code is significantly shortened, while avoiding single-node resource overload, thus achieving efficient and scalable distributed coverage analysis.

[0052] In some embodiments, sending multiple local subtree frameworks to multiple distributed computing nodes for local compilation includes: The local subtree framework is serialized to obtain the serialized local subtree framework; The serialized local subtree framework is sent to the distributed computing node, and the serialized local subtree framework is deserialized at the distributed computing node to obtain the local subtree framework for local compilation.

[0053] This approach reduces network transmission overhead by serializing local subtree frameworks into compact binary or text formats (such as Protocol Buffers / JSON), and then deserializing them through distributed nodes to restore the tree structure in memory, ensuring the integrity of syntactic information and the consistency of the compilation environment. For example, a subtree containing function scope is serialized into a byte stream and transmitted to the computing node. After deserialization, the node can directly perform compilation steps such as symbol analysis and intermediate code generation. This solves the bandwidth bottleneck of direct transmission of large-scale subtrees and ensures the reliability of distributed compilation through a standardized serialization-deserialization process, significantly improving cluster resource utilization and task processing throughput.

[0054] In step S350, the local coverage node tree generated by the local compilation is received; the local coverage node tree includes coverage nodes, and the coverage nodes include coverage data corresponding to the coverage statistics code in the local subtree framework.

[0055] After each distributed computing node completes its local compilation, it generates a local coverage node tree containing coverage nodes. Each coverage node precisely records the coverage data (such as execution count and hit rate) of the code unit (such as statement or branch) within its corresponding local subtree framework. For example, after node A processes the subtree of function foo(), the returned tree will contain the coverage count statistics for each branch within foo(). By tightly binding coverage data with the syntax structure, the integrity and accuracy of coverage information in a distributed environment are ensured, while providing a structured data foundation for subsequent global aggregation, effectively supporting refined coverage analysis of large-scale code.

[0056] Specifically, a coverage node can be a MetricData node, which is a node in the node tree used to store raw coverage information. It can be attached as a leaf node to a Bin type node or a Scope type node. Coverage nodes can store raw data, such as the number of times a line of code was executed or a branch was selected. They can also provide data support, providing the basic data support for coverage statistics and analysis.

[0057] In some embodiments, receiving the local coverage node tree generated by the local compilation includes: Receive a serialized local coverage node tree from the distributed computing nodes; The serialized local coverage node tree is deserialized to obtain the local coverage node tree.

[0058] This method utilizes serialization technology to convert the local coverage node tree generated by distributed computing nodes into a standard format (such as binary streams or JSON), enabling efficient transmission across the network. The receiving end then deserializes it back into a tree structure in memory. For example, after a node completes compilation, it serializes the tree containing branch coverage into a byte stream, which the master node receives and parses into an operable tree object. This effectively solves the compatibility and integrity challenges of data transmission in distributed systems, reducing network load while ensuring accurate correspondence between coverage data and grammatical structure, providing a reliable data foundation for subsequent global coverage statistics.

[0059] In some embodiments, the local coverage node tree further includes: a coverage target node, associated with the intermediate node and the leaf node of the intermediate node in the abstract syntax tree, for recording the coverage target during the source code compilation process.

[0060] This approach introduces coverage target nodes into the local coverage node tree, directly associating them with intermediate nodes and leaf nodes (such as statements and conditional expressions) in the abstract syntax tree. This allows for dynamic capture of coverage targets (such as specific branches, loop counts, or variable accesses) during compilation. For example, for the "if(x>0)" statement, the coverage target node records whether the branch was executed and the number of times it was executed. This ensures granular coverage statistics, accurately locating uncovered code paths. Furthermore, the deep binding with the syntax tree avoids statistical biases caused by insufficient abstraction levels in traditional solutions, significantly improving the accuracy of coverage analysis and debugging efficiency.

[0061] Specifically, the coverage target node can be of type Bin, used to associate with intermediate or leaf nodes of the syntax tree. A coverage target node is a node in the node tree used to record a specific coverage target, and can be associated with intermediate or leaf nodes of the syntax tree (such as branch conditions, line numbers, etc.). Coverage target nodes can be used to record coverage targets; for example, the Bin node corresponding to `if (x>0)` will record whether that branch was executed. Coverage target nodes can be used to support coverage statistics; by analyzing the execution status of Bin nodes, metrics such as branch coverage can be calculated.

[0062] In step S360, the coverage data of multiple local coverage node trees are aggregated to generate code coverage statistics.

[0063] Specifically, the system aggregates local coverage node trees based on globally unique identifiers and parent-child node relationships through distributed computing nodes. It also uses serialization / deserialization technology to achieve cross-node data transmission. Finally, it generates code coverage statistics based on coverage data in the global tree (such as statement execution counts and branch hit status). The implementation methods include node tree splicing, coverage target node association, and distributed task scheduling. This can improve the efficiency and accuracy of large-scale code verification, support the parallel processing of millions of lines of code, ensure accurate association of coverage data without omissions, and enhance the credibility and scalability of statistical results.

[0064] Specifically, the first step is to obtain the source code to be analyzed. This source code pre-embeds coverage statistics code, which is a counting and marking logic for tracking the execution status of the code. For example, "coverageCount++" counting statements are embedded at function entry points and branch nodes in the source code to record the execution status of the corresponding code segments, providing a foundation for subsequent coverage data collection. Then, the source code is compiled to generate intermediate code. Intermediate code sits between the source code and machine code, is independent of specific hardware devices, and only reflects the logical structure of the code, facilitating subsequent global analysis and distributed compilation processing.

[0065] The compiler is invoked to perform a comprehensive global syntax analysis on the intermediate code generated earlier, traversing all logical structures of the intermediate code. Combined with the coverage statistics code embedded in the source code, all scope-related structural information is filtered and extracted. The scope can be divided into function level, branch level, module level, etc. according to the code logic to ensure coverage of all core logical areas of the source code.

[0066] Based on the extracted scope information, a coverage node tree (global framework tree) containing only scope type nodes is constructed. During the construction process, a unique global ID is assigned to each scope to be split. Each global ID corresponds to one scope and is globally unique, serving as the core identifier for connecting subsequent stages and avoiding node confusion during distributed compilation and integration.

[0067] Global data such as the global ID of each scope and the hierarchical relationship (including child nodes and parent nodes) are processed using a preset serialization algorithm (such as JSON serialization or Protocol Buffers serialization) to transform it into a standardized format that can be stored and transmitted. Then, the serialized global information dataset is stored in a scalable storage medium (such as a distributed hard disk array) to form a global information storage file.

[0068] Based on the scope type nodes, the node tree is split into multiple subtrees, and multiple distributed computing nodes read the number of words stored in the storage medium for parallel compilation. Each computing node can focus on the code compilation task corresponding to its own assigned scope without needing to pay attention to the global logic, thus improving processing efficiency through concurrent compilation. During the compilation process, the focus is on identifying and parsing Bin type (related to binary instructions) and MetricData type (related to coverage metric data). For example, the binary execution instructions corresponding to the Bin type are identified, and the coverage count, execution count, and other metric information corresponding to the MetricData type are parsed. These two types of information are then associated with the corresponding scope nodes to construct the local coverage node tree for that scope.

[0069] After each compute node completes the generation of the local coverage node tree, it can serialize the node tree, store it in one or more scalable storage media, and associate it with the corresponding global ID.

[0070] Read the serialized local coverage node trees stored on all compute nodes from the scalable storage medium, and deserialize all local node trees. Simultaneously, extract the global ID corresponding to the scope node in each local node tree, and combine it with the child and parent hierarchy information contained in each scope node to match all local coverage node trees: locate the local node tree corresponding to each scope based on the global ID, determine the parent node of each local node tree based on the parent information, determine the child node based on the child information, sort out the logical relationship between nodes, and ensure that each local node tree can match the corresponding position in the global framework.

[0071] Following the original logical structure of the source code, all matched local node trees are spliced ​​and integrated to form a complete coverage node tree, achieving a unified summary of the original coverage information of all distributed nodes. For example, each local node tree is traversed, and its position in the global tree is found based on its global ID. Bin type nodes and MetricData type nodes are mounted to their corresponding positions in the global tree using parent-child node information. For Bin type data, a logical OR operation can be used (e.g., a branch is marked as covered as soon as it is executed once). For MetricData type data, an accumulation operation can be used (e.g., summing the number of iterations in a loop).

[0072] Traverse the global coverage node tree and calculate coverage metrics: statement coverage (covered_statements / total_statements), branch coverage (covered_branches / total_branches), and loop coverage (covered_loops / total_loops). Generate visual reports (such as HTML or JSON) or integrate directly into the CI / CD pipeline to obtain coverage statistics.

[0073] As can be seen, compared with traditional single-node coverage verification tools, this application solves the storage expansion problem. By supporting scalable storage media, it breaks the limitation of traditional tools that can only be bound to a single storage device, and can adapt to the data storage needs of large-scale prototype design verification processes, ensuring the smooth progress of verification work. It also solves the device adaptation limitation, by supporting scalable and distributed electronic devices, overcoming the compilation capability limitations of a single electronic device, and can support large-scale prototype design verification tasks by expanding electronic devices. Furthermore, it improves compilation efficiency by supporting distributed concurrent compilation, effectively accelerating the compilation process and significantly reducing compilation time.

[0074] This application also provides an electronic device. The electronic device may be... Figure 1The electronic device 100 may include a memory for storing a set of instructions; and at least one processor configured to execute the set of instructions to cause the electronic device to perform method 300.

[0075] This application also provides a non-transitory computer-readable storage medium. This non-transitory computer-readable storage medium stores a set of instructions for a computer, which, when executed, cause the electronic device to perform method 300.

[0076] The foregoing has described some embodiments of this application. Other embodiments are within the scope of the appended claims. In some cases, the actions or steps recited in the claims may be performed in a different order than that shown in the embodiments and may still achieve the desired result. Furthermore, the processes depicted in the drawings do not necessarily require the specific or sequential order shown to achieve the desired result. In some embodiments, multitasking and parallel processing are also possible or may be advantageous.

[0077] Those skilled in the art should understand that the discussion of any of the above embodiments is merely exemplary and is not intended to imply that the scope of this application (including the claims) is limited to these examples; within the framework of this application, the technical features of the above embodiments or different embodiments can also be combined, the steps can be implemented in any order, and there are many other variations of the different aspects of this application as described above, which are not provided in the details for the sake of brevity.

[0078] Although this application has been described in conjunction with specific embodiments thereof, many substitutions, modifications, and variations of these embodiments will be apparent to those skilled in the art from the foregoing description. For example, other memory architectures (e.g., dynamic RAM (DRAM)) may be used with the embodiments discussed.

[0079] This application is intended to cover all such substitutions, modifications, and variations that fall within the broad scope of the appended claims. Therefore, any omissions, modifications, equivalent substitutions, improvements, etc., made within the spirit and principles of this application should be included within the scope of protection of this application.

Claims

1. A code coverage statistics method, comprising: Compile the source code to generate intermediate code; The source code includes coverage statistics code; Perform global syntax analysis on the intermediate code to generate a node tree framework; The node tree framework includes hierarchical nodes, which are associated with the code structure of the intermediate code; Based on the hierarchical nodes, the node tree framework is split to obtain multiple local subtree frameworks; The multiple local subtree frameworks are sent to multiple distributed computing nodes for local compilation. Receive the local coverage node tree generated by the local compilation; the local coverage node tree includes coverage nodes, and the coverage nodes include coverage data corresponding to the coverage statistics code in the local subtree framework; The coverage data from multiple local coverage node trees are aggregated to generate code coverage statistics.

2. The method of claim 1, wherein, Perform global syntax analysis on the intermediate code to generate a node tree framework, including: Perform global syntax analysis on the intermediate code to generate an abstract syntax tree; The hierarchical nodes are generated based on the intermediate nodes and corresponding global identifiers in the abstract syntax tree; The node tree framework is obtained based on the parent-child node information of the hierarchical nodes.

3. The method according to claim 2, wherein, Aggregate the coverage data from multiple local coverage node trees to generate code coverage statistics, including: By aggregating multiple local coverage node trees, a global coverage node tree is obtained; Based on the coverage data in the global coverage node tree, code coverage statistics are generated.

4. The method according to claim 3, wherein, Aggregating multiple local coverage node trees yields a global coverage node tree, including: The local coverage node tree is aggregated based on the global identifier of the hierarchical nodes and the parent-child node information to obtain the global coverage node tree.

5. The method according to claim 1, wherein, Sending multiple local subtree frameworks to multiple distributed computing nodes for local compilation includes: The local subtree framework is serialized to obtain the serialized local subtree framework; The serialized local subtree framework is sent to the distributed computing node, and the serialized local subtree framework is deserialized at the distributed computing node to obtain the local subtree framework for local compilation.

6. The method according to claim 1, wherein, Receiving the local coverage node tree generated by the local compilation includes: Receive a serialized local coverage node tree from the distributed computing nodes; The serialized local coverage node tree is deserialized to obtain the local coverage node tree.

7. The method according to claim 2, wherein the local coverage node tree further comprises: The coverage target node is associated with the intermediate node and the leaf node of the intermediate node in the abstract syntax tree, and is used to record the coverage target in the source code compilation process.

8. The method according to claim 1, further comprising: The node tree framework is serialized to obtain a serialized node tree framework, and then stored in a storage medium.

9. An electronic device, comprising: A memory for storing a set of computer instructions; at least one processor for executing the computer instructions to cause the electronic device to perform the method as described in any one of claims 1 to 8.

10. A non-transitory computer-readable storage medium storing a set of instructions for a computer to perform the method of any one of claims 1 to 8.