[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/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",