Skip to content

Commit 6703790

Browse files
rswarbrickandreaskurth
authored andcommitted
[topgen,ral] Tweaks to support new memory description
Signed-off-by: Rupert Swarbrick <[email protected]>
1 parent 091cb4f commit 6703790

File tree

2 files changed

+91
-29
lines changed

2 files changed

+91
-29
lines changed

util/reggen/memory.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
33
# SPDX-License-Identifier: Apache-2.0
44

5-
from typing import Dict
6-
75
from reggen.lib import check_keys
6+
from reggen.window import Window
87

98

109
class Memory:
1110
'''A class representing a memory'''
1211

12+
windows: list[Window] = list()
13+
"""A list of windows into the memory"""
14+
1315
def __init__(self) -> None:
1416
pass
1517

@@ -19,5 +21,5 @@ def from_raw(raw: object) -> 'Memory':
1921
check_keys(raw, 'memory', [], [])
2022
return Memory()
2123

22-
def _asdict(self) -> Dict[str, object]:
24+
def _asdict(self) -> dict[str, object]:
2325
return {}

util/topgen.py

Lines changed: 86 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from mako.lookup import TemplateLookup
3030
from mako.template import Template
3131
from raclgen.lib import DEFAULT_RACL_CONFIG
32-
from reggen import access, gen_rtl, gen_sec_cm_testplan, window
32+
from reggen import access, gen_rtl, gen_sec_cm_testplan, params, reg_block, window
3333
from reggen.countermeasure import CounterMeasure
3434
from reggen.ip_block import IpBlock
3535
from topgen import get_hjsonobj_xbars
@@ -871,33 +871,90 @@ def generate_top_ral(topname: str, top: ConfigT, name_to_block: IpBlocksT,
871871
original_types = set()
872872
for module in top["module"]:
873873
if "memory" in module.keys() and len(module["memory"]) > 0:
874-
newtype = "{}_{}".format(module["type"], module["name"])
874+
mod_name = module["name"]
875+
newtype = "{}_{}".format(module["type"], mod_name)
875876
assert newtype not in name_to_block
876877

878+
# Take a copy of the block-level description of the thing that is
879+
# being instantiated as mod_name (so that we can configure it).
877880
block = deepcopy(name_to_block[module["type"]])
881+
882+
# Update name_to_block and inst_to_block so that they point at the
883+
# new, more specific, information about the block.
878884
name_to_block[newtype] = block
879-
inst_to_block[module["name"]] = newtype
885+
inst_to_block[mod_name] = newtype
880886

881887
original_types.add(module["type"])
882888

889+
# The instantiation might have requested a specific configuration
890+
# for some of the memories of the block. Apply that here.
883891
for mem_name, item in module["memory"].items():
884-
assert block.reg_blocks[mem_name]
885-
assert len(block.reg_blocks[mem_name].windows) <= 1
886-
item["name"] = mem_name
887-
888-
win = create_mem(item, addrsep, regwidth)
889-
if len(block.reg_blocks[mem_name].windows) > 0:
890-
blk_win = block.reg_blocks[mem_name].windows[0]
891-
892-
# Top can only add new info for mem, shouldn't overwrite
893-
# existing configuration
894-
assert win.items == blk_win.items
895-
assert win.byte_write == blk_win.byte_write
896-
assert win.data_intg_passthru == blk_win.data_intg_passthru
897-
898-
block.reg_blocks[mem_name].windows[0] = win
892+
block_mem = block.memories.get(mem_name)
893+
if block_mem is None:
894+
raise ValueError(f"The definition of {block.name} "
895+
f"(instantiated as {mod_name}) doesn't "
896+
f"declare a memory called {mem_name}.")
897+
898+
# We only support memories with at most a single window (if
899+
# there are several, we don't know which one to customise)
900+
if len(block_mem.windows) > 1:
901+
raise ValueError(f"The block {block.name} declares "
902+
f"multiple windows for its {mem_name} "
903+
f"memory, so topgen can't configure that "
904+
"memory.")
905+
906+
# This is the new window to use
907+
win = create_mem(mem_name, item, addrsep, regwidth)
908+
909+
# If the block doesn't define a window for this memory, we can
910+
# just make one. If it *does* define a window we can overwrite
911+
# it, but want to make sure we won't mess things up.
912+
if not block_mem.windows:
913+
block_mem.windows = [win]
899914
else:
900-
block.reg_blocks[mem_name].windows.append(win)
915+
blk_win = block_mem.windows[0]
916+
917+
# Check we end up with the same number of "items" in the
918+
# window (the window size divided by addrsep)
919+
if win.items != blk_win.items:
920+
raise ValueError(f"The {mod_name} instance of "
921+
f"{block.name} doesn't match number "
922+
f"of items for {mem_name}. Instance: "
923+
f"{win.items}; blk: {blk_win.items}")
924+
925+
# Check the byte_write setting matches
926+
if win.byte_write != blk_win.byte_write:
927+
raise ValueError(f"The {mod_name} instance of "
928+
f"{block.name} requests the memory "
929+
f"{mem_name} with byte_write="
930+
f"{win.byte_write}, but the block "
931+
f"declares it {blk_win.byte_write}.")
932+
933+
# Check the data_intg_passthru setting matches
934+
if win.data_intg_passthru != blk_win.data_intg_passthru:
935+
raise ValueError(f"The {mod_name} instance of "
936+
f"{block.name} requests the memory "
937+
f"{mem_name} with data_intg_passthru="
938+
f"{win.data_intg_passthru}, but the "
939+
f"block declares it as "
940+
f"{blk_win.data_intg_passthru}.")
941+
942+
# If we get here, the two definitions matched. Use the new
943+
# one.
944+
block_mem.windows[0] = win
945+
946+
# At the moment the RAL template does not know about memories
947+
# but it knows about windows in memory blocks. Therefoe we
948+
# create an empty register block for RAL.
949+
if_name = mem_name
950+
block.reg_blocks[if_name] = reg_block.RegBlock(regwidth, params.ReggenParams(),
951+
windows = block_mem.windows)
952+
953+
if_addr = {
954+
asid: int(addr, 0)
955+
for (asid, addr) in module["base_addrs"][if_name].items()
956+
}
957+
if_addrs[(mod_name, if_name)] = if_addr
901958

902959
for t in original_types:
903960
if t not in inst_to_block.values():
@@ -911,16 +968,19 @@ def generate_top_ral(topname: str, top: ConfigT, name_to_block: IpBlocksT,
911968
return gen_dv(chip, dv_base_names, str(out_path))
912969

913970

914-
def create_mem(item, addrsep, regwidth) -> window.Window:
915-
byte_write = ("byte_write" in item and
916-
item["byte_write"].lower() == "true")
917-
data_intg_passthru = ("data_intg_passthru" in item and
918-
item["data_intg_passthru"].lower() == "true")
919-
size_in_bytes = int(item["size"], 0)
971+
def create_mem(name: str, item: dict[str, object], addrsep: int, regwidth: int) -> window.Window:
972+
byte_write = item.get("byte_write", "false").lower() == "true"
973+
data_intg_passthru = item.get("data_intg_passthru", "false").lower() == "true"
974+
975+
item_size = item.get("size")
976+
if item_size is None:
977+
raise ValueError("Item describing memory window with no size")
978+
979+
size_in_bytes = int(item_size, 0)
920980
num_regs = size_in_bytes // addrsep
921981
swaccess = access.SWAccess("top-level memory", item.get("swaccess", "rw"))
922982

923-
return window.Window(name=item["name"],
983+
return window.Window(name=name,
924984
desc="(generated from top-level)",
925985
unusual=False,
926986
byte_write=byte_write,

0 commit comments

Comments
 (0)