diff --git a/hw/application_fpga/core/tk1/rtl/tk1.v b/hw/application_fpga/core/tk1/rtl/tk1.v index bd456421..2c1943c4 100644 --- a/hw/application_fpga/core/tk1/rtl/tk1.v +++ b/hw/application_fpga/core/tk1/rtl/tk1.v @@ -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 diff --git a/hw/application_fpga/data/application_fpga_tk1.pcf b/hw/application_fpga/data/application_fpga_tk1.pcf index c22b7fa3..7070a041 100644 --- a/hw/application_fpga/data/application_fpga_tk1.pcf +++ b/hw/application_fpga/data/application_fpga_tk1.pcf @@ -15,7 +15,7 @@ set_io interface_rx 26 set_io interface_tx 25 # set_io interface_cts 27 -# set_io interface_rts 28 +set_io interface_rts 28 # Touch sense. diff --git a/hw/application_fpga/rtl/application_fpga.v b/hw/application_fpga/rtl/application_fpga.v index 4f8b5e54..7c916994 100644 --- a/hw/application_fpga/rtl/application_fpga.v +++ b/hw/application_fpga/rtl/application_fpga.v @@ -19,6 +19,7 @@ module application_fpga( output wire interface_rx, input wire interface_tx, + input wire interface_rts, input wire touch_event, @@ -141,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 */ @@ -148,7 +150,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_sys_reset), + .clk(clk), + .rst_n(reset_n) + ); picorv32 #( @@ -317,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), diff --git a/hw/application_fpga/rtl/clk_reset_gen.v b/hw/application_fpga/rtl/clk_reset_gen.v index 4466f75a..c5ef1987 100644 --- a/hw/application_fpga/rtl/clk_reset_gen.v +++ b/hw/application_fpga/rtl/clk_reset_gen.v @@ -1,12 +1,15 @@ //====================================================================== // // clk_reset_gen.v -// ----------- +// --------------- // Clock and reset generator used in the Tillitis Key 1 design. +// // This module instantiate the internal SB_HFOSC clock source in the // Lattice ice40 UP device. It then connects it to the PLL, and // finally connects the output from the PLL to the global clock net. // +// The reset generator provides a stable reset of the design. +// // // Author: Joachim Strombergson // Copyright (C) 2022 - Tillitis AB @@ -18,6 +21,7 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) ( + input wire sys_reset, output wire clk, output wire rst_n ); @@ -33,6 +37,8 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) reg rst_n_reg = 1'h0; reg rst_n_new; + reg sys_reset_reg; + wire hfosc_clk; wire pll_clk; @@ -89,11 +95,15 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) //---------------------------------------------------------------- - // reg_update. + // reg_update + // + // Note no reset, since these registers are used to create + // the reset in the design. //---------------------------------------------------------------- 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; @@ -101,7 +111,15 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) //---------------------------------------------------------------- - // rst_logic. + // rst_logic + // + // From cold boot, when the bitstream has been loaded and + // all registers are zeroised. This means that the counter + // logic is active, and the reset is being asserted for + // RESET_CYCLES. Then the default reset reg value is applied. + // + // When a system reset is requested we reset the counter. + // This activates the counter logic and the reset is asserted. //---------------------------------------------------------------- always @* begin : rst_logic @@ -114,10 +132,15 @@ module clk_reset_gen #(parameter RESET_CYCLES = 200) rst_ctr_new = rst_ctr_reg + 1'h1; rst_ctr_we = 1'h1; end + + if (sys_reset_reg) begin + rst_ctr_new = 8'h0; + rst_ctr_we = 1'h1; + end end -endmodule // reset_gen +endmodule // clk_reset_gen //====================================================================== -// EOF reset_gen.v +// EOF clk_reset_gen.v //====================================================================== diff --git a/hw/application_fpga/tb/application_fpga_vsim.v b/hw/application_fpga/tb/application_fpga_vsim.v index b496daf5..fa3a3172 100644 --- a/hw/application_fpga/tb/application_fpga_vsim.v +++ b/hw/application_fpga/tb/application_fpga_vsim.v @@ -36,6 +36,7 @@ module application_fpga( output wire interface_rx, input wire interface_tx, + input wire interface_rts, input wire touch_event,