blob: 5e94515b2695ff6fcdf96005fc9470e795990203 [file] [log] [blame]
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
from typing import List, Tuple
from shared.insn_yaml import InsnsFile
from shared.mem_layout import get_memory_layout
from .program import Program
from .model import Model
from .snippet_gens import SnippetGens
from .snippet import Snippet
def gen_program(start_addr: int,
size: int,
insns_file: InsnsFile) -> Tuple[List[Snippet], Program]:
'''Generate a random program for OTBN
start_addr is the reset address (the value that should be programmed into
the START_ADDR register). size gives a rough upper bound for the number of
instructions that will be executed by the generated program.
Returns (snippets, program) where snippets is a list of instruction
snippets and program is the generated program.
'''
# Find the size of the memory that we can access. Both memories start
# at address 0: a strict Harvard architecture. (mems[x][0] is the LMA
# for memory x, not the VMA)
mems = get_memory_layout()
imem_lma, imem_size = mems['IMEM']
dmem_size = mems['DMEM'][1]
assert start_addr <= imem_size - 4
assert start_addr & 3 == 0
program = Program(imem_lma, imem_size)
model = Model(dmem_size, start_addr)
generators = SnippetGens(insns_file)
snippets = []
while size > 0:
snippet, done, new_size = generators.gen(size, model, program)
snippets.append(snippet)
if done:
break
# Each new snippet should consume some of size to guarantee
# termination.
assert new_size < size
size = new_size
return snippets, program
def snippets_to_program(snippets: List[Snippet]) -> Program:
'''Write a series of disjoint snippets to make a program'''
# Find the size of the memory that we can access. Both memories start
# at address 0: a strict Harvard architecture. (mems[x][0] is the LMA
# for memory x, not the VMA)
mems = get_memory_layout()
imem_lma, imem_size = mems['IMEM']
program = Program(imem_lma, imem_size)
for snippet in snippets:
snippet.insert_into_program(program)
return program