[otbn] Add specific ALU/comparison base operations
No real scope for sharing these with bignum ISA operations as encodings
and desired operations are too different.
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
diff --git a/hw/ip/otbn/rtl/otbn_alu_base.sv b/hw/ip/otbn/rtl/otbn_alu_base.sv
index 4c0ea46..3cb12c7 100644
--- a/hw/ip/otbn/rtl/otbn_alu_base.sv
+++ b/hw/ip/otbn/rtl/otbn_alu_base.sv
@@ -42,7 +42,7 @@
// setting addr_op_b_negate will cause a carry-in into bit 1. Combined with an inversion of
// operation_i.operand_b this gives a two's-complement negation (~b + 1)
- assign adder_op_b_negate = operation_i.op == AluOpSub;
+ assign adder_op_b_negate = operation_i.op == AluOpBaseSub;
assign adder_op_a = {operation_i.operand_a, 1'b1};
assign adder_op_b = adder_op_b_negate ? {~operation_i.operand_b, 1'b1} : {operation_i.operand_b, 1'b0};
@@ -77,8 +77,8 @@
// Shifter performs right arithmetic 33-bit shifts. Force top bit to 0 to get logical shifting
// otherwise replicate top bit of shift_in. Left shifts performed by reversing the input and
// output.
- assign shift_in[31:0] = (operation_i.op == AluOpSll) ? operand_a_reverse : operation_i.operand_a;
- assign shift_in[32] = (operation_i.op == AluOpSra) ? operation_i.operand_a[31] : 1'b0;
+ assign shift_in[31:0] = (operation_i.op == AluOpBaseSll) ? operand_a_reverse : operation_i.operand_a;
+ assign shift_in[32] = (operation_i.op == AluOpBaseSra) ? operation_i.operand_a[31] : 1'b0;
assign shift_out = signed'(shift_in) >>> shift_amt;
@@ -90,13 +90,13 @@
operation_result_o = adder_result[32:1];
unique case (operation_i.op)
- AluOpAnd: operation_result_o = and_result;
- AluOpOr: operation_result_o = or_result;
- AluOpXor: operation_result_o = xor_result;
- AluOpNot: operation_result_o = not_result;
- AluOpSra: operation_result_o = shift_out[31:0];
- AluOpSrl: operation_result_o = shift_out[31:0];
- AluOpSll: operation_result_o = shift_out_reverse;
+ AluOpBaseAnd: operation_result_o = and_result;
+ AluOpBaseOr: operation_result_o = or_result;
+ AluOpBaseXor: operation_result_o = xor_result;
+ AluOpBaseNot: operation_result_o = not_result;
+ AluOpBaseSra: operation_result_o = shift_out[31:0];
+ AluOpBaseSrl: operation_result_o = shift_out[31:0];
+ AluOpBaseSll: operation_result_o = shift_out_reverse;
default: ;
endcase
end
@@ -111,5 +111,5 @@
// avoiding an dedicated comparator.
assign is_equal = comparison_i.operand_a == comparison_i.operand_b;
- assign comparison_result_o = (comparison_i.op == ComparisonOpEq) ? is_equal : ~is_equal;
+ assign comparison_result_o = (comparison_i.op == ComparisonOpBaseEq) ? is_equal : ~is_equal;
endmodule
diff --git a/hw/ip/otbn/rtl/otbn_controller.sv b/hw/ip/otbn/rtl/otbn_controller.sv
index 4ab80e0..ae00f29 100644
--- a/hw/ip/otbn/rtl/otbn_controller.sv
+++ b/hw/ip/otbn/rtl/otbn_controller.sv
@@ -188,11 +188,11 @@
endcase
end
- assign alu_base_operation_o.op = insn_dec_ctrl_i.alu_op;
+ assign alu_base_operation_o.op = insn_dec_base_i.alu_op;
assign alu_base_comparison_o.operand_a = rf_base_rd_data_a_i;
assign alu_base_comparison_o.operand_b = rf_base_rd_data_b_i;
- assign alu_base_comparison_o.op = insn_dec_ctrl_i.comparison_op;
+ assign alu_base_comparison_o.op = insn_dec_base_i.comparison_op;
// Register file write MUX
// Suppress write for loads when controller isn't in stall state as load data for writeback is
diff --git a/hw/ip/otbn/rtl/otbn_decoder.sv b/hw/ip/otbn/rtl/otbn_decoder.sv
index 12bd852..ed7969e 100644
--- a/hw/ip/otbn/rtl/otbn_decoder.sv
+++ b/hw/ip/otbn/rtl/otbn_decoder.sv
@@ -62,11 +62,11 @@
logic [31:0] imm_u_type;
logic [31:0] imm_j_type;
- alu_op_e alu_operator; // ALU operation selection
- op_a_sel_e alu_op_a_mux_sel; // operand a selection: reg value, PC, immediate or zero
- op_b_sel_e alu_op_b_mux_sel; // operand b selection: reg value or immediate
+ alu_op_base_e alu_operator_base; // ALU operation selection for base ISA
+ op_a_sel_e alu_op_a_mux_sel; // operand a selection: reg value, PC, immediate or zero
+ op_b_sel_e alu_op_b_mux_sel; // operand b selection: reg value or immediate
- comparison_op_e comparison_operator;
+ comparison_op_base_e comparison_operator_base;
logic rf_ren_a;
logic rf_ren_b;
@@ -111,18 +111,18 @@
assign insn_illegal_o = insn_fetch_resp_valid_i & illegal_insn;
assign insn_dec_base_o = '{
- a: insn_rs1,
- b: insn_rs2,
- d: insn_rd,
- i: imm_b
+ a: insn_rs1,
+ b: insn_rs2,
+ d: insn_rd,
+ i: imm_b,
+ alu_op: alu_operator_base,
+ comparison_op: comparison_operator_base
};
assign insn_dec_ctrl_o = '{
subset: insn_subset,
op_a_sel: alu_op_a_mux_sel,
op_b_sel: alu_op_b_mux_sel,
- alu_op: alu_operator,
- comparison_op: comparison_operator,
rf_we: rf_we,
rf_wdata_sel: rf_wdata_sel,
ecall_insn: ecall_insn,
@@ -176,7 +176,7 @@
3'b001: begin
unique case (insn[31:27])
- 5'b0_0000: illegal_insn = 1'b0; // slli
+ 5'b0_0000: illegal_insn = 1'b0; // slli
default: illegal_insn = 1'b1;
endcase
end
@@ -184,8 +184,8 @@
3'b101: begin
if (!insn[26]) begin
unique case (insn[31:27])
- 5'b0_0000, // srli
- 5'b0_1000: illegal_insn = 1'b0; // srai
+ 5'b0_0000, // srli
+ 5'b0_1000: illegal_insn = 1'b0; // srai
default: illegal_insn = 1'b1;
endcase
@@ -325,15 +325,15 @@
/////////////////////////////
always_comb begin
- alu_operator = AluOpAdd;
- comparison_operator = ComparisonOpEq;
- alu_op_a_mux_sel = OpASelRegister;
- alu_op_b_mux_sel = OpBSelImmediate;
+ alu_operator_base = AluOpBaseAdd;
+ comparison_operator_base = ComparisonOpBaseEq;
+ alu_op_a_mux_sel = OpASelRegister;
+ alu_op_b_mux_sel = OpBSelImmediate;
- imm_a_mux_sel = ImmAZero;
- imm_b_mux_sel = ImmBI;
+ imm_a_mux_sel = ImmAZero;
+ imm_b_mux_sel = ImmBI;
- opcode_alu = insn_opcode_e'(insn_alu[6:0]);
+ opcode_alu = insn_opcode_e'(insn_alu[6:0]);
unique case (opcode_alu)
/////////
@@ -345,14 +345,14 @@
alu_op_b_mux_sel = OpBSelImmediate;
imm_a_mux_sel = ImmAZero;
imm_b_mux_sel = ImmBU;
- alu_operator = AluOpAdd;
+ alu_operator_base = AluOpBaseAdd;
end
InsnOpcodeBaseAuipc: begin // Add Upper Immediate to PC
alu_op_a_mux_sel = OpASelCurrPc;
alu_op_b_mux_sel = OpBSelImmediate;
imm_b_mux_sel = ImmBU;
- alu_operator = AluOpAdd;
+ alu_operator_base = AluOpBaseAdd;
end
InsnOpcodeBaseOpImm: begin // Register-Immediate ALU Operations
@@ -361,20 +361,20 @@
imm_b_mux_sel = ImmBI;
unique case (insn_alu[14:12])
- 3'b000: alu_operator = AluOpAdd; // Add Immediate
- 3'b100: alu_operator = AluOpXor; // Exclusive Or with Immediate
- 3'b110: alu_operator = AluOpOr; // Or with Immediate
- 3'b111: alu_operator = AluOpAnd; // And with Immediate
+ 3'b000: alu_operator_base = AluOpBaseAdd; // Add Immediate
+ 3'b100: alu_operator_base = AluOpBaseXor; // Exclusive Or with Immediate
+ 3'b110: alu_operator_base = AluOpBaseOr; // Or with Immediate
+ 3'b111: alu_operator_base = AluOpBaseAnd; // And with Immediate
3'b001: begin
- alu_operator = AluOpSll; // Shift Left Logical by Immediate
+ alu_operator_base = AluOpBaseSll; // Shift Left Logical by Immediate
end
3'b101: begin
if (insn_alu[31:27] == 5'b0_0000) begin
- alu_operator = AluOpSrl; // Shift Right Logical by Immediate
+ alu_operator_base = AluOpBaseSrl; // Shift Right Logical by Immediate
end else if (insn_alu[31:27] == 5'b0_1000) begin
- alu_operator = AluOpSra; // Shift Right Arithmetically by Immediate
+ alu_operator_base = AluOpBaseSra; // Shift Right Arithmetically by Immediate
end
end
@@ -389,14 +389,14 @@
if (!insn_alu[26]) begin
unique case ({insn_alu[31:25], insn_alu[14:12]})
// RV32I ALU operations
- {7'b000_0000, 3'b000}: alu_operator = AluOpAdd; // Add
- {7'b010_0000, 3'b000}: alu_operator = AluOpSub; // Sub
- {7'b000_0000, 3'b100}: alu_operator = AluOpXor; // Xor
- {7'b000_0000, 3'b110}: alu_operator = AluOpOr; // Or
- {7'b000_0000, 3'b111}: alu_operator = AluOpAnd; // And
- {7'b000_0000, 3'b001}: alu_operator = AluOpSll; // Shift Left Logical
- {7'b000_0000, 3'b101}: alu_operator = AluOpSrl; // Shift Right Logical
- {7'b010_0000, 3'b101}: alu_operator = AluOpSra; // Shift Right Arithmetic
+ {7'b000_0000, 3'b000}: alu_operator_base = AluOpBaseAdd; // Add
+ {7'b010_0000, 3'b000}: alu_operator_base = AluOpBaseSub; // Sub
+ {7'b000_0000, 3'b100}: alu_operator_base = AluOpBaseXor; // Xor
+ {7'b000_0000, 3'b110}: alu_operator_base = AluOpBaseOr; // Or
+ {7'b000_0000, 3'b111}: alu_operator_base = AluOpBaseAnd; // And
+ {7'b000_0000, 3'b001}: alu_operator_base = AluOpBaseSll; // Shift Left Logical
+ {7'b000_0000, 3'b101}: alu_operator_base = AluOpBaseSrl; // Shift Right Logical
+ {7'b010_0000, 3'b101}: alu_operator_base = AluOpBaseSra; // Shift Right Arithmetic
default: ;
endcase
end
@@ -407,17 +407,17 @@
//////////////////
InsnOpcodeBaseLoad: begin
- alu_op_a_mux_sel = OpASelRegister;
- alu_op_b_mux_sel = OpBSelImmediate;
- alu_operator = AluOpAdd;
- imm_b_mux_sel = ImmBI;
+ alu_op_a_mux_sel = OpASelRegister;
+ alu_op_b_mux_sel = OpBSelImmediate;
+ alu_operator_base = AluOpBaseAdd;
+ imm_b_mux_sel = ImmBI;
end
InsnOpcodeBaseStore: begin
- alu_op_a_mux_sel = OpASelRegister;
- alu_op_b_mux_sel = OpBSelImmediate;
- alu_operator = AluOpAdd;
- imm_b_mux_sel = ImmBS;
+ alu_op_a_mux_sel = OpASelRegister;
+ alu_op_b_mux_sel = OpBSelImmediate;
+ alu_operator_base = AluOpBaseAdd;
+ imm_b_mux_sel = ImmBS;
end
/////////////////
@@ -425,25 +425,25 @@
/////////////////
InsnOpcodeBaseBranch: begin
- alu_op_a_mux_sel = OpASelCurrPc;
- alu_op_b_mux_sel = OpBSelImmediate;
- alu_operator = AluOpAdd;
- imm_b_mux_sel = ImmBB;
- comparison_operator = insn_alu[12] ? ComparisonOpNeq : ComparisonOpEq;
+ alu_op_a_mux_sel = OpASelCurrPc;
+ alu_op_b_mux_sel = OpBSelImmediate;
+ alu_operator_base = AluOpBaseAdd;
+ imm_b_mux_sel = ImmBB;
+ comparison_operator_base = insn_alu[12] ? ComparisonOpBaseNeq : ComparisonOpBaseEq;
end
InsnOpcodeBaseJal: begin
- alu_op_a_mux_sel = OpASelCurrPc;
- alu_op_b_mux_sel = OpBSelImmediate;
- alu_operator = AluOpAdd;
- imm_b_mux_sel = ImmBJ;
+ alu_op_a_mux_sel = OpASelCurrPc;
+ alu_op_b_mux_sel = OpBSelImmediate;
+ alu_operator_base = AluOpBaseAdd;
+ imm_b_mux_sel = ImmBJ;
end
InsnOpcodeBaseJalr: begin
- alu_op_a_mux_sel = OpASelRegister;
- alu_op_b_mux_sel = OpBSelImmediate;
- alu_operator = AluOpAdd;
- imm_b_mux_sel = ImmBI;
+ alu_op_a_mux_sel = OpASelRegister;
+ alu_op_b_mux_sel = OpBSelImmediate;
+ alu_operator_base = AluOpBaseAdd;
+ imm_b_mux_sel = ImmBI;
end
/////////////
@@ -467,6 +467,6 @@
////////////////
// Selectors must be known/valid.
- `ASSERT(IbexRegImmAluOpKnown, (opcode == InsnOpcodeBaseOpImm) |->
+ `ASSERT(IbexRegImmAluOpBaseKnown, (opcode == InsnOpcodeBaseOpImm) |->
!$isunknown(insn[14:12]))
endmodule
diff --git a/hw/ip/otbn/rtl/otbn_pkg.sv b/hw/ip/otbn/rtl/otbn_pkg.sv
index 4e59501..57a6add 100644
--- a/hw/ip/otbn/rtl/otbn_pkg.sv
+++ b/hw/ip/otbn/rtl/otbn_pkg.sv
@@ -63,23 +63,23 @@
} insn_opcode_e;
typedef enum logic [3:0] {
- AluOpAdd,
- AluOpSub,
+ AluOpBaseAdd,
+ AluOpBaseSub,
- AluOpXor,
- AluOpOr,
- AluOpAnd,
- AluOpNot,
+ AluOpBaseXor,
+ AluOpBaseOr,
+ AluOpBaseAnd,
+ AluOpBaseNot,
- AluOpSra,
- AluOpSrl,
- AluOpSll
- } alu_op_e;
+ AluOpBaseSra,
+ AluOpBaseSrl,
+ AluOpBaseSll
+ } alu_op_base_e;
typedef enum logic {
- ComparisonOpEq,
- ComparisonOpNeq
- } comparison_op_e;
+ ComparisonOpBaseEq,
+ ComparisonOpBaseNeq
+ } comparison_op_base_e;
// Operand a source selection
typedef enum logic [1:0] {
@@ -149,10 +149,12 @@
// TODO: The variable names are rather short, especially "i" is confusing. Think about renaming.
typedef struct packed {
- logic [4:0] d; // Destination register
- logic [4:0] a; // First source register
- logic [4:0] b; // Second source register
- logic [31:0] i; // Immediate
+ logic [4:0] d; // Destination register
+ logic [4:0] a; // First source register
+ logic [4:0] b; // Second source register
+ logic [31:0] i; // Immediate
+ alu_op_base_e alu_op;
+ comparison_op_base_e comparison_op;
} insn_dec_base_t;
// Control signals from decoder to controller: additional information about the decoded
@@ -161,8 +163,6 @@
insn_subset_e subset;
op_a_sel_e op_a_sel;
op_b_sel_e op_b_sel;
- alu_op_e alu_op;
- comparison_op_e comparison_op;
logic rf_we;
rf_wd_sel_e rf_wdata_sel;
logic ecall_insn;
@@ -173,13 +173,13 @@
} insn_dec_ctrl_t;
typedef struct packed {
- alu_op_e op;
+ alu_op_base_e op;
logic [31:0] operand_a;
logic [31:0] operand_b;
} alu_base_operation_t;
typedef struct packed {
- comparison_op_e op;
+ comparison_op_base_e op;
logic [31:0] operand_a;
logic [31:0] operand_b;
} alu_base_comparison_t;