diff --git a/Bender.lock b/Bender.lock
index 5c6de69..eb0f76a 100644
--- a/Bender.lock
+++ b/Bender.lock
@@ -7,8 +7,8 @@ packages:
dependencies:
- common_cells
axi:
- revision: 2f395b176bee1c769c80f060a4345fda965bb04b
- version: 0.38.0
+ revision: f07498d53ecd5518b277c7d213ec3b71ca4df93c
+ version: 0.39.7
source:
Git: https://github.com/pulp-platform/axi.git
dependencies:
@@ -16,32 +16,22 @@ packages:
- common_verification
- tech_cells_generic
common_cells:
- revision: aed978efcef722859025085ae72e52c41ea45b32
- version: 1.31.0
+ revision: 9afda9abb565971649c2aa0985639c096f351171
+ version: 1.38.0
source:
Git: https://github.com/pulp-platform/common_cells.git
dependencies:
- common_verification
- tech_cells_generic
common_verification:
- revision: 9c07fa860593b2caabd9b5681740c25fac04b878
- version: 0.2.3
+ revision: fb1885f48ea46164a10568aeff51884389f67ae3
+ version: 0.2.5
source:
Git: https://github.com/pulp-platform/common_verification.git
dependencies: []
- register_interface:
- revision: 3b2bf592100b769977c76e51812c55cd742882f6
- version: 0.4.1
- source:
- Git: https://github.com/pulp-platform/register_interface.git
- dependencies:
- - apb
- - axi
- - common_cells
- - common_verification
tech_cells_generic:
- revision: a9cae21902e75b1434328ecf36f85327ba5717de
- version: 0.2.11
+ revision: 7968dd6e6180df2c644636bc6d2908a49f2190cf
+ version: 0.2.13
source:
Git: https://github.com/pulp-platform/tech_cells_generic.git
dependencies:
diff --git a/Bender.yml b/Bender.yml
index 4a7bf5d..1025f1e 100644
--- a/Bender.yml
+++ b/Bender.yml
@@ -9,8 +9,8 @@ package:
dependencies:
common_cells: { git: "https://github.com/pulp-platform/common_cells.git", version: 1.29.0 }
- register_interface: { git: "https://github.com/pulp-platform/register_interface.git", version: 0.4.1 }
axi: { git: "https://github.com/pulp-platform/axi.git", version: 0.39.1 }
+ apb: { git: "https://github.com/pulp-platform/apb.git", version: 0.2.4 }
sources:
# Level 1
diff --git a/Makefile b/Makefile
index 529cec6..fa5715b 100644
--- a/Makefile
+++ b/Makefile
@@ -4,11 +4,32 @@
BENDER ?= bender
-REG_PATH = $(shell $(BENDER) path register_interface)
-REG_TOOL = $(REG_PATH)/vendor/lowrisc_opentitan/util/regtool.py
+PEAKRDL ?= peakrdl
-REGS_HJSON = src/err_unit_regs.hjson
+.PHONY: gen_regs
+gen_regs: src/bus_err_unit_reg_pkg.sv src/bus_err_unit_reg_top.sv
+gen_regs: doc/bus_err_unit_reg.md
+gen_regs: driver/bus_err_unit_reg.h driver/bus_err_unit_reg_addrmap.h
+gen_regs: doc/axi_bus_err_unit_reg.md
+gen_regs: driver/axi_bus_err_unit_reg.h driver/axi_bus_err_unit_reg_addrmap.h
-gen_regs:
- python $(REG_TOOL) $(REGS_HJSON) -t src -r
- python $(REG_TOOL) $(REGS_HJSON) -D > driver/bus_err_unit.h
+src/bus_err_unit_reg_pkg.sv src/bus_err_unit_reg_top.sv: rdl/bus_err_unit.rdl
+ $(PEAKRDL) regblock $< -o src --cpuif apb4-flat --default-reset arst_n --module-name bus_err_unit_reg_top --package-name bus_err_unit_reg_pkg
+
+doc/bus_err_unit_reg.md: rdl/bus_err_unit.rdl
+ $(PEAKRDL) markdown $< -o $@
+
+driver/bus_err_unit_reg.h: rdl/bus_err_unit.rdl
+ $(PEAKRDL) c-header $< -o $@
+
+driver/bus_err_unit_reg_addrmap.h: rdl/bus_err_unit.rdl
+ $(PEAKRDL) raw-header $< -o $@ --format c
+
+doc/axi_bus_err_unit_reg.md: rdl/axi_bus_err_unit.rdl rdl/bus_err_unit.rdl
+ $(PEAKRDL) markdown $< -o $@ -I rdl
+
+driver/axi_bus_err_unit_reg.h: rdl/axi_bus_err_unit.rdl rdl/bus_err_unit.rdl
+ $(PEAKRDL) c-header $< -o $@ -I rdl
+
+driver/axi_bus_err_unit_reg_addrmap.h: rdl/axi_bus_err_unit.rdl rdl/bus_err_unit.rdl
+ $(PEAKRDL) raw-header $< -o $@ --format c -I rdl
diff --git a/doc/axi_bus_err_unit_reg.md b/doc/axi_bus_err_unit_reg.md
new file mode 100644
index 0000000..5432a52
--- /dev/null
+++ b/doc/axi_bus_err_unit_reg.md
@@ -0,0 +1,155 @@
+
+
+## axi_bus_err_unit address map
+
+- Absolute Address: 0x0
+- Base Offset: 0x0
+- Size: 0x30
+
+|Offset| Identifier |Name|
+|------|--------------|----|
+| 0x00 |write_err_unit| — |
+| 0x20 | read_err_unit| — |
+
+## write_err_unit address map
+
+- Absolute Address: 0x0
+- Base Offset: 0x0
+- Size: 0x10
+
+|Offset| Identifier |Name|
+|------|------------|----|
+| 0x0 | err_addr | — |
+| 0x4 |err_addr_top| — |
+| 0x8 | err_code | — |
+| 0xC | meta | — |
+
+### err_addr register
+
+- Absolute Address: 0x0
+- Base Offset: 0x0
+- Size: 0x4
+
+|Bits|Identifier|Access|Reset| Name |
+|----|----------|------|-----|--------|
+|31:0| err_addr | r | 0x0 |err_addr|
+
+#### err_addr field
+
+
Address of the bus error
+
+### err_addr_top register
+
+- Absolute Address: 0x4
+- Base Offset: 0x4
+- Size: 0x4
+
+|Bits| Identifier |Access|Reset| Name |
+|----|------------|------|-----|------------|
+|31:0|err_addr_top| r | 0x0 |err_addr_top|
+
+#### err_addr_top field
+
+Top of the address of the bus error
+
+### err_code register
+
+- Absolute Address: 0x8
+- Base Offset: 0x8
+- Size: 0x4
+
+|Bits|Identifier|Access|Reset| Name |
+|----|----------|------|-----|--------|
+|31:0| err_code | r | 0x0 |err_code|
+
+#### err_code field
+
+Type of the bus error
+
+### meta register
+
+- Absolute Address: 0xC
+- Base Offset: 0xC
+- Size: 0x4
+
+|Bits|Identifier|Access|Reset|Name|
+|----|----------|------|-----|----|
+|31:0| meta | r | 0x0 |meta|
+
+#### meta field
+
+Meta information of the bus error
+
+## read_err_unit address map
+
+- Absolute Address: 0x20
+- Base Offset: 0x20
+- Size: 0x10
+
+|Offset| Identifier |Name|
+|------|------------|----|
+| 0x0 | err_addr | — |
+| 0x4 |err_addr_top| — |
+| 0x8 | err_code | — |
+| 0xC | meta | — |
+
+### err_addr register
+
+- Absolute Address: 0x20
+- Base Offset: 0x0
+- Size: 0x4
+
+|Bits|Identifier|Access|Reset| Name |
+|----|----------|------|-----|--------|
+|31:0| err_addr | r | 0x0 |err_addr|
+
+#### err_addr field
+
+Address of the bus error
+
+### err_addr_top register
+
+- Absolute Address: 0x24
+- Base Offset: 0x4
+- Size: 0x4
+
+|Bits| Identifier |Access|Reset| Name |
+|----|------------|------|-----|------------|
+|31:0|err_addr_top| r | 0x0 |err_addr_top|
+
+#### err_addr_top field
+
+Top of the address of the bus error
+
+### err_code register
+
+- Absolute Address: 0x28
+- Base Offset: 0x8
+- Size: 0x4
+
+|Bits|Identifier|Access|Reset| Name |
+|----|----------|------|-----|--------|
+|31:0| err_code | r | 0x0 |err_code|
+
+#### err_code field
+
+Type of the bus error
+
+### meta register
+
+- Absolute Address: 0x2C
+- Base Offset: 0xC
+- Size: 0x4
+
+|Bits|Identifier|Access|Reset|Name|
+|----|----------|------|-----|----|
+|31:0| meta | r | 0x0 |meta|
+
+#### meta field
+
+Meta information of the bus error
diff --git a/doc/bus_err_unit_reg.md b/doc/bus_err_unit_reg.md
new file mode 100644
index 0000000..d10cf18
--- /dev/null
+++ b/doc/bus_err_unit_reg.md
@@ -0,0 +1,75 @@
+
+
+## bus_err_unit address map
+
+- Absolute Address: 0x0
+- Base Offset: 0x0
+- Size: 0x10
+
+|Offset| Identifier |Name|
+|------|------------|----|
+| 0x0 | err_addr | — |
+| 0x4 |err_addr_top| — |
+| 0x8 | err_code | — |
+| 0xC | meta | — |
+
+### err_addr register
+
+- Absolute Address: 0x0
+- Base Offset: 0x0
+- Size: 0x4
+
+|Bits|Identifier|Access|Reset| Name |
+|----|----------|------|-----|--------|
+|31:0| err_addr | r | 0x0 |err_addr|
+
+#### err_addr field
+
+Address of the bus error
+
+### err_addr_top register
+
+- Absolute Address: 0x4
+- Base Offset: 0x4
+- Size: 0x4
+
+|Bits| Identifier |Access|Reset| Name |
+|----|------------|------|-----|------------|
+|31:0|err_addr_top| r | 0x0 |err_addr_top|
+
+#### err_addr_top field
+
+Top of the address of the bus error
+
+### err_code register
+
+- Absolute Address: 0x8
+- Base Offset: 0x8
+- Size: 0x4
+
+|Bits|Identifier|Access|Reset| Name |
+|----|----------|------|-----|--------|
+|31:0| err_code | r | 0x0 |err_code|
+
+#### err_code field
+
+Type of the bus error
+
+### meta register
+
+- Absolute Address: 0xC
+- Base Offset: 0xC
+- Size: 0x4
+
+|Bits|Identifier|Access|Reset|Name|
+|----|----------|------|-----|----|
+|31:0| meta | r | 0x0 |meta|
+
+#### meta field
+
+Meta information of the bus error
diff --git a/driver/axi_bus_err_unit_reg.h b/driver/axi_bus_err_unit_reg.h
new file mode 100644
index 0000000..49e60b9
--- /dev/null
+++ b/driver/axi_bus_err_unit_reg.h
@@ -0,0 +1,60 @@
+// Generated by PeakRDL-cheader - A free and open-source header generator
+// https://github.com/SystemRDL/PeakRDL-cheader
+
+#ifndef AXI_BUS_ERR_UNIT_REG_H
+#define AXI_BUS_ERR_UNIT_REG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+// Reg - bus_err_unit::err_addr
+#define BUS_ERR_UNIT__ERR_ADDR__ERR_ADDR_bm 0xffffffff
+#define BUS_ERR_UNIT__ERR_ADDR__ERR_ADDR_bp 0
+#define BUS_ERR_UNIT__ERR_ADDR__ERR_ADDR_bw 32
+#define BUS_ERR_UNIT__ERR_ADDR__ERR_ADDR_reset 0x0
+
+// Reg - bus_err_unit::err_addr_top
+#define BUS_ERR_UNIT__ERR_ADDR_TOP__ERR_ADDR_TOP_bm 0xffffffff
+#define BUS_ERR_UNIT__ERR_ADDR_TOP__ERR_ADDR_TOP_bp 0
+#define BUS_ERR_UNIT__ERR_ADDR_TOP__ERR_ADDR_TOP_bw 32
+#define BUS_ERR_UNIT__ERR_ADDR_TOP__ERR_ADDR_TOP_reset 0x0
+
+// Reg - bus_err_unit::err_code
+#define BUS_ERR_UNIT__ERR_CODE__ERR_CODE_bm 0xffffffff
+#define BUS_ERR_UNIT__ERR_CODE__ERR_CODE_bp 0
+#define BUS_ERR_UNIT__ERR_CODE__ERR_CODE_bw 32
+#define BUS_ERR_UNIT__ERR_CODE__ERR_CODE_reset 0x0
+
+// Reg - bus_err_unit::meta
+#define BUS_ERR_UNIT__META__META_bm 0xffffffff
+#define BUS_ERR_UNIT__META__META_bp 0
+#define BUS_ERR_UNIT__META__META_bw 32
+#define BUS_ERR_UNIT__META__META_reset 0x0
+
+// Addrmap - bus_err_unit
+typedef struct __attribute__ ((__packed__)) {
+ uint32_t err_addr;
+ uint32_t err_addr_top;
+ uint32_t err_code;
+ uint32_t meta;
+} bus_err_unit_t;
+
+// Addrmap - axi_bus_err_unit
+typedef struct __attribute__ ((__packed__)) {
+ bus_err_unit_t write_err_unit;
+ uint8_t RESERVED_10_1f[0x10];
+ bus_err_unit_t read_err_unit;
+} axi_bus_err_unit_t;
+
+
+static_assert(sizeof(axi_bus_err_unit_t) == 0x30, "Packing error");
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AXI_BUS_ERR_UNIT_REG_H */
diff --git a/driver/axi_bus_err_unit_reg_addrmap.h b/driver/axi_bus_err_unit_reg_addrmap.h
new file mode 100644
index 0000000..a08a4bc
--- /dev/null
+++ b/driver/axi_bus_err_unit_reg_addrmap.h
@@ -0,0 +1,42 @@
+#ifndef AXI_BUS_ERR_UNIT_H
+#define AXI_BUS_ERR_UNIT_H
+
+
+#define AXI_BUS_ERR_UNIT_BASE_ADDR 0x00000000
+#define AXI_BUS_ERR_UNIT_SIZE 0x00000030
+
+
+#define AXI_BUS_ERR_UNIT_WRITE_ERR_UNIT_BASE_ADDR 0x00000000
+#define AXI_BUS_ERR_UNIT_WRITE_ERR_UNIT_SIZE 0x00000010
+
+#define AXI_BUS_ERR_UNIT_WRITE_ERR_UNIT_ERR_ADDR_REG_ADDR 0x00000000
+#define AXI_BUS_ERR_UNIT_WRITE_ERR_UNIT_ERR_ADDR_REG_OFFSET 0x00000000
+
+#define AXI_BUS_ERR_UNIT_WRITE_ERR_UNIT_ERR_ADDR_TOP_REG_ADDR 0x00000004
+#define AXI_BUS_ERR_UNIT_WRITE_ERR_UNIT_ERR_ADDR_TOP_REG_OFFSET 0x00000004
+
+#define AXI_BUS_ERR_UNIT_WRITE_ERR_UNIT_ERR_CODE_REG_ADDR 0x00000008
+#define AXI_BUS_ERR_UNIT_WRITE_ERR_UNIT_ERR_CODE_REG_OFFSET 0x00000008
+
+#define AXI_BUS_ERR_UNIT_WRITE_ERR_UNIT_META_REG_ADDR 0x0000000C
+#define AXI_BUS_ERR_UNIT_WRITE_ERR_UNIT_META_REG_OFFSET 0x0000000C
+
+
+#define AXI_BUS_ERR_UNIT_READ_ERR_UNIT_BASE_ADDR 0x00000020
+#define AXI_BUS_ERR_UNIT_READ_ERR_UNIT_SIZE 0x00000010
+
+#define AXI_BUS_ERR_UNIT_READ_ERR_UNIT_ERR_ADDR_REG_ADDR 0x00000020
+#define AXI_BUS_ERR_UNIT_READ_ERR_UNIT_ERR_ADDR_REG_OFFSET 0x00000000
+
+#define AXI_BUS_ERR_UNIT_READ_ERR_UNIT_ERR_ADDR_TOP_REG_ADDR 0x00000024
+#define AXI_BUS_ERR_UNIT_READ_ERR_UNIT_ERR_ADDR_TOP_REG_OFFSET 0x00000004
+
+#define AXI_BUS_ERR_UNIT_READ_ERR_UNIT_ERR_CODE_REG_ADDR 0x00000028
+#define AXI_BUS_ERR_UNIT_READ_ERR_UNIT_ERR_CODE_REG_OFFSET 0x00000008
+
+#define AXI_BUS_ERR_UNIT_READ_ERR_UNIT_META_REG_ADDR 0x0000002C
+#define AXI_BUS_ERR_UNIT_READ_ERR_UNIT_META_REG_OFFSET 0x0000000C
+
+
+
+#endif /* AXI_BUS_ERR_UNIT_H */
diff --git a/driver/bus_err_unit.h b/driver/bus_err_unit.h
deleted file mode 100644
index 2ed1a0a..0000000
--- a/driver/bus_err_unit.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Generated register defines for bus_err_unit
-
-// Copyright information found in source file:
-// Copyright 2023 ETH Zurich and University of Bologna.
-
-// Licensing information found in source file:
-//
-// SPDX-License-Identifier: SHL-0.51
-
-#ifndef _BUS_ERR_UNIT_REG_DEFS_
-#define _BUS_ERR_UNIT_REG_DEFS_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-// Register width
-#define BUS_ERR_UNIT_PARAM_REG_WIDTH 32
-
-// Address of the bus error
-#define BUS_ERR_UNIT_ERR_ADDR_REG_OFFSET 0x0
-
-// Top of the address of the bus error
-#define BUS_ERR_UNIT_ERR_ADDR_TOP_REG_OFFSET 0x4
-
-// Error code of the bus error
-#define BUS_ERR_UNIT_ERR_CODE_REG_OFFSET 0x8
-
-// Meta information of the bus error
-#define BUS_ERR_UNIT_META_REG_OFFSET 0xc
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-#endif // _BUS_ERR_UNIT_REG_DEFS_
-// End generated register defines for bus_err_unit
\ No newline at end of file
diff --git a/driver/bus_err_unit_reg.h b/driver/bus_err_unit_reg.h
new file mode 100644
index 0000000..70463a6
--- /dev/null
+++ b/driver/bus_err_unit_reg.h
@@ -0,0 +1,53 @@
+// Generated by PeakRDL-cheader - A free and open-source header generator
+// https://github.com/SystemRDL/PeakRDL-cheader
+
+#ifndef BUS_ERR_UNIT_REG_H
+#define BUS_ERR_UNIT_REG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+// Reg - bus_err_unit::err_addr
+#define BUS_ERR_UNIT__ERR_ADDR__ERR_ADDR_bm 0xffffffff
+#define BUS_ERR_UNIT__ERR_ADDR__ERR_ADDR_bp 0
+#define BUS_ERR_UNIT__ERR_ADDR__ERR_ADDR_bw 32
+#define BUS_ERR_UNIT__ERR_ADDR__ERR_ADDR_reset 0x0
+
+// Reg - bus_err_unit::err_addr_top
+#define BUS_ERR_UNIT__ERR_ADDR_TOP__ERR_ADDR_TOP_bm 0xffffffff
+#define BUS_ERR_UNIT__ERR_ADDR_TOP__ERR_ADDR_TOP_bp 0
+#define BUS_ERR_UNIT__ERR_ADDR_TOP__ERR_ADDR_TOP_bw 32
+#define BUS_ERR_UNIT__ERR_ADDR_TOP__ERR_ADDR_TOP_reset 0x0
+
+// Reg - bus_err_unit::err_code
+#define BUS_ERR_UNIT__ERR_CODE__ERR_CODE_bm 0xffffffff
+#define BUS_ERR_UNIT__ERR_CODE__ERR_CODE_bp 0
+#define BUS_ERR_UNIT__ERR_CODE__ERR_CODE_bw 32
+#define BUS_ERR_UNIT__ERR_CODE__ERR_CODE_reset 0x0
+
+// Reg - bus_err_unit::meta
+#define BUS_ERR_UNIT__META__META_bm 0xffffffff
+#define BUS_ERR_UNIT__META__META_bp 0
+#define BUS_ERR_UNIT__META__META_bw 32
+#define BUS_ERR_UNIT__META__META_reset 0x0
+
+// Addrmap - bus_err_unit
+typedef struct __attribute__ ((__packed__)) {
+ uint32_t err_addr;
+ uint32_t err_addr_top;
+ uint32_t err_code;
+ uint32_t meta;
+} bus_err_unit_t;
+
+
+static_assert(sizeof(bus_err_unit_t) == 0x10, "Packing error");
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BUS_ERR_UNIT_REG_H */
diff --git a/driver/bus_err_unit_reg_addrmap.h b/driver/bus_err_unit_reg_addrmap.h
new file mode 100644
index 0000000..be8a216
--- /dev/null
+++ b/driver/bus_err_unit_reg_addrmap.h
@@ -0,0 +1,22 @@
+#ifndef BUS_ERR_UNIT_H
+#define BUS_ERR_UNIT_H
+
+
+#define BUS_ERR_UNIT_BASE_ADDR 0x00000000
+#define BUS_ERR_UNIT_SIZE 0x00000010
+
+#define BUS_ERR_UNIT_ERR_ADDR_REG_ADDR 0x00000000
+#define BUS_ERR_UNIT_ERR_ADDR_REG_OFFSET 0x00000000
+
+#define BUS_ERR_UNIT_ERR_ADDR_TOP_REG_ADDR 0x00000004
+#define BUS_ERR_UNIT_ERR_ADDR_TOP_REG_OFFSET 0x00000004
+
+#define BUS_ERR_UNIT_ERR_CODE_REG_ADDR 0x00000008
+#define BUS_ERR_UNIT_ERR_CODE_REG_OFFSET 0x00000008
+
+#define BUS_ERR_UNIT_META_REG_ADDR 0x0000000C
+#define BUS_ERR_UNIT_META_REG_OFFSET 0x0000000C
+
+
+
+#endif /* BUS_ERR_UNIT_H */
diff --git a/rdl/axi_bus_err_unit.rdl b/rdl/axi_bus_err_unit.rdl
new file mode 100644
index 0000000..101bd70
--- /dev/null
+++ b/rdl/axi_bus_err_unit.rdl
@@ -0,0 +1,17 @@
+// Copyright 2025 ETH Zurich and University of Bologna.
+// Solderpad Hardware License, Version 0.51, see LICENSE for details.
+// SPDX-License-Identifier: SHL-0.51
+
+// Author: Michael Rogenmoser
+
+`ifndef AXI_BUS_ERR_UNIT_RDL
+`define AXI_BUS_ERR_UNIT_RDL
+
+`include "bus_err_unit.rdl"
+
+addrmap axi_bus_err_unit {
+ bus_err_unit write_err_unit @0x0;
+ bus_err_unit read_err_unit @0x20;
+};
+
+`endif // AXI_BUS_ERR_UNIT_RDL
diff --git a/rdl/bus_err_unit.rdl b/rdl/bus_err_unit.rdl
new file mode 100644
index 0000000..f723366
--- /dev/null
+++ b/rdl/bus_err_unit.rdl
@@ -0,0 +1,55 @@
+// Copyright 2025 ETH Zurich and University of Bologna.
+// Solderpad Hardware License, Version 0.51, see LICENSE for details.
+// SPDX-License-Identifier: SHL-0.51
+
+// Author: Michael Rogenmoser
+
+`ifndef BUS_ERR_UNIT_RDL
+`define BUS_ERR_UNIT_RDL
+
+addrmap bus_err_unit {
+
+ reg err_addr {
+ field {
+ name = "err_addr";
+ desc = "Address of the bus error";
+ sw = r;
+ hw = w;
+ } err_addr[31:0] = 0x0;
+ };
+
+ reg err_addr_top {
+ field {
+ name = "err_addr_top";
+ desc = "Top of the address of the bus error";
+ sw = r;
+ hw = w;
+ } err_addr_top[31:0] = 0x0;
+ };
+
+ reg err_code {
+ field {
+ name = "err_code";
+ desc = "Type of the bus error";
+ sw = r;
+ hw = rw;
+ // TODO: hwre
+ } err_code[31:0] = 0x0;
+ };
+
+ reg meta {
+ field {
+ name = "meta";
+ desc = "Meta information of the bus error";
+ sw = r;
+ hw = rw;
+ } meta[31:0] = 0x0;
+ };
+
+ external err_addr err_addr;
+ external err_addr_top err_addr_top;
+ external err_code err_code;
+ external meta meta;
+};
+
+`endif // BUS_ERR_UNIT_RDL
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..7d0588d
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,8 @@
+# Copyright 2025 ETH Zurich and University of Bologna.
+# Solderpad Hardware License, Version 0.51, see LICENSE for details.
+# SPDX-License-Identifier: SHL-0.51
+
+peakrdl
+peakrdl-cheader
+peakrdl-markdown
+peakrdl-rawheader @ git+github.com/micprog/peakrdl-rawheader.git
diff --git a/src/axi_err_unit_wrap.sv b/src/axi_err_unit_wrap.sv
index e53b4a7..5b8c1a8 100644
--- a/src/axi_err_unit_wrap.sv
+++ b/src/axi_err_unit_wrap.sv
@@ -15,8 +15,8 @@ module axi_err_unit_wrap #(
parameter bit DropOldest = 1'b0,
parameter type axi_req_t = logic,
parameter type axi_rsp_t = logic,
- parameter type reg_req_t = logic,
- parameter type reg_rsp_t = logic
+ parameter type apb_req_t = logic,
+ parameter type apb_rsp_t = logic
) (
input logic clk_i,
input logic rst_ni,
@@ -27,14 +27,14 @@ module axi_err_unit_wrap #(
output logic [1:0] err_irq_o,
- input reg_req_t reg_req_i,
- output reg_rsp_t reg_rsp_o
+ input apb_req_t apb_req_i,
+ output apb_rsp_t apb_rsp_o
);
logic [2**IdWidth-1:0] write_req_hs_valid, write_rsp_hs_valid, read_req_hs_valid, read_rsp_hs_valid, amo_r_req_hs_valid;
logic [UserErrBits+2-1:0] write_err, read_err;
- reg_req_t [1:0] reg_req_internal;
- reg_rsp_t [1:0] reg_rsp_internal;
+ apb_req_t [1:0] apb_req_internal;
+ apb_rsp_t [1:0] apb_rsp_internal;
for (genvar i = 0; i < 2**IdWidth; i++) begin
assign write_req_hs_valid[i] = axi_req_i.aw_valid & axi_rsp_i.aw_ready & (axi_req_i.aw.id == i);
@@ -53,18 +53,16 @@ module axi_err_unit_wrap #(
assign read_err[UserErrBits+2-1:2] = axi_rsp_i.r.user[UserErrBits+UserErrBitsOffset-1:UserErrBitsOffset];
end
- reg_demux #(
- .NoPorts ( 2 ),
- .req_t ( reg_req_t ),
- .rsp_t ( reg_rsp_t )
- ) i_reg_demux (
- .clk_i,
- .rst_ni,
- .in_select_i(reg_req_i.addr[5]),
- .in_req_i (reg_req_i),
- .in_rsp_o (reg_rsp_o),
- .out_req_o (reg_req_internal),
- .out_rsp_i (reg_rsp_internal)
+ apb_demux #(
+ .NoMstPorts ( 2 ),
+ .req_t ( apb_req_t ),
+ .resp_t ( apb_rsp_t )
+ ) i_apb_demux (
+ .select_i (apb_req_i.addr[5]),
+ .slv_req_i (apb_req_i),
+ .slv_resp_o (apb_rsp_o),
+ .mst_req_o (apb_req_internal),
+ .mst_resp_i (apb_rsp_internal)
);
bus_err_unit #(
@@ -76,8 +74,8 @@ module axi_err_unit_wrap #(
.NumReqPorts (1),
.NumChannels (2**IdWidth),
.DropOldest (DropOldest),
- .reg_req_t (reg_req_t),
- .reg_rsp_t (reg_rsp_t)
+ .apb_req_t (apb_req_t),
+ .apb_rsp_t (apb_rsp_t)
) i_write_err_unit (
.clk_i,
.rst_ni,
@@ -92,8 +90,8 @@ module axi_err_unit_wrap #(
.err_irq_o ( err_irq_o[0] ),
- .reg_req_i (reg_req_internal[0]),
- .reg_rsp_o (reg_rsp_internal[0])
+ .apb_req_i (apb_req_internal[0]),
+ .apb_rsp_o (apb_rsp_internal[0])
);
bus_err_unit #(
@@ -105,8 +103,8 @@ module axi_err_unit_wrap #(
.NumReqPorts (2),
.NumChannels (2**IdWidth),
.DropOldest (DropOldest),
- .reg_req_t (reg_req_t),
- .reg_rsp_t (reg_rsp_t)
+ .apb_req_t (apb_req_t),
+ .apb_rsp_t (apb_rsp_t)
) i_read_err_unit (
.clk_i,
@@ -122,8 +120,8 @@ module axi_err_unit_wrap #(
.err_irq_o ( err_irq_o[1] ),
- .reg_req_i (reg_req_internal[1]),
- .reg_rsp_o (reg_rsp_internal[1])
+ .apb_req_i (apb_req_internal[1]),
+ .apb_rsp_o (apb_rsp_internal[1])
);
diff --git a/src/bus_err_unit.sv b/src/bus_err_unit.sv
index 26d15fd..8a1967f 100644
--- a/src/bus_err_unit.sv
+++ b/src/bus_err_unit.sv
@@ -14,8 +14,8 @@ module bus_err_unit #(
parameter int unsigned NumReqPorts = 1,
parameter int unsigned NumChannels = 1, // Channels are one-hot!
parameter bit DropOldest = 1'b0,
- parameter type reg_req_t = logic,
- parameter type reg_rsp_t = logic
+ parameter type apb_req_t = logic,
+ parameter type apb_rsp_t = logic
) (
input logic clk_i,
input logic rst_ni,
@@ -30,8 +30,8 @@ module bus_err_unit #(
output logic err_irq_o,
- input reg_req_t reg_req_i,
- output reg_rsp_t reg_rsp_o
+ input apb_req_t apb_req_i,
+ output apb_rsp_t apb_rsp_o
);
@@ -40,39 +40,48 @@ module bus_err_unit #(
logic [ ErrBits-1:0] read_err_err;
logic read_err_overflow;
- bus_err_unit_reg_pkg::bus_err_unit_reg2hw_t reg2hw;
- bus_err_unit_reg_pkg::bus_err_unit_hw2reg_t hw2reg;
+ bus_err_unit_reg_pkg::bus_err_unit__out_t reg2hw;
+ bus_err_unit_reg_pkg::bus_err_unit__in_t hw2reg;
- assign hw2reg.err_addr.d = read_err_addr[31:0];
+ assign hw2reg.err_addr.rd_data.err_addr = read_err_addr[31:0];
if (AddrWidth > 32) begin
always_comb begin
- hw2reg.err_addr_top.d = '0;
- hw2reg.err_addr_top.d[AddrWidth-32-1:0] = read_err_addr[AddrWidth-1:32];
+ hw2reg.err_addr_top.rd_data.err_addr_top = '0;
+ hw2reg.err_addr_top.rd_data.err_addr_top[AddrWidth-32-1:0] = read_err_addr[AddrWidth-1:32];
end
end else begin
- assign hw2reg.err_addr_top.d = '0;
+ assign hw2reg.err_addr_top.rd_data.err_addr_top = '0;
end
always_comb begin : proc_err_code
- hw2reg.err_code.d = '0;
- hw2reg.err_code.d[ErrBits-1:0] = read_err_err;
- hw2reg.err_code.d[31] = read_err_overflow;
+ hw2reg.err_code.rd_data.err_code = '0;
+ hw2reg.err_code.rd_data.err_code[ErrBits-1:0] = read_err_err;
+ hw2reg.err_code.rd_data.err_code[31] = read_err_overflow;
end
always_comb begin
- hw2reg.meta.d = '0;
- hw2reg.meta.d[MetaDataWidth-1:0] = read_err_meta;
+ hw2reg.meta.rd_data.meta = '0;
+ hw2reg.meta.rd_data.meta[MetaDataWidth-1:0] = read_err_meta;
end
- bus_err_unit_reg_top #(
- .reg_req_t ( reg_req_t ),
- .reg_rsp_t ( reg_rsp_t )
- ) i_regs (
- .clk_i,
- .rst_ni,
- .reg_req_i,
- .reg_rsp_o,
- .reg2hw (reg2hw),
- .hw2reg (hw2reg),
- .devmode_i ('0)
+ assign hw2reg.err_addr.rd_ack = reg2hw.err_addr.req & ~reg2hw.err_addr.req_is_wr;
+ assign hw2reg.err_addr_top.rd_ack = reg2hw.err_addr_top.req & ~reg2hw.err_addr_top.req_is_wr;
+ assign hw2reg.err_code.rd_ack = reg2hw.err_code.req & ~reg2hw.err_code.req_is_wr;
+ assign hw2reg.meta.rd_ack = reg2hw.meta.req & ~reg2hw.meta.req_is_wr;
+
+ bus_err_unit_reg_top i_regs (
+ .clk (clk_i),
+ .arst_n (rst_ni),
+ .s_apb_psel (apb_req_i.psel),
+ .s_apb_penable (apb_req_i.penable),
+ .s_apb_pwrite (apb_req_i.pwrite),
+ .s_apb_pprot (apb_req_i.pprot),
+ .s_apb_paddr (apb_req_i.paddr[bus_err_unit_reg_pkg::BUS_ERR_UNIT_REG_TOP_MIN_ADDR_WIDTH-1:0]),
+ .s_apb_pwdata (apb_req_i.pwdata),
+ .s_apb_pstrb (apb_req_i.pstrb),
+ .s_apb_pready (apb_rsp_o.pready),
+ .s_apb_prdata (apb_rsp_o.prdata),
+ .s_apb_pslverr (apb_rsp_o.pslverr),
+ .hwif_out (reg2hw),
+ .hwif_in (hw2reg)
);
bus_err_unit_bare #(
@@ -98,7 +107,7 @@ module bus_err_unit #(
.err_irq_o,
- .err_fifo_pop_i ( reg2hw.err_code.re ),
+ .err_fifo_pop_i ( reg2hw.err_code.req & ~reg2hw.err_code.req_is_wr ),
.err_code_o ( read_err_err ),
.err_addr_o ( read_err_addr ),
.err_meta_o ( read_err_meta ),
diff --git a/src/bus_err_unit_reg_pkg.sv b/src/bus_err_unit_reg_pkg.sv
index c05d536..fee9e90 100644
--- a/src/bus_err_unit_reg_pkg.sv
+++ b/src/bus_err_unit_reg_pkg.sv
@@ -1,79 +1,81 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Register Package auto-generated by `reggen` containing data structure
+// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
+// https://github.com/SystemRDL/PeakRDL-regblock
package bus_err_unit_reg_pkg;
- // Address widths within the block
- parameter int BlockAw = 4;
-
- ////////////////////////////
- // Typedefs for registers //
- ////////////////////////////
-
- typedef struct packed {
- logic [31:0] q;
- logic re;
- } bus_err_unit_reg2hw_err_code_reg_t;
-
- typedef struct packed {
- logic [31:0] d;
- } bus_err_unit_hw2reg_err_addr_reg_t;
-
- typedef struct packed {
- logic [31:0] d;
- } bus_err_unit_hw2reg_err_addr_top_reg_t;
-
- typedef struct packed {
- logic [31:0] d;
- } bus_err_unit_hw2reg_err_code_reg_t;
-
- typedef struct packed {
- logic [31:0] d;
- } bus_err_unit_hw2reg_meta_reg_t;
-
- // Register -> HW type
- typedef struct packed {
- bus_err_unit_reg2hw_err_code_reg_t err_code; // [32:0]
- } bus_err_unit_reg2hw_t;
-
- // HW -> register type
- typedef struct packed {
- bus_err_unit_hw2reg_err_addr_reg_t err_addr; // [127:96]
- bus_err_unit_hw2reg_err_addr_top_reg_t err_addr_top; // [95:64]
- bus_err_unit_hw2reg_err_code_reg_t err_code; // [63:32]
- bus_err_unit_hw2reg_meta_reg_t meta; // [31:0]
- } bus_err_unit_hw2reg_t;
-
- // Register offsets
- parameter logic [BlockAw-1:0] BUS_ERR_UNIT_ERR_ADDR_OFFSET = 4'h 0;
- parameter logic [BlockAw-1:0] BUS_ERR_UNIT_ERR_ADDR_TOP_OFFSET = 4'h 4;
- parameter logic [BlockAw-1:0] BUS_ERR_UNIT_ERR_CODE_OFFSET = 4'h 8;
- parameter logic [BlockAw-1:0] BUS_ERR_UNIT_META_OFFSET = 4'h c;
-
- // Reset values for hwext registers and their fields
- parameter logic [31:0] BUS_ERR_UNIT_ERR_ADDR_RESVAL = 32'h 0;
- parameter logic [31:0] BUS_ERR_UNIT_ERR_ADDR_TOP_RESVAL = 32'h 0;
- parameter logic [31:0] BUS_ERR_UNIT_ERR_CODE_RESVAL = 32'h 0;
- parameter logic [31:0] BUS_ERR_UNIT_META_RESVAL = 32'h 0;
-
- // Register index
- typedef enum int {
- BUS_ERR_UNIT_ERR_ADDR,
- BUS_ERR_UNIT_ERR_ADDR_TOP,
- BUS_ERR_UNIT_ERR_CODE,
- BUS_ERR_UNIT_META
- } bus_err_unit_id_e;
-
- // Register width information to check illegal writes
- parameter logic [3:0] BUS_ERR_UNIT_PERMIT [4] = '{
- 4'b 1111, // index[0] BUS_ERR_UNIT_ERR_ADDR
- 4'b 1111, // index[1] BUS_ERR_UNIT_ERR_ADDR_TOP
- 4'b 1111, // index[2] BUS_ERR_UNIT_ERR_CODE
- 4'b 1111 // index[3] BUS_ERR_UNIT_META
- };
-
+ localparam BUS_ERR_UNIT_REG_TOP_DATA_WIDTH = 32;
+ localparam BUS_ERR_UNIT_REG_TOP_MIN_ADDR_WIDTH = 4;
+ localparam BUS_ERR_UNIT_REG_TOP_SIZE = 'h10;
+
+
+
+ typedef struct packed {
+ logic [31:0] err_addr;
+ } bus_err_unit__err_addr__external__fields__in_t;
+
+ typedef struct {
+ logic rd_ack;
+ bus_err_unit__err_addr__external__fields__in_t rd_data;
+ } bus_err_unit__err_addr__external__in_t;
+
+ typedef struct packed {
+ logic [31:0] err_addr_top;
+ } bus_err_unit__err_addr_top__external__fields__in_t;
+
+ typedef struct {
+ logic rd_ack;
+ bus_err_unit__err_addr_top__external__fields__in_t rd_data;
+ } bus_err_unit__err_addr_top__external__in_t;
+
+ typedef struct packed {
+ logic [31:0] err_code;
+ } bus_err_unit__err_code__external__fields__in_t;
+
+ typedef struct {
+ logic rd_ack;
+ bus_err_unit__err_code__external__fields__in_t rd_data;
+ } bus_err_unit__err_code__external__in_t;
+
+ typedef struct packed {
+ logic [31:0] meta;
+ } bus_err_unit__meta__external__fields__in_t;
+
+ typedef struct {
+ logic rd_ack;
+ bus_err_unit__meta__external__fields__in_t rd_data;
+ } bus_err_unit__meta__external__in_t;
+
+ typedef struct {
+ bus_err_unit__err_addr__external__in_t err_addr;
+ bus_err_unit__err_addr_top__external__in_t err_addr_top;
+ bus_err_unit__err_code__external__in_t err_code;
+ bus_err_unit__meta__external__in_t meta;
+ } bus_err_unit__in_t;
+
+ typedef struct {
+ logic req;
+ logic req_is_wr;
+ } bus_err_unit__err_addr__external__out_t;
+
+ typedef struct {
+ logic req;
+ logic req_is_wr;
+ } bus_err_unit__err_addr_top__external__out_t;
+
+ typedef struct {
+ logic req;
+ logic req_is_wr;
+ } bus_err_unit__err_code__external__out_t;
+
+ typedef struct {
+ logic req;
+ logic req_is_wr;
+ } bus_err_unit__meta__external__out_t;
+
+ typedef struct {
+ bus_err_unit__err_addr__external__out_t err_addr;
+ bus_err_unit__err_addr_top__external__out_t err_addr_top;
+ bus_err_unit__err_code__external__out_t err_code;
+ bus_err_unit__meta__external__out_t meta;
+ } bus_err_unit__out_t;
endpackage
-
diff --git a/src/bus_err_unit_reg_top.sv b/src/bus_err_unit_reg_top.sv
index c35d7ff..ed50fd9 100644
--- a/src/bus_err_unit_reg_top.sv
+++ b/src/bus_err_unit_reg_top.sv
@@ -1,265 +1,219 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Register Top module auto-generated by `reggen`
-
-
-`include "common_cells/assertions.svh"
-
-module bus_err_unit_reg_top #(
- parameter type reg_req_t = logic,
- parameter type reg_rsp_t = logic,
- parameter int AW = 4
-) (
- input logic clk_i,
- input logic rst_ni,
- input reg_req_t reg_req_i,
- output reg_rsp_t reg_rsp_o,
- // To HW
- output bus_err_unit_reg_pkg::bus_err_unit_reg2hw_t reg2hw, // Write
- input bus_err_unit_reg_pkg::bus_err_unit_hw2reg_t hw2reg, // Read
-
-
- // Config
- input devmode_i // If 1, explicit error return for unmapped register access
-);
-
- import bus_err_unit_reg_pkg::* ;
-
- localparam int DW = 32;
- localparam int DBW = DW/8; // Byte Width
-
- // register signals
- logic reg_we;
- logic reg_re;
- logic [BlockAw-1:0] reg_addr;
- logic [DW-1:0] reg_wdata;
- logic [DBW-1:0] reg_be;
- logic [DW-1:0] reg_rdata;
- logic reg_error;
-
- logic addrmiss, wr_err;
-
- logic [DW-1:0] reg_rdata_next;
-
- // Below register interface can be changed
- reg_req_t reg_intf_req;
- reg_rsp_t reg_intf_rsp;
-
-
- assign reg_intf_req = reg_req_i;
- assign reg_rsp_o = reg_intf_rsp;
-
-
- assign reg_we = reg_intf_req.valid & reg_intf_req.write;
- assign reg_re = reg_intf_req.valid & ~reg_intf_req.write;
- assign reg_addr = reg_intf_req.addr[BlockAw-1:0];
- assign reg_wdata = reg_intf_req.wdata;
- assign reg_be = reg_intf_req.wstrb;
- assign reg_intf_rsp.rdata = reg_rdata;
- assign reg_intf_rsp.error = reg_error;
- assign reg_intf_rsp.ready = 1'b1;
-
- assign reg_rdata = reg_rdata_next ;
- assign reg_error = (devmode_i & addrmiss) | wr_err;
-
-
- // Define SW related signals
- // Format: __{wd|we|qs}
- // or _{wd|we|qs} if field == 1 or 0
- logic [31:0] err_addr_qs;
- logic err_addr_re;
- logic [31:0] err_addr_top_qs;
- logic err_addr_top_re;
- logic [31:0] err_code_qs;
- logic err_code_re;
- logic [31:0] meta_qs;
- logic meta_re;
-
- // Register instances
- // R[err_addr]: V(True)
-
- prim_subreg_ext #(
- .DW (32)
- ) u_err_addr (
- .re (err_addr_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.err_addr.d),
- .qre (),
- .qe (),
- .q (),
- .qs (err_addr_qs)
- );
-
-
- // R[err_addr_top]: V(True)
-
- prim_subreg_ext #(
- .DW (32)
- ) u_err_addr_top (
- .re (err_addr_top_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.err_addr_top.d),
- .qre (),
- .qe (),
- .q (),
- .qs (err_addr_top_qs)
- );
-
-
- // R[err_code]: V(True)
-
- prim_subreg_ext #(
- .DW (32)
- ) u_err_code (
- .re (err_code_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.err_code.d),
- .qre (reg2hw.err_code.re),
- .qe (),
- .q (reg2hw.err_code.q ),
- .qs (err_code_qs)
- );
-
-
- // R[meta]: V(True)
-
- prim_subreg_ext #(
- .DW (32)
- ) u_meta (
- .re (meta_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.meta.d),
- .qre (),
- .qe (),
- .q (),
- .qs (meta_qs)
- );
-
-
-
-
- logic [3:0] addr_hit;
- always_comb begin
- addr_hit = '0;
- addr_hit[0] = (reg_addr == BUS_ERR_UNIT_ERR_ADDR_OFFSET);
- addr_hit[1] = (reg_addr == BUS_ERR_UNIT_ERR_ADDR_TOP_OFFSET);
- addr_hit[2] = (reg_addr == BUS_ERR_UNIT_ERR_CODE_OFFSET);
- addr_hit[3] = (reg_addr == BUS_ERR_UNIT_META_OFFSET);
- end
-
- assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
-
- // Check sub-word write is permitted
- always_comb begin
- wr_err = (reg_we &
- ((addr_hit[0] & (|(BUS_ERR_UNIT_PERMIT[0] & ~reg_be))) |
- (addr_hit[1] & (|(BUS_ERR_UNIT_PERMIT[1] & ~reg_be))) |
- (addr_hit[2] & (|(BUS_ERR_UNIT_PERMIT[2] & ~reg_be))) |
- (addr_hit[3] & (|(BUS_ERR_UNIT_PERMIT[3] & ~reg_be)))));
- end
-
- assign err_addr_re = addr_hit[0] & reg_re & !reg_error;
-
- assign err_addr_top_re = addr_hit[1] & reg_re & !reg_error;
-
- assign err_code_re = addr_hit[2] & reg_re & !reg_error;
-
- assign meta_re = addr_hit[3] & reg_re & !reg_error;
-
- // Read data return
- always_comb begin
- reg_rdata_next = '0;
- unique case (1'b1)
- addr_hit[0]: begin
- reg_rdata_next[31:0] = err_addr_qs;
- end
-
- addr_hit[1]: begin
- reg_rdata_next[31:0] = err_addr_top_qs;
- end
-
- addr_hit[2]: begin
- reg_rdata_next[31:0] = err_code_qs;
- end
-
- addr_hit[3]: begin
- reg_rdata_next[31:0] = meta_qs;
- end
-
- default: begin
- reg_rdata_next = '1;
- end
- endcase
- end
-
- // Unused signal tieoff
-
- // wdata / byte enable are not always fully used
- // add a blanket unused statement to handle lint waivers
- logic unused_wdata;
- logic unused_be;
- assign unused_wdata = ^reg_wdata;
- assign unused_be = ^reg_be;
-
- // Assertions for Register Interface
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
-
-endmodule
-
-module bus_err_unit_reg_top_intf
-#(
- parameter int AW = 4,
- localparam int DW = 32
-) (
- input logic clk_i,
- input logic rst_ni,
- REG_BUS.in regbus_slave,
- // To HW
- output bus_err_unit_reg_pkg::bus_err_unit_reg2hw_t reg2hw, // Write
- input bus_err_unit_reg_pkg::bus_err_unit_hw2reg_t hw2reg, // Read
- // Config
- input devmode_i // If 1, explicit error return for unmapped register access
-);
- localparam int unsigned STRB_WIDTH = DW/8;
-
-`include "register_interface/typedef.svh"
-`include "register_interface/assign.svh"
-
- // Define structs for reg_bus
- typedef logic [AW-1:0] addr_t;
- typedef logic [DW-1:0] data_t;
- typedef logic [STRB_WIDTH-1:0] strb_t;
- `REG_BUS_TYPEDEF_ALL(reg_bus, addr_t, data_t, strb_t)
-
- reg_bus_req_t s_reg_req;
- reg_bus_rsp_t s_reg_rsp;
-
- // Assign SV interface to structs
- `REG_BUS_ASSIGN_TO_REQ(s_reg_req, regbus_slave)
- `REG_BUS_ASSIGN_FROM_RSP(regbus_slave, s_reg_rsp)
-
-
-
- bus_err_unit_reg_top #(
- .reg_req_t(reg_bus_req_t),
- .reg_rsp_t(reg_bus_rsp_t),
- .AW(AW)
- ) i_regs (
- .clk_i,
- .rst_ni,
- .reg_req_i(s_reg_req),
- .reg_rsp_o(s_reg_rsp),
- .reg2hw, // Write
- .hw2reg, // Read
- .devmode_i
- );
-
+// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
+// https://github.com/SystemRDL/PeakRDL-regblock
+
+module bus_err_unit_reg_top (
+ input wire clk,
+ input wire arst_n,
+
+ input wire s_apb_psel,
+ input wire s_apb_penable,
+ input wire s_apb_pwrite,
+ input wire [2:0] s_apb_pprot,
+ input wire [3:0] s_apb_paddr,
+ input wire [31:0] s_apb_pwdata,
+ input wire [3:0] s_apb_pstrb,
+ output logic s_apb_pready,
+ output logic [31:0] s_apb_prdata,
+ output logic s_apb_pslverr,
+
+ input bus_err_unit_reg_pkg::bus_err_unit__in_t hwif_in,
+ output bus_err_unit_reg_pkg::bus_err_unit__out_t hwif_out
+ );
+
+ //--------------------------------------------------------------------------
+ // CPU Bus interface logic
+ //--------------------------------------------------------------------------
+ logic cpuif_req;
+ logic cpuif_req_is_wr;
+ logic [3:0] cpuif_addr;
+ logic [31:0] cpuif_wr_data;
+ logic [31:0] cpuif_wr_biten;
+ logic cpuif_req_stall_wr;
+ logic cpuif_req_stall_rd;
+
+ logic cpuif_rd_ack;
+ logic cpuif_rd_err;
+ logic [31:0] cpuif_rd_data;
+
+ logic cpuif_wr_ack;
+ logic cpuif_wr_err;
+
+ // Request
+ logic is_active;
+ always_ff @(posedge clk or negedge arst_n) begin
+ if(~arst_n) begin
+ is_active <= '0;
+ cpuif_req <= '0;
+ cpuif_req_is_wr <= '0;
+ cpuif_addr <= '0;
+ cpuif_wr_data <= '0;
+ cpuif_wr_biten <= '0;
+ end else begin
+ if(~is_active) begin
+ if(s_apb_psel) begin
+ is_active <= '1;
+ cpuif_req <= '1;
+ cpuif_req_is_wr <= s_apb_pwrite;
+ cpuif_addr <= {s_apb_paddr[3:2], 2'b0};
+ cpuif_wr_data <= s_apb_pwdata;
+ for(int i=0; i<4; i++) begin
+ cpuif_wr_biten[i*8 +: 8] <= {8{s_apb_pstrb[i]}};
+ end
+ end
+ end else begin
+ cpuif_req <= '0;
+ if(cpuif_rd_ack || cpuif_wr_ack) begin
+ is_active <= '0;
+ end
+ end
+ end
+ end
+
+ // Response
+ assign s_apb_pready = cpuif_rd_ack | cpuif_wr_ack;
+ assign s_apb_prdata = cpuif_rd_data;
+ assign s_apb_pslverr = cpuif_rd_err | cpuif_wr_err;
+
+ logic cpuif_req_masked;
+ logic external_req;
+ logic external_pending;
+ logic external_wr_ack;
+ logic external_rd_ack;
+ always_ff @(posedge clk or negedge arst_n) begin
+ if(~arst_n) begin
+ external_pending <= '0;
+ end else begin
+ if(external_req & ~external_wr_ack & ~external_rd_ack) external_pending <= '1;
+ else if(external_wr_ack | external_rd_ack) external_pending <= '0;
+ `ifndef SYNTHESIS
+ assert(!external_wr_ack || (external_pending | external_req))
+ else $error("An external wr_ack strobe was asserted when no external request was active");
+ assert(!external_rd_ack || (external_pending | external_req))
+ else $error("An external rd_ack strobe was asserted when no external request was active");
+ `endif
+ end
+ end
+
+ // Read & write latencies are balanced. Stalls not required
+ // except if external
+ assign cpuif_req_stall_rd = external_pending;
+ assign cpuif_req_stall_wr = external_pending;
+ assign cpuif_req_masked = cpuif_req
+ & !(!cpuif_req_is_wr & cpuif_req_stall_rd)
+ & !(cpuif_req_is_wr & cpuif_req_stall_wr);
+
+ //--------------------------------------------------------------------------
+ // Address Decode
+ //--------------------------------------------------------------------------
+ typedef struct {
+ logic err_addr;
+ logic err_addr_top;
+ logic err_code;
+ logic meta;
+ } decoded_reg_strb_t;
+ decoded_reg_strb_t decoded_reg_strb;
+ logic decoded_strb_is_external;
+
+ logic decoded_req;
+ logic decoded_req_is_wr;
+ logic [31:0] decoded_wr_data;
+ logic [31:0] decoded_wr_biten;
+
+ always_comb begin
+ automatic logic is_external;
+ is_external = '0;
+ decoded_reg_strb.err_addr = cpuif_req_masked & (cpuif_addr == 4'h0);
+ is_external |= cpuif_req_masked & (cpuif_addr == 4'h0) & !cpuif_req_is_wr;
+ decoded_reg_strb.err_addr_top = cpuif_req_masked & (cpuif_addr == 4'h4);
+ is_external |= cpuif_req_masked & (cpuif_addr == 4'h4) & !cpuif_req_is_wr;
+ decoded_reg_strb.err_code = cpuif_req_masked & (cpuif_addr == 4'h8);
+ is_external |= cpuif_req_masked & (cpuif_addr == 4'h8) & !cpuif_req_is_wr;
+ decoded_reg_strb.meta = cpuif_req_masked & (cpuif_addr == 4'hc);
+ is_external |= cpuif_req_masked & (cpuif_addr == 4'hc) & !cpuif_req_is_wr;
+ decoded_strb_is_external = is_external;
+ external_req = is_external;
+ end
+
+ // Pass down signals to next stage
+ assign decoded_req = cpuif_req_masked;
+ assign decoded_req_is_wr = cpuif_req_is_wr;
+ assign decoded_wr_data = cpuif_wr_data;
+ assign decoded_wr_biten = cpuif_wr_biten;
+
+ //--------------------------------------------------------------------------
+ // Field logic
+ //--------------------------------------------------------------------------
+
+
+
+
+
+ assign hwif_out.err_addr.req = !decoded_req_is_wr ? decoded_reg_strb.err_addr : '0;
+ assign hwif_out.err_addr.req_is_wr = decoded_req_is_wr;
+
+ assign hwif_out.err_addr_top.req = !decoded_req_is_wr ? decoded_reg_strb.err_addr_top : '0;
+ assign hwif_out.err_addr_top.req_is_wr = decoded_req_is_wr;
+
+ assign hwif_out.err_code.req = !decoded_req_is_wr ? decoded_reg_strb.err_code : '0;
+ assign hwif_out.err_code.req_is_wr = decoded_req_is_wr;
+
+ assign hwif_out.meta.req = !decoded_req_is_wr ? decoded_reg_strb.meta : '0;
+ assign hwif_out.meta.req_is_wr = decoded_req_is_wr;
+
+ //--------------------------------------------------------------------------
+ // Write response
+ //--------------------------------------------------------------------------
+ always_comb begin
+ automatic logic wr_ack;
+ wr_ack = '0;
+
+ external_wr_ack = wr_ack;
+ end
+ assign cpuif_wr_ack = external_wr_ack | (decoded_req & decoded_req_is_wr & ~decoded_strb_is_external);
+ // Writes are always granted with no error response
+ assign cpuif_wr_err = '0;
+
+ //--------------------------------------------------------------------------
+ // Readback
+ //--------------------------------------------------------------------------
+ logic readback_external_rd_ack_c;
+ always_comb begin
+ automatic logic rd_ack;
+ rd_ack = '0;
+ rd_ack |= hwif_in.err_addr.rd_ack;
+ rd_ack |= hwif_in.err_addr_top.rd_ack;
+ rd_ack |= hwif_in.err_code.rd_ack;
+ rd_ack |= hwif_in.meta.rd_ack;
+ readback_external_rd_ack_c = rd_ack;
+ end
+
+ logic readback_external_rd_ack;
+
+ assign readback_external_rd_ack = readback_external_rd_ack_c;
+
+ logic readback_err;
+ logic readback_done;
+ logic [31:0] readback_data;
+
+ // Assign readback values to a flattened array
+ logic [31:0] readback_array[4];
+ assign readback_array[0] = hwif_in.err_addr.rd_ack ? hwif_in.err_addr.rd_data : '0;
+ assign readback_array[1] = hwif_in.err_addr_top.rd_ack ? hwif_in.err_addr_top.rd_data : '0;
+ assign readback_array[2] = hwif_in.err_code.rd_ack ? hwif_in.err_code.rd_data : '0;
+ assign readback_array[3] = hwif_in.meta.rd_ack ? hwif_in.meta.rd_data : '0;
+
+ // Reduce the array
+ always_comb begin
+ automatic logic [31:0] readback_data_var;
+ readback_done = decoded_req & ~decoded_req_is_wr & ~decoded_strb_is_external;
+ readback_err = '0;
+ readback_data_var = '0;
+ for(int i=0; i<4; i++) readback_data_var |= readback_array[i];
+ readback_data = readback_data_var;
+ end
+
+ assign external_rd_ack = readback_external_rd_ack;
+ assign cpuif_rd_ack = readback_done | readback_external_rd_ack;
+ assign cpuif_rd_data = readback_data;
+ assign cpuif_rd_err = readback_err;
endmodule
-
-
diff --git a/src/err_unit_regs.hjson b/src/err_unit_regs.hjson
deleted file mode 100644
index b5c2d3c..0000000
--- a/src/err_unit_regs.hjson
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2023 ETH Zurich and University of Bologna.
-// Solderpad Hardware License, Version 0.51, see LICENSE for details.
-// SPDX-License-Identifier: SHL-0.51
-
-// Author: Michael Rogenmoser
-
-{
- name: "bus_err_unit",
- clock_primary: "clk_i",
- reset_primary: "rst_ni",
- bus_interfaces: [
- { protocol: "reg_iface",
- direction: "device"
- }
- ],
-
- regwidth: "32",
-
- registers: [
- { name: "err_addr",
- desc: "Address of the bus error",
- swaccess: "ro",
- hwaccess: "hwo",
- hwext: "true",
- fields: [
- { bits: "31:0",
- name: "err_addr",
- desc: "Address of the bus error"
- }
- ]
- },
- { name: "err_addr_top",
- desc: "Top of the address of the bus error",
- swaccess: "ro",
- hwaccess: "hwo",
- hwext: "true",
- fields: [
- { bits: "31:0",
- name: "err_addr",
- desc: "Address of the bus error"
- }
- ]
- },
- { name: "err_code",
- desc: "Error code of the bus error",
- swaccess: "ro",
- hwaccess: "hrw",
- hwext: "true",
- hwre: "true",
- fields: [
- { bits: "31:0",
- name: "err_code",
- desc: "Error code of the bus error"
- }
- ]
- },
- { name: "meta",
- desc: "Meta information of the bus error",
- swaccess: "ro",
- hwaccess: "hwo",
- hwext: "true",
- fields: [
- { bits: "31:0",
- name: "meta",
- desc: "Meta information of the bus error"
- }
- ]
- }
- ]
-}
diff --git a/src/obi_err_unit_wrap.sv b/src/obi_err_unit_wrap.sv
index 8075aa2..bec4d88 100644
--- a/src/obi_err_unit_wrap.sv
+++ b/src/obi_err_unit_wrap.sv
@@ -12,8 +12,8 @@ module obi_err_unit_wrap #(
parameter int unsigned NumOutstanding = 2,
parameter int unsigned NumStoredErrors = 1,
parameter bit DropOldest = 1'b0,
- parameter type reg_req_t = logic,
- parameter type reg_rsp_t = logic
+ parameter type apb_req_t = logic,
+ parameter type apb_rsp_t = logic
) (
input logic clk_i,
input logic rst_ni,
@@ -28,8 +28,8 @@ module obi_err_unit_wrap #(
output logic err_irq_o,
- input reg_req_t reg_req_i,
- output reg_rsp_t reg_rsp_o
+ input apb_req_t apb_req_i,
+ output apb_rsp_t apb_rsp_o
);
bus_err_unit #(
@@ -40,8 +40,8 @@ module obi_err_unit_wrap #(
.NumStoredErrors(NumStoredErrors),
.NumChannels (1),
.DropOldest (DropOldest),
- .reg_req_t (reg_req_t),
- .reg_rsp_t (reg_rsp_t)
+ .apb_req_t (apb_req_t),
+ .apb_rsp_t (apb_rsp_t)
) i_err_unit (
.clk_i,
.rst_ni,
@@ -56,8 +56,8 @@ module obi_err_unit_wrap #(
.err_irq_o,
- .reg_req_i,
- .reg_rsp_o
+ .apb_req_i,
+ .apb_rsp_o
);
endmodule