Skip to content

Commit bfa702d

Browse files
committed
WIP: Fix I2C core and its test
1 parent a7f4573 commit bfa702d

File tree

4 files changed

+85
-83
lines changed

4 files changed

+85
-83
lines changed

clash-cores/src/Clash/Cores/I2C/ByteMaster.hs

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ data ByteStateMachine = Idle | Active | Start | Read | Write | Ack | Stop
1717
deriving (Show, Generic, NFDataX, Eq)
1818

1919
data I2COperation = ReadData | WriteData (BitVector 8)
20-
deriving (Generic, NFDataX)
20+
deriving (Generic, NFDataX, BitPack)
21+
2122
getWriteData :: I2COperation -> BitVector 8
2223
getWriteData ReadData = 0
2324
getWriteData (WriteData d) = d
25+
2426
data ByteMasterS
2527
= ByteS
2628
{ _srState :: ShiftRegister

clash-cores/test/Test/Cores/I2C.hs

+6-7
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@ system0 clk arst = bundle (registerFile,done,fault)
2020
(_dout,hostAck,_busy,al,ackOut,i2cO) =
2121
i2c clk arst rst (pure True) (pure 19) claim i2cOp (pure True) i2cI
2222

23-
i2cOp = mux claim (Just <$> mux write (WriteData <$> din) (pure ReadData)) (pure Nothing)
24-
25-
(claim,write,din,done,fault) = unbundle $
26-
config clk (bundle (rst, fmap not rst,hostAck,ackOut,al))
23+
(claim,i2cOp,done,fault) =
24+
unbundle $ config clk (bundle (rst,fmap not rst,hostAck,ackOut,al))
2725

2826
(sclOut,sdaOut) = unbundle i2cO
2927
scl = fmap (bitCoerce . isNothing) sclOut
@@ -46,7 +44,8 @@ systemResult :: (Vec 16 (Unsigned 8), Bool, Bool)
4644
systemResult = L.last (sampleN 200050 system)
4745

4846
i2cTest :: TestTree
49-
i2cTest = testCase "i2c core testcase passed."
50-
$ assertBool "i2c core test procedure failed" (not f)
47+
i2cTest = testCase "i2c core testcase passed"
48+
$ assertBool "i2c core test procedure failed" (not fault)
5149
where
52-
(_, _, f) = L.last $ takeWhile (\ (_, done, _) -> not done) $ sample system
50+
fault =
51+
L.or $ fmap (\(_,_,f) -> f) $ takeWhile (\ (_, done, _) -> not done) $ sample system

clash-cores/test/Test/Cores/I2C/Config.hs

+57-63
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,31 @@ module Test.Cores.I2C.Config where
44

55
import Clash.Prelude
66
import Clash.Explicit.SimIO
7-
7+
import Clash.Cores.I2C.ByteMaster(I2COperation(..))
8+
import Numeric (showHex)
89
data ConfStateMachine = CONFena |
910
CONFaddr | CONFaddrAck |
1011
CONFreg | CONFregAck |
1112
CONFdata | CONFdataAck |
1213
CONFstop
1314
deriving Show
1415

15-
data ConfS = ConfS { i2cConfStateM :: ConfStateMachine
16-
, i2cClaim :: Bool
17-
, i2cWrite :: Bool
18-
, i2cDin :: Vec 8 Bit
19-
, i2cLutIndex :: Index 16
20-
, i2cFault :: Bool
16+
data ConfS = ConfS { i2cConfStateM :: ConfStateMachine
17+
, i2cConfClaim :: Bool
18+
, i2cConfOp :: Maybe (I2COperation)
19+
, i2cConfLutIndex :: Index 16
20+
, i2cConfFault :: Bool
2121
}
2222

2323
type ConfI = (Bool,Bool,Bool,Bool,Bool)
24-
type ConfO = (Bool,Bool,BitVector 8,Bool,Bool)
24+
type ConfO = (Bool,Maybe (I2COperation),Bool,Bool)
2525

2626
confInit :: ConfS
2727
confInit = ConfS { i2cConfStateM = CONFena
28-
, i2cClaim = False
29-
, i2cWrite = False
30-
, i2cDin = repeat low
31-
, i2cLutIndex = 0
32-
, i2cFault = False
28+
, i2cConfClaim = False
29+
, i2cConfOp = Nothing
30+
, i2cConfLutIndex = 0
31+
, i2cConfFault = False
3332
}
3433

3534
configT
@@ -38,7 +37,7 @@ configT
3837
-> SimIO ConfO
3938
configT s0 (rst,ena,cmdAck,rxAck,al) = do
4039
s <- readReg s0
41-
let ConfS confStateM claim write din lutIndex fault = s
40+
let ConfS confStateM claim i2cOp lutIndex fault = s
4241

4342
let i2cSlvAddr = 0x34 :: BitVector 8
4443

@@ -48,91 +47,86 @@ configT s0 (rst,ena,cmdAck,rxAck,al) = do
4847

4948
let lutData = configLut lutIndex
5049

51-
sNext <- if rst then pure confInit else case confStateM of
50+
sNext <-
51+
if rst then pure confInit else case confStateM of
5252
CONFena
5353
| ena && not done
54-
-> pure s { i2cConfStateM = CONFaddr }
54+
-> pure s { i2cConfStateM = CONFaddr
55+
, i2cConfClaim = True
56+
}
5557
| done
5658
-> do display "done"
5759
pure s
5860

5961
CONFaddr
60-
-> pure s { i2cConfStateM = CONFaddrAck
61-
, i2cClaim = True
62-
, i2cWrite = True
63-
, i2cDin = unpack i2cSlvAddr
64-
}
62+
-> do
63+
display $ "CONFaddr, writing: " <> showHex i2cSlvAddr ""
64+
pure s { i2cConfStateM = CONFaddrAck
65+
, i2cConfOp = Just (WriteData (unpack i2cSlvAddr))
66+
}
6567

6668
CONFaddrAck
6769
| success
68-
-> do display "CONFaddrAck"
69-
pure s { i2cConfStateM = CONFreg
70-
, i2cWrite = False
70+
-> if rxAck then do
71+
display "CONFaddrAck"
72+
pure s { i2cConfStateM = CONFreg
73+
, i2cConfOp = Nothing
74+
}
75+
else do
76+
display "Failure CONFaddr"
77+
pure s { i2cConfStateM = CONFena
78+
, i2cConfFault = True
7179
}
7280

7381
CONFreg
74-
-> if not rxAck then do
82+
-> do
83+
display $ "CONFreg, writing: " <> showHex (fst lutData) "" <> ", lutIndex: " <> show lutIndex
84+
pure s { i2cConfStateM = CONFregAck
85+
, i2cConfOp = Just (WriteData (unpack (fst lutData)))
86+
}
87+
CONFregAck
88+
| success
89+
-> if rxAck then do
7590
display "Success CONFreg"
76-
pure s { i2cConfStateM = CONFregAck
77-
, i2cWrite = True
78-
, i2cDin = unpack (fst lutData)
79-
, i2cFault = False
91+
pure s { i2cConfStateM = CONFdata
92+
, i2cConfOp = Nothing
8093
}
8194
else do
8295
display "Failure CONFreg"
83-
_ <- finish 1
8496
pure s { i2cConfStateM = CONFena
85-
, i2cFault = True
97+
, i2cConfFault = True
8698
}
8799

88-
CONFregAck
89-
| success
90-
-> do display "CONFregAck"
91-
pure s { i2cConfStateM = CONFdata
92-
, i2cWrite = False
93-
}
94-
95100
CONFdata
96-
-> if not rxAck then do
101+
-> do display $ "CONFdata, writing: " <> showHex (snd lutData) ""
102+
pure s { i2cConfStateM = CONFdataAck
103+
, i2cConfOp = Just (WriteData (unpack (snd lutData)))
104+
}
105+
CONFdataAck
106+
| success
107+
-> if rxAck then do
97108
display "Success CONFdata"
98-
pure s { i2cConfStateM = CONFdataAck
99-
, i2cWrite = True
100-
, i2cClaim = False
101-
, i2cDin = unpack (snd lutData)
102-
, i2cFault = False
109+
pure s { i2cConfStateM = CONFstop
110+
, i2cConfOp = Nothing
103111
}
104112
else do
105113
display "Failure CONFdata"
106-
_ <- finish 1
107114
pure s { i2cConfStateM = CONFena
108-
, i2cFault = True
115+
, i2cConfFault = True
109116
}
110117

111-
CONFdataAck
112-
| success
113-
-> do display "CONFdataAck"
114-
pure s { i2cConfStateM = CONFstop
115-
, i2cWrite = False
116-
}
117-
118118
CONFstop
119-
-> if not rxAck then do
119+
-> do
120120
display "Success CONFstop"
121121
pure s { i2cConfStateM = CONFena
122-
, i2cLutIndex = lutIndex + 1
123-
, i2cFault = False
124-
}
125-
else do
126-
display "Failure CONFstop"
127-
_ <- finish 1
128-
pure s { i2cConfStateM = CONFena
129-
, i2cFault = True
122+
, i2cConfClaim = False
123+
, i2cConfLutIndex = lutIndex + 1
130124
}
131125

132126
_ -> pure s
133127

134128
writeReg s0 sNext
135-
pure (claim,write,pack din,done,fault)
129+
pure (claim,i2cOp,done,fault)
136130

137131
configLut :: Index 16 -> (BitVector 8, BitVector 8)
138132
configLut i

clash-cores/test/Test/Cores/I2C/Slave.hs

+19-12
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,23 @@ i2cSlaveT s0 (scl,sda) = do
4646
display "valid addr"
4747
pure s { i2cSlaveAtStateM = ATaddrAck
4848
, i2cSlaveAddr = repeat low
49-
, i2cSlaveCntr = 0 }
49+
, i2cSlaveCntr = 0
50+
}
5051
else do
51-
display "invalid addr"
52+
display $ "invalid addr: " <> show addr
5253
pure s { i2cSlaveAtStateM = ATidle
5354
, i2cSlaveAddr = repeat low
54-
, i2cSlaveCntr = 0}
55+
, i2cSlaveCntr = 0
56+
}
5557
| sclRising -> pure s { i2cSlaveCntr = cntr + 1
5658
, i2cSlaveAddr = addr <<+ sda
57-
, i2cSlaveSdaOut = high }
59+
, i2cSlaveSdaOut = high
60+
}
5861
ATaddrAck
5962
| sclRising -> do display "addrAck"
60-
pure s { i2cSlaveAtStateM = ATreg, i2cSlaveSdaOut = low }
63+
pure s { i2cSlaveAtStateM = ATreg
64+
, i2cSlaveSdaOut = low
65+
}
6166
ATreg
6267
| cntr == 8 -> if validRegAddr then do
6368
display "valid reg addr"
@@ -67,18 +72,19 @@ i2cSlaveT s0 (scl,sda) = do
6772
, i2cSlaveRegAddr = shiftR (bitCoerce addr) 1
6873
}
6974
else do
70-
display "invalid reg addr"
75+
display $ "invalid reg addr: " <> show addr
7176
pure s { i2cSlaveAtStateM = ATidle
7277
, i2cSlaveAddr = repeat low
7378
, i2cSlaveCntr = 0
7479
}
7580
| sclRising -> pure s { i2cSlaveCntr = cntr + 1
7681
, i2cSlaveAddr = addr <<+ sda
77-
, i2cSlaveSdaOut = high }
82+
, i2cSlaveSdaOut = high
83+
}
7884
ATregAck
7985
| sclRising -> do display "regAck"
80-
pure s { i2cSlaveSdaOut = low
81-
, i2cSlaveAtStateM = ATval
86+
pure s { i2cSlaveAtStateM = ATval
87+
, i2cSlaveSdaOut = low
8288
}
8389
ATval
8490
| cntr == 8 -> do display "val"
@@ -90,11 +96,12 @@ i2cSlaveT s0 (scl,sda) = do
9096
}
9197
| sclRising -> pure s { i2cSlaveCntr = cntr + 1
9298
, i2cSlaveAddr = addr <<+ sda
93-
, i2cSlaveSdaOut = high }
99+
, i2cSlaveSdaOut = high
100+
}
94101
ATvalAck
95102
| sclRising -> do display "valAck"
96-
pure s { i2cSlaveSdaOut = low
97-
, i2cSlaveAtStateM = ATstop
103+
pure s { i2cSlaveAtStateM = ATstop
104+
, i2cSlaveSdaOut = low
98105
}
99106
ATstop
100107
| stopCondition -> do display "stop"

0 commit comments

Comments
 (0)