[go: up one dir, main page]

Skip to content

Commit

Permalink
Fix lint errors, implement memory field config
Browse files Browse the repository at this point in the history
  • Loading branch information
jvanstraten committed Sep 4, 2019
1 parent 389dd1b commit efd91b3
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 11 deletions.
21 changes: 18 additions & 3 deletions doc/md/axi.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ This structure supports the following configuration keys.

## `mode`

Configures the supported bus access modes.
This key configures the supported bus access modes.

The following values are supported:

Expand All @@ -43,7 +43,7 @@ This key is optional unless required by context. If not specified, the default v

## `interrupt-internal`

Configures driving an internal signal high when the
This key configures driving an internal signal high when the
`vhdmmio`-specific interrupt signal associated with the outgoing AXI4L
stream is asserted. This internal signal can then be tied to an
internal interrupt to propagate the flag.
Expand All @@ -54,4 +54,19 @@ The following values are supported:

- a string matching `[a-zA-Z][a-zA-Z0-9_]*`: an internal signal with the given name is created (if necessary) and driven by the incoming interrupt signal.

This key is optional unless required by context. If not specified, the default value (`null`) is used.
This key is optional unless required by context. If not specified, the default value (`null`) is used.

## `bus-flatten`

This key specifies whether records or flattened signals are desired
for the bus interface. Note that `flatten` (defined
[here](interfaceconfig.md#flatten)) should also be set to `yes` to make
this work.

The following values are supported:

- `no` (default): the bus is not flattened; the records from `vhdmmio_pkg.vhd` are used.

- `yes`: the bus is flattened; the standard AXI4-lite signal names are used.

This key is optional unless required by context. If not specified, the default value (`no`) is used.
2 changes: 1 addition & 1 deletion doc/md/fieldconfig.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ This key can take the following values:

- Fields for interfacing with memories:

- [`memory`](memory.md): not yet implemented!
- [`memory`](memory.md): infers a local memory inside the register file.

- Fields for controlling `vhdmmio`-managed interrupts:

Expand Down
98 changes: 96 additions & 2 deletions doc/md/memory.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,99 @@
# `memory` behavior

Not yet implemented!
This field behavior infers a local memory inside the register file.
The memory can be accessed through the field and/or a single-cycle,
synchronous RAM port generated on the entity interface.

This structure does not support any configuration keys.
Whether the inferred memory actually maps to memory resources on the
FPGA depends on how smart the synthesizer is. If it doesn't work, use the
`memory-interface` behavior instead, and infer the memory however the
synthesizer expects it to be inferred outside the generated register
file.

This structure supports the following configuration keys.

## `bus-mode`

This key configures the supported bus access modes.

The following values are supported:

- `read-write` (default): both read and write accesses are supported.

- `read-only`: only read accesses are supported.

- `write-only`: only write accesses are supported.

This key is optional unless required by context. If not specified, the default value (`read-write`) is used.

## `hw-mode`

This key configures the supported hardware access modes.

The following values are supported:

- `read-or-write` (default): a shared read-write interface is generated.

- `read-and-write`: independent read and write interfaces are generated.

- `read-only`: only a read interface is generated.

- `write-only`: only a write interface is generated.

- `disabled`: no hardware interface is generated.

This key is optional unless required by context. If not specified, the default value (`read-or-write`) is used.

## `portedness`

This key specifies the memory port configuration.

The following values are supported:

- `auto` (default): `vhdmmio` will choose a fitting configuration based on `bus-mode` and `hw-mode`.

- `1R`: infer a single-port ROM.

- `1RW`: infer a RAM with one shared read-write port.

- `1R1W`: infer a RAM with single independent read and write ports.

- `2R`: infer a dual-port ROM.

- `2RW`: infer a RAM with two shared read-write ports.

- `2R1W`: infer a RAM with two independent read ports and one independent write port.

- `2R2W`: infer a RAM with two independent read ports and two independent write ports.

This key is optional unless required by context. If not specified, the default value (`auto`) is used.

## `byte-enable`

This key specifies whether this memory should support byte
enables. This is only supported when the bitrange of the field is
byte-aligned.

The following values are supported:

- `no` (default): no byte write enable signal is created. Any incomplete bus writes result in zeros being written.

- `yes`: the inferred memory supports a byte write enable signal.

This key is optional unless required by context. If not specified, the default value (`no`) is used.

## `initial-data`

This key specifies the initial data for the inferred memory. Whether
this actually works depends on whether the synthesizer/FPGA
architecture supports inferring initialized memories.

The following values are supported:

- `null` (default): the memory is not initialized. Simulation yields `'U'`s until the first write.

- an integer: each memory location is initialized with the given value.

- a string: the memory is initialized using the given data file. The filename is relative to the configuration file, or relative to the current working directory if the configuration is loaded using the Python API. If the filename ends in `.bin`, the file is treated as little-endian binary; in this case, the width of the memory must be an integer number of bytes. If a different file extension is used, the file is expected to consist of the correct number of spacing-separated integers, such that each integer corresponds to a memory location. These integers can be specified in hexadecimal, binary, or decimal format, selected using the usual `0x`/`0b`/lack of a prefix.

This key is optional unless required by context. If not specified, the default value (`null`) is used.
2 changes: 1 addition & 1 deletion tests/integration/test_axi_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def test_flattened(self):
'f_a_wstrb',
'f_a_wvalid',
))
with rft as objs:
with rft:
# This should probably be tested beyond just compiling. On the
# other hand, What Could Possibly Go Wrong? (TM)
pass
Expand Down
75 changes: 72 additions & 3 deletions vhdmmio/config/behavior/memory.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,82 @@
"""Submodule for `Memory` configurable."""

