Open gergoerdi opened 2 years ago
Note that scalIn
is never written back to SCL
.
The curried version looks OK:
topEntity
:: "CLK_50MHZ" ::: Clock System
-> "RESET" ::: Reset System
-> "SCL" ::: BiSignalIn 'PullUp System (BitSize Bit)
-> "SDA" ::: BiSignalIn 'PullUp System (BitSize Bit)
-> ( "SCL" ::: BiSignalOut 'PullUp System (BitSize Bit)
, "SDA" ::: BiSignalOut 'PullUp System (BitSize Bit)
)
topEntity clk reset = exposeClockResetEnable run clk reset enableGen
run
:: (HiddenClockResetEnable dom)
=> BiSignalIn 'PullUp dom (BitSize Bit)
-> BiSignalIn 'PullUp dom (BitSize Bit)
-> ( BiSignalOut 'PullUp dom (BitSize Bit)
, BiSignalOut 'PullUp dom (BitSize Bit)
)
run sclIn sdaIn = (sclOut, sdaOut)
where
sclOut = writeToBiSignal sclIn sclOut'
sdaOut = writeToBiSignal sdaIn sdaOut'
sclOut' = pure $ Just high
sdaOut' = pure $ Just low
makeTopEntityWithName 'topEntity "bisignal"
module bisignal
( // Inputs
input CLK_50MHZ // clock
, input RESET // reset
, inout [0:0] SCL
, inout [0:0] SDA
// No outputs
);
// writeToBiSignal# begin
assign SDA = (1'b1 == 1'b1) ? 1'b0 : {1 {1'bz}};
// writeToBiSignal# end
// writeToBiSignal# begin
assign SCL = (1'b1 == 1'b1) ? 1'b1 : {1 {1'bz}};
// writeToBiSignal# end
endmodule
I'm using Clash 1.6.1, and for boring reasons can't try out 1.6.3 right now; do let me know if there's been relevant changes in between.
No changes related to that. Thanks for the report!
Seems clash is supposed to report an error when arguments are of composite types containing BiSignalIn
s, like a tuple containing two BiSignalIn
s.
https://github.com/clash-lang/clash-compiler/blob/acf574ab8869f8c89223bd36782364d446cad105/clash-lib/src/Clash/Netlist/Util.hs#L970-L978
But somehow this error isn't being triggered.
That function is only called for non-topentities. If you add a NOINLINE pragma for run
the error should trigger.
We could try to make BiSignalIn non-representable and see if the testsuite still passes: https://github.com/clash-lang/clash-compiler/blob/acf574ab8869f8c89223bd36782364d446cad105/clash-lib/src/Clash/Netlist/Util.hs#L661
that’s the easiest way to force Clash to inline the things we want inlined.
A similar issue arises when packing the BiSignalIn into some structure.
In this example, I wanted to produce an IO where individual bits could be controlled, which is not possible with the standard BiSignalIn 'Floating dom n
.
No InOut ports are generated and no error is triggered.
topEntityComparisonIoBuffer ::
Clock XilinxSystem ->
Reset XilinxSystem ->
Enable XilinxSystem ->
Signal XilinxSystem (BitVector 8) -> -- Input from FSM
Signal XilinxSystem (BitVector 8) -> -- Input Direction
Vec 8 (BiSignalIn 'Floating XilinxSystem 1) -> -- Input from Outside
(Signal XilinxSystem (BitVector 8), Vec 8 (BiSignalOut 'Floating XilinxSystem 1)) -- (Output to FSM, Output to Outside)
topEntityComparisonIoBuffer clk rst en = withClockResetEnable clk rst en ioBuffer
ioBuffer ::
forall dom regSize.
(HiddenClockResetEnable dom, KnownNat regSize) =>
Signal dom (BitVector regSize) -> -- Input from FSM
Signal dom (BitVector regSize) -> -- Input Direction
Vec regSize (BiSignalIn 'Floating dom 1) -> -- Input from Outside
(Signal dom (BitVector regSize), Vec regSize (BiSignalOut 'Floating dom 1)) -- (Output to FSM, Output to Outside)
ioBuffer inp inpD inpO = (outFsm, outO)
where
-- Change Signal BitVector to Vec (Signal Bit)
vecEnableBits = unbundle $ bv2v <$> inpD
-- Read Bit i only if inpD[i] is high
readIfBit :: Signal dom Bit -> BiSignalIn 'Floating dom 1 -> Signal dom Bit
readIfBit rd i = mux (bitToBool <$> rd) (readFromBiSignal i) undefined-- shoud generate "-" in vhdl when Bit should not be read
readEnabledBits = zipWith readIfBit vecEnableBits inpO
-- Bundle the read bits from Vec (Signal Bit) to Signal BitVector
outFsm = v2bv <$> bundle readEnabledBits
-- Write Bit i only if inpD[i] is low
-- writeToBiSignal will only write on a Just value
-- Enable, valuetoWrite, bisignal -> bisignalout
writeIfBit :: Signal dom Bit -> Signal dom Bit -> BiSignalIn 'Floating dom 1 -> BiSignalOut 'Floating dom 1
writeIfBit wr dat i = writeToBiSignal i (bitsToMaybe <$> wr <*> dat)
bitsToMaybe :: Bit -> Bit -> Maybe Bit
bitsToMaybe b1 b2 = if bitToBool b1 then Just b2 else Nothing
vecInputBits = unbundle $ bv2v <$> inp
outO = zipWith3 writeIfBit vecEnableBits vecInputBits inpO