Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle IP definition missing registers #7

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A set of utilities that can be used to develop digital IPs in Verilog HDL. This

- [Code Generators](/generators) based on IP definition in YAML or JSON
- Bus wrapper Verilog RTL for AMBA AHB lite and APB.
- A testbech template in Verilog for the IP.
- A testbench template in Verilog for the IP.
- C header file that contains the I/O register definitions.
- IP documentation in Markdown format.
- [RTL Library of Components](/rtl)
Expand Down
95 changes: 49 additions & 46 deletions generators/amba_wrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,47 +248,48 @@ def print_registers(bus_type):
Returns:
None
"""
for r in IP['registers']:
if r['fifo'] is True:
print(f"\twire\t[{r['size']}-1:0]\t{r['name']}_WIRE;")
else:
if r['mode'] == 'rw':
# 'rw' registers cannot have field
print(f"\treg\t[{r['size']}-1:0]\t{r['name']}_REG;")
if "registers" in IP:
for r in IP['registers']:
if r['fifo'] is True:
print(f"\twire\t[{r['size']}-1:0]\t{r['name']}_WIRE;")
print(f"\tassign\t{r['name']}_WIRE = {r['read_port']};")
print(f"\tassign\t{r['write_port']} = {r['name']}_REG;")
print(f"\t`{bus_type}_REG({r['name']}_REG, 0, 8)")
elif r['mode'] == 'w':
print(f"\treg [{r['size']}-1:0]\t{r['name']}_REG;")
if "fields" in r and "write_port" not in r:
for f in r['fields']:
if isinstance(f['bit_width'], int):
to = f['bit_width'] + f['bit_offset'] - 1
else:
if f['bit_offset'] == 0:
to = f"({f['bit_width']} - 1)"
else:
to = f"({f['bit_width']} + {f['bit_offset'] - 1})"
print(f"\tassign\t{f['write_port']}\t=\t{r['name']}_REG[{to} : {f['bit_offset']}];")
else:
else:
if r['mode'] == 'rw':
# 'rw' registers cannot have field
print(f"\treg\t[{r['size']}-1:0]\t{r['name']}_REG;")
print(f"\twire\t[{r['size']}-1:0]\t{r['name']}_WIRE;")
print(f"\tassign\t{r['name']}_WIRE = {r['read_port']};")
print(f"\tassign\t{r['write_port']} = {r['name']}_REG;")
print(f"\t`{bus_type}_REG({r['name']}_REG, {r['init'] if 'init' in r else 0}, {r['size']})")
elif r['mode'] == 'r':
print(f"\twire [{r['size']}-1:0]\t{r['name']}_WIRE;")
if "fields" in r:
for f in r['fields']:
if isinstance(f['bit_width'], int):
to = f['bit_width'] + f['bit_offset'] - 1
else:
if f['bit_offset'] == 0:
to = f"({f['bit_width']} - 1)"
print(f"\t`{bus_type}_REG({r['name']}_REG, 0, 8)")
elif r['mode'] == 'w':
print(f"\treg [{r['size']}-1:0]\t{r['name']}_REG;")
if "fields" in r and "write_port" not in r:
for f in r['fields']:
if isinstance(f['bit_width'], int):
to = f['bit_width'] + f['bit_offset'] - 1
else:
to = f"({f['bit_width']} + {f['bit_offset'] - 1})"
print(f"\tassign\t{r['name']}_WIRE[{to} : {f['bit_offset']}] = {f['read_port']};")
else:
print(f"\tassign\t{r['name']}_WIRE = {r['read_port']};")

if f['bit_offset'] == 0:
to = f"({f['bit_width']} - 1)"
else:
to = f"({f['bit_width']} + {f['bit_offset'] - 1})"
print(f"\tassign\t{f['write_port']}\t=\t{r['name']}_REG[{to} : {f['bit_offset']}];")
else:
print(f"\tassign\t{r['write_port']} = {r['name']}_REG;")
print(f"\t`{bus_type}_REG({r['name']}_REG, {r['init'] if 'init' in r else 0}, {r['size']})")
elif r['mode'] == 'r':
print(f"\twire [{r['size']}-1:0]\t{r['name']}_WIRE;")
if "fields" in r:
for f in r['fields']:
if isinstance(f['bit_width'], int):
to = f['bit_width'] + f['bit_offset'] - 1
else:
if f['bit_offset'] == 0:
to = f"({f['bit_width']} - 1)"
else:
to = f"({f['bit_width']} + {f['bit_offset'] - 1})"
print(f"\tassign\t{r['name']}_WIRE[{to} : {f['bit_offset']}] = {f['read_port']};")
else:
print(f"\tassign\t{r['name']}_WIRE = {r['read_port']};")

print()

def get_port_width(port):
Expand Down Expand Up @@ -391,8 +392,9 @@ def print_registers_offsets(bus_type):
None
"""
# user defined registers
for r in IP['registers']:
print(f"\tlocalparam\t{r['name']}_REG_OFFSET = `{bus_type}_AW'd{r['offset']};")
if "registers" in IP:
for r in IP['registers']:
print(f"\tlocalparam\t{r['name']}_REG_OFFSET = `{bus_type}_AW'd{r['offset']};")

