clash-lang / clash-compiler

Haskell to VHDL/Verilog/SystemVerilog compiler
https://clash-lang.org/
Other
1.44k stars 154 forks source link

VHDL type / signal naming collisions #2293

Open lmbollen opened 2 years ago

lmbollen commented 2 years ago

I encountered a situation where Vivado could not process my HDL because a type "A" collided with a signal name "a". GHC version: 9.0.2 Clash version: 1.6.3

Consider the following reproducer consisting of two files.

module Example.HasA where
import Clash.Explicit.Prelude

data AorB = A | B deriving (NFDataX, Generic)

flipAB :: AorB -> AorB
flipAB A = B
flipAB B = A

{-# NOINLINE flipAB #-}

And

module Example.Project where

import Clash.Prelude
import Example.HasA

topEntity ::
  Clock System ->
  Reset System ->
  Enable System ->
  Signal System AorB ->
  Signal System Bool ->
  Signal System AorB
topEntity clk rst en a b = withClockResetEnable clk rst en $ mux b a (register A $ flipAB <$> a)

Compiling this to vhdl with:

cabal run -- clash Example.Project --vhdl

produces the following 5 files:

  1. clash-manifest.json
  2. Example_Project_topEntity_types.vhdl
  3. flipAB.vhdl
  4. topEntity.sdc
  5. topEntity.vhdl

That when processed, produces two of the same errors, namely:

[Synth 8-2778] type error near a ; expected type aorb ["/somePath/vhdl/Example.Project.topEntity/topEntity.vhdl":35]`

Caused by the port name a colliding with the type A.

The first error in a signal definition:

signal topEntity1_f1  : Example_Project_topEntity_types.AorB := AorB'(A);

The second in a signal assignment:

topEntity1_f1 <= AorB'(A);

Removing the NOINLINE makes the problem disappear, and removing the register also makes the problem disappear.

martijnbastiaan commented 2 years ago

A workaround would be to compile the code with -fclash-no-render-enums.