diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-09-26 10:28:18 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-09-26 10:28:18 -0600 |
| commit | dec51abad98cfdee3e0262ff667a53f510c33360 (patch) | |
| tree | e090e7fab51fe0a57e54f0ee215a9eb71fbbef31 /rtl/core/alu/shifter.sv | |
| parent | af2f49f863deaeb6dc905bbb15701b50bc139873 (diff) | |
Fix shifter addressing modes
Diffstat (limited to 'rtl/core/alu/shifter.sv')
| -rw-r--r-- | rtl/core/alu/shifter.sv | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/rtl/core/alu/shifter.sv b/rtl/core/alu/shifter.sv index 4385b41..1f99e99 100644 --- a/rtl/core/alu/shifter.sv +++ b/rtl/core/alu/shifter.sv @@ -12,24 +12,31 @@ module core_alu_shifter output logic c ); - logic [W - 1:0] b_no_c, b_shl, b_shr, b_ror; - logic [W:0] sign_mask; - logic c_shl, c_shr; + localparam LOG = $clog2(W); + + logic[W - 1:0] b_no_c, b_shl, b_shr, b_ror; + logic[W:0] sign_mask; + logic c_shl, c_shr, c_ror; 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; + logic ror_cycle; + logic[LOG - 1:0] ror_shift; + logic[2 * W:0] ror_out; + + assign ror_shift = shift[LOG - 1:0]; + assign ror_cycle = |shift[7:LOG] & ~|ror_shift; + assign ror_out = {base, base, c_in} >> {ror_cycle, ror_shift}; + assign {b_ror, c_ror} = ror_out[W:0]; always_comb if(ctrl.ror) - b = b_ror; + {c, b} = {c_ror, b_ror}; else if(ctrl.shr) - b = {b_shr[W - 1] | (ctrl.put_carry & c_in), b_shr[W - 2:0]}; + {c, b} = {c_shr, b_shr[W - 1] | (ctrl.put_carry & c_in), b_shr[W - 2:0]}; else - b = b_shl; + {c, b} = {c_shl, b_shl}; endmodule |
