Skip to content

Commit e5e4b53

Browse files
committed
recovery_executor: INDIRECT_FIFO_CTRL reads from I3C
Update read value from INDIRECT_FIFO_CTRL from I3C to match current CSR layout. Add I3C recovery read test from FIFO_CTRL to ensure proper behavior. Signed-off-by: Wiktoria Kuna <[email protected]>
1 parent 8a02110 commit e5e4b53

File tree

2 files changed

+104
-3
lines changed

2 files changed

+104
-3
lines changed

src/recovery/recovery_executor.sv

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ module recovery_executor
296296

297297
// CSR read data mux (registered)
298298
logic [31:0] indirect_fifo_status_0;
299-
logic [31:0] indirect_fifo_ctrl_0;
299+
logic [31:0] indirect_fifo_ctrl_0, indirect_fifo_ctrl_1;
300300
logic [31:0] prot_cap_2, prot_cap_3;
301301
logic [31:0] device_id_0;
302302
logic [31:0] device_status_0, device_status_1;
@@ -324,7 +324,7 @@ module recovery_executor
324324
CSR_HW_STATUS: csr_data <= hw_status;
325325

326326
CSR_INDIRECT_FIFO_CTRL_0: csr_data <= indirect_fifo_ctrl_0;
327-
CSR_INDIRECT_FIFO_CTRL_1: csr_data <= hwif_rec_i.INDIRECT_FIFO_CTRL_1.IMAGE_SIZE.value;
327+
CSR_INDIRECT_FIFO_CTRL_1: csr_data <= indirect_fifo_ctrl_1;
328328
CSR_INDIRECT_FIFO_STATUS_0: csr_data <= indirect_fifo_status_0;
329329
CSR_INDIRECT_FIFO_STATUS_1: csr_data <= hwif_rec_i.INDIRECT_FIFO_STATUS_1.WRITE_INDEX.value;
330330
CSR_INDIRECT_FIFO_STATUS_2: csr_data <= hwif_rec_i.INDIRECT_FIFO_STATUS_2.READ_INDEX.value;
@@ -396,11 +396,16 @@ module recovery_executor
396396
};
397397

398398
assign indirect_fifo_ctrl_0 = {
399-
16'd0,
399+
hwif_rec_i.INDIRECT_FIFO_CTRL_1.IMAGE_SIZE.value[15:0],
400400
hwif_rec_i.INDIRECT_FIFO_CTRL_0.RESET.value,
401401
hwif_rec_i.INDIRECT_FIFO_CTRL_0.CMS.value
402402
};
403403

404+
assign indirect_fifo_ctrl_1 = {
405+
16'h0,
406+
hwif_rec_i.INDIRECT_FIFO_CTRL_1.IMAGE_SIZE.value[31:16]
407+
};
408+
404409
// INDIRECT_FIFO_STATUS_0 as a 32-bit word
405410
assign indirect_fifo_status_0 = {
406411
// b3,b2

verification/cocotb/top/lib_i3c_top/test_recovery.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,102 @@ async def test_write(dut):
352352
assert data1 == 0x44332211
353353

354354

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+
355451
@cocotb.test()
356452
async def test_indirect_fifo_write(dut):
357453
"""

0 commit comments

Comments
 (0)