Skip to content
STIMSMITH

gen_program()

CodeArtifact WIKI v1 · 5/26/2026

`gen_program()` is the main RISC-V assembly program generation function described for the `riscv_asm_program_gen.sv` class in the CHIPS Alliance `riscv-dv` random instruction generator. It orchestrates header generation, GPR initialization, directed and random instruction stream generation, subprogram insertion, host-interface code, and trap-handling support to produce complete randomized RISC-V assembly programs for processor IP verification.

gen_program()

gen_program() is the main function described for generating all sections of a RISC-V assembly program in the riscv_asm_program_gen.sv class. It is part of the CHIPS Alliance open-source riscv-dv random instruction generator, which is used for RISC-V processor verification. [C1][C2]

Role in program generation

The function is called from an upper layer and then invokes other functions in riscv_asm_program_gen sequentially to build a complete assembly test program. The generated program can include initialization routines, instruction sections, data sections, stack sections, page tables, interrupt handling, and exception handling. [C2]

The generated output is a full RISC-V assembly program containing randomized instructions, randomized general-purpose register selections, and varied instruction patterns suitable for verification stimulus. [C9]

Configuration input

Before gen_program() runs, riscv_instr_gen_config is randomized from riscv_instr_base_test.sv. This configuration determines properties such as the RISC-V extension under test, supported privilege mode, instruction counts for the main program and subprograms, and whether certain instruction classes are disabled through variables such as no_ebreak, no_dret, no_fence, and no_wfi. [C3]

Generation flow

The documented flow includes the following steps:

  1. Directed instruction stream setup: gen_program() calls get_directed_instr_stream() and uses add_directed_instr_stream() to select directed-instruction generation ratios. The evidence includes an example log line adding a riscv_jal_instr stream at a ratio of 30/1000. [C4]

  2. Program header generation: gen_program() calls gen_program_header(), which fills the instr_stream string array with header content such as .include "user_init.s". gen_program_header() also calls gen_section("_start", str) to insert header instructions into the stream. [C5]

  3. GPR initialization: gen_program() calls init_gpr(), whose documented purpose is to initialize general-purpose registers with random values. [C6]

  4. Directed and randomized instruction generation: generate_directed_instr_stream() decides insertion ratios, inserts directed instruction streams, randomizes instructions, and selects rs1, rs2, and rd based on instruction type. The post_random() function of riscv_instr helps produce instructions using GPRs x0 through x31. [C7]

  5. Instruction stream conversion: riscv_instr_sequence.generate_instr_stream() operates on the available instruction stream and uses convert2asm(). main_program[hart].generate_instr_stream() is called from riscv_asm_program_gen to convert the instruction stream into string format. [C8]

  6. Illegal and HINT instruction checks: The generator checks whether illegal-instruction or HINT-instruction ratios are defined; if those ratios are zero, no illegal or HINT instructions are generated. [C8]

  7. Subprogram insertion: If subprogram instructions are generated, insert_sub_program(sub_program[hart], instr_stream) is called. [C10]

  8. Host-interface code insertion: After main-program and subprogram generation, host-interface-related instructions are added through gen_section(). The evidence shows labels and instructions including write_tohost:, sw gp, tohost, t1, and _exit:. [C10]

  9. Trap-handling support: push_gpr_to_kernel_stack() pushes general-purpose registers to the stack for trap handling. The program generator also uses gen_section() to select an mtvec_handler section with exception_handler and interrupt_handler definitions. [C11]

Output

Together with helper classes such as riscv_instruction_sequence, base test classes, and configuration helpers, gen_program() produces complete RISC-V assembly programs for robust IP verification. These programs contain randomized instructions, randomized GPR choices, and different instruction patterns. [C9]

CITATIONS

11 sources
11 citations
[1] CHIPS Alliance developed the open-source `riscv-dv` random instruction generator for RISC-V processor verification. RISC-V source class riscv_asm_program_gen, the brain behind ...
[2] `gen_program()` is the main function used to generate all sections of the program and calls other functions in `riscv_asm_program_gen` sequentially. RISC-V source class riscv_asm_program_gen, the brain behind ...
[3] `riscv_instr_gen_config` is randomized from `riscv_instr_base_test.sv` and controls extension, privilege mode, instruction counts, and instruction-disabling options such as `no_ebreak`, `no_dret`, `no_fence`, and `no_wfi`. RISC-V source class riscv_asm_program_gen, the brain behind ...
[4] `gen_program()` calls `get_directed_instr_stream()` and uses `add_directed_instr_stream()` to select directed-instruction generation ratios, with an example `riscv_jal_instr` ratio of `30/1000`. RISC-V source class riscv_asm_program_gen, the brain behind ...
[5] `gen_program()` calls `gen_program_header()`, which fills `instr_stream` with header content and calls `gen_section("_start", str)`. RISC-V source class riscv_asm_program_gen, the brain behind ...
[6] `gen_program()` calls `init_gpr()` to initialize general-purpose registers with random values. RISC-V source class riscv_asm_program_gen, the brain behind ...
[7] `generate_directed_instr_stream()` decides ratios, inserts directed instruction streams, randomizes instructions, and selects `rs1`, `rs2`, and `rd` based on instruction type, using GPRs `x0` through `x31` with help from `riscv_instr.post_random()`. RISC-V source class riscv_asm_program_gen, the brain behind ...
[8] `riscv_instr_sequence.generate_instr_stream()` uses `convert2asm()`, and `main_program[hart].generate_instr_stream()` converts the instruction stream to string format; illegal and HINT instructions are not generated when their ratios are zero. RISC-V source class riscv_asm_program_gen, the brain behind ...
[9] `gen_program()` and associated helpers produce complete RISC-V assembly programs with random instructions, random GPR selections, and different instruction patterns for robust IP verification. RISC-V source class riscv_asm_program_gen, the brain behind ...
[10] If subprogram instructions are generated, `insert_sub_program(sub_program[hart], instr_stream)` is called; after main and subprogram generation, host-interface code is added through `gen_section()` with content such as `write_tohost:`, `sw gp, tohost, t1`, and `_exit:`. RISC-V source class riscv_asm_program_gen, the brain behind ...
[11] `push_gpr_to_kernel_stack()` pushes general-purpose registers to the stack for trap handling, and `gen_section()` selects an `mtvec_handler` section containing `exception_handler` and `interrupt_handler` definitions. RISC-V source class riscv_asm_program_gen, the brain behind ...