from ...configurable import configurable, Configurable
from ...configurable import configurable, Configurable, choice
from .registry import behavior, behavior_doc

behavior_doc('Fields for interfacing with memories:')

@behavior(
'memory', 'not yet implemented!', 1)
'memory', 'infers a local memory inside the register file.', 1)
@configurable(name='`memory` behavior')
class Memory(Configurable):
"""Not yet implemented!""" # TODO
"""This field behavior infers a local memory inside the register file.
The memory can be accessed through the field and/or a single-cycle,
synchronous RAM port generated on the entity interface.
Whether the inferred memory actually maps to memory resources on the
FPGA depends on how smart the synthesizer is. If it doesn't work, use the
`memory-interface` behavior instead, and infer the memory however the
synthesizer expects it to be inferred outside the generated register
file."""
#pylint: disable=E0211,E0213

@choice
def bus_mode():
"""This key configures the supported bus access modes."""
yield 'read-write', 'both read and write accesses are supported.'
yield 'read-only', 'only read accesses are supported.'
yield 'write-only', 'only write accesses are supported.'

@choice
def hw_mode():
"""This key configures the supported hardware access modes."""
yield 'read-or-write', 'a shared read-write interface is generated.'
yield 'read-and-write', 'independent read and write interfaces are generated.'
yield 'read-only', 'only a read interface is generated.'
yield 'write-only', 'only a write interface is generated.'
yield 'disabled', 'no hardware interface is generated.'

@choice
def portedness():
"""This key specifies the memory port configuration."""
yield ('auto', '`vhdmmio` will choose a fitting configuration '
'based on `bus-mode` and `hw-mode`.')
yield '1R', 'infer a single-port ROM.'
yield '1RW', 'infer a RAM with one shared read-write port.'
yield '1R1W', 'infer a RAM with single independent read and write ports.'
yield '2R', 'infer a dual-port ROM.'
yield '2RW', 'infer a RAM with two shared read-write ports.'
yield ('2R1W', 'infer a RAM with two independent read ports and '
'one independent write port.')
yield ('2R2W', 'infer a RAM with two independent read ports and '
'two independent write ports.')

@choice
def byte_enable():
"""This key specifies whether this memory should support byte
enables. This is only supported when the bitrange of the field is
byte-aligned."""
yield (False, 'no byte write enable signal is created. Any incomplete '
'bus writes result in zeros being written.')
yield (True, 'the inferred memory supports a byte write enable signal.')

@choice
def initial_data():
"""This key specifies the initial data for the inferred memory. Whether
this actually works depends on whether the synthesizer/FPGA
architecture supports inferring initialized memories."""
yield (None, 'the memory is not initialized. Simulation yields '
'`\'U\'`s until the first write.')
yield int, 'each memory location is initialized with the given value.'
yield (str, 'the memory is initialized using the given data file. The '
'filename is relative to the configuration file, or relative to '
'the current working directory if the configuration is loaded '
'using the Python API. If the filename ends in `.bin`, the '
'file is treated as little-endian binary; in this case, the '
'width of the memory must be an integer number of bytes. If a '
'different file extension is used, the file is expected to '
'consist of the correct number of spacing-separated integers, '
'such that each integer corresponds to a memory location. '
'These integers can be specified in hexadecimal, binary, or '
'decimal format, selected using the usual `0x`/`0b`/lack of a '
'prefix.')
2 changes: 1 addition & 1 deletion vhdmmio/vhdl/behavior/axi.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def generate(self):
tple['rready'] = self.add_output('rready')
tple['rdata'] = self.add_input('rdata', bus_width)
tple['rresp'] = self.add_input('rresp', 2)
tple['uirq'] = self.add_input('uirq')
tple['uirq'] = self.add_input('uirq')
else:
tple['m2s'] = self.add_output('o', typ=Axi4Lite('m2s', bus_width))
tple['s2m'] = self.add_input('i', typ=Axi4Lite('s2m', bus_width))
Expand Down

0 comments on commit efd91b3

Please sign in to comment.