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/shifter.sv | |
| parent | 14d06f0bc047ad79830890807bfe6195ba3de8ff (diff) | |
Implement ALU shifter
Diffstat (limited to 'rtl/core/alu/shifter.sv')
| -rw-r--r-- | rtl/core/alu/shifter.sv | 33 |
1 files changed, 28 insertions, 5 deletions
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 |
