clash-lang / clash-compiler

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

Warn about out-of-range constants #2582

Open kleinreact opened 1 year ago

kleinreact commented 1 year ago

The following example compiles without errors / warnings and does not wrap the used out-of-range constant:

module Test where

import Clash.Prelude

topEntity :: Signal System (Unsigned 2)
topEntity = 4
/* AUTOMATICALLY GENERATED VERILOG-2001 SOURCE CODE.
** GENERATED BY CLASH 1.7.0. DO NOT MODIFY.
*/
`default_nettype none
`timescale 100fs/100fs
module topEntity
    ( // No inputs

      // Outputs
      output wire [1:0] result
    );

  assign result = 2'd4;

endmodule

The produced verilog, however, produces a warning on most simulators / synthesizers. Hence, it may be a good idea to produce a warning in Clash as well.


Questa

Questa Intel Starter FPGA Edition-64 vlog 2021.2 Compiler 2021.04 Apr 14 2021
Start time: 14:06:32 on Oct 02,2023
vlog verilog/Test.topEntity/topEntity.v
-- Compiling module topEntity

Top level modules:
    topEntity
End time: 14:06:32 on Oct 02,2023, Elapsed time: 0:00:00
Errors: 0, Warnings: 0

iVerilog (v12.0)

verilog/Test.topEntity/topEntity.v:14: warning: Numeric constant truncated to 2 bits.

Yosys (v0.31)

Warning: Literal has a width of 2 bit, but value requires 3 bit. (verilog/Test.topEntity/topEntity.v:14)

Verilator (v5.002 2022-10-29)

%Warning-WIDTH: verilog/Test.topEntity/topEntity.v:14:19: Value too large for 2 bit number: 4
   14 |   assign result = 2'd4;
      |                   ^~~~
                ... For warning description see https://verilator.org/warn/WIDTH?v=5.002
                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.
leonschoorl commented 1 year ago

GHC is able to do this for builtin types:

GHCi, version 9.6.2: https://www.haskell.org/ghc/  :? for help
ghci> import Data.Word
ghci> x = 256 :: Word8

<interactive>:2:5: warning: [GHC-97441] [-Woverflowed-literals]
    Literal 256 is out of the Word8 range 0..255

And only in a monomorphic setting:

ghci> y = 256
ghci> z = y :: Word8
ghci> -- no warning
ghci> y
256
ghci> z
0
ghci>
ghci> :t y
y :: Num a => a
ghci> :t z
z :: Word8