Newer
Older
for mv in collection:
if mv not in self:
raise ValueError(
f'{mv.__repr__()} is not part of {self.__repr__()}.'
)
# Make sure that concurrent reads/writes do not surpass the port setting
for mv in self:
def filter_write(p):
return p.start_time == mv.start_time
def filter_read(p):
return (
(p.start_time + p.execution_time) % self._schedule_time
== mv.start_time + mv.execution_time % self._schedule_time
)
needed_write_ports = len(list(filter(filter_write, self)))
needed_read_ports = len(list(filter(filter_read, self)))
if needed_write_ports > write_ports + 1:
raise ValueError(
f'More than {write_ports} write ports needed ({needed_write_ports})'
' to generate HDL for this ProcessCollection'
if needed_read_ports > read_ports + 1:
raise ValueError(
f'More than {read_ports} read ports needed ({needed_read_ports}) to'
' generate HDL for this ProcessCollection'
with open(filename, 'w') as f:
from b_asic.codegen.vhdl import architecture, common, entity
common.write_b_asic_vhdl_preamble(f)
common.write_ieee_header(f)
entity.write_memory_based_storage(
f, entity_name=entity_name, collection=self, word_length=word_length
f,
assignment=assignment,
entity_name=entity_name,
word_length=word_length,
read_ports=read_ports,
write_ports=write_ports,
total_ports=total_ports,

Mikael Henriksson
committed
input_sync=input_sync,
)
def generate_register_based_storage_vhdl(
self,
filename: str,
word_length: int,
entity_name: str,
read_ports: int = 1,
write_ports: int = 1,
total_ports: int = 2,
Generate VHDL code for register based storages of processes based on Forward-Backward Register Allocation [1].
[1]: K. Parhi: VLSI Digital Signal Processing Systems: Design and Implementation, Ch. 6.3.2
Parameters
----------
filename : str
Filename of output file.
word_length : int
Word length of the memory variable objects.
entity_name : str
Name used for the VHDL entity.
read_ports : int, default: 1
The number of read ports used when splitting process collection based on
memory variable access. If total ports in unset, this parameter has to be set
and total_ports is assumed to be read_ports + write_ports.
write_ports : int, default: 1
The number of write ports used when splitting process collection based on
memory variable access. If total ports is unset, this parameter has to be set
and total_ports is assumed to be read_ports + write_ports.
total_ports : int, default: 2
The total number of ports used when splitting process collection based on
memory variable access.
"""
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
# Check that this is a ProcessCollection of (Plain)MemoryVariables
is_memory_variable = all(
isinstance(process, MemoryVariable) for process in self._collection
)
is_plain_memory_variable = all(
isinstance(process, PlainMemoryVariable) for process in self._collection
)
if not (is_memory_variable or is_plain_memory_variable):
raise ValueError(
"HDL can only be generated for ProcessCollection of"
" (Plain)MemoryVariables"
)
# Sanitize port settings
read_ports, write_ports, total_ports = _sanitize_port_option(
read_ports, write_ports, total_ports
)
# Create the forward-backward table
forward_backward_table = _ForwardBackwardTable(self)
with open(filename, 'w') as f:
from b_asic.codegen import vhdl
vhdl.common.write_b_asic_vhdl_preamble(f)
vhdl.common.write_ieee_header(f)
vhdl.entity.write_register_based_storage(
f, entity_name=entity_name, collection=self, word_length=word_length
)
vhdl.architecture.write_register_based_storage(
f,
forward_backward_table=forward_backward_table,
entity_name=entity_name,
word_length=word_length,
read_ports=read_ports,
write_ports=write_ports,
total_ports=total_ports,
)