aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-11-03 21:14:43 +0100
committerTristan Gingold <tgingold@free.fr>2019-11-03 21:15:09 +0100
commit33d2c1c6861ce3e349f98ffd8eac0face8ec3f6b (patch)
treeed9e41d8a28d523d4ffe45135e6202d515c03549 /src
parentd9cb3f5313b4dd6a39fab9dc72fa2cf336dd6b08 (diff)
downloadghdl-33d2c1c6861ce3e349f98ffd8eac0face8ec3f6b.tar.gz
ghdl-33d2c1c6861ce3e349f98ffd8eac0face8ec3f6b.tar.bz2
ghdl-33d2c1c6861ce3e349f98ffd8eac0face8ec3f6b.zip
netlists-expands: expand rol.
Diffstat (limited to 'src')
-rw-r--r--src/synth/netlists-expands.adb30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/synth/netlists-expands.adb b/src/synth/netlists-expands.adb
index 7e6b1bff4..a34302ef8 100644
--- a/src/synth/netlists-expands.adb
+++ b/src/synth/netlists-expands.adb
@@ -415,6 +415,32 @@ package body Netlists.Expands is
Remove_Instance (Inst);
end Expand_Dyn_Insert;
+ procedure Expand_Rol (Ctxt : Context_Acc; Inst : Instance)
+ is
+ Val : constant Input := Get_Input (Inst, 0);
+ Amt : constant Input := Get_Input (Inst, 1);
+ Val_N : constant Net := Get_Driver (Val);
+ Amt_N : constant Net := Get_Driver (Amt);
+ W_Val : constant Width := Get_Width (Val_N);
+ W_Amt : constant Width := Clog2 (W_Val);
+ Shl : Net;
+ R_Amt : Net;
+ Shr : Net;
+ Res : Net;
+ begin
+ Shl := Build_Shift_Rotate (Ctxt, Id_Lsl, Val_N, Amt_N);
+ R_Amt := Build_Dyadic (Ctxt, Id_Sub,
+ Build_Const_UB32 (Ctxt, W_Val, W_Amt),
+ Build2_Uresize (Ctxt, Amt_N, W_Amt));
+ Shr := Build_Shift_Rotate (Ctxt, Id_Lsr, Val_N, R_Amt);
+ Res := Build_Dyadic (Ctxt, Id_Or, Shl, Shr);
+
+ Redirect_Inputs (Get_Output (Inst, 0), Res);
+ Disconnect (Val);
+ Disconnect (Amt);
+ Remove_Instance (Inst);
+ end Expand_Rol;
+
procedure Expand_Gates (Ctxt : Context_Acc; M : Module)
is
Inst : Instance;
@@ -431,6 +457,10 @@ package body Netlists.Expands is
when Id_Dyn_Insert =>
Expand_Dyn_Insert (Ctxt, Inst);
+ when Id_Rol =>
+ -- a rol b == shl (a, b) | shr (a, l - b)
+ Expand_Rol (Ctxt, Inst);
+
when others =>
null;
end case;