# Interrupt registers
print(f"\tlocalparam\tIM_REG_OFFSET = `{bus_type}_AW'd{IM_OFF};")
Expand All @@ -411,12 +413,13 @@ def print_rdata(bus_type):
else:
print(f"\tassign\tHRDATA = ")

for index,r in enumerate(IP['registers']):
if "r" in r['mode'] or r['fifo'] is True:
print(f"\t\t\t({prefix}ADDR[`{bus_type}_AW-1:0] == {r['name']}_REG_OFFSET)\t? {r['name']}_WIRE :")
else:
print(f"\t\t\t({prefix}ADDR[`{bus_type}_AW-1:0] == {r['name']}_REG_OFFSET)\t? {r['name']}_REG :")

if "registers" in IP:
for index, r in enumerate(IP['registers']):
if "r" in r['mode'] or r['fifo'] is True:
print(f"\t\t\t({prefix}ADDR[`{bus_type}_AW-1:0] == {r['name']}_REG_OFFSET)\t? {r['name']}_WIRE :")
else:
print(f"\t\t\t({prefix}ADDR[`{bus_type}_AW-1:0] == {r['name']}_REG_OFFSET)\t? {r['name']}_REG :")

if "flags" in IP:
for r in IRQ_REGS:
print(f"\t\t\t({prefix}ADDR[`{bus_type}_AW-1:0] == {r}_REG_OFFSET)\t? {r}_REG :")
Expand Down
10 changes: 5 additions & 5 deletions generators/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

## A Typical Workflow

1. Describe the IP in YAML or JSON format. The format is outlined in the following section. To make things easier, ```v2yaml.py``` may be used to generate a template YAML file from the IP RTL Verilog file with some of the sections filled aautomatically for you.
1. Describe the IP in YAML or JSON format. The format is outlined in the following section. To make things easier, ```v2yaml.py``` may be used to generate a template YAML file from the IP RTL Verilog file with some of the sections filled automatically for you.

2. [Optional] Convert the YAML file into JSON using tools such as [this one](https://onlineyamltools.com/convert-yaml-to-json).

Expand Down Expand Up @@ -78,7 +78,7 @@ info:

### Parameter Definitions

This section is used if the IP RTL model is parameterized. The parameters defined in this section can be used in other sections to specify width of fields and registers.
This section is used if the IP RTL model is parameterized. The parameters defined in this section can be used in other sections to specify the width of fields and registers.

```YAML
parameters:
Expand Down Expand Up @@ -167,9 +167,9 @@ registers:
- The ``mode`` property can be set to:
- ``w`` for registers that are meant for writing only; reading from it returns the last written data value.
- ``r`` for registers that are meant for reading only; hence they cannot be written.
- ``rw`` for registers that are read and written differently; for an example, the data register of a GPIO peripheral. Reading this register returns the data provided on input GPIO pins and writting the register sets the values of output GPIO pins.
- ``rw`` for registers that are read and written differently; for example, the data register of a GPIO peripheral. Reading this register returns the data provided on input GPIO pins and writing the register sets the values of output GPIO pins.

- The ``bit_access`` property is used to enable bit level access (Not implemented functionality).
- The ``bit_access`` property is used to enable bit-level access (Not implemented functionality).
- The ``fifo`` property is used to specify whether this register is used to access a FIFO. If it is set to ``yes`` the FIFO has to be defined.

### FIFO Definitions
Expand All @@ -193,7 +193,7 @@ fifos:

### Event Flag Definitions

Event flags used for generating interrupts. For an example:
Event flags are used for generating interrupts. For an example:

```yaml
flags:
Expand Down
2 changes: 1 addition & 1 deletion generators/v2yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
type: <soft|hard|firm>
status: <verified|fpga|silicon>
qualification: <Comm|Ind|Automotive|Mil>
cell_count: "<count>
cell_count: <count>
width: <width>
height: <height>
technology: <tech>
Expand Down