diff --git a/hw/application_fpga/application_fpga.bin.sha256 b/hw/application_fpga/application_fpga.bin.sha256 index 22a420c..1e46e0a 100644 --- a/hw/application_fpga/application_fpga.bin.sha256 +++ b/hw/application_fpga/application_fpga.bin.sha256 @@ -1 +1 @@ -c6105a3f769c0846a9619e194ed3bc171467612b9fef9edc1aaeda4941316ff5 application_fpga.bin +24e642b0dc78a7dbf4cd87c223dd26eefb1ad444c96858e1c2b373f35701ccc0 application_fpga.bin diff --git a/hw/application_fpga/core/tk1/README.md b/hw/application_fpga/core/tk1/README.md index 2c10be5..5b97f22 100644 --- a/hw/application_fpga/core/tk1/README.md +++ b/hw/application_fpga/core/tk1/README.md @@ -248,6 +248,32 @@ see the datasheet: https://www.mouser.se/datasheet/2/949/w25q80dv_dl_revh_10022015-1489677.pdf +## System Reset + +The TK1 includes an ability for FW and applications to trigger a +hardware reset of the FPGA by writing to an API address. + +The hardware reset will force all registers that are in the Tkey FPGA +design reset circuit to be reset to their default values. Basically +this is all registers in the Tkey FPGA design. + +The reset will not clear the RAM. However since the CPU program +counter is reset to its reset vector, the CPU will unconditionally +start executing the FW. As part of the device initialization, the FW +will fill the RAM with random data, overwriting any app and +data present in the RAM before the reset was triggered. + +The hardware reset will not force the FPGA to read its +configuration. That requires a power cycle of the Tkey device. + +The reset is controlled by the following API address. Note that +any value written to the address will trigger the reset. + +``` +localparam ADDR_SYSTEM_RESET = 8'h70; +``` + + ## Implementation The core is implemented as a single module. Future versions will diff --git a/hw/application_fpga/core/tk1/rtl/tk1.v b/hw/application_fpga/core/tk1/rtl/tk1.v index 350530f..fe9c243 100644 --- a/hw/application_fpga/core/tk1/rtl/tk1.v +++ b/hw/application_fpga/core/tk1/rtl/tk1.v @@ -24,6 +24,7 @@ module tk1( input wire cpu_instr, input wire cpu_valid, output wire force_trap, + output system_reset, output wire [14 : 0] ram_addr_rand, output wire [31 : 0] ram_data_rand, @@ -93,6 +94,8 @@ module tk1( localparam ADDR_CPU_MON_FIRST = 8'h61; localparam ADDR_CPU_MON_LAST = 8'h62; + localparam ADDR_SYSTEM_RESET = 8'h70; + `ifdef INCLUDE_SPI_MASTER localparam ADDR_SPI_EN = 8'h80; localparam ADDR_SPI_XFER = 8'h81; @@ -146,6 +149,9 @@ module tk1( reg [31 : 0] ram_data_rand_reg; reg ram_data_rand_we; + reg system_reset_reg; + reg system_reset_new; + reg cpu_mon_en_reg; reg cpu_mon_en_we; reg [31 : 0] cpu_mon_first_reg; @@ -196,6 +202,8 @@ module tk1( assign ram_addr_rand = ram_addr_rand_reg; assign ram_data_rand = ram_data_rand_reg; + assign system_reset = system_reset_reg; + //---------------------------------------------------------------- // Module instance. @@ -276,11 +284,14 @@ module tk1( ram_addr_rand_reg <= 15'h0; ram_data_rand_reg <= 32'h0; force_trap_reg <= 1'h0; + system_reset_reg <= 1'h0; end else begin cpu_trap_ctr_reg <= cpu_trap_ctr_new; + system_reset_reg <= system_reset_new; + gpio1_reg[0] <= gpio1; gpio1_reg[1] <= gpio1_reg[0]; @@ -429,6 +440,7 @@ module tk1( cdi_mem_we = 1'h0; ram_addr_rand_we = 1'h0; ram_data_rand_we = 1'h0; + system_reset_new = 1'h0; cpu_mon_en_we = 1'h0; cpu_mon_first_we = 1'h0; cpu_mon_last_we = 1'h0; @@ -473,6 +485,10 @@ module tk1( end end + if (address == ADDR_SYSTEM_RESET) begin + system_reset_new = 1'h1; + end + if (address == ADDR_BLAKE2S) begin if (!switch_app_reg) begin blake2s_addr_we = 1'h1; diff --git a/hw/application_fpga/fw/tk1_mem.h b/hw/application_fpga/fw/tk1_mem.h index 96d8ef3..8bd5c07 100644 --- a/hw/application_fpga/fw/tk1_mem.h +++ b/hw/application_fpga/fw/tk1_mem.h @@ -144,6 +144,8 @@ #define TK1_MMIO_TK1_CPU_MON_FIRST 0xff000184 #define TK1_MMIO_TK1_CPU_MON_LAST 0xff000188 +#define TK1_MMIO_TK1_SYSTEM_RESET 0xff0001C0 + #define TK1_MMIO_TK1_SPI_EN 0xff000200 #define TK1_MMIO_TK1_SPI_XFER 0xff000204 #define TK1_MMIO_TK1_SPI_DATA 0xff000208 diff --git a/hw/application_fpga/rtl/application_fpga.v b/hw/application_fpga/rtl/application_fpga.v index 7ea2f02..92c91f0 100644 --- a/hw/application_fpga/rtl/application_fpga.v +++ b/hw/application_fpga/rtl/application_fpga.v @@ -148,6 +148,7 @@ module application_fpga( wire force_trap; wire [14 : 0] ram_addr_rand; wire [31 : 0] ram_data_rand; + wire tk1_system_reset; /* verilator lint_on UNOPTFLAT */ @@ -155,7 +156,11 @@ module application_fpga( // Module instantiations. //---------------------------------------------------------------- clk_reset_gen #(.RESET_CYCLES(200)) - reset_gen_inst(.clk(clk), .rst_n(reset_n)); + reset_gen_inst( + .sys_reset(tk1_system_reset), + .clk(clk), + .rst_n(reset_n) + ); picorv32 #( @@ -321,6 +326,8 @@ module application_fpga( .cpu_trap(cpu_trap), .force_trap(force_trap), + .system_reset(tk1_system_reset), + .ram_addr_rand(ram_addr_rand), .ram_data_rand(ram_data_rand), diff --git a/hw/application_fpga/rtl/clk_reset_gen.v b/hw/application_fpga/rtl/clk_reset_gen.v index 4466f75..820b0d6 100644 --- a/hw/application_fpga/rtl/clk_reset_gen.v +++ b/hw/application_fpga/rtl/clk_reset_gen.v @@ -18,6 +18,8 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) ( + input wire sys_reset, + output wire clk, output wire rst_n ); @@ -33,6 +35,12 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) reg rst_n_reg = 1'h0; reg rst_n_new; + reg sys_reset_reg; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- wire hfosc_clk; wire pll_clk; @@ -93,7 +101,8 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) //---------------------------------------------------------------- always @(posedge clk) begin : reg_update - rst_n_reg <= rst_n_new; + rst_n_reg <= rst_n_new; + sys_reset_reg <= sys_reset; if (rst_ctr_we) rst_ctr_reg <= rst_ctr_new; @@ -109,7 +118,12 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) rst_ctr_new = 8'h0; rst_ctr_we = 1'h0; - if (rst_ctr_reg < RESET_CYCLES) begin + if (sys_reset_reg) begin + rst_ctr_new = 8'h0; + rst_ctr_we = 1'h1; + end + + else if (rst_ctr_reg < RESET_CYCLES) begin rst_n_new = 1'h0; rst_ctr_new = rst_ctr_reg + 1'h1; rst_ctr_we = 1'h1;