mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-24 13:57:19 -04:00
[rtl] Add Pointer Authentication
This commit is contained in:
parent
b1ff52dc67
commit
f13ac7b8b9
13 changed files with 579 additions and 64 deletions
|
@ -78,6 +78,12 @@ parameters:
|
||||||
paramtype: vlogparam
|
paramtype: vlogparam
|
||||||
description: "Number of PMP regions"
|
description: "Number of PMP regions"
|
||||||
|
|
||||||
|
PointerAuthentication:
|
||||||
|
datatype: int
|
||||||
|
default: 0
|
||||||
|
paramtype: vlogparam
|
||||||
|
description: "Enable pointer authentication (EXPERIMENTAL) [0/1]"
|
||||||
|
|
||||||
targets:
|
targets:
|
||||||
sim:
|
sim:
|
||||||
default_tool: verilator
|
default_tool: verilator
|
||||||
|
@ -94,6 +100,7 @@ targets:
|
||||||
- PMPEnable
|
- PMPEnable
|
||||||
- PMPGranularity
|
- PMPGranularity
|
||||||
- PMPNumRegions
|
- PMPNumRegions
|
||||||
|
- PointerAuthentication
|
||||||
toplevel: ibex_riscv_compliance
|
toplevel: ibex_riscv_compliance
|
||||||
tools:
|
tools:
|
||||||
verilator:
|
verilator:
|
||||||
|
|
|
@ -24,6 +24,7 @@ module ibex_riscv_compliance (
|
||||||
parameter MultiplierImplementation = "fast";
|
parameter MultiplierImplementation = "fast";
|
||||||
parameter bit BranchTargetALU = 1'b0;
|
parameter bit BranchTargetALU = 1'b0;
|
||||||
parameter bit WritebackStage = 1'b0;
|
parameter bit WritebackStage = 1'b0;
|
||||||
|
parameter bit PointerAuthentication = 1'b0;
|
||||||
|
|
||||||
logic clk_sys, rst_sys_n;
|
logic clk_sys, rst_sys_n;
|
||||||
|
|
||||||
|
@ -120,7 +121,8 @@ module ibex_riscv_compliance (
|
||||||
.BranchTargetALU (BranchTargetALU ),
|
.BranchTargetALU (BranchTargetALU ),
|
||||||
.WritebackStage (WritebackStage ),
|
.WritebackStage (WritebackStage ),
|
||||||
.DmHaltAddr (32'h00000000 ),
|
.DmHaltAddr (32'h00000000 ),
|
||||||
.DmExceptionAddr (32'h00000000 )
|
.DmExceptionAddr (32'h00000000 ),
|
||||||
|
.PointerAuthentication (PointerAuthentication )
|
||||||
) u_core (
|
) u_core (
|
||||||
.clk_i (clk_sys ),
|
.clk_i (clk_sys ),
|
||||||
.rst_ni (rst_sys_n ),
|
.rst_ni (rst_sys_n ),
|
||||||
|
|
|
@ -88,6 +88,12 @@ parameters:
|
||||||
paramtype: vlogparam
|
paramtype: vlogparam
|
||||||
description: "Number of PMP regions"
|
description: "Number of PMP regions"
|
||||||
|
|
||||||
|
PointerAuthentication:
|
||||||
|
datatype: int
|
||||||
|
default: 0
|
||||||
|
paramtype: vlogparam
|
||||||
|
description: "Enable pointer authentication (EXPERIMENTAL) [0/1]"
|
||||||
|
|
||||||
targets:
|
targets:
|
||||||
default: &default_target
|
default: &default_target
|
||||||
filesets:
|
filesets:
|
||||||
|
@ -106,7 +112,7 @@ targets:
|
||||||
- PMPGranularity
|
- PMPGranularity
|
||||||
- PMPNumRegions
|
- PMPNumRegions
|
||||||
- SRAMInitFile
|
- SRAMInitFile
|
||||||
|
- PointerAuthentication
|
||||||
lint:
|
lint:
|
||||||
<<: *default_target
|
<<: *default_target
|
||||||
default_tool: verilator
|
default_tool: verilator
|
||||||
|
|
|
@ -34,6 +34,7 @@ module ibex_simple_system (
|
||||||
parameter bit WritebackStage = 1'b0;
|
parameter bit WritebackStage = 1'b0;
|
||||||
parameter MultiplierImplementation = "fast";
|
parameter MultiplierImplementation = "fast";
|
||||||
parameter SRAMInitFile = "";
|
parameter SRAMInitFile = "";
|
||||||
|
parameter bit PointerAuthentication = 1'b0;
|
||||||
|
|
||||||
logic clk_sys = 1'b0, rst_sys_n;
|
logic clk_sys = 1'b0, rst_sys_n;
|
||||||
|
|
||||||
|
@ -159,7 +160,8 @@ module ibex_simple_system (
|
||||||
.WritebackStage ( WritebackStage ),
|
.WritebackStage ( WritebackStage ),
|
||||||
.MultiplierImplementation ( MultiplierImplementation ),
|
.MultiplierImplementation ( MultiplierImplementation ),
|
||||||
.DmHaltAddr ( 32'h00100000 ),
|
.DmHaltAddr ( 32'h00100000 ),
|
||||||
.DmExceptionAddr ( 32'h00100000 )
|
.DmExceptionAddr ( 32'h00100000 ),
|
||||||
|
.PointerAuthentication ( PointerAuthentication )
|
||||||
) u_core (
|
) u_core (
|
||||||
.clk_i (clk_sys),
|
.clk_i (clk_sys),
|
||||||
.rst_ni (rst_sys_n),
|
.rst_ni (rst_sys_n),
|
||||||
|
|
|
@ -37,6 +37,8 @@ filesets:
|
||||||
# - rtl/ibex_register_file_fpga.sv # FPGA
|
# - rtl/ibex_register_file_fpga.sv # FPGA
|
||||||
- rtl/ibex_register_file_ff.sv # generic FF-based
|
- rtl/ibex_register_file_ff.sv # generic FF-based
|
||||||
- rtl/ibex_core.sv
|
- rtl/ibex_core.sv
|
||||||
|
- rtl/ibex_pointer_authentication.sv
|
||||||
|
- rtl/ibex_cipher.sv
|
||||||
file_type: systemVerilogSource
|
file_type: systemVerilogSource
|
||||||
|
|
||||||
files_lint_verilator:
|
files_lint_verilator:
|
||||||
|
@ -130,6 +132,12 @@ parameters:
|
||||||
paramtype: vlogparam
|
paramtype: vlogparam
|
||||||
description: "Number of PMP regions"
|
description: "Number of PMP regions"
|
||||||
|
|
||||||
|
PointerAuthentication:
|
||||||
|
datatype: int
|
||||||
|
default: 0
|
||||||
|
paramtype: vlogparam
|
||||||
|
description: "Enable pointer authentication (EXPERIMENTAL) [0/1]"
|
||||||
|
|
||||||
targets:
|
targets:
|
||||||
default: &default_target
|
default: &default_target
|
||||||
filesets:
|
filesets:
|
||||||
|
|
87
rtl/ibex_cipher.sv
Normal file
87
rtl/ibex_cipher.sv
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
// Copyright lowRISC contributors.
|
||||||
|
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
// This is just a placeholder for the actual cipher core that will be connected later.
|
||||||
|
module ibex_cipher (
|
||||||
|
input logic clk_i,
|
||||||
|
input logic rst_ni,
|
||||||
|
|
||||||
|
input logic [127:0] key_i,
|
||||||
|
|
||||||
|
input logic [63:0] in_data_i,
|
||||||
|
input logic in_valid_i,
|
||||||
|
output logic in_ready_o,
|
||||||
|
|
||||||
|
output logic [31:0] out_data_o,
|
||||||
|
output logic out_valid_o,
|
||||||
|
input logic out_ready_i
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [127:0] key_q, key_d;
|
||||||
|
logic [63:0] data_q, data_d;
|
||||||
|
|
||||||
|
typedef enum logic [2:0] {
|
||||||
|
C_INPUT, C_CALC1, C_CALC2, C_CALC3, C_OUTPUT
|
||||||
|
} c_fsm_e;
|
||||||
|
c_fsm_e c_fsm_q, c_fsm_d;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
key_d = key_q;
|
||||||
|
data_d = data_q;
|
||||||
|
in_ready_o = '0;
|
||||||
|
out_data_o = '0;
|
||||||
|
out_valid_o = '0;
|
||||||
|
c_fsm_d = c_fsm_q;
|
||||||
|
|
||||||
|
unique case (c_fsm_q)
|
||||||
|
|
||||||
|
C_INPUT: begin
|
||||||
|
in_ready_o = 1'b1;
|
||||||
|
if (in_valid_i) begin
|
||||||
|
data_d = in_data_i;
|
||||||
|
key_d = key_i;
|
||||||
|
c_fsm_d = C_CALC1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
C_CALC1: begin
|
||||||
|
data_d = key_q[63:0] ^ data_q; // placeholder calculation
|
||||||
|
c_fsm_d = C_CALC2;
|
||||||
|
end
|
||||||
|
C_CALC2: begin
|
||||||
|
data_d = key_q[127:64] ^ data_q; // placeholder calculation
|
||||||
|
c_fsm_d = C_CALC3;
|
||||||
|
end
|
||||||
|
C_CALC3: begin
|
||||||
|
data_d = key_q[63:0] ^ data_q; // placeholder calculation
|
||||||
|
c_fsm_d = C_OUTPUT;
|
||||||
|
end
|
||||||
|
|
||||||
|
C_OUTPUT: begin
|
||||||
|
if (out_ready_i) begin
|
||||||
|
out_data_o = data_q[31:0] ^ data_q[63:32];
|
||||||
|
out_valid_o = 1'b1;
|
||||||
|
c_fsm_d = C_INPUT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
default: begin
|
||||||
|
c_fsm_d = C_INPUT;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||||
|
if (~rst_ni) begin
|
||||||
|
c_fsm_q <= C_INPUT;
|
||||||
|
key_q <= '0;
|
||||||
|
data_q <= '0;
|
||||||
|
end else begin
|
||||||
|
c_fsm_q <= c_fsm_d;
|
||||||
|
key_q <= key_d;
|
||||||
|
data_q <= data_d;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -33,7 +33,8 @@ module ibex_core #(
|
||||||
parameter bit DbgTriggerEn = 1'b0,
|
parameter bit DbgTriggerEn = 1'b0,
|
||||||
parameter bit SecureIbex = 1'b0,
|
parameter bit SecureIbex = 1'b0,
|
||||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||||
parameter int unsigned DmExceptionAddr = 32'h1A110808
|
parameter int unsigned DmExceptionAddr = 32'h1A110808,
|
||||||
|
parameter bit PointerAuthentication = 1'b0
|
||||||
) (
|
) (
|
||||||
// Clock and Reset
|
// Clock and Reset
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -344,6 +345,16 @@ module ibex_core #(
|
||||||
logic [31:0] rvfi_mem_addr_q;
|
logic [31:0] rvfi_mem_addr_q;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
// Pointer Authentication
|
||||||
|
logic pa_pac_en;
|
||||||
|
logic pa_aut_en;
|
||||||
|
logic [31:0] pa_data0;
|
||||||
|
logic [31:0] pa_data1;
|
||||||
|
logic pa_ready_id;
|
||||||
|
logic [31:0] pa_result;
|
||||||
|
logic pa_valid;
|
||||||
|
logic [127:0] csr_pa_key;
|
||||||
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
// Clock management //
|
// Clock management //
|
||||||
//////////////////////
|
//////////////////////
|
||||||
|
@ -467,13 +478,14 @@ module ibex_core #(
|
||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
ibex_id_stage #(
|
ibex_id_stage #(
|
||||||
.RV32E ( RV32E ),
|
.RV32E ( RV32E ),
|
||||||
.RV32M ( RV32M ),
|
.RV32M ( RV32M ),
|
||||||
.RV32B ( RV32B ),
|
.RV32B ( RV32B ),
|
||||||
.BranchTargetALU ( BranchTargetALU ),
|
.BranchTargetALU ( BranchTargetALU ),
|
||||||
.DataIndTiming ( DataIndTiming ),
|
.DataIndTiming ( DataIndTiming ),
|
||||||
.SpecBranch ( SpecBranch ),
|
.SpecBranch ( SpecBranch ),
|
||||||
.WritebackStage ( WritebackStage )
|
.WritebackStage ( WritebackStage ),
|
||||||
|
.PointerAuthentication ( PointerAuthentication )
|
||||||
) id_stage_i (
|
) id_stage_i (
|
||||||
.clk_i ( clk ),
|
.clk_i ( clk ),
|
||||||
.rst_ni ( rst_ni ),
|
.rst_ni ( rst_ni ),
|
||||||
|
@ -616,7 +628,16 @@ module ibex_core #(
|
||||||
.perf_mul_wait_o ( perf_mul_wait ),
|
.perf_mul_wait_o ( perf_mul_wait ),
|
||||||
.perf_div_wait_o ( perf_div_wait ),
|
.perf_div_wait_o ( perf_div_wait ),
|
||||||
.instr_id_done_o ( instr_id_done ),
|
.instr_id_done_o ( instr_id_done ),
|
||||||
.instr_id_done_compressed_o ( instr_id_done_compressed )
|
.instr_id_done_compressed_o ( instr_id_done_compressed ),
|
||||||
|
|
||||||
|
// Pointer Authentication
|
||||||
|
.pac_en_dec_o ( pa_pac_en ),
|
||||||
|
.aut_en_dec_o ( pa_aut_en ),
|
||||||
|
.pa_data0_o ( pa_data0 ),
|
||||||
|
.pa_data1_o ( pa_data1 ),
|
||||||
|
.pa_ready_id_o ( pa_ready_id ),
|
||||||
|
.pa_result_i ( pa_result ),
|
||||||
|
.pa_valid_i ( pa_valid )
|
||||||
);
|
);
|
||||||
|
|
||||||
// for RVFI only
|
// for RVFI only
|
||||||
|
@ -906,17 +927,18 @@ module ibex_core #(
|
||||||
assign csr_addr = csr_num_e'(csr_access ? alu_operand_b_ex[11:0] : 12'b0);
|
assign csr_addr = csr_num_e'(csr_access ? alu_operand_b_ex[11:0] : 12'b0);
|
||||||
|
|
||||||
ibex_cs_registers #(
|
ibex_cs_registers #(
|
||||||
.DbgTriggerEn ( DbgTriggerEn ),
|
.DbgTriggerEn ( DbgTriggerEn ),
|
||||||
.DataIndTiming ( DataIndTiming ),
|
.DataIndTiming ( DataIndTiming ),
|
||||||
.DummyInstructions ( DummyInstructions ),
|
.DummyInstructions ( DummyInstructions ),
|
||||||
.ICache ( ICache ),
|
.ICache ( ICache ),
|
||||||
.MHPMCounterNum ( MHPMCounterNum ),
|
.MHPMCounterNum ( MHPMCounterNum ),
|
||||||
.MHPMCounterWidth ( MHPMCounterWidth ),
|
.MHPMCounterWidth ( MHPMCounterWidth ),
|
||||||
.PMPEnable ( PMPEnable ),
|
.PMPEnable ( PMPEnable ),
|
||||||
.PMPGranularity ( PMPGranularity ),
|
.PMPGranularity ( PMPGranularity ),
|
||||||
.PMPNumRegions ( PMPNumRegions ),
|
.PMPNumRegions ( PMPNumRegions ),
|
||||||
.RV32E ( RV32E ),
|
.RV32E ( RV32E ),
|
||||||
.RV32M ( RV32M )
|
.RV32M ( RV32M ),
|
||||||
|
.PointerAuthentication ( PointerAuthentication )
|
||||||
) cs_registers_i (
|
) cs_registers_i (
|
||||||
.clk_i ( clk ),
|
.clk_i ( clk ),
|
||||||
.rst_ni ( rst_ni ),
|
.rst_ni ( rst_ni ),
|
||||||
|
@ -956,6 +978,9 @@ module ibex_core #(
|
||||||
.csr_pmp_cfg_o ( csr_pmp_cfg ),
|
.csr_pmp_cfg_o ( csr_pmp_cfg ),
|
||||||
.csr_pmp_addr_o ( csr_pmp_addr ),
|
.csr_pmp_addr_o ( csr_pmp_addr ),
|
||||||
|
|
||||||
|
// Pointer Authenticaiton
|
||||||
|
.csr_pa_key_o ( csr_pa_key ),
|
||||||
|
|
||||||
// debug
|
// debug
|
||||||
.csr_depc_o ( csr_depc ),
|
.csr_depc_o ( csr_depc ),
|
||||||
.debug_mode_i ( debug_mode ),
|
.debug_mode_i ( debug_mode ),
|
||||||
|
@ -1385,4 +1410,36 @@ module ibex_core #(
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
if (PointerAuthentication) begin : g_pa
|
||||||
|
ibex_pointer_authentication pointer_authentication_i (
|
||||||
|
.clk_i ( clk ),
|
||||||
|
.rst_ni ( rst_ni ),
|
||||||
|
.csr_pa_key_i ( csr_pa_key ),
|
||||||
|
.pac_en_i ( pa_pac_en ),
|
||||||
|
.aut_en_i ( pa_aut_en ),
|
||||||
|
.pa_data0_i ( pa_data0 ),
|
||||||
|
.pa_data1_i ( pa_data1 ),
|
||||||
|
.pa_ready_id_i ( pa_ready_id ),
|
||||||
|
.pa_result_o ( pa_result ),
|
||||||
|
.pa_valid_o ( pa_valid )
|
||||||
|
);
|
||||||
|
end else begin : g_no_pa
|
||||||
|
logic unused_pa_pac_en;
|
||||||
|
logic unused_pa_aut_en;
|
||||||
|
logic [31:0] unused_pa_data0;
|
||||||
|
logic [31:0] unused_pa_data1;
|
||||||
|
logic unused_pa_ready_id;
|
||||||
|
logic [127:0] unused_csr_pa_key;
|
||||||
|
assign unused_pa_pac_en = pa_pac_en;
|
||||||
|
assign unused_pa_aut_en = pa_aut_en;
|
||||||
|
assign unused_pa_data0 = pa_data0;
|
||||||
|
assign unused_pa_data1 = pa_data1;
|
||||||
|
assign unused_pa_ready_id = pa_ready_id;
|
||||||
|
assign unused_csr_pa_key = csr_pa_key;
|
||||||
|
|
||||||
|
// Output tieoff
|
||||||
|
assign pa_result = '0;
|
||||||
|
assign pa_valid = '0;
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -27,7 +27,8 @@ module ibex_core_tracing #(
|
||||||
parameter bit DbgTriggerEn = 1'b0,
|
parameter bit DbgTriggerEn = 1'b0,
|
||||||
parameter bit SecureIbex = 1'b0,
|
parameter bit SecureIbex = 1'b0,
|
||||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||||
parameter int unsigned DmExceptionAddr = 32'h1A110808
|
parameter int unsigned DmExceptionAddr = 32'h1A110808,
|
||||||
|
parameter bit PointerAuthentication = 1'b0
|
||||||
) (
|
) (
|
||||||
// Clock and Reset
|
// Clock and Reset
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -123,7 +124,8 @@ module ibex_core_tracing #(
|
||||||
.WritebackStage ( WritebackStage ),
|
.WritebackStage ( WritebackStage ),
|
||||||
.SecureIbex ( SecureIbex ),
|
.SecureIbex ( SecureIbex ),
|
||||||
.DmHaltAddr ( DmHaltAddr ),
|
.DmHaltAddr ( DmHaltAddr ),
|
||||||
.DmExceptionAddr ( DmExceptionAddr )
|
.DmExceptionAddr ( DmExceptionAddr ),
|
||||||
|
.PointerAuthentication ( PointerAuthentication )
|
||||||
) u_ibex_core (
|
) u_ibex_core (
|
||||||
.clk_i,
|
.clk_i,
|
||||||
.rst_ni,
|
.rst_ni,
|
||||||
|
|
|
@ -13,17 +13,18 @@
|
||||||
`include "prim_assert.sv"
|
`include "prim_assert.sv"
|
||||||
|
|
||||||
module ibex_cs_registers #(
|
module ibex_cs_registers #(
|
||||||
parameter bit DbgTriggerEn = 0,
|
parameter bit DbgTriggerEn = 0,
|
||||||
parameter bit DataIndTiming = 1'b0,
|
parameter bit DataIndTiming = 1'b0,
|
||||||
parameter bit DummyInstructions = 1'b0,
|
parameter bit DummyInstructions = 1'b0,
|
||||||
parameter bit ICache = 1'b0,
|
parameter bit ICache = 1'b0,
|
||||||
parameter int unsigned MHPMCounterNum = 10,
|
parameter int unsigned MHPMCounterNum = 10,
|
||||||
parameter int unsigned MHPMCounterWidth = 40,
|
parameter int unsigned MHPMCounterWidth = 40,
|
||||||
parameter bit PMPEnable = 0,
|
parameter bit PMPEnable = 0,
|
||||||
parameter int unsigned PMPGranularity = 0,
|
parameter int unsigned PMPGranularity = 0,
|
||||||
parameter int unsigned PMPNumRegions = 4,
|
parameter int unsigned PMPNumRegions = 4,
|
||||||
parameter bit RV32E = 0,
|
parameter bit RV32E = 0,
|
||||||
parameter bit RV32M = 0
|
parameter bit RV32M = 0,
|
||||||
|
parameter bit PointerAuthentication = 0
|
||||||
) (
|
) (
|
||||||
// Clock and Reset
|
// Clock and Reset
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -66,6 +67,9 @@ module ibex_cs_registers #(
|
||||||
output ibex_pkg::pmp_cfg_t csr_pmp_cfg_o [PMPNumRegions],
|
output ibex_pkg::pmp_cfg_t csr_pmp_cfg_o [PMPNumRegions],
|
||||||
output logic [33:0] csr_pmp_addr_o [PMPNumRegions],
|
output logic [33:0] csr_pmp_addr_o [PMPNumRegions],
|
||||||
|
|
||||||
|
// Pointer Authentication
|
||||||
|
output logic [127:0] csr_pa_key_o,
|
||||||
|
|
||||||
// debug
|
// debug
|
||||||
input logic debug_mode_i,
|
input logic debug_mode_i,
|
||||||
input ibex_pkg::dbg_cause_e debug_cause_i,
|
input ibex_pkg::dbg_cause_e debug_cause_i,
|
||||||
|
@ -199,6 +203,9 @@ module ibex_cs_registers #(
|
||||||
logic [31:0] pmp_addr_rdata [PMP_MAX_REGIONS];
|
logic [31:0] pmp_addr_rdata [PMP_MAX_REGIONS];
|
||||||
logic [PMP_CFG_W-1:0] pmp_cfg_rdata [PMP_MAX_REGIONS];
|
logic [PMP_CFG_W-1:0] pmp_cfg_rdata [PMP_MAX_REGIONS];
|
||||||
|
|
||||||
|
// Key for Pointer Authentication
|
||||||
|
logic [127:0] pa_key;
|
||||||
|
|
||||||
// Hardware performance monitor signals
|
// Hardware performance monitor signals
|
||||||
logic [31:0] mcountinhibit;
|
logic [31:0] mcountinhibit;
|
||||||
// Only have mcountinhibit flops for counters that actually exist
|
// Only have mcountinhibit flops for counters that actually exist
|
||||||
|
@ -431,6 +438,11 @@ module ibex_cs_registers #(
|
||||||
csr_rdata_int = '0;
|
csr_rdata_int = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// Custom CSR for Pointer Authentication (cannot be read)
|
||||||
|
CSR_PAKEY0, CSR_PAKEY1, CSR_PAKEY2, CSR_PAKEY3: begin
|
||||||
|
csr_rdata_int = '0;
|
||||||
|
end
|
||||||
|
|
||||||
default: begin
|
default: begin
|
||||||
illegal_csr = 1'b1;
|
illegal_csr = 1'b1;
|
||||||
end
|
end
|
||||||
|
@ -855,6 +867,36 @@ module ibex_cs_registers #(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
// Pointer Authentication //
|
||||||
|
////////////////////////////
|
||||||
|
|
||||||
|
if (PointerAuthentication) begin : g_pa_key
|
||||||
|
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||||
|
if (!rst_ni) begin
|
||||||
|
pa_key <= '0;
|
||||||
|
end else begin
|
||||||
|
if (csr_we_int && (csr_addr == CSR_PAKEY0)) begin
|
||||||
|
pa_key[31:0] <= csr_wdata_int;
|
||||||
|
end
|
||||||
|
if (csr_we_int && (csr_addr == CSR_PAKEY1)) begin
|
||||||
|
pa_key[63:32] <= csr_wdata_int;
|
||||||
|
end
|
||||||
|
if (csr_we_int && (csr_addr == CSR_PAKEY2)) begin
|
||||||
|
pa_key[95:64] <= csr_wdata_int;
|
||||||
|
end
|
||||||
|
if (csr_we_int && (csr_addr == CSR_PAKEY3)) begin
|
||||||
|
pa_key[127:96] <= csr_wdata_int;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else begin : g_no_pa_key
|
||||||
|
// Generate tieoff when PointerAuthentication is not configured
|
||||||
|
assign pa_key = '0;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign csr_pa_key_o = pa_key;
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
// Performance monitor //
|
// Performance monitor //
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
|
@ -14,10 +14,11 @@
|
||||||
`include "prim_assert.sv"
|
`include "prim_assert.sv"
|
||||||
|
|
||||||
module ibex_decoder #(
|
module ibex_decoder #(
|
||||||
parameter bit RV32E = 0,
|
parameter bit RV32E = 0,
|
||||||
parameter bit RV32M = 1,
|
parameter bit RV32M = 1,
|
||||||
parameter bit BranchTargetALU = 0,
|
parameter bit BranchTargetALU = 0,
|
||||||
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone
|
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone,
|
||||||
|
parameter bit PointerAuthentication = 0
|
||||||
) (
|
) (
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
input logic rst_ni,
|
input logic rst_ni,
|
||||||
|
@ -94,7 +95,11 @@ module ibex_decoder #(
|
||||||
|
|
||||||
// jump/branches
|
// jump/branches
|
||||||
output logic jump_in_dec_o, // jump is being calculated in ALU
|
output logic jump_in_dec_o, // jump is being calculated in ALU
|
||||||
output logic branch_in_dec_o
|
output logic branch_in_dec_o,
|
||||||
|
|
||||||
|
// Pointer Authentication
|
||||||
|
output logic pac_en_dec_o,
|
||||||
|
output logic aut_en_dec_o
|
||||||
);
|
);
|
||||||
|
|
||||||
import ibex_pkg::*;
|
import ibex_pkg::*;
|
||||||
|
@ -115,6 +120,9 @@ module ibex_decoder #(
|
||||||
logic use_rs3_d;
|
logic use_rs3_d;
|
||||||
logic use_rs3_q;
|
logic use_rs3_q;
|
||||||
|
|
||||||
|
logic pa_use_rs3;
|
||||||
|
logic pa_write_to_rs1;
|
||||||
|
|
||||||
csr_op_e csr_op;
|
csr_op_e csr_op;
|
||||||
|
|
||||||
opcode_e opcode;
|
opcode_e opcode;
|
||||||
|
@ -154,11 +162,11 @@ module ibex_decoder #(
|
||||||
assign instr_rs2 = instr[24:20];
|
assign instr_rs2 = instr[24:20];
|
||||||
assign instr_rs3 = instr[31:27];
|
assign instr_rs3 = instr[31:27];
|
||||||
assign rf_raddr_a_o = (use_rs3_q & ~instr_first_cycle_i) ? instr_rs3 : instr_rs1; // rs3 / rs1
|
assign rf_raddr_a_o = (use_rs3_q & ~instr_first_cycle_i) ? instr_rs3 : instr_rs1; // rs3 / rs1
|
||||||
assign rf_raddr_b_o = instr_rs2; // rs2
|
assign rf_raddr_b_o = pa_use_rs3 ? instr_rs3 : instr_rs2; // rs3 / rs2
|
||||||
|
|
||||||
// destination register
|
// destination register
|
||||||
assign instr_rd = instr[11:7];
|
assign instr_rd = instr[11:7];
|
||||||
assign rf_waddr_o = instr_rd; // rd
|
assign rf_waddr_o = pa_write_to_rs1 ? instr_rs1 : instr_rd; // rs1 / rd
|
||||||
|
|
||||||
////////////////////
|
////////////////////
|
||||||
// Register check //
|
// Register check //
|
||||||
|
@ -219,6 +227,11 @@ module ibex_decoder #(
|
||||||
ecall_insn_o = 1'b0;
|
ecall_insn_o = 1'b0;
|
||||||
wfi_insn_o = 1'b0;
|
wfi_insn_o = 1'b0;
|
||||||
|
|
||||||
|
pac_en_dec_o = 1'b0;
|
||||||
|
aut_en_dec_o = 1'b0;
|
||||||
|
pa_use_rs3 = 1'b0;
|
||||||
|
pa_write_to_rs1 = 1'b0;
|
||||||
|
|
||||||
opcode = opcode_e'(instr[6:0]);
|
opcode = opcode_e'(instr[6:0]);
|
||||||
|
|
||||||
unique case (opcode)
|
unique case (opcode)
|
||||||
|
@ -612,6 +625,45 @@ module ibex_decoder #(
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
// Pointer Authentication //
|
||||||
|
////////////////////////////
|
||||||
|
|
||||||
|
OPCODE_PA: begin // Custom Operations for Pointer Authentication
|
||||||
|
unique case (instr[14:12])
|
||||||
|
3'b000: begin // PAC
|
||||||
|
pac_en_dec_o = (PointerAuthentication) ? 1'b1 : 1'b0;
|
||||||
|
rf_wdata_sel_o = RF_WD_PA;
|
||||||
|
rf_we = 1'b1;
|
||||||
|
if (instr_first_cycle_i) begin
|
||||||
|
// First write magic number and LSBs of pointer to rs1
|
||||||
|
pa_write_to_rs1 = 1'b1;
|
||||||
|
end else begin
|
||||||
|
// Then write MSBs of pointer and pac to rd
|
||||||
|
pa_write_to_rs1 = 1'b0;
|
||||||
|
end
|
||||||
|
illegal_insn = (PointerAuthentication) ? 1'b0 : 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
3'b001: begin // AUT
|
||||||
|
aut_en_dec_o = (PointerAuthentication) ? 1'b1 : 1'b0;
|
||||||
|
rf_wdata_sel_o = RF_WD_PA;
|
||||||
|
rf_we = 1'b1;
|
||||||
|
if (instr_first_cycle_i) begin
|
||||||
|
// First read MSBs of pointer and pac from rs2
|
||||||
|
pa_use_rs3 = 1'b0;
|
||||||
|
end else begin
|
||||||
|
// Then read LSBs of pointer from rs1 and read context from rs3
|
||||||
|
pa_use_rs3 = 1'b1;
|
||||||
|
end
|
||||||
|
illegal_insn = (PointerAuthentication) ? 1'b0 : 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
default:
|
||||||
|
illegal_insn = 1'b1;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
default: begin
|
default: begin
|
||||||
illegal_insn = 1'b1;
|
illegal_insn = 1'b1;
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,13 +17,14 @@
|
||||||
`include "prim_assert.sv"
|
`include "prim_assert.sv"
|
||||||
|
|
||||||
module ibex_id_stage #(
|
module ibex_id_stage #(
|
||||||
parameter bit RV32E = 0,
|
parameter bit RV32E = 0,
|
||||||
parameter bit RV32M = 1,
|
parameter bit RV32M = 1,
|
||||||
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone,
|
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone,
|
||||||
parameter bit DataIndTiming = 1'b0,
|
parameter bit DataIndTiming = 1'b0,
|
||||||
parameter bit BranchTargetALU = 0,
|
parameter bit BranchTargetALU = 0,
|
||||||
parameter bit SpecBranch = 0,
|
parameter bit SpecBranch = 0,
|
||||||
parameter bit WritebackStage = 0
|
parameter bit WritebackStage = 0,
|
||||||
|
parameter bit PointerAuthentication = 0
|
||||||
) (
|
) (
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
input logic rst_ni,
|
input logic rst_ni,
|
||||||
|
@ -177,7 +178,16 @@ module ibex_id_stage #(
|
||||||
output logic perf_mul_wait_o,
|
output logic perf_mul_wait_o,
|
||||||
output logic perf_div_wait_o,
|
output logic perf_div_wait_o,
|
||||||
output logic instr_id_done_o,
|
output logic instr_id_done_o,
|
||||||
output logic instr_id_done_compressed_o
|
output logic instr_id_done_compressed_o,
|
||||||
|
|
||||||
|
// Pointer Authentication
|
||||||
|
output logic pac_en_dec_o,
|
||||||
|
output logic aut_en_dec_o,
|
||||||
|
output logic [31:0] pa_data0_o,
|
||||||
|
output logic [31:0] pa_data1_o,
|
||||||
|
output logic pa_ready_id_o,
|
||||||
|
input logic [31:0] pa_result_i,
|
||||||
|
input logic pa_valid_i
|
||||||
);
|
);
|
||||||
|
|
||||||
import ibex_pkg::*;
|
import ibex_pkg::*;
|
||||||
|
@ -273,6 +283,10 @@ module ibex_id_stage #(
|
||||||
logic [31:0] alu_operand_a;
|
logic [31:0] alu_operand_a;
|
||||||
logic [31:0] alu_operand_b;
|
logic [31:0] alu_operand_b;
|
||||||
|
|
||||||
|
// Pointer Authentication
|
||||||
|
logic pa_en_dec;
|
||||||
|
logic stall_pa;
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
// LSU Mux //
|
// LSU Mux //
|
||||||
/////////////
|
/////////////
|
||||||
|
@ -401,6 +415,7 @@ module ibex_id_stage #(
|
||||||
unique case (rf_wdata_sel)
|
unique case (rf_wdata_sel)
|
||||||
RF_WD_EX: rf_wdata_id_o = result_ex_i;
|
RF_WD_EX: rf_wdata_id_o = result_ex_i;
|
||||||
RF_WD_CSR: rf_wdata_id_o = csr_rdata_i;
|
RF_WD_CSR: rf_wdata_id_o = csr_rdata_i;
|
||||||
|
RF_WD_PA: rf_wdata_id_o = pa_result_i;
|
||||||
default: rf_wdata_id_o = result_ex_i;
|
default: rf_wdata_id_o = result_ex_i;
|
||||||
endcase;
|
endcase;
|
||||||
end
|
end
|
||||||
|
@ -410,10 +425,11 @@ module ibex_id_stage #(
|
||||||
/////////////
|
/////////////
|
||||||
|
|
||||||
ibex_decoder #(
|
ibex_decoder #(
|
||||||
.RV32E ( RV32E ),
|
.RV32E ( RV32E ),
|
||||||
.RV32M ( RV32M ),
|
.RV32M ( RV32M ),
|
||||||
.RV32B ( RV32B ),
|
.RV32B ( RV32B ),
|
||||||
.BranchTargetALU ( BranchTargetALU )
|
.BranchTargetALU ( BranchTargetALU ),
|
||||||
|
.PointerAuthentication (PointerAuthentication )
|
||||||
) decoder_i (
|
) decoder_i (
|
||||||
.clk_i ( clk_i ),
|
.clk_i ( clk_i ),
|
||||||
.rst_ni ( rst_ni ),
|
.rst_ni ( rst_ni ),
|
||||||
|
@ -484,7 +500,11 @@ module ibex_id_stage #(
|
||||||
|
|
||||||
// jump/branches
|
// jump/branches
|
||||||
.jump_in_dec_o ( jump_in_dec ),
|
.jump_in_dec_o ( jump_in_dec ),
|
||||||
.branch_in_dec_o ( branch_in_dec )
|
.branch_in_dec_o ( branch_in_dec ),
|
||||||
|
|
||||||
|
// Pointer Authentication
|
||||||
|
.pac_en_dec_o ( pac_en_dec_o ),
|
||||||
|
.aut_en_dec_o ( aut_en_dec_o )
|
||||||
);
|
);
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
@ -638,6 +658,8 @@ module ibex_id_stage #(
|
||||||
assign multdiv_operand_a_ex_o = rf_rdata_a_fwd;
|
assign multdiv_operand_a_ex_o = rf_rdata_a_fwd;
|
||||||
assign multdiv_operand_b_ex_o = rf_rdata_b_fwd;
|
assign multdiv_operand_b_ex_o = rf_rdata_b_fwd;
|
||||||
|
|
||||||
|
assign pa_en_dec = pac_en_dec_o | aut_en_dec_o;
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// Branch set control //
|
// Branch set control //
|
||||||
////////////////////////
|
////////////////////////
|
||||||
|
@ -723,6 +745,7 @@ module ibex_id_stage #(
|
||||||
stall_jump = 1'b0;
|
stall_jump = 1'b0;
|
||||||
stall_branch = 1'b0;
|
stall_branch = 1'b0;
|
||||||
stall_alu = 1'b0;
|
stall_alu = 1'b0;
|
||||||
|
stall_pa = 1'b0;
|
||||||
branch_set_d = 1'b0;
|
branch_set_d = 1'b0;
|
||||||
branch_spec = 1'b0;
|
branch_spec = 1'b0;
|
||||||
jump_set = 1'b0;
|
jump_set = 1'b0;
|
||||||
|
@ -776,6 +799,22 @@ module ibex_id_stage #(
|
||||||
id_fsm_d = MULTI_CYCLE;
|
id_fsm_d = MULTI_CYCLE;
|
||||||
rf_we_raw = 1'b0;
|
rf_we_raw = 1'b0;
|
||||||
end
|
end
|
||||||
|
pa_en_dec: begin
|
||||||
|
if (pac_en_dec_o) begin // PAC
|
||||||
|
if (ready_wb_i) begin
|
||||||
|
id_fsm_d = MULTI_CYCLE;
|
||||||
|
rf_we_raw = 1'b1;
|
||||||
|
end else begin
|
||||||
|
// Wait until the writeback stage is ready
|
||||||
|
id_fsm_d = FIRST_CYCLE;
|
||||||
|
rf_we_raw = 1'b0;
|
||||||
|
end
|
||||||
|
end else begin // AUT
|
||||||
|
id_fsm_d = MULTI_CYCLE;
|
||||||
|
rf_we_raw = 1'b0;
|
||||||
|
end
|
||||||
|
stall_pa = 1'b1;
|
||||||
|
end
|
||||||
default: begin
|
default: begin
|
||||||
id_fsm_d = FIRST_CYCLE;
|
id_fsm_d = FIRST_CYCLE;
|
||||||
end
|
end
|
||||||
|
@ -787,12 +826,17 @@ module ibex_id_stage #(
|
||||||
rf_we_raw = rf_we_dec & ex_valid_i;
|
rf_we_raw = rf_we_dec & ex_valid_i;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (pa_en_dec) begin
|
||||||
|
rf_we_raw = rf_we_dec & pa_valid_i;
|
||||||
|
end
|
||||||
|
|
||||||
if (multicycle_done & ready_wb_i) begin
|
if (multicycle_done & ready_wb_i) begin
|
||||||
id_fsm_d = FIRST_CYCLE;
|
id_fsm_d = FIRST_CYCLE;
|
||||||
end else begin
|
end else begin
|
||||||
stall_multdiv = multdiv_en_dec;
|
stall_multdiv = multdiv_en_dec;
|
||||||
stall_branch = branch_in_dec;
|
stall_branch = branch_in_dec;
|
||||||
stall_jump = jump_in_dec;
|
stall_jump = jump_in_dec;
|
||||||
|
stall_pa = pa_en_dec;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -805,12 +849,13 @@ module ibex_id_stage #(
|
||||||
|
|
||||||
// Note for the two-stage configuration ready_wb_i is always set
|
// Note for the two-stage configuration ready_wb_i is always set
|
||||||
assign multdiv_ready_id_o = ready_wb_i;
|
assign multdiv_ready_id_o = ready_wb_i;
|
||||||
|
assign pa_ready_id_o = ready_wb_i;
|
||||||
|
|
||||||
`ASSERT(StallIDIfMulticycle, (id_fsm_q == FIRST_CYCLE) & (id_fsm_d == MULTI_CYCLE) |-> stall_id)
|
`ASSERT(StallIDIfMulticycle, (id_fsm_q == FIRST_CYCLE) & (id_fsm_d == MULTI_CYCLE) |-> stall_id)
|
||||||
|
|
||||||
// Stall ID/EX stage for reason that relates to instruction in ID/EX
|
// Stall ID/EX stage for reason that relates to instruction in ID/EX
|
||||||
assign stall_id = stall_ld_hz | stall_mem | stall_multdiv | stall_jump | stall_branch |
|
assign stall_id = stall_ld_hz | stall_mem | stall_multdiv | stall_jump | stall_branch |
|
||||||
stall_alu;
|
stall_alu | stall_pa;
|
||||||
|
|
||||||
assign instr_done = ~stall_id & ~flush_id & instr_executing;
|
assign instr_done = ~stall_id & ~flush_id & instr_executing;
|
||||||
|
|
||||||
|
@ -833,7 +878,8 @@ module ibex_id_stage #(
|
||||||
|
|
||||||
logic instr_kill;
|
logic instr_kill;
|
||||||
|
|
||||||
assign multicycle_done = lsu_req_dec ? ~stall_mem : ex_valid_i;
|
assign multicycle_done = lsu_req_dec ? ~stall_mem :
|
||||||
|
pa_en_dec ? pa_valid_i : ex_valid_i;
|
||||||
|
|
||||||
// Is a memory access ongoing that isn't finishing this cycle
|
// Is a memory access ongoing that isn't finishing this cycle
|
||||||
assign outstanding_memory_access = (outstanding_load_wb_i | outstanding_store_wb_i) &
|
assign outstanding_memory_access = (outstanding_load_wb_i | outstanding_store_wb_i) &
|
||||||
|
@ -910,7 +956,7 @@ module ibex_id_stage #(
|
||||||
lsu_we ? WB_INSTR_STORE :
|
lsu_we ? WB_INSTR_STORE :
|
||||||
WB_INSTR_LOAD;
|
WB_INSTR_LOAD;
|
||||||
|
|
||||||
assign en_wb_o = instr_done;
|
assign en_wb_o = instr_done | (pac_en_dec_o & instr_first_cycle);
|
||||||
|
|
||||||
assign instr_id_done_o = en_wb_o & ready_wb_i;
|
assign instr_id_done_o = en_wb_o & ready_wb_i;
|
||||||
|
|
||||||
|
@ -921,7 +967,8 @@ module ibex_id_stage #(
|
||||||
(outstanding_memory_access | stall_ld_hz);
|
(outstanding_memory_access | stall_ld_hz);
|
||||||
end else begin : gen_no_stall_mem
|
end else begin : gen_no_stall_mem
|
||||||
|
|
||||||
assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i : ex_valid_i;
|
assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i :
|
||||||
|
pa_en_dec ? pa_valid_i : ex_valid_i;
|
||||||
|
|
||||||
assign data_req_allowed = instr_first_cycle;
|
assign data_req_allowed = instr_first_cycle;
|
||||||
|
|
||||||
|
@ -981,6 +1028,9 @@ module ibex_id_stage #(
|
||||||
|
|
||||||
assign instr_id_done_compressed_o = instr_id_done_o & instr_is_compressed_i;
|
assign instr_id_done_compressed_o = instr_id_done_o & instr_is_compressed_i;
|
||||||
|
|
||||||
|
assign pa_data0_o = rf_rdata_a_fwd;
|
||||||
|
assign pa_data1_o = rf_rdata_b_fwd;
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
// Assertions //
|
// Assertions //
|
||||||
////////////////
|
////////////////
|
||||||
|
@ -1004,7 +1054,8 @@ module ibex_id_stage #(
|
||||||
IMM_B_INCR_PC})
|
IMM_B_INCR_PC})
|
||||||
`ASSERT(IbexRegfileWdataSelValid, instr_valid_i |-> rf_wdata_sel inside {
|
`ASSERT(IbexRegfileWdataSelValid, instr_valid_i |-> rf_wdata_sel inside {
|
||||||
RF_WD_EX,
|
RF_WD_EX,
|
||||||
RF_WD_CSR})
|
RF_WD_CSR,
|
||||||
|
RF_WD_PA})
|
||||||
`ASSERT_KNOWN(IbexWbStateKnown, id_fsm_q)
|
`ASSERT_KNOWN(IbexWbStateKnown, id_fsm_q)
|
||||||
|
|
||||||
// Branch decision must be valid when jumping.
|
// Branch decision must be valid when jumping.
|
||||||
|
|
|
@ -24,6 +24,7 @@ typedef enum integer {
|
||||||
|
|
||||||
typedef enum logic [6:0] {
|
typedef enum logic [6:0] {
|
||||||
OPCODE_LOAD = 7'h03,
|
OPCODE_LOAD = 7'h03,
|
||||||
|
OPCODE_PA = 7'h0b,
|
||||||
OPCODE_MISC_MEM = 7'h0f,
|
OPCODE_MISC_MEM = 7'h0f,
|
||||||
OPCODE_OP_IMM = 7'h13,
|
OPCODE_OP_IMM = 7'h13,
|
||||||
OPCODE_AUIPC = 7'h17,
|
OPCODE_AUIPC = 7'h17,
|
||||||
|
@ -224,9 +225,10 @@ typedef enum logic [2:0] {
|
||||||
} imm_b_sel_e;
|
} imm_b_sel_e;
|
||||||
|
|
||||||
// Regfile write data selection
|
// Regfile write data selection
|
||||||
typedef enum logic {
|
typedef enum logic [1:0] {
|
||||||
RF_WD_EX,
|
RF_WD_EX,
|
||||||
RF_WD_CSR
|
RF_WD_CSR,
|
||||||
|
RF_WD_PA
|
||||||
} rf_wd_sel_e;
|
} rf_wd_sel_e;
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
|
@ -466,7 +468,11 @@ typedef enum logic[11:0] {
|
||||||
CSR_MHPMCOUNTER30H = 12'hB9E,
|
CSR_MHPMCOUNTER30H = 12'hB9E,
|
||||||
CSR_MHPMCOUNTER31H = 12'hB9F,
|
CSR_MHPMCOUNTER31H = 12'hB9F,
|
||||||
CSR_CPUCTRL = 12'h7C0,
|
CSR_CPUCTRL = 12'h7C0,
|
||||||
CSR_SECURESEED = 12'h7C1
|
CSR_SECURESEED = 12'h7C1,
|
||||||
|
CSR_PAKEY0 = 12'h7C2,
|
||||||
|
CSR_PAKEY1 = 12'h7C3,
|
||||||
|
CSR_PAKEY2 = 12'h7C4,
|
||||||
|
CSR_PAKEY3 = 12'h7C5
|
||||||
} csr_num_e;
|
} csr_num_e;
|
||||||
|
|
||||||
// CSR pmp-related offsets
|
// CSR pmp-related offsets
|
||||||
|
|
193
rtl/ibex_pointer_authentication.sv
Normal file
193
rtl/ibex_pointer_authentication.sv
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
// Copyright lowRISC contributors.
|
||||||
|
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
module ibex_pointer_authentication #(
|
||||||
|
// This parameter is used in PAC instruction to rewrite MSBs of pointer to an invalid value
|
||||||
|
parameter logic [3:0] MSBsInvalidPointer = 4'b1010
|
||||||
|
) (
|
||||||
|
input logic clk_i,
|
||||||
|
input logic rst_ni,
|
||||||
|
|
||||||
|
input logic [127:0] csr_pa_key_i,
|
||||||
|
|
||||||
|
input logic pac_en_i,
|
||||||
|
input logic aut_en_i,
|
||||||
|
input logic [31:0] pa_data0_i,
|
||||||
|
input logic [31:0] pa_data1_i,
|
||||||
|
|
||||||
|
input logic pa_ready_id_i,
|
||||||
|
|
||||||
|
output logic [31:0] pa_result_o,
|
||||||
|
output logic pa_valid_o
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [3:0] msbs_pointer_q, msbs_pointer_d;
|
||||||
|
|
||||||
|
// We could theoretically avoid to buffer the pac
|
||||||
|
// by changing the decoder to provide the following outputs:
|
||||||
|
// Cycle 1: ptr MSBs (just store ptr MSBs, ignore the pac coming from same register)
|
||||||
|
// Cycle 2: ptr LSBs + context (now we can start the cipher)
|
||||||
|
// Cycle 3 onwards: pac
|
||||||
|
// But this is not currently done as it requires a lot of changes.
|
||||||
|
logic [27:0] pac_q, pac_d;
|
||||||
|
|
||||||
|
logic [63:0] cipher_in_data;
|
||||||
|
logic cipher_in_ready;
|
||||||
|
logic cipher_in_valid;
|
||||||
|
logic [31:0] cipher_out_data;
|
||||||
|
logic cipher_out_ready;
|
||||||
|
logic cipher_out_valid;
|
||||||
|
|
||||||
|
ibex_cipher ibex_cipher_i (
|
||||||
|
.clk_i ( clk_i ),
|
||||||
|
.rst_ni ( rst_ni ),
|
||||||
|
.key_i ( csr_pa_key_i ),
|
||||||
|
.in_data_i ( cipher_in_data ),
|
||||||
|
.in_valid_i ( cipher_in_valid ),
|
||||||
|
.in_ready_o ( cipher_in_ready ),
|
||||||
|
.out_data_o ( cipher_out_data ),
|
||||||
|
.out_valid_o ( cipher_out_valid ),
|
||||||
|
.out_ready_i ( cipher_out_ready )
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef enum logic [1:0] {
|
||||||
|
PA_IDLE, PA_START_AUT, PA_WAIT
|
||||||
|
} pa_fsm_e;
|
||||||
|
pa_fsm_e pa_fsm_q, pa_fsm_d;
|
||||||
|
|
||||||
|
typedef enum logic [1:0] {
|
||||||
|
PAC_START, PAC_DONE, AUT_SUCCESS, AUT_FAILURE
|
||||||
|
} pa_result_sel_e;
|
||||||
|
pa_result_sel_e pa_result_sel;
|
||||||
|
|
||||||
|
typedef enum logic [1:0] {
|
||||||
|
CIPHER_IDLE, CIPHER_PAC_START, CIPHER_AUT_START
|
||||||
|
} cipher_in_data_sel_e;
|
||||||
|
cipher_in_data_sel_e cipher_in_data_sel;
|
||||||
|
|
||||||
|
always_comb begin : pa_result_mux
|
||||||
|
unique case (pa_result_sel)
|
||||||
|
// MSBs of invalid pointer, LSBs of pointer
|
||||||
|
PAC_START: pa_result_o = {MSBsInvalidPointer, pa_data0_i[27:0]};
|
||||||
|
// MSBs of pointer, Pointer Authentication Code
|
||||||
|
PAC_DONE: pa_result_o = {msbs_pointer_q, cipher_out_data[27:0]};
|
||||||
|
// MSBs of pointer, LSB of pointer
|
||||||
|
AUT_SUCCESS: pa_result_o = {msbs_pointer_q, pa_data0_i[27:0]};
|
||||||
|
// We should make sure that the invalid bits get filled in the pointer
|
||||||
|
// no matter the content of msbs_pointer_q
|
||||||
|
// MSBs of invalid pointer, LSBs of pointer
|
||||||
|
AUT_FAILURE: pa_result_o = {MSBsInvalidPointer, pa_data0_i[27:0]};
|
||||||
|
// We usually take the first value from above,
|
||||||
|
// but AUT_FAILURE seems to be more sensible in this scenario
|
||||||
|
default: pa_result_o = {MSBsInvalidPointer, pa_data0_i[27:0]};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin : cipher_in_data_mux
|
||||||
|
unique case (cipher_in_data_sel)
|
||||||
|
CIPHER_IDLE: cipher_in_data = '0;
|
||||||
|
// context, MSBs of pointer, LSBs of pointer
|
||||||
|
CIPHER_PAC_START: cipher_in_data = {pa_data1_i, msbs_pointer_d, pa_data0_i[27:0]};
|
||||||
|
CIPHER_AUT_START: cipher_in_data = {pa_data1_i, msbs_pointer_q, pa_data0_i[27:0]};
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
// FSM
|
||||||
|
always_comb begin
|
||||||
|
pa_result_sel = AUT_FAILURE;
|
||||||
|
pa_valid_o = '0;
|
||||||
|
|
||||||
|
msbs_pointer_d = msbs_pointer_q;
|
||||||
|
pac_d = pac_q;
|
||||||
|
|
||||||
|
cipher_in_data_sel = CIPHER_IDLE;
|
||||||
|
cipher_in_valid = '0;
|
||||||
|
cipher_out_ready = '0;
|
||||||
|
|
||||||
|
pa_fsm_d = pa_fsm_q;
|
||||||
|
|
||||||
|
unique case (pa_fsm_q)
|
||||||
|
|
||||||
|
PA_IDLE: begin
|
||||||
|
unique case (1'b1)
|
||||||
|
pac_en_i: begin
|
||||||
|
pa_result_sel = PAC_START;
|
||||||
|
msbs_pointer_d = pa_data0_i[31:28];
|
||||||
|
cipher_in_data_sel = CIPHER_PAC_START;
|
||||||
|
cipher_in_valid = 1'b1;
|
||||||
|
if (cipher_in_ready) begin
|
||||||
|
pa_fsm_d = PA_WAIT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
aut_en_i: begin
|
||||||
|
msbs_pointer_d = pa_data1_i[31:28];
|
||||||
|
pac_d = pa_data1_i[27:0];
|
||||||
|
pa_fsm_d = PA_START_AUT;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
pa_fsm_d = PA_IDLE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
PA_START_AUT: begin
|
||||||
|
cipher_in_data_sel = CIPHER_AUT_START;
|
||||||
|
cipher_in_valid = 1'b1;
|
||||||
|
if (cipher_in_ready) begin
|
||||||
|
pa_fsm_d = PA_WAIT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
PA_WAIT: begin
|
||||||
|
unique case (1'b1)
|
||||||
|
pac_en_i: begin
|
||||||
|
if (pa_ready_id_i) begin
|
||||||
|
cipher_out_ready = 1'b1;
|
||||||
|
end
|
||||||
|
if (cipher_out_ready && cipher_out_valid) begin
|
||||||
|
pa_result_sel = PAC_DONE;
|
||||||
|
pa_valid_o = 1'b1;
|
||||||
|
pa_fsm_d = PA_IDLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
aut_en_i: begin
|
||||||
|
if (pa_ready_id_i) begin
|
||||||
|
cipher_out_ready = 1'b1;
|
||||||
|
end
|
||||||
|
if (cipher_out_ready && cipher_out_valid) begin
|
||||||
|
if (pac_q == cipher_out_data[27:0]) begin // Authentication success
|
||||||
|
pa_result_sel = AUT_SUCCESS;
|
||||||
|
end else begin // Authentication failure
|
||||||
|
pa_result_sel = AUT_FAILURE;
|
||||||
|
end
|
||||||
|
pa_valid_o = 1'b1;
|
||||||
|
pa_fsm_d = PA_IDLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
pa_fsm_d = PA_IDLE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
default: begin
|
||||||
|
pa_fsm_d = PA_IDLE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
// registers for FSM
|
||||||
|
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||||
|
if(~rst_ni) begin
|
||||||
|
pa_fsm_q <= PA_IDLE;
|
||||||
|
msbs_pointer_q <= '0;
|
||||||
|
pac_q <= '0;
|
||||||
|
end else begin
|
||||||
|
pa_fsm_q <= pa_fsm_d;
|
||||||
|
msbs_pointer_q <= msbs_pointer_d;
|
||||||
|
pac_q <= pac_d;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
Loading…
Add table
Add a link
Reference in a new issue