diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-03-20 08:53:55 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-03-20 09:08:09 +0100 |
commit | d77a17b1ca2c3eed06b66fb8205963ad49723c80 (patch) | |
tree | de5347f65bec7d144cddd28ea94a294df4e2b699 /src | |
parent | 6058f2f6e79683e6b80b4974220a753373a8b411 (diff) | |
download | ghdl-d77a17b1ca2c3eed06b66fb8205963ad49723c80.tar.gz ghdl-d77a17b1ca2c3eed06b66fb8205963ad49723c80.tar.bz2 ghdl-d77a17b1ca2c3eed06b66fb8205963ad49723c80.zip |
synth-vhdl_expr: minor refactoring - add comments
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/synth-vhdl_expr.adb | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/src/synth/synth-vhdl_expr.adb b/src/synth/synth-vhdl_expr.adb index 07d94ecae..834f1de47 100644 --- a/src/synth/synth-vhdl_expr.adb +++ b/src/synth/synth-vhdl_expr.adb @@ -211,10 +211,10 @@ package body Synth.Vhdl_Expr is end loop; end Uns2logvec; - -- Insert bit from VAL into VEC at offset OFF. Increment OFF. + -- Insert bit from VAL into VEC at offset OFF. procedure Bit2logvec (Val : Uns32; - Vec : in out Logvec_Array; - Off : in out Uns32) + Off : Uns32; + Vec : in out Logvec_Array) is pragma Assert (Val <= 1); Idx : constant Digit_Index := Digit_Index (Off / 32); @@ -224,13 +224,12 @@ package body Synth.Vhdl_Expr is Va := Shift_Left (Val, Pos); Vec (Idx).Val := Vec (Idx).Val or Va; Vec (Idx).Zx := 0; - Off := Off + 1; end Bit2logvec; -- Likewise for std_logic procedure Logic2logvec (Val : Int64; + Off : Uns32; Vec : in out Logvec_Array; - Off : in out Uns32; Has_Zx : in out Boolean) is pragma Assert (Val <= 8); @@ -245,9 +244,13 @@ package body Synth.Vhdl_Expr is Zx := Shift_Left (Zx, Pos); Vec (Idx).Val := Vec (Idx).Val or Va; Vec (Idx).Zx := Vec (Idx).Zx or Zx; - Off := Off + 1; end Logic2logvec; + -- Read W bits at offset OFF from MEM+TYP and write to VEC at VEC_OFF. + -- Set HAS_ZX if one bit read is Z or X. + -- OFF may be greather than the size of MEM. + -- Update OFF, W, VEC_OFF according to the number of bits + -- read (or skipped). procedure Value2logvec (Mem : Memory_Ptr; Typ : Type_Acc; Off : in out Uns32; @@ -262,20 +265,27 @@ package body Synth.Vhdl_Expr is return; end if; if W = 0 then + -- Nothing to read. return; end if; case Typ.Kind is when Type_Bit => -- Scalar bits cannot be cut. - pragma Assert (Off = 0 and W >= Typ.W); - Bit2logvec (Uns32 (Read_U8 (Mem)), Vec, Vec_Off); - W := W - Typ.W; + pragma Assert (Typ.W = 1); + pragma Assert (Off = 0 and W >= 1); + Bit2logvec (Uns32 (Read_U8 (Mem)), Vec_Off, Vec); + -- One bit read and written. + Vec_Off := Vec_Off + 1; + W := W - 1; when Type_Logic => -- Scalar bits cannot be cut. - pragma Assert (Off = 0 and W >= Typ.W); - Logic2logvec (Int64 (Read_U8 (Mem)), Vec, Vec_Off, Has_Zx); - W := W - Typ.W; + pragma Assert (Typ.W = 1); + pragma Assert (Off = 0 and W >= 1); + Logic2logvec (Int64 (Read_U8 (Mem)), Vec_Off, Vec, Has_Zx); + -- One bit read and written. + Vec_Off := Vec_Off + 1; + W := W - 1; when Type_Discrete => -- Scalar bits cannot be cut. pragma Assert (Off = 0 and W >= Typ.W); @@ -291,31 +301,39 @@ package body Synth.Vhdl_Expr is W := W - Typ.W; when Type_Vector => declare - Vlen : Uns32; + Vlen : constant Uns32 := Uns32 (Vec_Length (Typ)); Len : Uns32; begin - Vlen := Uns32 (Vec_Length (Typ)); pragma Assert (Off < Vlen); pragma Assert (Vlen > 0); if Vlen > Off + W then + -- The vector is longer than the number of bits to read. + -- Read less. Len := Off + W; else + -- Read the whole vector. Len := Vlen; end if; + + -- In memory MEM, bits are stored from left to right, so in + -- big endian (MSB is written at offset 0, LSB at + -- offset VLEN - 1). Need to reverse: LSB is read first. case Typ.Vec_El.Kind is when Type_Bit => -- TODO: optimize off mod 32 = 0. for I in Off .. Len - 1 loop Bit2logvec (Uns32 (Read_U8 (Mem + Size_Type (Vlen - 1 - I))), - Vec, Vec_Off); + Vec_Off, Vec); + Vec_Off := Vec_Off + 1; end loop; when Type_Logic => for I in Off .. Len - 1 loop Logic2logvec (Int64 (Read_U8 (Mem + Size_Type (Vlen - 1 - I))), - Vec, Vec_Off, Has_Zx); + Vec_Off, Vec, Has_Zx); + Vec_Off := Vec_Off + 1; end loop; when others => raise Internal_Error; |