Hi, for the code below:
module Spec where
import Clash.Prelude
import Clash.Annotations.TopEntity
data ValidInt = ValidInt {
value :: Int,
valid :: Bool
} deriving (Generic, NFDataX)
data Inputs = Inputs {
input0 :: ValidInt
} deriving (Generic, NFDataX)
machine :: HiddenClockResetEnable dom => Signal dom Inputs -> Signal dom Int
machine inputs = pure 42
topEntity :: Clock System -> Reset System -> Enable System ->
Signal System Inputs -> Signal System Int
topEntity clk rst en inputs = exposeClockResetEnable (machine inputs) clk rst en
Clash flattens the inputs in the generated verilog like this:
/* AUTOMATICALLY GENERATED VERILOG-2001 SOURCE CODE.
** GENERATED BY CLASH 1.8.2. DO NOT MODIFY.
*/
`default_nettype none
`timescale 100fs/100fs
module topEntity
( // Inputs
input wire clk // clock
, input wire rst // reset
, input wire en // enable
, input wire [64:0] inputs
// Outputs
, output wire signed [63:0] result
);
assign result = 64'sd42;
endmodule
I want two different wires instead. Something like:
input wire [63:0] input0_0; -- value
input wire input0_1; -- valid
Is there a way to do this?
As a potential solution, I tried annotating TopEntity like:
{-# ANN topEntity
(Synthesize
{
t_name = "myModule",
t_inputs = [
PortName "clk",
PortName "rst",
PortName "en",
PortProduct "inputs" [
PortProduct "input0" [
PortName "value",
PortName "valid"
]
]
],
...
}) #-}
However, it gives me the error:
*** Exception: Saw a PortProduct in a Synthesize annotation:
PortProduct "inputs" [PortProduct "input0" [PortName "value",PortName "valid"]]
but the port type:
Product "Spec.ValidInt" (Just ["value","valid"]) [Signed 64,Bool]
is not a product!
CallStack (from HasCallStack):
error, called at src/Clash/Netlist/Util.hs:1946:8 in clash-lib-1.8.2-8ZihzcIDdiCEsBBuhDMByd:Clash.Netlist.Util
expandTopEntityOrErrM, called at src/Clash/Netlist/Util.hs:790:8 in clash-lib-1.8.2-8ZihzcIDdiCEsBBuhDMByd:Clash.Netlist.Util
mkUniqueNormalized, called at src/Clash/Netlist.hs:267:9 in clash-lib-1.8.2-8ZihzcIDdiCEsBBuhDMByd:Clash.Netlist
genComponentT, called at src/Clash/Netlist.hs:241:41 in clash-lib-1.8.2-8ZihzcIDdiCEsBBuhDMByd:Clash.Netlist
genComponent, called at src/Clash/Netlist.hs:119:9 in clash-lib-1.8.2-8ZihzcIDdiCEsBBuhDMByd:Clash.Netlist
I also tried annotating the ValidInt
with InlinePrimitive
but I couldn’t make that work and it felt a bit clunky.
I know if I change Inputs
into a tuple, Clash doesn’t flatten like this, but I prefer using Record due to the 12-item limit of tuple size in Clash. Also, when I have multiple input fields in Inputs
Clash doesn’t flatten like this.
Is there a clean way to deal with this?