Skip to content

CLaSH compiler generates unused signed integers when converting from type Bit to Bool #329

Closed
@Nrmize

Description

@Nrmize

Hi all,

I noticed something peculiar in a piece of code that I made to combine and invert two reset signals into one. Here is the code block I made:

module ResetEither where

import Clash.Prelude
import Clash.Signal.Internal

{-# ANN topEntityResEither
  (Synthesize
    { t_name   = "ResetEither"
    , t_inputs = [ PortName "A_RST"
                 , PortName "B_RST"
                 ]
    , t_output = PortName "RST_OUT"
    }) #-}
topEntityResEither
  :: Reset System Synchronous--A_RST
  -> Reset System Synchronous--B_RST
  -> Reset System Synchronous--RST_OUT
topEntityResEither = resetEither

resetEither
  :: Reset System Synchronous--A_RST
  -> Reset System Synchronous--B_RST
  -> Reset System Synchronous--RST_OUT
resetEither rsta rstb = reset_out
  where
    rstaBool = fromSyncReset rsta
    rstbBool = fromSyncReset rstb
    andA = ((.==.) (pure False) rstaBool) 
    andB = ((.==.) (pure False) rstbBool)

    reset_out = unsafeToSyncReset ((.||.) andA andB)

This code will generate the following VHDL:

-- Automatically generated VHDL-93
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.MATH_REAL.ALL;
use std.textio.all;
use work.all;
use work.reseteither_types.all;

entity ResetEither is
  port(-- asynchronous reset: active high
       A_RST   : in std_logic;
       -- asynchronous reset: active high
       B_RST   : in std_logic;
       -- asynchronous reset: active high
       RST_OUT : out std_logic);
end;

architecture structural of ResetEither is
  signal ds1      : boolean;
  signal result   : boolean;
  signal ds1_0    : boolean;
  signal result_0 : boolean;
begin
  ds1 <= true when A_RST = '1' else false;

  result <= false when ds1 else
            true;

  ds1_0 <= true when B_RST = '1' else false;

  result_0 <= false when ds1_0 else
              true;

  RST_OUT <= '1' when (result or result_0) else '0';
end;

Now, if I were to change the following lines in my source Haskell code from:

    andA = ((.==.) (pure False) rstaBool) 
    andB = ((.==.) (pure False) rstbBool)

To:

    andA = ((.==.) (pure (bitToBool rst_val)) rstaBool) 
    andB = ((.==.) (pure (bitToBool rst_val)) rstbBool)

Where I use bitToBool to create my first Bool value and 'rst_val' is a Bit type that is equal to '0'. The functionality remains the same, however the following VHDL is generated instead:

-- Automatically generated VHDL-93
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.MATH_REAL.ALL;
use std.textio.all;
use work.all;
use work.reseteither_types.all;

entity ResetEither is
  port(-- asynchronous reset: active high
       A_RST   : in std_logic;
       -- asynchronous reset: active high
       B_RST   : in std_logic;
       -- asynchronous reset: active high
       RST_OUT : out std_logic);
end;

architecture structural of ResetEither is
  signal \#case_alt\            : boolean;
  signal ds1                    : boolean;
  signal result                 : boolean;
  signal \#case_alt_0\          : boolean;
  signal ds1_0                  : boolean;
  signal result_0               : boolean;
  signal result_selection_res   : std_logic_vector(0 downto 0);
  signal \#i\                   : signed(63 downto 0);
  signal result_0_selection_res : std_logic_vector(0 downto 0);
  signal \#i_0\                 : signed(63 downto 0);
begin
  \#case_alt\ <= false when ds1 else
                 true;

  ds1 <= true when A_RST = '1' else false;

  \#i\ <= to_signed(0,64);

  result_selection_res <= std_logic_vector'(0 => '0');

  with (result_selection_res) select
    result <= ds1 when "1",
              \#case_alt\ when others;

  \#case_alt_0\ <= false when ds1_0 else
                   true;

  ds1_0 <= true when B_RST = '1' else false;

  \#i_0\ <= to_signed(0,64);

  result_0_selection_res <= std_logic_vector'(0 => '0');

  with (result_0_selection_res) select
    result_0 <= ds1_0 when "1",
                \#case_alt_0\ when others;

  RST_OUT <= '1' when (result or result_0) else '0';
end;

As, you can see, there are several instances where the compiler generated signed 64 bit integers in the VHDL that are not being used (signals #i\ and #i_0). Has anyone else had similar issues with the 'boolToBit' or 'bittoBool' functions found in Clash.Class.BitPack ?

I would prefer to have each signal be of Bit type rather than Bool for my particular application. But this issue tends to bloat the VHDL signal declarations on my other larger designs that use 'bitToBool' more often.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions