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 [14 : 0] ram_aslr,
output wire [31 : 0] ram_scramble, output wire [31 : 0] ram_scramble,
input wire external_reset,
output wire sys_reset,
output wire led_r, output wire led_r,
output wire led_g, output wire led_g,
output wire led_b, output wire led_b,
@ -144,6 +147,15 @@ module tk1(
reg force_trap_reg; reg force_trap_reg;
reg force_trap_set; 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. // Wires.
@ -173,6 +185,8 @@ module tk1(
assign ram_aslr = ram_aslr_reg; assign ram_aslr = ram_aslr_reg;
assign ram_scramble = ram_scramble_reg; assign ram_scramble = ram_scramble_reg;
assign sys_reset = sys_reset_reg;
//---------------------------------------------------------------- //----------------------------------------------------------------
// Module instance. // Module instance.
@ -204,35 +218,40 @@ module tk1(
//---------------------------------------------------------------- //----------------------------------------------------------------
// reg_update // 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) always @ (posedge clk)
begin : reg_update begin : reg_update
if (!reset_n) begin if (!reset_n) begin
switch_app_reg <= 1'h0; switch_app_reg <= 1'h0;
led_reg <= 3'h6; led_reg <= 3'h6;
gpio1_reg <= 2'h0; gpio1_reg <= 2'h0;
gpio2_reg <= 2'h0; gpio2_reg <= 2'h0;
gpio3_reg <= 1'h0; gpio3_reg <= 1'h0;
gpio4_reg <= 1'h0; gpio4_reg <= 1'h0;
app_start_reg <= 32'h0; app_start_reg <= 32'h0;
app_size_reg <= 32'h0; app_size_reg <= 32'h0;
blake2s_addr_reg <= 32'h0; blake2s_addr_reg <= 32'h0;
cdi_mem[0] <= 32'h0; cdi_mem[0] <= 32'h0;
cdi_mem[1] <= 32'h0; cdi_mem[1] <= 32'h0;
cdi_mem[2] <= 32'h0; cdi_mem[2] <= 32'h0;
cdi_mem[3] <= 32'h0; cdi_mem[3] <= 32'h0;
cdi_mem[4] <= 32'h0; cdi_mem[4] <= 32'h0;
cdi_mem[5] <= 32'h0; cdi_mem[5] <= 32'h0;
cdi_mem[6] <= 32'h0; cdi_mem[6] <= 32'h0;
cdi_mem[7] <= 32'h0; cdi_mem[7] <= 32'h0;
cpu_trap_ctr_reg <= 24'h0; cpu_trap_ctr_reg <= 24'h0;
cpu_trap_led_reg <= 3'h0; cpu_trap_led_reg <= 3'h0;
cpu_mon_en_reg <= 1'h0; cpu_mon_en_reg <= 1'h0;
cpu_mon_first_reg <= 32'h0; cpu_mon_first_reg <= 32'h0;
cpu_mon_last_reg <= 32'h0; cpu_mon_last_reg <= 32'h0;
ram_aslr_reg <= 15'h0; ram_aslr_reg <= 15'h0;
ram_scramble_reg <= 32'h0; ram_scramble_reg <= 32'h0;
force_trap_reg <= 1'h0; force_trap_reg <= 1'h0;
sys_reset_reg <= 1'h0;
external_reset_sample_reg <= 2'h0;
end end
else begin else begin
@ -244,6 +263,17 @@ module tk1(
gpio2_reg[0] <= gpio2; gpio2_reg[0] <= gpio2;
gpio2_reg[1] <= gpio2_reg[0]; 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 if (switch_app_we) begin
switch_app_reg <= 1'h1; switch_app_reg <= 1'h1;
end end
@ -330,6 +360,30 @@ module tk1(
end 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 // security_monitor
// //
@ -476,7 +530,7 @@ module tk1(
end end
if (address == ADDR_SWITCH_APP) begin 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 end
if (address == ADDR_LED) begin if (address == ADDR_LED) begin

View File

@ -142,6 +142,7 @@ module application_fpga(
wire force_trap; wire force_trap;
wire [14 : 0] ram_aslr; wire [14 : 0] ram_aslr;
wire [31 : 0] ram_scramble; wire [31 : 0] ram_scramble;
wire tk1_sys_reset;
/* verilator lint_on UNOPTFLAT */ /* verilator lint_on UNOPTFLAT */
@ -150,7 +151,7 @@ module application_fpga(
//---------------------------------------------------------------- //----------------------------------------------------------------
clk_reset_gen #(.RESET_CYCLES(200)) clk_reset_gen #(.RESET_CYCLES(200))
reset_gen_inst( reset_gen_inst(
.host_reset(interface_rts), .sys_reset(tk1_sys_reset),
.clk(clk), .clk(clk),
.rst_n(reset_n) .rst_n(reset_n)
); );
@ -322,6 +323,9 @@ module application_fpga(
.ram_aslr(ram_aslr), .ram_aslr(ram_aslr),
.ram_scramble(ram_scramble), .ram_scramble(ram_scramble),
.external_reset(interface_rts),
.sys_reset(tk1_sys_reset),
.led_r(led_r), .led_r(led_r),
.led_g(led_g), .led_g(led_g),
.led_b(led_b), .led_b(led_b),

View File

@ -21,7 +21,7 @@
module clk_reset_gen #(parameter RESET_CYCLES = 200) module clk_reset_gen #(parameter RESET_CYCLES = 200)
( (
input wire host_reset, input wire sys_reset,
output wire clk, output wire clk,
output wire rst_n 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_reg = 1'h0;
reg rst_n_new; reg rst_n_new;
reg [1 : 0] host_reset_sample_reg = 2'h0; reg sys_reset_reg;
wire hfosc_clk; wire hfosc_clk;
wire pll_clk; wire pll_clk;
@ -102,8 +102,8 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200)
//---------------------------------------------------------------- //----------------------------------------------------------------
always @(posedge clk) always @(posedge clk)
begin : reg_update begin : reg_update
rst_n_reg <= rst_n_new; rst_n_reg <= rst_n_new;
host_reset_sample_reg <= {host_reset_sample_reg[0], host_reset}; sys_reset_reg <= sys_reset;
if (rst_ctr_we) if (rst_ctr_we)
rst_ctr_reg <= rst_ctr_new; 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 // logic is active, and the reset is being asserted for
// RESET_CYCLES. Then the default reset reg value is applied. // RESET_CYCLES. Then the default reset reg value is applied.
// //
// When a second reset is requested from the host we // When a system reset is requested we reset the counter.
// reset the counter. This activates the counter logic. // This activates the counter logic and the reset is asserted.
//---------------------------------------------------------------- //----------------------------------------------------------------
always @* always @*
begin : rst_logic begin : rst_logic
@ -133,7 +133,7 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200)
rst_ctr_we = 1'h1; rst_ctr_we = 1'h1;
end end
if (host_reset_sample_reg[1]) begin if (sys_reset_reg) begin
rst_ctr_new = 8'h0; rst_ctr_new = 8'h0;
rst_ctr_we = 1'h1; rst_ctr_we = 1'h1;
end end