[aes] Ignore writes to control register when not idle
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
diff --git a/hw/ip/aes/data/aes.hjson b/hw/ip/aes/data/aes.hjson
index 589789d..ce09b74 100644
--- a/hw/ip/aes/data/aes.hjson
+++ b/hw/ip/aes/data/aes.hjson
@@ -88,10 +88,14 @@
##############################################################################
# control and status registers
{ name: "CTRL",
- desc: "Control Register",
+ desc: '''
+ Control Register. Can only be updated when the AES unit is idle. If the
+ AES unit is non-idle, writes to this register are ignored.
+ '''
swaccess: "rw",
hwaccess: "hro",
- hwqe: "true",
+ hwext: "true",
+ hwqe: "true",
fields: [
{ bits: "0",
name: "MODE",
diff --git a/hw/ip/aes/rtl/aes_control.sv b/hw/ip/aes/rtl/aes_control.sv
index 0b68b5e..a05acdb 100644
--- a/hw/ip/aes/rtl/aes_control.sv
+++ b/hw/ip/aes/rtl/aes_control.sv
@@ -13,8 +13,8 @@
// Main control inputs
input aes_pkg::mode_e mode_i,
input aes_pkg::key_len_e key_len_i,
- input logic force_data_overwrite_i,
input logic manual_start_trigger_i,
+ input logic force_data_overwrite_i,
input logic start_i,
input logic key_clear_i,
input logic data_in_clear_i,
diff --git a/hw/ip/aes/rtl/aes_core.sv b/hw/ip/aes/rtl/aes_core.sv
index ec5af2f..b4afff3 100644
--- a/hw/ip/aes/rtl/aes_core.sv
+++ b/hw/ip/aes/rtl/aes_core.sv
@@ -25,8 +25,13 @@
logic [7:0][31:0] key_init;
logic [7:0] key_init_qe;
- mode_e mode, key_expand_mode;
- key_len_e key_len_q, key_len;
+ logic ctrl_qe;
+ logic ctrl_we;
+ mode_e mode_d, mode_q;
+ key_len_e key_len;
+ key_len_e key_len_d, key_len_q;
+ logic manual_start_trigger_q;
+ logic force_data_overwrite_q;
logic [3:0][3:0][7:0] state_init;
logic [3:0][3:0][7:0] state_d;
@@ -54,6 +59,7 @@
logic key_dec_we;
key_dec_sel_e key_dec_sel;
logic [7:0][31:0] key_expand_out;
+ mode_e key_expand_mode;
logic key_expand_step;
logic key_expand_clear;
logic [3:0] key_expand_round;
@@ -71,9 +77,6 @@
// Unused signals
logic [3:0][31:0] unused_data_out_q;
- logic unused_mode_qe;
- logic unused_manual_start_trigger_qe;
- logic unused_force_data_overwrite_qe;
////////////
// Inputs //
@@ -102,23 +105,20 @@
end
end
- assign mode = mode_e'(reg2hw.ctrl.mode.q);
+ assign mode_d = mode_e'(reg2hw.ctrl.mode.q);
- assign key_len_q = key_len_e'(reg2hw.ctrl.key_len.q);
+ assign key_len = key_len_e'(reg2hw.ctrl.key_len.q);
always_comb begin : get_key_len
- unique case (key_len_q)
- AES_128: key_len = AES_128;
- AES_256: key_len = AES_256;
- AES_192: key_len = AES192Enable ? AES_192 : AES_128;
- default: key_len = AES_128; // unsupported values are mapped to AES_128
+ unique case (key_len)
+ AES_128: key_len_d = AES_128;
+ AES_256: key_len_d = AES_256;
+ AES_192: key_len_d = AES192Enable ? AES_192 : AES_128;
+ default: key_len_d = AES_128; // unsupported values are mapped to AES_128
endcase
end
- // Unused inputs
- // key_len is hrw and hwqe, other fields of ctrl reg are hro and don't need hwqe
- assign unused_mode_qe = reg2hw.ctrl.mode.qe;
- assign unused_manual_start_trigger_qe = reg2hw.ctrl.manual_start_trigger.qe;
- assign unused_force_data_overwrite_qe = reg2hw.ctrl.force_data_overwrite.qe;
+ assign ctrl_qe = reg2hw.ctrl.mode.qe & reg2hw.ctrl.key_len.qe &
+ reg2hw.ctrl.manual_start_trigger.qe & reg2hw.ctrl.force_data_overwrite.qe;
//////////
// Data //
@@ -147,19 +147,19 @@
// Cipher data path
aes_sub_bytes aes_sub_bytes (
- .mode_i ( mode ),
+ .mode_i ( mode_q ),
.data_i ( state_q ),
.data_o ( sub_bytes_out )
);
aes_shift_rows aes_shift_rows (
- .mode_i ( mode ),
+ .mode_i ( mode_q ),
.data_i ( sub_bytes_out ),
.data_o ( shift_rows_out )
);
aes_mix_columns aes_mix_columns (
- .mode_i ( mode ),
+ .mode_i ( mode_q ),
.data_i ( shift_rows_out ),
.data_o ( mix_columns_out )
);
@@ -246,7 +246,7 @@
.step_i ( key_expand_step ),
.clear_i ( key_expand_clear ),
.round_i ( key_expand_round ),
- .key_len_i ( key_len ),
+ .key_len_i ( key_len_q ),
.key_i ( key_full_q ),
.key_o ( key_expand_out )
);
@@ -289,10 +289,10 @@
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
- .mode_i ( mode ),
- .key_len_i ( key_len ),
- .force_data_overwrite_i ( reg2hw.ctrl.force_data_overwrite.q ),
- .manual_start_trigger_i ( reg2hw.ctrl.manual_start_trigger.q ),
+ .mode_i ( mode_q ),
+ .key_len_i ( key_len_q ),
+ .manual_start_trigger_i ( manual_start_trigger_q ),
+ .force_data_overwrite_i ( force_data_overwrite_q ),
.start_i ( reg2hw.trigger.start.q ),
.key_clear_i ( reg2hw.trigger.key_clear.q ),
.data_in_clear_i ( reg2hw.trigger.data_in_clear.q ),
@@ -349,6 +349,23 @@
end
end
+ // Control register
+ assign ctrl_we = ctrl_qe & hw2reg.status.idle.d;
+
+ always_ff @(posedge clk_i or negedge rst_ni) begin : ctrl_reg
+ if (!rst_ni) begin
+ mode_q <= AES_ENC;
+ key_len_q <= AES_128;
+ manual_start_trigger_q <= '0;
+ force_data_overwrite_q <= '0;
+ end else if (ctrl_we) begin
+ mode_q <= mode_d;
+ key_len_q <= key_len_d;
+ manual_start_trigger_q <= reg2hw.ctrl.manual_start_trigger.q;
+ force_data_overwrite_q <= reg2hw.ctrl.force_data_overwrite.q;
+ end
+ end
+
/////////////
// Outputs //
/////////////
@@ -377,7 +394,6 @@
end
end
- assign hw2reg.ctrl.key_len.d = {key_len};
- assign hw2reg.ctrl.key_len.de = reg2hw.ctrl.key_len.qe;
+ assign hw2reg.ctrl.key_len.d = {key_len_q};
endmodule
diff --git a/hw/ip/aes/rtl/aes_reg_pkg.sv b/hw/ip/aes/rtl/aes_reg_pkg.sv
index 9bccb69..7a49cf1 100644
--- a/hw/ip/aes/rtl/aes_reg_pkg.sv
+++ b/hw/ip/aes/rtl/aes_reg_pkg.sv
@@ -79,7 +79,6 @@
typedef struct packed {
struct packed {
logic [2:0] d;
- logic de;
} key_len;
} aes_hw2reg_ctrl_reg_t;
@@ -137,12 +136,12 @@
// Internal design logic to register //
///////////////////////////////////////
typedef struct packed {
- aes_hw2reg_key_mreg_t [7:0] key; // [535:280]
- aes_hw2reg_data_in_mreg_t [3:0] data_in; // [279:148]
- aes_hw2reg_data_out_mreg_t [3:0] data_out; // [147:20]
- aes_hw2reg_ctrl_reg_t ctrl; // [19:10]
- aes_hw2reg_trigger_reg_t trigger; // [9:6]
- aes_hw2reg_status_reg_t status; // [5:6]
+ aes_hw2reg_key_mreg_t [7:0] key; // [534:279]
+ aes_hw2reg_data_in_mreg_t [3:0] data_in; // [278:147]
+ aes_hw2reg_data_out_mreg_t [3:0] data_out; // [146:19]
+ aes_hw2reg_ctrl_reg_t ctrl; // [18:9]
+ aes_hw2reg_trigger_reg_t trigger; // [8:5]
+ aes_hw2reg_status_reg_t status; // [4:5]
} aes_hw2reg_t;
// Register Address
diff --git a/hw/ip/aes/rtl/aes_reg_top.sv b/hw/ip/aes/rtl/aes_reg_top.sv
index d02d28e..d343722 100644
--- a/hw/ip/aes/rtl/aes_reg_top.sv
+++ b/hw/ip/aes/rtl/aes_reg_top.sv
@@ -104,15 +104,19 @@
logic ctrl_mode_qs;
logic ctrl_mode_wd;
logic ctrl_mode_we;
+ logic ctrl_mode_re;
logic [2:0] ctrl_key_len_qs;
logic [2:0] ctrl_key_len_wd;
logic ctrl_key_len_we;
+ logic ctrl_key_len_re;
logic ctrl_manual_start_trigger_qs;
logic ctrl_manual_start_trigger_wd;
logic ctrl_manual_start_trigger_we;
+ logic ctrl_manual_start_trigger_re;
logic ctrl_force_data_overwrite_qs;
logic ctrl_force_data_overwrite_wd;
logic ctrl_force_data_overwrite_we;
+ logic ctrl_force_data_overwrite_re;
logic trigger_start_qs;
logic trigger_start_wd;
logic trigger_start_we;
@@ -433,108 +437,64 @@
);
- // R[ctrl]: V(False)
+ // R[ctrl]: V(True)
// F[mode]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
+ prim_subreg_ext #(
+ .DW (1)
) u_ctrl_mode (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
+ .re (ctrl_mode_re),
.we (ctrl_mode_we),
.wd (ctrl_mode_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
+ .d ('0),
+ .qre (),
.qe (reg2hw.ctrl.mode.qe),
.q (reg2hw.ctrl.mode.q ),
-
- // to register interface (read)
.qs (ctrl_mode_qs)
);
// F[key_len]: 3:1
- prim_subreg #(
- .DW (3),
- .SWACCESS("RW"),
- .RESVAL (3'h1)
+ prim_subreg_ext #(
+ .DW (3)
) u_ctrl_key_len (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
+ .re (ctrl_key_len_re),
.we (ctrl_key_len_we),
.wd (ctrl_key_len_wd),
-
- // from internal hardware
- .de (hw2reg.ctrl.key_len.de),
- .d (hw2reg.ctrl.key_len.d ),
-
- // to internal hardware
+ .d (hw2reg.ctrl.key_len.d),
+ .qre (),
.qe (reg2hw.ctrl.key_len.qe),
.q (reg2hw.ctrl.key_len.q ),
-
- // to register interface (read)
.qs (ctrl_key_len_qs)
);
// F[manual_start_trigger]: 4:4
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
+ prim_subreg_ext #(
+ .DW (1)
) u_ctrl_manual_start_trigger (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
+ .re (ctrl_manual_start_trigger_re),
.we (ctrl_manual_start_trigger_we),
.wd (ctrl_manual_start_trigger_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
+ .d ('0),
+ .qre (),
.qe (reg2hw.ctrl.manual_start_trigger.qe),
.q (reg2hw.ctrl.manual_start_trigger.q ),
-
- // to register interface (read)
.qs (ctrl_manual_start_trigger_qs)
);
// F[force_data_overwrite]: 5:5
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
+ prim_subreg_ext #(
+ .DW (1)
) u_ctrl_force_data_overwrite (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
+ .re (ctrl_force_data_overwrite_re),
.we (ctrl_force_data_overwrite_we),
.wd (ctrl_force_data_overwrite_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
+ .d ('0),
+ .qre (),
.qe (reg2hw.ctrl.force_data_overwrite.qe),
.q (reg2hw.ctrl.force_data_overwrite.q ),
-
- // to register interface (read)
.qs (ctrl_force_data_overwrite_qs)
);
@@ -845,15 +805,19 @@
assign ctrl_mode_we = addr_hit[16] & reg_we & ~wr_err;
assign ctrl_mode_wd = reg_wdata[0];
+ assign ctrl_mode_re = addr_hit[16] && reg_re;
assign ctrl_key_len_we = addr_hit[16] & reg_we & ~wr_err;
assign ctrl_key_len_wd = reg_wdata[3:1];
+ assign ctrl_key_len_re = addr_hit[16] && reg_re;
assign ctrl_manual_start_trigger_we = addr_hit[16] & reg_we & ~wr_err;
assign ctrl_manual_start_trigger_wd = reg_wdata[4];
+ assign ctrl_manual_start_trigger_re = addr_hit[16] && reg_re;
assign ctrl_force_data_overwrite_we = addr_hit[16] & reg_we & ~wr_err;
assign ctrl_force_data_overwrite_wd = reg_wdata[5];
+ assign ctrl_force_data_overwrite_re = addr_hit[16] && reg_re;
assign trigger_start_we = addr_hit[17] & reg_we & ~wr_err;
assign trigger_start_wd = reg_wdata[0];