From bd45d3b0ddd365c9eb63fc38c05a81d35480b1d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Str=C3=B6mbergson?= Date: Thu, 4 Apr 2024 14:46:14 +0200 Subject: [PATCH] Move reset control and status into the tk1 core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tk1 core is now able to handle external and internal reset request, trigger a system and store reset status that persists the reset. The reset status is exposed to SW as bits 17..16 in the FW_APP register. The fw_app status is now bound to bit 0. Signed-off-by: Joachim Strömbergson --- hw/application_fpga/core/tk1/rtl/tk1.v | 106 ++++++++++++++++----- hw/application_fpga/rtl/application_fpga.v | 6 +- hw/application_fpga/rtl/clk_reset_gen.v | 14 +-- 3 files changed, 92 insertions(+), 34 deletions(-) diff --git a/hw/application_fpga/core/tk1/rtl/tk1.v b/hw/application_fpga/core/tk1/rtl/tk1.v index bd45642..2c1943c 100644 --- a/hw/application_fpga/core/tk1/rtl/tk1.v +++ b/hw/application_fpga/core/tk1/rtl/tk1.v @@ -28,6 +28,9 @@ module tk1( output wire [14 : 0] ram_aslr, output wire [31 : 0] ram_scramble, + input wire external_reset, + output wire sys_reset, + output wire led_r, output wire led_g, output wire led_b, @@ -144,6 +147,15 @@ module tk1( reg force_trap_reg; reg force_trap_set; + reg [1 : 0] external_reset_sample_reg = 2'h0; + reg [1 : 0] external_reset_sample_new; + reg sys_reset_reg; + reg sys_reset_we; + + reg [1 : 0] reset_status_reg = 2'h0; + reg [1 : 0] reset_status_new; + reg reset_status_we; + //---------------------------------------------------------------- // Wires. @@ -173,6 +185,8 @@ module tk1( assign ram_aslr = ram_aslr_reg; assign ram_scramble = ram_scramble_reg; + assign sys_reset = sys_reset_reg; + //---------------------------------------------------------------- // Module instance. @@ -204,35 +218,40 @@ module tk1( //---------------------------------------------------------------- // reg_update + // + // Note that the reset_status_reg is not reset, since that would + // erase the status info we want to persist between reboots. //---------------------------------------------------------------- always @ (posedge clk) begin : reg_update if (!reset_n) begin - switch_app_reg <= 1'h0; - led_reg <= 3'h6; - gpio1_reg <= 2'h0; - gpio2_reg <= 2'h0; - gpio3_reg <= 1'h0; - gpio4_reg <= 1'h0; - app_start_reg <= 32'h0; - app_size_reg <= 32'h0; - blake2s_addr_reg <= 32'h0; - cdi_mem[0] <= 32'h0; - cdi_mem[1] <= 32'h0; - cdi_mem[2] <= 32'h0; - cdi_mem[3] <= 32'h0; - cdi_mem[4] <= 32'h0; - cdi_mem[5] <= 32'h0; - cdi_mem[6] <= 32'h0; - cdi_mem[7] <= 32'h0; - cpu_trap_ctr_reg <= 24'h0; - cpu_trap_led_reg <= 3'h0; - cpu_mon_en_reg <= 1'h0; - cpu_mon_first_reg <= 32'h0; - cpu_mon_last_reg <= 32'h0; - ram_aslr_reg <= 15'h0; - ram_scramble_reg <= 32'h0; - force_trap_reg <= 1'h0; + switch_app_reg <= 1'h0; + led_reg <= 3'h6; + gpio1_reg <= 2'h0; + gpio2_reg <= 2'h0; + gpio3_reg <= 1'h0; + gpio4_reg <= 1'h0; + app_start_reg <= 32'h0; + app_size_reg <= 32'h0; + blake2s_addr_reg <= 32'h0; + cdi_mem[0] <= 32'h0; + cdi_mem[1] <= 32'h0; + cdi_mem[2] <= 32'h0; + cdi_mem[3] <= 32'h0; + cdi_mem[4] <= 32'h0; + cdi_mem[5] <= 32'h0; + cdi_mem[6] <= 32'h0; + cdi_mem[7] <= 32'h0; + cpu_trap_ctr_reg <= 24'h0; + cpu_trap_led_reg <= 3'h0; + cpu_mon_en_reg <= 1'h0; + cpu_mon_first_reg <= 32'h0; + cpu_mon_last_reg <= 32'h0; + ram_aslr_reg <= 15'h0; + ram_scramble_reg <= 32'h0; + force_trap_reg <= 1'h0; + sys_reset_reg <= 1'h0; + external_reset_sample_reg <= 2'h0; end else begin @@ -244,6 +263,17 @@ module tk1( gpio2_reg[0] <= gpio2; gpio2_reg[1] <= gpio2_reg[0]; + external_reset_sample_reg <= external_reset_sample_new; + + + if (sys_reset_we) begin + sys_reset_reg <= 1'h1; + end + + if (reset_status_we) begin + reset_status_reg <= reset_status_new; + end + if (switch_app_we) begin switch_app_reg <= 1'h1; end @@ -330,6 +360,30 @@ module tk1( end + //---------------------------------------------------------------- + // system_reset_logic + // + // Sample the external reset request input. If it is set, we + // assert the sys_reset signal and sets the reset status reg + // to indicate that the reset was caused by external request. + // When the reset happens the sys_reset_reg will be cleared. + //---------------------------------------------------------------- + always @* + begin : system_reset_logic + sys_reset_we = 1'h0; + reset_status_new = 2'h0; + reset_status_we = 1'h0; + + external_reset_sample_new = {external_reset_sample_reg[0], external_reset}; + + if (external_reset_sample_reg[1]) begin + sys_reset_we = 1'h1; + reset_status_new = 2'h1; + reset_status_we = 1'h1; + end + end + + //---------------------------------------------------------------- // security_monitor // @@ -476,7 +530,7 @@ module tk1( end if (address == ADDR_SWITCH_APP) begin - tmp_read_data = {32{switch_app_reg}}; + tmp_read_data = {14'h0, reset_status_reg, 15'h0, switch_app_reg}; end if (address == ADDR_LED) begin diff --git a/hw/application_fpga/rtl/application_fpga.v b/hw/application_fpga/rtl/application_fpga.v index 4cc5d21..7c91699 100644 --- a/hw/application_fpga/rtl/application_fpga.v +++ b/hw/application_fpga/rtl/application_fpga.v @@ -142,6 +142,7 @@ module application_fpga( wire force_trap; wire [14 : 0] ram_aslr; wire [31 : 0] ram_scramble; + wire tk1_sys_reset; /* verilator lint_on UNOPTFLAT */ @@ -150,7 +151,7 @@ module application_fpga( //---------------------------------------------------------------- clk_reset_gen #(.RESET_CYCLES(200)) reset_gen_inst( - .host_reset(interface_rts), + .sys_reset(tk1_sys_reset), .clk(clk), .rst_n(reset_n) ); @@ -322,6 +323,9 @@ module application_fpga( .ram_aslr(ram_aslr), .ram_scramble(ram_scramble), + .external_reset(interface_rts), + .sys_reset(tk1_sys_reset), + .led_r(led_r), .led_g(led_g), .led_b(led_b), diff --git a/hw/application_fpga/rtl/clk_reset_gen.v b/hw/application_fpga/rtl/clk_reset_gen.v index 95fb168..c5ef198 100644 --- a/hw/application_fpga/rtl/clk_reset_gen.v +++ b/hw/application_fpga/rtl/clk_reset_gen.v @@ -21,7 +21,7 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) ( - input wire host_reset, + input wire sys_reset, output wire clk, output wire rst_n ); @@ -37,7 +37,7 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) reg rst_n_reg = 1'h0; reg rst_n_new; - reg [1 : 0] host_reset_sample_reg = 2'h0; + reg sys_reset_reg; wire hfosc_clk; wire pll_clk; @@ -102,8 +102,8 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) //---------------------------------------------------------------- always @(posedge clk) begin : reg_update - rst_n_reg <= rst_n_new; - host_reset_sample_reg <= {host_reset_sample_reg[0], host_reset}; + rst_n_reg <= rst_n_new; + sys_reset_reg <= sys_reset; if (rst_ctr_we) rst_ctr_reg <= rst_ctr_new; @@ -118,8 +118,8 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) // logic is active, and the reset is being asserted for // RESET_CYCLES. Then the default reset reg value is applied. // - // When a second reset is requested from the host we - // reset the counter. This activates the counter logic. + // When a system reset is requested we reset the counter. + // This activates the counter logic and the reset is asserted. //---------------------------------------------------------------- always @* begin : rst_logic @@ -133,7 +133,7 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) rst_ctr_we = 1'h1; end - if (host_reset_sample_reg[1]) begin + if (sys_reset_reg) begin rst_ctr_new = 8'h0; rst_ctr_we = 1'h1; end