1212from math import ceil
1313
1414import cocotb
15- from cocotb .triggers import ClockCycles
15+ from cocotb .triggers import ClockCycles , Timer
1616from cocotb .regression import TestFactory
1717
1818TGT_ADR = 0x5A
@@ -95,6 +95,51 @@ async def test_TE0_HDR_exit(dut):
9595 == 0xa2
9696 ) # WaitHDRExitOrIdle
9797 await i3c_controller .send_hdr_exit ()
98+ i3c_controller .give_bus_control ()
99+ assert (
100+ int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
101+ == 0
102+ ) # Idle
103+
104+
105+ @cocotb .test ()
106+ async def test_TE0_idle_exit (dut ):
107+
108+ (STATIC_ADDR , VIRT_STATIC_ADDR , DYNAMIC_ADDR , VIRT_DYNAMIC_ADDR ) = random .sample (VALID_I3C_ADDRESSES , 4 )
109+ ADDRs = [random .choice ([STATIC_ADDR , DYNAMIC_ADDR ]), random .choice ([VIRT_STATIC_ADDR , VIRT_DYNAMIC_ADDR ])]
110+
111+ i3c_controller , i3c_target , tb = await test_setup (dut , STATIC_ADDR , VIRT_STATIC_ADDR ,
112+ dynamic_addr = DYNAMIC_ADDR , virtual_dynamic_addr = VIRT_DYNAMIC_ADDR )
113+ await ClockCycles (tb .clk , 50 )
114+
115+ idle_time_in_cycles = ceil (60000 / (1000 / FCLK ))
116+ await tb .write_csr_field (
117+ tb .reg_map .I3C_EC .SOCMGMTIF .T_IDLE_REG .base_addr ,
118+ tb .reg_map .I3C_EC .SOCMGMTIF .T_IDLE_REG .T_IDLE ,
119+ idle_time_in_cycles
120+ )
121+
122+ incorrect_addrs = [
123+ (0x3E , True ), (0x5E , True ), (0x6E , True ), (0x76 , True ), (0x7A , True ),
124+ (0x7C , True ), (0x7F , True ), (0x7E , False )
125+ ]
126+
127+ for _ in range (2 ):
128+ addr , write = random .choice (incorrect_addrs )
129+ assert (
130+ int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
131+ == 0
132+ ) # Idle
133+ await i3c_controller .take_bus_control ()
134+ await i3c_controller .send_start ()
135+ ack = await i3c_controller .write_addr_header (addr , read = not write )
136+ await i3c_controller .send_stop ()
137+ i3c_controller .give_bus_control ()
138+ assert (
139+ int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
140+ == 0xa2
141+ ) # WaitHDRExitOrIdle
142+ await Timer (60 , "us" )
98143 assert (
99144 int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
100145 == 0
@@ -133,6 +178,46 @@ async def test_TE1_HDR_exit(dut):
133178 == 0xa2
134179 ) # WaitHDRExitOrIdle
135180 await i3c_controller .send_hdr_exit ()
181+ i3c_controller .give_bus_control ()
182+ assert (
183+ int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
184+ == 0
185+ ) # Idle
186+
187+
188+ @cocotb .test ()
189+ async def test_TE1_idle_exit (dut ):
190+
191+ (STATIC_ADDR , VIRT_STATIC_ADDR , DYNAMIC_ADDR , VIRT_DYNAMIC_ADDR ) = random .sample (VALID_I3C_ADDRESSES , 4 )
192+ ADDRs = [random .choice ([STATIC_ADDR , DYNAMIC_ADDR ]), random .choice ([VIRT_STATIC_ADDR , VIRT_DYNAMIC_ADDR ])]
193+
194+ i3c_controller , i3c_target , tb = await test_setup (dut , STATIC_ADDR , VIRT_STATIC_ADDR ,
195+ dynamic_addr = DYNAMIC_ADDR , virtual_dynamic_addr = VIRT_DYNAMIC_ADDR )
196+ await ClockCycles (tb .clk , 50 )
197+
198+ idle_time_in_cycles = ceil (60000 / (1000 / FCLK ))
199+ await tb .write_csr_field (
200+ tb .reg_map .I3C_EC .SOCMGMTIF .T_IDLE_REG .base_addr ,
201+ tb .reg_map .I3C_EC .SOCMGMTIF .T_IDLE_REG .T_IDLE ,
202+ idle_time_in_cycles
203+ )
204+
205+ for _ in range (2 ):
206+ assert (
207+ int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
208+ == 0
209+ ) # Idle
210+ await i3c_controller .take_bus_control ()
211+ await i3c_controller .send_start ()
212+ ack = await i3c_controller .write_addr_header (0x7E , read = False )
213+ await i3c_controller .send_byte_tbit (random .randint (0 , 0xFF ), True )
214+ await i3c_controller .send_stop ()
215+ i3c_controller .give_bus_control ()
216+ assert (
217+ int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
218+ == 0xa2
219+ ) # WaitHDRExitOrIdle
220+ await Timer (60 , "us" )
136221 assert (
137222 int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
138223 == 0
@@ -150,7 +235,7 @@ async def test_TE5_read_on_write(dut):
150235
151236 COMMANDs = [0x87 , 0x88 , 0x89 , 0x8A , 0x80 , 0x81 , 0x98 ]
152237
153- for _ in range (random . randint ( 10 , 15 ) ):
238+ for _ in range (2 ):
154239 assert (
155240 int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
156241 == 0
@@ -164,6 +249,7 @@ async def test_TE5_read_on_write(dut):
164249 ack = await i3c_controller .write_addr_header (DYNAMIC_ADDR , read = True )
165250 assert ack == False
166251 await i3c_controller .send_stop ()
252+ i3c_controller .give_bus_control ()
167253 assert (
168254 int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
169255 == 0
@@ -199,6 +285,7 @@ async def test_TE5_write_on_read(dut):
199285 ack = await i3c_controller .write_addr_header (DYNAMIC_ADDR , read = False )
200286 assert ack == False
201287 await i3c_controller .send_stop ()
288+ i3c_controller .give_bus_control ()
202289 assert (
203290 int (dut .xi3c_wrapper .i3c .xcontroller .xcontroller_standby .xcontroller_standby_i3c .xi3c_target_fsm .state_d .value )
204291 == 0
0 commit comments