From 49858bd37724c2e1f8aba208fbc7b92a54cbe46a Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Sun, 29 Mar 2020 09:57:01 +0200 Subject: synth: improve output of memory initial value. --- src/synth/netlists-disp_vhdl.adb | 40 ++++++++++++++++++++++++++++++++++++---- src/synth/netlists-memories.adb | 11 ++++++++--- src/synth/synth-context.adb | 38 +++++++++++++++++++++++++++++++++++++- src/synth/synth-expr.ads | 2 +- 4 files changed, 82 insertions(+), 9 deletions(-) (limited to 'src/synth') 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; -- cgit v1.2.3