aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/synth-insts.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-03-23 06:48:46 +0100
committerTristan Gingold <tgingold@free.fr>2020-03-23 06:48:46 +0100
commite1e293701bb457af7bffc2e18a890cf552599144 (patch)
tree7a0776b854dcac395b522da787441a95fe554534 /src/synth/synth-insts.adb
parent0cd37c83c170b5292b5ec9800013da6b4f63c1c1 (diff)
downloadghdl-e1e293701bb457af7bffc2e18a890cf552599144.tar.gz
ghdl-e1e293701bb457af7bffc2e18a890cf552599144.tar.bz2
ghdl-e1e293701bb457af7bffc2e18a890cf552599144.zip
synth: add id_inout gate to handle inout behaviour. Fir #1166
Diffstat (limited to 'src/synth/synth-insts.adb')
-rw-r--r--src/synth/synth-insts.adb44
1 files changed, 31 insertions, 13 deletions
diff --git a/src/synth/synth-insts.adb b/src/synth/synth-insts.adb
index b33df7097..fae1a5a65 100644
--- a/src/synth/synth-insts.adb
+++ b/src/synth/synth-insts.adb
@@ -1309,31 +1309,49 @@ package body Synth.Insts is
Val : Value_Acc)
is
Default : constant Node := Get_Default_Value (Inter);
+ Desc : constant Port_Desc :=
+ Get_Output_Desc (Get_Module (Self_Inst), Idx);
Inter_Typ : Type_Acc;
Value : Net;
Init : Value_Acc;
Inp : Input;
- W : Width;
begin
pragma Assert (Val.Kind = Value_Wire);
-- Create a gate for the output, so that it could be read.
Val.W := Alloc_Wire (Wire_Output, Inter);
- W := Get_Output_Desc (Get_Module (Self_Inst), Idx).W;
- pragma Assert (W = Get_Type_Width (Val.Typ));
- if Default /= Null_Node then
- Inter_Typ := Get_Value_Type (Syn_Inst, Get_Type (Inter));
- Init := Synth_Expression_With_Type
- (Syn_Inst, Default, Inter_Typ);
- Init := Synth_Subtype_Conversion
- (Init, Inter_Typ, False, Inter);
- Value := Builders.Build_Ioutput (Build_Context, Get_Net (Init));
+ pragma Assert (Desc.W = Get_Type_Width (Val.Typ));
+
+ Inp := Get_Input (Self_Inst, Idx);
+
+ if Desc.Is_Inout then
+ if Default /= Null_Node then
+ -- TODO: initialized inout.
+ raise Internal_Error;
+ end if;
+ declare
+ Io_Inst : Instance;
+ begin
+ Io_Inst := Builders.Build_Inout (Build_Context, Desc.W);
+ -- Connect port1 of gate inout to the pin.
+ Connect (Inp, Get_Output (Io_Inst, 1));
+ -- And port0 of the gate will be use to read from the pin.
+ Value := Get_Output (Io_Inst, 0);
+ end;
else
- Value := Builders.Build_Output (Build_Context, W);
+ if Default /= Null_Node then
+ Inter_Typ := Get_Value_Type (Syn_Inst, Get_Type (Inter));
+ Init := Synth_Expression_With_Type
+ (Syn_Inst, Default, Inter_Typ);
+ Init := Synth_Subtype_Conversion
+ (Init, Inter_Typ, False, Inter);
+ Value := Builders.Build_Ioutput (Build_Context, Get_Net (Init));
+ else
+ Value := Builders.Build_Output (Build_Context, Desc.W);
+ end if;
+ Connect (Inp, Value);
end if;
Set_Location (Value, Inter);
- Inp := Get_Input (Self_Inst, Idx);
- Connect (Inp, Value);
Set_Wire_Gate (Val.W, Value);
end Create_Output_Wire;