@@ -352,6 +352,102 @@ async def test_write(dut):
352
352
assert data1 == 0x44332211
353
353
354
354
355
+ @cocotb .test ()
356
+ async def test_read_fifo_ctrl (dut ):
357
+ """
358
+ Tests CSR read(s) using the recovery protocol
359
+ """
360
+
361
+ # Initialize
362
+ i3c_controller , _ , tb , recovery = await initialize (dut )
363
+
364
+ # set regular device dynamic address
365
+ await i3c_controller .i3c_ccc_write (
366
+ ccc = CCC .DIRECT .SETDASA , directed_data = [(STATIC_ADDR , [DYNAMIC_ADDR << 1 ])]
367
+ )
368
+ # set virtual device dynamic address
369
+ await i3c_controller .i3c_ccc_write (
370
+ ccc = CCC .DIRECT .SETDASA , directed_data = [(VIRT_STATIC_ADDR , [VIRT_DYNAMIC_ADDR << 1 ])]
371
+ )
372
+
373
+ # Write to the RESET CSR (one word)
374
+ await recovery .command_write (
375
+ VIRT_DYNAMIC_ADDR , I3cRecoveryInterface .Command .DEVICE_RESET , [0xAA , 0xBB , 0xCC , 0xDD ]
376
+ )
377
+
378
+ # Wait & read the CSR from the AHB/AXI side
379
+ await Timer (1 , "us" )
380
+
381
+ status = dword2int (
382
+ await tb .read_csr (tb .reg_map .I3C_EC .SECFWRECOVERYIF .DEVICE_STATUS_0 .base_addr , 4 )
383
+ )
384
+ dut ._log .info (f"DEVICE_STATUS = 0x{ status :08X} " )
385
+ data = dword2int (await tb .read_csr (tb .reg_map .I3C_EC .SECFWRECOVERYIF .DEVICE_RESET .base_addr , 4 ))
386
+ dut ._log .info (f"DEVICE_RESET = 0x{ data :08X} " )
387
+
388
+ # Check
389
+ protocol_status = (status >> 8 ) & 0xFF
390
+ assert protocol_status == 0
391
+ assert data == 0xCCBBAA # 0xDD trimmed because this register is only 3 bytes
392
+
393
+ # Data to be written to INDIRECT_FIFO_CTRL
394
+ fifo_ctrl_data = [random .randint (0 , 255 ) for _ in range (6 )]
395
+
396
+ # RESET is W1C, expect to read CMS only
397
+ exp_fifo_ctrl_0 = fifo_ctrl_data [0 ]
398
+
399
+ # IMAGE_SIZE
400
+ exp_fifo_ctrl_1 = (
401
+ fifo_ctrl_data [5 ] << 24
402
+ | fifo_ctrl_data [4 ] << 16
403
+ | fifo_ctrl_data [3 ] << 8
404
+ | fifo_ctrl_data [2 ]
405
+ )
406
+
407
+ # Write to the FIFO_CTRL CSR (two words)
408
+ await recovery .command_write (
409
+ VIRT_DYNAMIC_ADDR ,
410
+ I3cRecoveryInterface .Command .INDIRECT_FIFO_CTRL ,
411
+ fifo_ctrl_data ,
412
+ )
413
+
414
+ # Wait & read the CSR from the AHB/AXI side
415
+ await Timer (1 , "us" )
416
+
417
+ status = dword2int (
418
+ await tb .read_csr (tb .reg_map .I3C_EC .SECFWRECOVERYIF .DEVICE_STATUS_0 .base_addr , 4 )
419
+ )
420
+ dut ._log .info (f"DEVICE_STATUS = 0x{ status :08X} " )
421
+
422
+ # Readback the FIFO_CTRL CSR via I3C
423
+ data , _ = await recovery .command_read (
424
+ VIRT_DYNAMIC_ADDR , I3cRecoveryInterface .Command .INDIRECT_FIFO_CTRL
425
+ )
426
+ data0 , data1 = data [:2 ], data [2 :]
427
+
428
+ # Check
429
+ protocol_status = (status >> 8 ) & 0xFF
430
+ assert protocol_status == 0
431
+
432
+ fifo_ctrl_data [1 ] = 0 # RESET is W1C
433
+ assert data == fifo_ctrl_data
434
+ assert data0 == fifo_ctrl_data [:2 ]
435
+ assert data1 == fifo_ctrl_data [2 :]
436
+
437
+ # Ensure the same is read via AXI / AHB
438
+ bus_data0 = dword2int (
439
+ await tb .read_csr (tb .reg_map .I3C_EC .SECFWRECOVERYIF .INDIRECT_FIFO_CTRL_0 .base_addr , 4 )
440
+ )
441
+ dut ._log .info (f"INDIRECT_FIFO_CTRL_0 = 0x{ bus_data0 :08X} " )
442
+ bus_data1 = dword2int (
443
+ await tb .read_csr (tb .reg_map .I3C_EC .SECFWRECOVERYIF .INDIRECT_FIFO_CTRL_1 .base_addr , 4 )
444
+ )
445
+ dut ._log .info (f"INDIRECT_FIFO_CTRL_1 = 0x{ bus_data1 :08X} " )
446
+
447
+ assert exp_fifo_ctrl_0 == bus_data0
448
+ assert exp_fifo_ctrl_1 == bus_data1
449
+
450
+
355
451
@cocotb .test ()
356
452
async def test_indirect_fifo_write (dut ):
357
453
"""
0 commit comments