diff options
| -rw-r--r-- | rtl/alu.sv | 61 | ||||
| -rw-r--r-- | rtl/montreal_pkg.sv | 28 |
2 files changed, 89 insertions, 0 deletions
diff --git a/rtl/alu.sv b/rtl/alu.sv new file mode 100644 index 0000000..f5dde19 --- /dev/null +++ b/rtl/alu.sv @@ -0,0 +1,61 @@ +module alu + import montreal_pkg::*; +#( + parameter int unsigned XLEN = config_pkg::XLEN, + parameter int unsigned SLICE_WIDTH = config_pkg::SLICE_WIDTH, + + localparam int unsigned SLICE_ADDR_WIDTH = $clog2(XLEN / SLICE_WIDTH) +) ( + input logic clk_i, + input logic rst_ni, + input fu_op_t alu_op_i, + + input logic [SLICE_ADDR_WIDTH-1:0] count_i, + + input slice_t a_i, + input slice_t b_i, + + output slice_t result_o, + output logic carry_o +); + + logic negate_b; + + /* We used Karnaugh maps here. If the encoding for fu_op_t changes, this has to be updated. */ + assign negate_b = alu_op_i[3] || (!alu_op_i[2] && alu_op_i[1]); + + /* Adder width is SLICE_WIDTH + 1 to account for carry-out. */ + logic [SLICE_WIDTH:0] adder_a, adder_b, adder_result; + + assign adder_a = {1'b0, a_i}; + assign adder_b = {1'b0, (b_i ^ {SLICE_WIDTH{negate_b}})}; + + /* Carry signals. */ + logic carry, carry_d, carry_q; + + assign carry = (count_i == '0) ? negate_b : carry_q; + + /* Combinational arithmetic/logic core. */ + always_comb begin : alu_core + unique casez (alu_op_i[2:0]) + /* ADD, SUB, SLT, SLTU. */ + 3'b0??: begin end + /* XOR. */ + 3'b100: begin end + /* OR. */ + 3'b110: begin end + /* AND. */ + 3'b111: begin end + default: begin end + endcase + end : alu_core + + always_ff @(posedge clk_i) begin : carry_ff + if (!rst_ni) begin + carry_q <= '0; + end else begin + carry_q <= carry_d; + end + end : carry_ff + +endmodule : alu diff --git a/rtl/montreal_pkg.sv b/rtl/montreal_pkg.sv new file mode 100644 index 0000000..741a926 --- /dev/null +++ b/rtl/montreal_pkg.sv @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: CERN-OHL-P-2.0 */ + +package montreal_pkg; + + typedef logic unsigned [config_pkg::XLEN-1:0] word_t; + typedef logic unsigned [config_pkg::SLICE_WIDTH-1:0] slice_t; + + typedef enum logic [3:0] { + /* Arithmetic operations. */ + ADD = 4'b0000, + SUB = 4'b1000, + /* Logical operations. */ + XOR = 4'b0100, + OR = 4'b0110, + AND = 4'b0111, + /* Shift operations. */ + SLL = 4'b0001, + SRL = 4'b0101, + SRA = 4'b1101, + /* Conditional set operations. */ + SLT = 4'b0010, + SLTU = 4'b0011, + /* Zicond operations. */ + CZERO_EQZ = 4'b1001, + CZERO_NEZ = 4'b1011 + } fu_op_t; + +endpackage : montreal_pkg |