aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-05-12 19:24:42 +0200
committerTristan Gingold <tgingold@free.fr>2020-05-13 06:01:08 +0200
commitf74e3804a1aea0634e346f0f6ab47ec9db87a5eb (patch)
tree58b48af00500d55203cb1026fb0229a7ba3f6467 /src
parent54cd0b5bd2cb29668fc41946a95bba0d13a67199 (diff)
downloadghdl-f74e3804a1aea0634e346f0f6ab47ec9db87a5eb.tar.gz
ghdl-f74e3804a1aea0634e346f0f6ab47ec9db87a5eb.tar.bz2
ghdl-f74e3804a1aea0634e346f0f6ab47ec9db87a5eb.zip
synth: handle any constant as edge value. Fix #1302
Diffstat (limited to 'src')
-rw-r--r--src/synth/synth-expr.adb64
1 files changed, 37 insertions, 27 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index f17682d75..faebd7c93 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -1547,13 +1547,14 @@ package body Synth.Expr is
function Extract_Clock_Level
(Syn_Inst : Synth_Instance_Acc; Expr : Node; Prefix : Node) return Net
is
- Ctxt : constant Context_Acc := Get_Build (Syn_Inst);
- Clk : Net;
- Imp : Node;
+ Ctxt : constant Context_Acc := Get_Build (Syn_Inst);
+ Clk : Net;
+ Imp : Node;
Left, Right : Node;
- Lit : Node;
- Posedge : Boolean;
- Res : Net;
+ Lit : Valtyp;
+ Lit_Type : Node;
+ Posedge : Boolean;
+ Res : Net;
begin
Clk := Get_Net (Ctxt, Synth_Name (Syn_Inst, Prefix));
if Get_Kind (Expr) /= Iir_Kind_Equality_Operator then
@@ -1569,32 +1570,41 @@ package body Synth.Expr is
Set_Location (Res, Expr);
return Res;
end if;
+
Left := Get_Left (Expr);
- Right := Get_Right (Expr);
- if Get_Kind (Right) /= Iir_Kind_Character_Literal then
- Error_Msg_Synth
- (+Expr, "ill-formed clock-level, '0' or '1' expected");
- Res := Build_Posedge (Ctxt, Clk);
- Set_Location (Res, Expr);
- return Res;
+ if not Is_Same_Node (Prefix, Left) then
+ Error_Msg_Synth (+Left, "clock signal name doesn't match");
end if;
- Lit := Get_Named_Entity (Right);
- if Lit = Vhdl.Std_Package.Bit_0
- or else Lit = Vhdl.Ieee.Std_Logic_1164.Std_Ulogic_0
- then
- Posedge := False;
- elsif Lit = Vhdl.Std_Package.Bit_1
- or else Lit = Vhdl.Ieee.Std_Logic_1164.Std_Ulogic_1
- then
+ Right := Get_Right (Expr);
+ Lit_Type := Get_Base_Type (Get_Type (Right));
+ Lit := Synth_Expression (Syn_Inst, Right);
+ if Lit.Val.Kind /= Value_Memory then
+ Error_Msg_Synth (+Right, "clock-level is not a constant");
Posedge := True;
else
- Error_Msg_Synth
- (+Lit, "ill-formed clock-level, '0' or '1' expected");
- Posedge := True;
- end if;
- if not Is_Same_Node (Prefix, Left) then
- Error_Msg_Synth (+Left, "clock signal name doesn't match");
+ if Lit_Type = Vhdl.Ieee.Std_Logic_1164.Std_Ulogic_Type then
+ case Read_U8 (Lit.Val.Mem) is
+ when Vhdl.Ieee.Std_Logic_1164.Std_Logic_0_Pos =>
+ Posedge := False;
+ when Vhdl.Ieee.Std_Logic_1164.Std_Logic_1_Pos =>
+ Posedge := True;
+ when others =>
+ Error_Msg_Synth
+ (+Right, "clock-level must be either '0' or '1'");
+ Posedge := True;
+ end case;
+ else
+ pragma Assert (Lit_Type = Vhdl.Std_Package.Bit_Type_Definition);
+ case Read_U8 (Lit.Val.Mem) is
+ when 0 =>
+ Posedge := False;
+ when 1 =>
+ Posedge := True;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end if;
end if;
if Posedge then
Res := Build_Posedge (Ctxt, Clk);