[topgen] Handle multi clock ports in topgen/module/xbar
Construction is very similar to reset support.
Each target is defined with a clock_connection that is used to
connect in top_*.sv
Inside validate.py, validate_clock / validate_reset are currently
very similar, but is expected to diverge in the future/
Related to #346
diff --git a/hw/ip/flash_ctrl/doc/flash_ctrl.hjson b/hw/ip/flash_ctrl/doc/flash_ctrl.hjson
index cc56e24..ae12131 100644
--- a/hw/ip/flash_ctrl/doc/flash_ctrl.hjson
+++ b/hw/ip/flash_ctrl/doc/flash_ctrl.hjson
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "FLASH_CTRL",
- clock_primary: "main",
+ clock_primary: "clk_i",
bus_device: "tlul",
interrupt_list: [
{ name: "prog_empty", desc: "Program FIFO empty" },
diff --git a/hw/ip/gpio/doc/gpio.hjson b/hw/ip/gpio/doc/gpio.hjson
index c27a6d7..132917f 100644
--- a/hw/ip/gpio/doc/gpio.hjson
+++ b/hw/ip/gpio/doc/gpio.hjson
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
{
name: "gpio",
- clock_primary: "clk",
+ clock_primary: "clk_i",
bus_device: "tlul",
bus_host: "",
available_inout_list: [
diff --git a/hw/ip/hmac/doc/hmac.hjson b/hw/ip/hmac/doc/hmac.hjson
index b8e5bcd..0bb95d7 100644
--- a/hw/ip/hmac/doc/hmac.hjson
+++ b/hw/ip/hmac/doc/hmac.hjson
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "hmac",
- clock_primary: "clk_fixed",
+ clock_primary: "clk_i",
bus_device: "tlul",
bus_host: "none",
available_input_list: [],
diff --git a/hw/ip/rv_plic/doc/rv_plic.tpl.hjson b/hw/ip/rv_plic/doc/rv_plic.tpl.hjson
index 7b7355c..048637a 100644
--- a/hw/ip/rv_plic/doc/rv_plic.tpl.hjson
+++ b/hw/ip/rv_plic/doc/rv_plic.tpl.hjson
@@ -10,7 +10,7 @@
# - prio: Max value of interrupt priorities
{
name: "RV_PLIC",
- clock_primary: "clk_fixed",
+ clock_primary: "clk_i",
bus_device: "tlul",
param_list: [
diff --git a/hw/ip/rv_timer/doc/rv_timer.hjson b/hw/ip/rv_timer/doc/rv_timer.hjson
index ff6f703..9c10792 100644
--- a/hw/ip/rv_timer/doc/rv_timer.hjson
+++ b/hw/ip/rv_timer/doc/rv_timer.hjson
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
//
{ name: "rv_timer",
- clock_primary: "clk_fixed",
+ clock_primary: "clk_i",
bus_device: "tlul",
bus_host: "none",
available_input_list: [
@@ -124,4 +124,3 @@
},
],
}
-
diff --git a/hw/ip/spi_device/doc/spi_device.hjson b/hw/ip/spi_device/doc/spi_device.hjson
index 9c38243..f80e663 100644
--- a/hw/ip/spi_device/doc/spi_device.hjson
+++ b/hw/ip/spi_device/doc/spi_device.hjson
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "SPI_DEVICE",
- clock_primary: "main",
+ clock_primary: "clk_i",
bus_device: "tlul",
available_input_list: [
{ name: "sck", desc: "SPI Clock" },
diff --git a/hw/ip/uart/doc/uart.hjson b/hw/ip/uart/doc/uart.hjson
index 3822790..a55f44b 100644
--- a/hw/ip/uart/doc/uart.hjson
+++ b/hw/ip/uart/doc/uart.hjson
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "uart",
- clock_primary: "clk_fixed",
+ clock_primary: "clk_i",
bus_device: "tlul",
bus_host: "none",
available_input_list: [
diff --git a/hw/top_earlgrey/doc/top_earlgrey.gen.hjson b/hw/top_earlgrey/doc/top_earlgrey.gen.hjson
index 37dd6af..5515a7d 100644
--- a/hw/top_earlgrey/doc/top_earlgrey.gen.hjson
+++ b/hw/top_earlgrey/doc/top_earlgrey.gen.hjson
@@ -41,14 +41,16 @@
{
name: uart
type: uart
- clock: main
+ clock_connections:
+ {
+ clk_i: main
+ }
reset_connections:
{
rst_ni: sys
}
base_addr: 0x40000000
size: 0x1000
- ip_clock: main
bus_device: tlul
bus_host: none
available_input_list:
@@ -116,14 +118,16 @@
{
name: gpio
type: gpio
- clock: main
+ clock_connections:
+ {
+ clk_i: main
+ }
reset_connections:
{
rst_ni: sys
}
base_addr: 0x40010000
size: 0x1000
- ip_clock: main
bus_device: tlul
bus_host: none
available_input_list: []
@@ -149,14 +153,16 @@
{
name: spi_device
type: spi_device
- clock: main
+ clock_connections:
+ {
+ clk_i: main
+ }
reset_connections:
{
rst_ni: spi_device
}
base_addr: 0x40020000
size: 0x1000
- ip_clock: main
bus_device: tlul
bus_host: none
available_input_list:
@@ -224,14 +230,16 @@
{
name: flash_ctrl
type: flash_ctrl
- clock: main
+ clock_connections:
+ {
+ clk_i: main
+ }
reset_connections:
{
rst_ni: lc
}
base_addr: 0x40030000
size: 0x1000
- ip_clock: main
bus_device: tlul
bus_host: none
available_input_list: []
@@ -275,14 +283,16 @@
{
name: rv_timer
type: rv_timer
- clock: main
+ clock_connections:
+ {
+ clk_i: main
+ }
reset_connections:
{
rst_ni: sys
}
base_addr: 0x40080000
size: 0x1000
- ip_clock: main
bus_device: tlul
bus_host: none
available_input_list: []
@@ -301,14 +311,16 @@
{
name: hmac
type: hmac
- clock: main
+ clock_connections:
+ {
+ clk_i: main
+ }
reset_connections:
{
rst_ni: sys
}
base_addr: 0x40120000
size: 0x1000
- ip_clock: main
bus_device: tlul
bus_host: none
available_input_list: []
@@ -332,7 +344,10 @@
{
name: rv_plic
type: rv_plic
- clock: main
+ clock_connections:
+ {
+ clk_i: main
+ }
reset_connections:
{
rst_ni: sys
@@ -344,7 +359,6 @@
FIND_MAX: MATRIX
}
size: 0x1000
- ip_clock: main
bus_device: tlul
bus_host: none
available_input_list: []
@@ -358,6 +372,10 @@
[
{
name: rom
+ clock_connections:
+ {
+ clk_i: main
+ }
reset_connections:
{
rst_ni: sys
@@ -368,6 +386,10 @@
}
{
name: ram_main
+ clock_connections:
+ {
+ clk_i: main
+ }
reset_connections:
{
rst_ni: sys
@@ -378,6 +400,10 @@
}
{
name: eflash
+ clock_connections:
+ {
+ clk_i: main
+ }
reset_connections:
{
rst_ni: lc
@@ -391,7 +417,10 @@
[
{
name: main
- clock: main
+ clock_connections:
+ {
+ clk_main_i: main
+ }
reset: sys
reset_connections:
{
@@ -571,6 +600,7 @@
pipeline: "true"
}
]
+ clock: main
}
]
interrupt_module:
diff --git a/hw/top_earlgrey/doc/top_earlgrey.hjson b/hw/top_earlgrey/doc/top_earlgrey.hjson
index 281455b..c19ce8e 100644
--- a/hw/top_earlgrey/doc/top_earlgrey.hjson
+++ b/hw/top_earlgrey/doc/top_earlgrey.hjson
@@ -34,48 +34,52 @@
type: "uart", // Must be matched to the ip name in `ip.hson` (_reg, _cfg permitted)
// and `hw/ip/{type}`
- clock: "main", // `ip.hjson` clock is internal name, here top determines
- // actual clock (signal matched at the top)
+ // clock connections defines the port to top level clock connection
+ // the ip.hjson will declare the clock port names
+ // If none are defined at ip.hjson, clk_i is used by default
+ clock_connections: {clk_i: "main"},
// reset connections defines the port to top level reset connection
// the ip.hjson will declare the reset port names
+ // If none are defined at ip.hjson, rst_ni is used by default
reset_connections: {rst_ni: "sys"},
+
base_addr: "0x40000000",
},
{ name: "gpio",
type: "gpio",
- clock: "main",
+ clock_connections: {clk_i: "main"},
reset_connections: {rst_ni: "sys"},
base_addr: "0x40010000",
}
{ name: "spi_device",
type: "spi_device",
- clock: "main",
+ clock_connections: {clk_i: "main"},
reset_connections: {rst_ni: "spi_device"},
base_addr: "0x40020000",
},
{ name: "flash_ctrl",
type: "flash_ctrl",
- clock: "main",
+ clock_connections: {clk_i: "main"},
reset_connections: {rst_ni: "lc"},
base_addr: "0x40030000",
},
{ name: "rv_timer",
type: "rv_timer",
- clock: "main",
+ clock_connections: {clk_i: "main"},
reset_connections: {rst_ni: "sys"},
base_addr: "0x40080000",
},
{ name: "hmac",
type: "hmac",
- clock: "main",
+ clock_connections: {clk_i: "main"},
reset_connections: {rst_ni: "sys"},
base_addr: "0x40120000",
},
{ name: "rv_plic",
type: "rv_plic",
- clock: "main",
+ clock_connections: {clk_i: "main"},
reset_connections: {rst_ni: "sys"},
base_addr: "0x40090000",
generated: "true" // Indicate this module is generated in the topgen
@@ -90,9 +94,25 @@
// Memories (ROM, RAM, eFlash) are defined at the top.
// It utilizes the primitive cells but configurable
memory: [
- { name: "rom", reset_connections: {rst_ni: "sys"}, type: "rom", base_addr: "0x00008000", size: "0x2000" },
- { name: "ram_main", reset_connections: {rst_ni: "sys"}, type: "ram_1p", base_addr: "0x10000000", size: "0x10000" },
- { name: "eflash", reset_connections: {rst_ni: "lc"}, type: "eflash", base_addr: "0x20000000", size: "0x80000" },
+ { name: "rom",
+ clock_connections: {clk_i: "main"},
+ reset_connections: {rst_ni: "sys"},
+ type: "rom",
+ base_addr: "0x00008000",
+ size: "0x2000"
+ },
+ { name: "ram_main",
+ clock_connections: {clk_i: "main"},
+ reset_connections: {rst_ni: "sys"},
+ type: "ram_1p",
+ base_addr: "0x10000000",
+ size: "0x10000" },
+ { name: "eflash",
+ clock_connections: {clk_i: "main"},
+ reset_connections: {rst_ni: "lc"},
+ type: "eflash",
+ base_addr: "0x20000000",
+ size: "0x80000" },
],
debug_mem_base_addr: "0x1A110000",
@@ -102,7 +122,7 @@
// Assume xbar.hjson is located in the same directory of top.hjson
xbar: [
{ name: "main",
- clock: "main", // Main clock, used in sockets
+ clock_connections: {clk_main_i: "main"},
reset: "sys",
reset_connections: {rst_main_ni: "sys"}
},
diff --git a/hw/top_earlgrey/doc/top_earlgrey.tpl.sv b/hw/top_earlgrey/doc/top_earlgrey.tpl.sv
index 8ce39f8..9b146cd 100644
--- a/hw/top_earlgrey/doc/top_earlgrey.tpl.sv
+++ b/hw/top_earlgrey/doc/top_earlgrey.tpl.sv
@@ -82,6 +82,11 @@
logic ${reset['name']}_rst_n;
% endfor
+ //clock wires declaration
+% for clock in top['clocks']:
+ logic ${clock['name']}_clk;
+% endfor
+
<%
interrupt_num = sum([x["width"] if "width" in x else 1 for x in top["interrupt"]])
%>\
@@ -103,6 +108,11 @@
logic [0:0] msip;
+ // clock assignments
+% for clock in top['clocks']:
+ assign ${clock['name']}_clk = clk_i;
+% endfor
+
// Non-debug module reset == reset for everything except for the debug module
logic ndmreset_req;
@@ -133,7 +143,7 @@
.PipeLine (IbexPipeLine)
) core (
// clock and reset
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (sys_rst_n),
.test_en_i (1'b0),
// static pinning
@@ -168,7 +178,7 @@
// xxxxxxxxxxx manufacturer id
// 1 required by standard
) u_dm_top (
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (lc_rst_n),
.testmode_i (1'b0),
.ndmreset_o (ndmreset_req),
@@ -197,6 +207,7 @@
% for m in top["memory"]:
<%
resets = m['reset_connections']
+ clocks = m['clock_connections']
%>\
% if m["type"] == "ram_1p":
<%
@@ -220,7 +231,9 @@
.SramDw(${data_width}),
.Outstanding(1)
) tl_adapter_${m["name"]} (
- .clk_i,
+ % for key in clocks:
+ .${key} (${clocks[key]}_clk),
+ % endfor
% for key in resets:
.${key} (${resets[key]}_rst_n),
% endfor
@@ -244,7 +257,9 @@
.Depth(${sram_depth}),
.DataBitsPerMask(${int(data_width/4)})
) u_ram1p_${m["name"]} (
- .clk_i,
+ % for key in clocks:
+ .${key} (${clocks[key]}_clk),
+ % endfor
% for key in resets:
.${key} (${resets[key]}_rst_n),
% endfor
@@ -276,7 +291,9 @@
.Outstanding(1),
.ErrOnWrite(1)
) tl_adapter_${m["name"]} (
- .clk_i,
+ % for key in clocks:
+ .${key} (${clocks[key]}_clk),
+ % endfor
% for key in resets:
.${key} (${resets[key]}_rst_n),
% endfor
@@ -300,7 +317,9 @@
.Width(${data_width}),
.Depth(${rom_depth})
) u_rom_${m["name"]} (
- .clk_i,
+ % for key in clocks:
+ .${key} (${clocks[key]}_clk),
+ % endfor
% for key in resets:
.${key} (${resets[key]}_rst_n),
% endfor
@@ -330,7 +349,9 @@
.ByteAccess(0),
.ErrOnWrite(1)
) tl_adapter_${m["name"]} (
- .clk_i,
+ % for key in clocks:
+ .${key} (${clocks[key]}_clk),
+ % endfor
% for key in resets:
.${key} (${resets[key]}_rst_n),
% endfor
@@ -355,7 +376,9 @@
.WordsPerPage(FLASH_WORDS_PER_PAGE),
.DataWidth(${data_width})
) u_flash_${m["name"]} (
- .clk_i,
+ % for key in clocks:
+ .${key} (${clocks[key]}_clk),
+ % endfor
% for key in resets:
.${key} (${resets[key]}_rst_n),
% endfor
@@ -429,7 +452,9 @@
% if m["scan"] == "true":
.scanmode_i (scanmode_i),
% endif
- .clk_i (${"clk_i" if m["clock"] == "main" else "clk_"+ m["clock"] + "_i"}),
+ % for k, v in m["clock_connections"].items():
+ .${k} (${v}_clk),
+ % endfor
% for k, v in m["reset_connections"].items():
% if loop.last:
.${k} (${v}_rst_n)
@@ -452,17 +477,13 @@
};
// TL-UL Crossbar
- logic clk_main;
- assign clk_main = clk_i;
-
-
% for xbar in top["xbar"]:
<%
name_len = max([len(x["name"]) for x in xbar["nodes"]]);
%>\
xbar_${xbar["name"]} u_xbar_${xbar["name"]} (
- % for clock in xbar["clocks"]:
- .clk_${clock}_i (clk_${clock}),
+ % for k, v in xbar["clock_connections"].items():
+ .${k} (${v}_clk),
% endfor
% for k, v in xbar["reset_connections"].items():
.${k} (${v}_rst_n),
diff --git a/hw/top_earlgrey/doc/xbar_main.hjson b/hw/top_earlgrey/doc/xbar_main.hjson
index 2c49d87..64c8a6b 100644
--- a/hw/top_earlgrey/doc/xbar_main.hjson
+++ b/hw/top_earlgrey/doc/xbar_main.hjson
@@ -1,7 +1,9 @@
{ name: "main",
type: "xbar",
- clock: "main", // Main clock, used in sockets
+ clock: "main",
+ clock_primary: "clk_main_i", // Main clock, used in sockets
reset_primary: "rst_main_ni", // Main reset, used in sockets
+
nodes: [
{ name: "corei",
type: "host",
diff --git a/hw/top_earlgrey/ip/rv_plic/doc/autogen/rv_plic.hjson b/hw/top_earlgrey/ip/rv_plic/doc/autogen/rv_plic.hjson
index 7a27972..5b35774 100644
--- a/hw/top_earlgrey/ip/rv_plic/doc/autogen/rv_plic.hjson
+++ b/hw/top_earlgrey/ip/rv_plic/doc/autogen/rv_plic.hjson
@@ -18,7 +18,7 @@
# - prio: Max value of interrupt priorities
{
name: "RV_PLIC",
- clock_primary: "clk_fixed",
+ clock_primary: "clk_i",
bus_device: "tlul",
param_list: [
diff --git a/hw/top_earlgrey/ip/xbar/doc/xbar_main.gen.hjson b/hw/top_earlgrey/ip/xbar/doc/xbar_main.gen.hjson
index c246a2b..955fe76 100644
--- a/hw/top_earlgrey/ip/xbar/doc/xbar_main.gen.hjson
+++ b/hw/top_earlgrey/ip/xbar/doc/xbar_main.gen.hjson
@@ -8,7 +8,10 @@
{
name: main
- clock: main
+ clock_connections:
+ {
+ clk_main_i: main
+ }
reset: sys
reset_connections:
{
@@ -188,4 +191,5 @@
pipeline: "true"
}
]
+ clock: main
}
\ No newline at end of file
diff --git a/hw/top_earlgrey/rtl/top_earlgrey.sv b/hw/top_earlgrey/rtl/top_earlgrey.sv
index 5e46916..ac5dda5 100644
--- a/hw/top_earlgrey/rtl/top_earlgrey.sv
+++ b/hw/top_earlgrey/rtl/top_earlgrey.sv
@@ -82,6 +82,9 @@
logic sys_rst_n;
logic spi_device_rst_n;
+ //clock wires declaration
+ logic main_clk;
+
logic [53:0] intr_vector;
// Interrupt source list
logic intr_uart_tx_watermark;
@@ -115,6 +118,9 @@
logic [0:0] msip;
+ // clock assignments
+ assign main_clk = clk_i;
+
// Non-debug module reset == reset for everything except for the debug module
logic ndmreset_req;
@@ -141,7 +147,7 @@
.PipeLine (IbexPipeLine)
) core (
// clock and reset
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (sys_rst_n),
.test_en_i (1'b0),
// static pinning
@@ -176,7 +182,7 @@
// xxxxxxxxxxx manufacturer id
// 1 required by standard
) u_dm_top (
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (lc_rst_n),
.testmode_i (1'b0),
.ndmreset_o (ndmreset_req),
@@ -213,7 +219,7 @@
.Outstanding(1),
.ErrOnWrite(1)
) tl_adapter_rom (
- .clk_i,
+ .clk_i (main_clk),
.rst_ni (sys_rst_n),
.tl_i (tl_rom_d_h2d),
@@ -234,7 +240,7 @@
.Width(32),
.Depth(2048)
) u_rom_rom (
- .clk_i,
+ .clk_i (main_clk),
.rst_ni (sys_rst_n),
.cs_i (rom_req),
.addr_i (rom_addr),
@@ -256,7 +262,7 @@
.SramDw(32),
.Outstanding(1)
) tl_adapter_ram_main (
- .clk_i,
+ .clk_i (main_clk),
.rst_ni (sys_rst_n),
.tl_i (tl_ram_main_d_h2d),
.tl_o (tl_ram_main_d_d2h),
@@ -277,7 +283,7 @@
.Depth(16384),
.DataBitsPerMask(8)
) u_ram1p_ram_main (
- .clk_i,
+ .clk_i (main_clk),
.rst_ni (sys_rst_n),
.req_i (ram_main_req),
@@ -307,7 +313,7 @@
.ByteAccess(0),
.ErrOnWrite(1)
) tl_adapter_eflash (
- .clk_i,
+ .clk_i (main_clk),
.rst_ni (lc_rst_n),
.tl_i (tl_eflash_d_h2d),
@@ -330,7 +336,7 @@
.WordsPerPage(FLASH_WORDS_PER_PAGE),
.DataWidth(32)
) u_flash_eflash (
- .clk_i,
+ .clk_i (main_clk),
.rst_ni (lc_rst_n),
.host_req_i (flash_host_req),
.host_addr_i (flash_host_addr),
@@ -357,7 +363,7 @@
.intr_rx_timeout_o (intr_uart_rx_timeout),
.intr_rx_parity_err_o (intr_uart_rx_parity_err),
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (sys_rst_n)
);
@@ -369,7 +375,7 @@
.cio_gpio_en_o (cio_gpio_gpio_en_d2p_o),
.intr_gpio_o (intr_gpio_gpio),
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (sys_rst_n)
);
@@ -389,7 +395,7 @@
.intr_txunderflow_o (intr_spi_device_txunderflow),
.scanmode_i (scanmode_i),
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (spi_device_rst_n)
);
@@ -405,7 +411,7 @@
.flash_o(flash_c2m),
.flash_i(flash_m2c),
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (lc_rst_n)
);
@@ -414,7 +420,7 @@
.tl_o (tl_rv_timer_d_d2h),
.intr_timer_expired_0_0_o (intr_rv_timer_timer_expired_0_0),
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (sys_rst_n)
);
@@ -424,7 +430,7 @@
.intr_hmac_done_o (intr_hmac_hmac_done),
.intr_fifo_full_o (intr_hmac_fifo_full),
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (sys_rst_n)
);
@@ -438,7 +444,7 @@
.irq_id_o (irq_id),
.msip_o (msip),
- .clk_i (clk_i),
+ .clk_i (main_clk),
.rst_ni (sys_rst_n)
);
@@ -470,12 +476,8 @@
};
// TL-UL Crossbar
- logic clk_main;
- assign clk_main = clk_i;
-
-
xbar_main u_xbar_main (
- .clk_main_i (clk_main),
+ .clk_main_i (main_clk),
.rst_main_ni (sys_rst_n),
.tl_corei_i (tl_corei_h_h2d),
.tl_corei_o (tl_corei_h_d2h),