aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-03-29 09:57:01 +0200
committerTristan Gingold <tgingold@free.fr>2020-03-29 09:57:01 +0200
commit49858bd37724c2e1f8aba208fbc7b92a54cbe46a (patch)
treec43260b2c258750bab91cb3bfc529dafd7ebcb3c /src/synth
parentc742f92ae4a1f8363a3a9df34f7ba3f251b3c971 (diff)
downloadghdl-49858bd37724c2e1f8aba208fbc7b92a54cbe46a.tar.gz
ghdl-49858bd37724c2e1f8aba208fbc7b92a54cbe46a.tar.bz2
ghdl-49858bd37724c2e1f8aba208fbc7b92a54cbe46a.zip
synth: improve output of memory initial value.
Diffstat (limited to 'src/synth')
-rw-r--r--src/synth/netlists-disp_vhdl.adb40
-rw-r--r--src/synth/netlists-memories.adb11
-rw-r--r--src/synth/synth-context.adb38
-rw-r--r--src/synth/synth-expr.ads2
4 files changed, 82 insertions, 9 deletions
diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb
index a9086785c..8f53ae9d1 100644
--- a/src/synth/netlists-disp_vhdl.adb
+++ b/src/synth/netlists-disp_vhdl.adb
@@ -364,9 +364,8 @@ package body Netlists.Disp_Vhdl is
end case;
end Disp_Constant_Inline;
- procedure Disp_Const_Bit (Cst : Net; Off : Uns32)
+ procedure Disp_Const_Bit (Inst : Instance; Off : Uns32)
is
- Inst : constant Instance := Get_Net_Parent (Cst);
Val : Uns32;
Zx : Uns32;
begin
@@ -388,16 +387,49 @@ package body Netlists.Disp_Vhdl is
Val := 0;
end if;
Val := Shift_Right (Val, Natural (Off mod 32)) and 1;
+ when Id_Const_X =>
+ Zx := 1;
+ Val := 1;
when others =>
raise Internal_Error;
end case;
Put (Bchar (Zx * 2 + Val));
end Disp_Const_Bit;
+ procedure Disp_Memory_Init_Full (W : Width; Val : Character) is
+ begin
+ Put (" (others => ");
+ if W = 1 then
+ Put ("'");
+ Put (Val);
+ Put ("'");
+ else
+ Put ("(others => '");
+ Put (Val);
+ Put ("')");
+ end if;
+ Put_Line (");");
+ end Disp_Memory_Init_Full;
+
procedure Disp_Memory_Init (Val : Net; W : Width; Depth : Width)
is
+ Inst : constant Instance := Get_Net_Parent (Val);
Q : constant Character := Get_Lit_Quote (W);
begin
+ case Get_Id (Inst) is
+ when Id_Const_X =>
+ Disp_Memory_Init_Full (W, 'X');
+ return;
+ when Id_Const_UB32 =>
+ if Get_Param_Uns32 (Inst, 0) = 0 then
+ Disp_Memory_Init_Full (W, '0');
+ return;
+ end if;
+ when others =>
+ null;
+ end case;
+
+ New_Line;
for I in reverse 0 .. Depth - 1 loop
Put (" ");
if I = Depth - 1 then
@@ -409,7 +441,7 @@ package body Netlists.Disp_Vhdl is
Put (" => ");
Put (Q);
for J in reverse 0 .. W - 1 loop
- Disp_Const_Bit (Val, I * W + J);
+ Disp_Const_Bit (Inst, I * W + J);
end loop;
Put (Q);
if I /= 0 then
@@ -683,7 +715,7 @@ package body Netlists.Disp_Vhdl is
if Get_Id (Val_Inst) = Id_Isignal then
Val := Get_Input_Net (Val_Inst, 1);
end if;
- Put_Line (" :=");
+ Put (" :=");
Disp_Memory_Init (Val, Data_W, Depth);
end;
else
diff --git a/src/synth/netlists-memories.adb b/src/synth/netlists-memories.adb
index 38e1e4b64..4833f16f0 100644
--- a/src/synth/netlists-memories.adb
+++ b/src/synth/netlists-memories.adb
@@ -977,11 +977,16 @@ package body Netlists.Memories is
N : Net;
begin
N := Build_Const_UB32 (Ctxt, 0, Mem_Wd);
- Copy_Const_Content
- (Cst, Off, Cst_Wd, Get_Net_Parent (N), Wd, Depth,
- Copy_Mode_Bit);
+ -- Optimize: no need to copy if the value is 0.
+ if Get_Param_Uns32 (Cst, 0) /= 0 then
+ Copy_Const_Content
+ (Cst, Off, Cst_Wd, Get_Net_Parent (N), Wd, Depth,
+ Copy_Mode_Bit);
+ end if;
return N;
end;
+ when Id_Const_X =>
+ return Build_Const_X (Ctxt, Mem_Wd);
when others =>
raise Internal_Error;
end case;
diff --git a/src/synth/synth-context.adb b/src/synth/synth-context.adb
index adcafec27..0b6c73c72 100644
--- a/src/synth/synth-context.adb
+++ b/src/synth/synth-context.adb
@@ -436,12 +436,43 @@ package body Synth.Context is
pragma Unreferenced (Vec2net);
+ -- Set Is_0 to True iff VEC is 000...
+ -- Set Is_X to True iff VEC is XXX...
+ procedure Is_Full (Vec : Logvec_Array;
+ Is_0 : out Boolean;
+ Is_X : out Boolean)
+ is
+ Val : Uns32;
+ Zx : Uns32;
+ begin
+ Val := Vec (0).Val;
+ Zx := Vec (0).Zx;
+ Is_0 := False;
+ Is_X := False;
+ if Val = 0 and Zx = 0 then
+ Is_0 := True;
+ Is_X := False;
+ elsif Val = not 0 and Zx = not 0 then
+ Is_0 := False;
+ Is_X := True;
+ end if;
+
+ for I in 1 .. Vec'Last loop
+ if Vec (I).Val /= Val or else Vec (I).Zx /= Zx then
+ Is_0 := False;
+ Is_X := False;
+ return;
+ end if;
+ end loop;
+ end Is_Full;
+
procedure Value2net
(Val : Value_Acc; W : Width; Vec : in out Logvec_Array; Res : out Net)
is
Off : Uns32;
Has_Zx : Boolean;
Inst : Instance;
+ Is_0, Is_X : Boolean;
begin
Has_Zx := False;
Off := 0;
@@ -459,7 +490,12 @@ package body Synth.Context is
end if;
return;
else
- if not Has_Zx then
+ Is_Full (Vec, Is_0, Is_X);
+ if Is_0 then
+ Res := Build_Const_UB32 (Build_Context, 0, W);
+ elsif Is_X then
+ Res := Build_Const_X (Build_Context, W);
+ elsif not Has_Zx then
Inst := Build_Const_Bit (Build_Context, W);
for I in Vec'Range loop
Set_Param_Uns32 (Inst, Param_Idx (I), Vec (I).Val);
diff --git a/src/synth/synth-expr.ads b/src/synth/synth-expr.ads
index eee5f1d4d..4ceeafc4b 100644
--- a/src/synth/synth-expr.ads
+++ b/src/synth/synth-expr.ads
@@ -127,7 +127,7 @@ package Synth.Expr is
type Logic_32 is record
Val : Uns32; -- AKA aval
- Zx : Uns32; -- AKA bval
+ Zx : Uns32; -- AKA bval (z=10, x=11)
end record;
type Digit_Index is new Natural;