diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-09-26 09:26:35 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-09-26 09:26:35 -0600 |
| commit | af2f49f863deaeb6dc905bbb15701b50bc139873 (patch) | |
| tree | e86dfc675f18ce49b91f4034788d1aaea4cbf2d3 /rtl/core/alu | |
| parent | 14d06f0bc047ad79830890807bfe6195ba3de8ff (diff) | |
Implement ALU shifter
Diffstat (limited to 'rtl/core/alu')
| -rw-r--r-- | rtl/core/alu/alu.sv | 14 | ||||
| -rw-r--r-- | rtl/core/alu/shifter.sv | 33 |
2 files changed, 40 insertions, 7 deletions
diff --git a/rtl/core/alu/alu.sv b/rtl/core/alu/alu.sv index 914b40e..f5a0487 100644 --- a/rtl/core/alu/alu.sv +++ b/rtl/core/alu/alu.sv @@ -5,7 +5,8 @@ module core_alu ( input alu_control ctrl, input logic[W - 1:0] a, - b, + base, + input logic[7:0] shift, input logic c_in, output logic[W - 1:0] q, @@ -14,12 +15,21 @@ module core_alu ); logic c, v, swap, sub, and_not, c_shifter, c_add, v_add; - logic[W - 1:0] swap_a, swap_b, neg_b, c_in_add, q_add, q_and, q_orr, q_xor; + logic[W - 1:0] b, swap_a, swap_b, neg_b, c_in_add, q_add, q_and, q_orr, q_xor; assign swap_a = swap ? b : a; assign swap_b = swap ? a : b; assign neg_b = -swap_b; + core_alu_shifter #(.W(W)) shifter + ( + .base(base), + .shift(shift), + .b(b), + .c(c_shifter), + .* + ); + core_alu_add #(.W(W)) op_add ( .a(swap_a), diff --git a/rtl/core/alu/shifter.sv b/rtl/core/alu/shifter.sv index 3effb2c..4385b41 100644 --- a/rtl/core/alu/shifter.sv +++ b/rtl/core/alu/shifter.sv @@ -1,12 +1,35 @@ -module alu_shl +`include "core/uarch.sv" + +module core_alu_shifter #(parameter W=16) ( - input logic[W - 1:0] a, - b, - output logic[W - 1:0] q, + input alu_control ctrl, + input logic[W - 1:0] base, + input logic[7:0] shift, + input logic c_in, + + output logic[W - 1:0] b, output logic c ); - assign {c, q} = {1'b0, a} << b; + logic [W - 1:0] b_no_c, b_shl, b_shr, b_ror; + logic [W:0] sign_mask; + logic c_shl, c_shr; + + assign sign_mask = {(W + 1){ctrl.sign_extend & base[W - 1]}}; + assign {c_shl, b_shl} = {c_in, base} << shift; + assign {b_shr, c_shr} = {base, c_in} >> shift | ~(sign_mask >> shift); + assign b_ror = b_shr | base << (W - shift); + + assign b = {b_no_c[W - 1] | (ctrl.put_carry & c_in), b_no_c[W - 2:0]}; + assign c = ctrl.shr | ctrl.ror ? c_shr : c_shl; + + always_comb + if(ctrl.ror) + b = b_ror; + else if(ctrl.shr) + b = {b_shr[W - 1] | (ctrl.put_carry & c_in), b_shr[W - 2:0]}; + else + b = b_shl; endmodule |
