Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FPGA: Add system reset API #242

Merged
merged 1 commit into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hw/application_fpga/application_fpga.bin.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
c6105a3f769c0846a9619e194ed3bc171467612b9fef9edc1aaeda4941316ff5 application_fpga.bin
24e642b0dc78a7dbf4cd87c223dd26eefb1ad444c96858e1c2b373f35701ccc0 application_fpga.bin
26 changes: 26 additions & 0 deletions hw/application_fpga/core/tk1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions hw/application_fpga/core/tk1/rtl/tk1.v
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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];

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions hw/application_fpga/fw/tk1_mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion hw/application_fpga/rtl/application_fpga.v
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,19 @@ 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 */


//----------------------------------------------------------------
// 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 #(
Expand Down Expand Up @@ -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),

Expand Down
18 changes: 16 additions & 2 deletions hw/application_fpga/rtl/clk_reset_gen.v
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

module clk_reset_gen #(parameter RESET_CYCLES = 200)
(
input wire sys_reset,

output wire clk,
output wire rst_n
);
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down