Description
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.