[top] First draft of reset controller integration - This PR does not implement the actual reset controller, but simply wires up the top level resets as if the controller existed - The purpose of this PR is to get agreement on the general connectivity or reset nets and ports
diff --git a/hw/top_earlgrey/doc/top_earlgrey.gen.hjson b/hw/top_earlgrey/doc/top_earlgrey.gen.hjson index b31b81c..37dd6af 100644 --- a/hw/top_earlgrey/doc/top_earlgrey.gen.hjson +++ b/hw/top_earlgrey/doc/top_earlgrey.gen.hjson
@@ -16,6 +16,25 @@ freq: "100000000" } ] + resets: + [ + { + name: lc + type: root + clk: main + } + { + name: sys + type: root + clk: main + } + { + name: spi_device + type: leaf + root: sys + clk: main + } + ] num_cores: "1" module: [ @@ -23,6 +42,10 @@ name: uart type: uart clock: main + reset_connections: + { + rst_ni: sys + } base_addr: 0x40000000 size: 0x1000 ip_clock: main @@ -94,6 +117,10 @@ name: gpio type: gpio clock: main + reset_connections: + { + rst_ni: sys + } base_addr: 0x40010000 size: 0x1000 ip_clock: main @@ -123,6 +150,10 @@ name: spi_device type: spi_device clock: main + reset_connections: + { + rst_ni: spi_device + } base_addr: 0x40020000 size: 0x1000 ip_clock: main @@ -194,6 +225,10 @@ name: flash_ctrl type: flash_ctrl clock: main + reset_connections: + { + rst_ni: lc + } base_addr: 0x40030000 size: 0x1000 ip_clock: main @@ -241,6 +276,10 @@ name: rv_timer type: rv_timer clock: main + reset_connections: + { + rst_ni: sys + } base_addr: 0x40080000 size: 0x1000 ip_clock: main @@ -263,6 +302,10 @@ name: hmac type: hmac clock: main + reset_connections: + { + rst_ni: sys + } base_addr: 0x40120000 size: 0x1000 ip_clock: main @@ -290,6 +333,10 @@ name: rv_plic type: rv_plic clock: main + reset_connections: + { + rst_ni: sys + } base_addr: 0x40090000 generated: "true" parameter: @@ -311,18 +358,30 @@ [ { 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 @@ -333,6 +392,11 @@ { name: main clock: main + reset: sys + reset_connections: + { + rst_main_ni: sys + } connections: { corei:
diff --git a/hw/top_earlgrey/doc/top_earlgrey.hjson b/hw/top_earlgrey/doc/top_earlgrey.hjson index 9a56d44..281455b 100644 --- a/hw/top_earlgrey/doc/top_earlgrey.hjson +++ b/hw/top_earlgrey/doc/top_earlgrey.hjson
@@ -12,6 +12,17 @@ { name: "main", freq: "100000000" } ] + // Reset attributes + // name: name of reset. Real name is `name`_rst_n + // type: reset type, either root or leaf + // root: if reset type not root, the root reset it is related to + // clk: related clock domain for synchronous release + resets: [ + { name: "lc", type: "root", clk: "main"} + { name: "sys", type: "root", clk: "main"} + { name: "spi_device", type: "leaf", root: "sys", clk: "main"} + ] + // Number of cores: used in rv_plic and timer num_cores: "1", @@ -22,39 +33,50 @@ { name: "uart", // instance name 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) + + // reset connections defines the port to top level reset connection + // the ip.hjson will declare the reset port names + reset_connections: {rst_ni: "sys"}, base_addr: "0x40000000", }, { name: "gpio", type: "gpio", clock: "main", + reset_connections: {rst_ni: "sys"}, base_addr: "0x40010000", } { name: "spi_device", type: "spi_device", clock: "main", + reset_connections: {rst_ni: "spi_device"}, base_addr: "0x40020000", }, { name: "flash_ctrl", type: "flash_ctrl", clock: "main", + reset_connections: {rst_ni: "lc"}, base_addr: "0x40030000", }, { name: "rv_timer", type: "rv_timer", clock: "main", + reset_connections: {rst_ni: "sys"}, base_addr: "0x40080000", }, { name: "hmac", type: "hmac", clock: "main", + reset_connections: {rst_ni: "sys"}, base_addr: "0x40120000", }, { name: "rv_plic", type: "rv_plic", clock: "main", + reset_connections: {rst_ni: "sys"}, base_addr: "0x40090000", generated: "true" // Indicate this module is generated in the topgen parameter: { @@ -68,9 +90,9 @@ // Memories (ROM, RAM, eFlash) are defined at the top. // It utilizes the primitive cells but configurable memory: [ - { name: "rom", type: "rom", base_addr: "0x00008000", size: "0x2000" }, - { name: "ram_main", type: "ram_1p", base_addr: "0x10000000", size: "0x10000" }, - { name: "eflash", type: "eflash", base_addr: "0x20000000", size: "0x80000" }, + { 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" }, ], debug_mem_base_addr: "0x1A110000", @@ -81,6 +103,8 @@ xbar: [ { name: "main", clock: "main", // Main clock, used in sockets + 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 d2bc994..8ce39f8 100644 --- a/hw/top_earlgrey/doc/top_earlgrey.tpl.sv +++ b/hw/top_earlgrey/doc/top_earlgrey.tpl.sv
@@ -76,6 +76,12 @@ tl_h2d_t tl_${m["name"]}_d_h2d; tl_d2h_t tl_${m["name"]}_d_d2h; % endfor + + //reset wires declaration +% for reset in top['resets']: + logic ${reset['name']}_rst_n; +% endfor + <% interrupt_num = sum([x["width"] if "width" in x else 1 for x in top["interrupt"]]) %>\ @@ -96,12 +102,24 @@ logic [${(interrupt_num).bit_length()-1}:0] irq_id[1]; logic [0:0] msip; - // Non-debug module reset == reset for everything except for the debug module - // and the logic required to access it. - logic ndmreset_n; - logic ndmreset_from_dm; - assign ndmreset_n = (scanmode_i) ? rst_ni : ~ndmreset_from_dm & rst_ni; + // Non-debug module reset == reset for everything except for the debug module + logic ndmreset_req; + + // root resets + // TODO: lc_rst_n is not the true root reset. It will be differentiated once the + // the reset controller logic is present + assign lc_rst_n = rst_ni; + assign sys_rst_n = (scanmode_i) ? lc_rst_n : ~ndmreset_req & lc_rst_n; + + //non-root reset assignments +% for reset in top['resets']: + % if reset['type'] in ['leaf']: + assign ${reset['name']}_rst_n = ${reset['root']}_rst_n; + % endif +% endfor + + // debug request from rv_dm to core logic debug_req; // processor core @@ -116,7 +134,7 @@ ) core ( // clock and reset .clk_i (clk_i), - .rst_ni (ndmreset_n), + .rst_ni (sys_rst_n), .test_en_i (1'b0), // static pinning .hart_id_i (32'b0), @@ -151,9 +169,9 @@ // 1 required by standard ) u_dm_top ( .clk_i (clk_i), - .rst_ni (rst_ni), + .rst_ni (lc_rst_n), .testmode_i (1'b0), - .ndmreset_o (ndmreset_from_dm), + .ndmreset_o (ndmreset_req), .dmactive_o (), .debug_req_o (debug_req), .unavailable_i (1'b0), @@ -177,12 +195,16 @@ ## Memory Instantiation % for m in top["memory"]: +<% + resets = m['reset_connections'] +%>\ % if m["type"] == "ram_1p": <% data_width = int(top["datawidth"]) dw_byte = data_width // 8 addr_width = ((int(m["size"], 0) // dw_byte) -1).bit_length() sram_depth = (int(m["size"], 0) // dw_byte) + %>\ // sram device logic ${m["name"]}_req; @@ -199,8 +221,9 @@ .Outstanding(1) ) tl_adapter_${m["name"]} ( .clk_i, - .rst_ni (ndmreset_n), - + % for key in resets: + .${key} (${resets[key]}_rst_n), + % endfor .tl_i (tl_${m["name"]}_d_h2d), .tl_o (tl_${m["name"]}_d_d2h), @@ -222,7 +245,9 @@ .DataBitsPerMask(${int(data_width/4)}) ) u_ram1p_${m["name"]} ( .clk_i, - .rst_ni (ndmreset_n), + % for key in resets: + .${key} (${resets[key]}_rst_n), + % endfor .req_i (${m["name"]}_req), .write_i (${m["name"]}_we), @@ -252,7 +277,9 @@ .ErrOnWrite(1) ) tl_adapter_${m["name"]} ( .clk_i, - .rst_ni (ndmreset_n), + % for key in resets: + .${key} (${resets[key]}_rst_n), + % endfor .tl_i (tl_${m["name"]}_d_h2d), .tl_o (tl_${m["name"]}_d_d2h), @@ -274,7 +301,9 @@ .Depth(${rom_depth}) ) u_rom_${m["name"]} ( .clk_i, - .rst_ni (ndmreset_n), + % for key in resets: + .${key} (${resets[key]}_rst_n), + % endfor .cs_i (${m["name"]}_req), .addr_i (${m["name"]}_addr), .dout_o (${m["name"]}_rdata), @@ -302,7 +331,9 @@ .ErrOnWrite(1) ) tl_adapter_${m["name"]} ( .clk_i, - .rst_ni (ndmreset_n), + % for key in resets: + .${key} (${resets[key]}_rst_n), + % endfor .tl_i (tl_${m["name"]}_d_h2d), .tl_o (tl_${m["name"]}_d_d2h), @@ -325,7 +356,9 @@ .DataWidth(${data_width}) ) u_flash_${m["name"]} ( .clk_i, - .rst_ni, + % for key in resets: + .${key} (${resets[key]}_rst_n), + % endfor .host_req_i (flash_host_req), .host_addr_i (flash_host_addr), .host_req_rdy_o (flash_host_req_rdy), @@ -339,9 +372,12 @@ // flash memory is embedded within controller % endif % endfor - ## Peripheral Instantiation + % for m in top["module"]: +<% + +%>\ % if "parameter" in m: ${m["type"]} #( % for k, v in m["parameter"].items(): @@ -389,11 +425,18 @@ .irq_id_o (irq_id), .msip_o (msip), % endif + % if m["scan"] == "true": .scanmode_i (scanmode_i), % endif - .clk_i(${"clk_i" if m["clock"] == "main" else "clk_"+ m["clock"] + "_i"}), - .rst_ni(${"ndmreset_n" if m["clock"] == "main" else "rst_" + m["clock"] + "_ni"}) + .clk_i (${"clk_i" if m["clock"] == "main" else "clk_"+ m["clock"] + "_i"}), + % for k, v in m["reset_connections"].items(): + % if loop.last: + .${k} (${v}_rst_n) + % else: + .${k} (${v}_rst_n), + % endif + % endfor ); % endfor @@ -410,10 +453,8 @@ // TL-UL Crossbar logic clk_main; - logic ndmreset_sync_main_n; // ndmreset synchronized to clk_main - assign clk_main = clk_i; - assign ndmreset_sync_main_n = ndmreset_n; + % for xbar in top["xbar"]: <% @@ -421,11 +462,11 @@ %>\ xbar_${xbar["name"]} u_xbar_${xbar["name"]} ( % for clock in xbar["clocks"]: - ## TODO: How we can handle the reset? .clk_${clock}_i (clk_${clock}), - .rst_${clock}_ni (ndmreset_sync_${clock}_n), % endfor - + % for k, v in xbar["reset_connections"].items(): + .${k} (${v}_rst_n), + % endfor % for node in xbar["nodes"]: % if node["type"] == "device": .tl_${(node["name"]+"_o").ljust(name_len+2)} (tl_${node["name"]}_d_h2d),
diff --git a/hw/top_earlgrey/doc/xbar_main.hjson b/hw/top_earlgrey/doc/xbar_main.hjson index 6694c7c..2c49d87 100644 --- a/hw/top_earlgrey/doc/xbar_main.hjson +++ b/hw/top_earlgrey/doc/xbar_main.hjson
@@ -1,6 +1,7 @@ { name: "main", type: "xbar", clock: "main", // Main clock, used in sockets + reset_primary: "rst_main_ni", // Main reset, used in sockets nodes: [ { name: "corei", type: "host",