Move reset control and status into the tk1 core

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 <joachim@assured.se>
This commit is contained in:
Joachim Strömbergson 2024-04-04 14:46:14 +02:00 committed by Michael Cardell Widerkrantz
parent 16eba3b8dd
commit bd45d3b0dd
No known key found for this signature in database
GPG Key ID: D3DB3DDF57E704E5
3 changed files with 92 additions and 34 deletions

View File

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

View File

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

View File

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