Bug in clash compiler causing illegal names (Version 1.2.5)

71 views
Skip to first unread message

L Bollen

unread,
Jun 7, 2021, 9:35:42 AM6/7/21
to Clash - Hardware Description Language
Dear Devs,

I encountered a bug in the clash compiler that generates signals with illegal characters(namely * from the <*> function, see attached figure).
bugReport.png

Code to reproduce this problem below:


module BugReport where
import Clash.Prelude
import qualified Clash.Signal.Delayed.Bundle as D
type Clk = Clock System
type Rst = Reset System
type Sig = Signal System

infixl 4 <<*>>
(<<*>>) :: (Applicative f, Applicative g) => f (g (a -> b)) -> f (g a) -> f (g b)
(<<*>>) = liftA2 (<*>)

infixl 4 <<$>>
(<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
(<<$>>) = fmap . fmap


topEntity :: Clk -> Rst -> DSignal System 0 (Maybe (Signed 8),Maybe (Signed 8)) -> DSignal System 5 (Maybe Bool)
topEntity clk rst input =  exposeClockResetEnable (checkConditions2 a b) clk rst enableGen
    where
        (a,b) = D.unbundle  input

checkConditions2 :: HiddenClockResetEnable dom => DSignal dom 0 (Maybe (Signed 8)) -> DSignal dom 0 (Maybe (Signed 8)) -> DSignal dom 5 (Maybe Bool)
checkConditions2 i ad = (&&) <<$>> (delayedI (Just False) inBounds) <<*>> adInrange
    where
        inBounds    = (\i -> i>=0 && i < 100) <<$>> i
        adInrange   = (delayN d5 Nothing $ (>) <<$>> (pure $ Just $ 12) <<*>> ad)
{-# NOINLINE checkConditions2 #-}

al...@qbaylogic.com

unread,
Jun 7, 2021, 11:57:07 AM6/7/21
to Clash - Hardware Description Language
I can't reproduce this locally (with my development version of Clash, or Clash 1.4.2 installed with snap). I think this issue may have been fixed in the 1.4 release, can you upgrade and see if that helps?

  - Alex

Christiaan Baaij

unread,
Jun 7, 2021, 12:22:35 PM6/7/21
to clash-l...@googlegroups.com
Could you upload the generated Verilog somewhere?

Christiaan

On 7 Jun 2021, at 15:35, L Bollen <luuc...@gmail.com> wrote:

Dear Devs,

I encountered a bug in the clash compiler that generates signals with illegal characters(namely * from the <*> function, see attached figure).
<bugReport.png>


Code to reproduce this problem below:


module BugReport where
import Clash.Prelude
import qualified Clash.Signal.Delayed.Bundle as D
type Clk = Clock System
type Rst = Reset System
type Sig = Signal System

infixl 4 <<*>>
(<<*>>) :: (Applicative f, Applicative g) => f (g (a -> b)) -> f (g a) -> f (g b)
(<<*>>) = liftA2 (<*>)

infixl 4 <<$>>
(<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
(<<$>>) = fmap . fmap


topEntity :: Clk -> Rst -> DSignal System 0 (Maybe (Signed 8),Maybe (Signed 8)) -> DSignal System 5 (Maybe Bool)
topEntity clk rst input =  exposeClockResetEnable (checkConditions2 a b) clk rst enableGen
    where
        (a,b) = D.unbundle  input

checkConditions2 :: HiddenClockResetEnable dom => DSignal dom 0 (Maybe (Signed 8)) -> DSignal dom 0 (Maybe (Signed 8)) -> DSignal dom 5 (Maybe Bool)
checkConditions2 i ad = (&&) <<$>> (delayedI (Just False) inBounds) <<*>> adInrange
    where
        inBounds    = (\i -> i>=0 && i < 100) <<$>> i
        adInrange   = (delayN d5 Nothing $ (>) <<$>> (pure $ Just $ 12) <<*>> ad)
{-# NOINLINE checkConditions2 #-}

--
You received this message because you are subscribed to the Google Groups "Clash - Hardware Description Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clash-languag...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clash-language/64de6213-3b8d-4dc1-ba12-2414de9e08f8n%40googlegroups.com.
<bugReport.png>

L Bollen

unread,
Jun 7, 2021, 2:24:05 PM6/7/21
to Clash - Hardware Description Language
The generated code is VHDL, available here: https://drive.google.com/drive/folders/1c4hvvzXRbWSYTkdNe6PIRFFTVTJWKvKM?usp=sharing
I already updated to 1.4.2, so I won't be able to generate verilog with 1.2.5 anymore. It seems that this issue was already resolved after 1.2.5, because the characters are not present in the vhdl code generated with 1.4.2.

Thanks for the quick response!
Op maandag 7 juni 2021 om 18:22:35 UTC+2 schreef christia...@gmail.com:

L Bollen

unread,
Jun 7, 2021, 3:22:31 PM6/7/21
to Clash - Hardware Description Language
After upgrading to 1.4.2, the clash compiler has trouble transforming constant floating point values to binary with vhdl generation.
transform_bug.png
Op maandag 7 juni 2021 om 20:24:05 UTC+2 schreef L Bollen:

al...@qbaylogic.com

unread,
Jun 7, 2021, 4:27:36 PM6/7/21
to Clash - Hardware Description Language
> It seems that this issue was already resolved after 1.2.5, because the characters are not present in the vhdl code generated with 1.4.2.

Good to hear!

> After upgrading to 1.4.2, the clash compiler has trouble transforming constant floating point values to binary with vhdl generation.

That particular error occurs during the compile-time evaluation of case expressions which happens in normalisation. The problem (from Clash's point of view) is that it can only match Integer and Natural literals, and this is a Float literal (in Haskell, Float is a boxed type which contains a Float#, the underlying value type). Floating point support is somewhat sparse currently, but being improved in Clash at the moment (if you're interested there's a branch here, but it won't help with this issue). I'm also curious what your intent is, pattern matching on a floating point type will typically be more brittle than is desired, and depending on your use case you may be more interested in using Clash's fixed point data type.

If you can provide some information about what you're looking to do, then maybe me / one of my colleagues / a friendly mailing list user can help you out (even if you're just playing around with Clash)

  - Alex

L Bollen

unread,
Jun 7, 2021, 4:49:46 PM6/7/21
to Clash - Hardware Description Language

I'm currently using Clash to implement a hardware accelerator for my master thesis. I'm pretty sure I don't use case expressions or pattern matching on floating point values so I don't quite know the cause of this. I tested the implementation with fixed point values and got undesirable results, so I am using single precision floating point. I implemented my own floating point support using IP Cores and black boxes. My implementation contains some constant floating point values(mainly for multiplication and comparison), which can unfortunately not be synthesized anymore after the update, so I have to find some way to resolve this.

- Lucas
Op maandag 7 juni 2021 om 22:27:36 UTC+2 schreef al...@qbaylogic.com:

Christiaan Baaij

unread,
Jun 7, 2021, 5:07:38 PM6/7/21
to clash-l...@googlegroups.com
Hi Lucas,

Looking at the output it seems that somehow Clash is trying to synthesize `(* 14.302396) :: Float -> Float`, so you're probably right that Clash is not picking up your black boxes for floating point multiplication (any longer?).
Would it be possible to share your code? It's a whole lot easier to help you then.

- Christiaan

al...@qbaylogic.com

unread,
Jun 8, 2021, 3:44:51 AM6/8/21
to Clash - Hardware Description Language
Hi Lucas,

Having had a brief look at the code on Google drive: Clash recently switched from .json as the format for files with primitives / black boxes to .primitives. I believe you need to rename the file to have a .primitives extension for Clash to load it during compilation, which would explain why your black boxes now don't seem to load.

  - Alex

Alex McKenna

unread,
Jun 8, 2021, 12:24:43 PM6/8/21
to Clash - Hardware Description Language
> Clash recently switched from .json as the format for files with primitives / black boxes to .primitives.

It occurs to me maybe I should be clearer on this point for readers. The contents / format of the file are the same, but the extension is different. This was motivated by the fact that the format is not spec-compliant JSON (as JSON does not allow line breaks in strings, which is how the templates are typically written for clarity). It also means that Clash won't try and load JSON files which are in a project directory but are not primitives / black boxes. So migrating is simply a case of changing the file extension.

  - Alex

Martijn Bastiaan

unread,
Jun 9, 2021, 8:34:25 AM6/9/21
to clash-l...@googlegroups.com
It occurs to me maybe I should be clearer on this point for readers. The contents / format of the file are the same, but the extension is different. This was motivated by the fact that the format is not spec-compliant JSON (as JSON does not allow line breaks in strings, which is how the templates are typically written for clarity). It also means that Clash won't try and load JSON files which are in a project directory but are not primitives / black boxes. So migrating is simply a case of changing the file extension.

Yep! All the other changes can be found in the changelog:


Concerning the main issue of this thread: Clash 1.4 overhauled the way it generates identifiers in its HDL backends. This made it a bit easier to test against the various spec; sounds like it paid off! :-)

Kind regards,
Martijn

Op di 8 jun. 2021 om 18:24 schreef Alex McKenna <al...@qbaylogic.com>:

lucas....@hotmail.com

unread,
Jun 10, 2021, 7:50:21 AM6/10/21
to clash-l...@googlegroups.com
Hi Alex,

Thank you for your timely response, it seems like that was indeed the problem!

Kind regards,
Lucas

You received this message because you are subscribed to a topic in the Google Groups "Clash - Hardware Description Language" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clash-language/mBSy3HKyoRA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clash-languag...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clash-language/deb4019d-8578-4884-9b7c-8e6fcf6005e7n%40googlegroups.com.

lucas....@hotmail.com

unread,
Jun 10, 2021, 7:50:34 AM6/10/21
to clash-l...@googlegroups.com
I made a new folder named "BlackBox" in the previously shared folder ( https://drive.google.com/drive/folders/1c4hvvzXRbWSYTkdNe6PIRFFTVTJWKvKM?usp=sharing ).
It contains a .hs file with the definitions for the floating point operations (each operation consists of three functions) and a .json file with the black box information for VHDL generation.
I also included a new bugReport.hs that shows that instantiating the black box no longer works as I expected where I can use {-# NOINLINE mult_block #-} to instantiate the black box and prevent Clash from processing the contents of mult_block.

-Lucas

lucas....@hotmail.com

unread,
Jun 10, 2021, 7:50:50 AM6/10/21
to clash-l...@googlegroups.com
Unfortunately I found that also in 1.4.2, illegal names are still being generated. Also it seems like I found a case in which generated VHDL can not be processed by Quartus 18.0 (Targeting Cyclone V devices) unless I insert an extra delay.
I updated the google drive with a new folder containing the code and generated VHDL. I'm not sure if the quartus problem has to do with the generated VHDL or some problem with quartus itself, but I thought I'd mention it....
For now I simply fix the illegal character problem by manually replacing all <*> with <_>, which does work. 

All I know about the quartus problem is this:
image.png

- Lucas

Alex McKenna

unread,
Jun 10, 2021, 7:59:51 AM6/10/21
to Clash - Hardware Description Language
Hi Lucas,

Some things that might help: Clash has a -fclash-no-escaped-identifiers flag which means it will only generate basic ids instead of extended ids as well. For other problems specific to Quartus, there is also -fclash-hdlsyn Quartus, which works around some known quirks in Quartus. You should be able to fix your problem with the first, but it never hurts to know the second.

  - Alex

Reply all
Reply to author
Forward
0 new messages