FPGA: Add system reset API

Add API address to trigger system reset.
      When written to will send system_reset signal
      to the reset generator, which then perform a complete
      reset cycle of the FPGA system.

Signed-off-by: Joachim Strömbergson <joachim@assured.se>
This commit is contained in:
Joachim Strömbergson 2024-06-24 13:27:51 +02:00 committed by Daniel Jobson
parent b5ba21148d
commit 00599549e3
No known key found for this signature in database
GPG Key ID: 3707A9DBF4BB8F1A
6 changed files with 69 additions and 4 deletions

View File

@ -1 +1 @@
c6105a3f769c0846a9619e194ed3bc171467612b9fef9edc1aaeda4941316ff5 application_fpga.bin
24e642b0dc78a7dbf4cd87c223dd26eefb1ad444c96858e1c2b373f35701ccc0 application_fpga.bin

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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),

View File

@ -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;
@ -94,6 +102,7 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200)
always @(posedge clk)
begin : reg_update
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;