Skip to content

Commit

Permalink
CCC: improve dynamic address handling
Browse files Browse the repository at this point in the history
  • Loading branch information
kgugala committed Dec 23, 2024
1 parent d30341e commit c3ff246
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 29 deletions.
24 changes: 18 additions & 6 deletions src/ctrl/ccc.sv
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ module ccc
// I3C_BCAST_SETXTIME

// Set Dynamic Address from Static Address
output logic [7:0] set_dasa_o,
output logic [6:0] set_dasa_o,
output logic set_dasa_valid_o,

// Target Reset Action
Expand Down Expand Up @@ -287,9 +287,9 @@ module ccc
logic last_tbit_valid;

logic set_dasa_valid;
logic [7:0] set_dasa_addr;
logic [6:0] set_dasa_addr;
logic set_aasa_valid;
logic [7:0] set_aasa_addr;
logic [6:0] set_aasa_addr;

logic get_status_in_progress;

Expand Down Expand Up @@ -358,6 +358,8 @@ module ccc

logic is_byte_our_addr;

logic [7:0] rx_data_count;

always_comb begin : addr_matching
if (target_dyn_address_valid_i) begin
is_byte_our_addr = command_addr == target_dyn_address_i;
Expand Down Expand Up @@ -541,7 +543,6 @@ module ccc
end

// GET interface handler

always_ff @(posedge clk_i or negedge rst_ni) begin : proc_tx_data_id
if (~rst_ni) begin
tx_data_id <= '0;
Expand All @@ -553,6 +554,17 @@ module ccc
end
end

// GET data counter
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
rx_data_count <= '0;
end else if (state_q == WaitCCC && ccc_valid_i) begin
rx_data_count <= '0;
end else if (state_q == RxDataTbit && bus_rx_done_i) begin
rx_data_count <= rx_data_count + 1'b1;
end
end

// Done, no more bytes to send in this CCC
assign tx_data_done = tx_data_id == 8'h00;

Expand Down Expand Up @@ -619,8 +631,8 @@ module ccc
case (command_code)
// setdasa has only one data byte - dynamic address
`I3C_DIRECT_SETDASA: begin
if (state_q == RxDataTbit && bus_rx_done_i && ~is_byte_rsvd_addr) begin
set_dasa_addr <= rx_data;
if (state_q == RxDataTbit && bus_rx_done_i && ~is_byte_rsvd_addr && rx_data_count == 8'd0) begin
set_dasa_addr <= rx_data[7:1];
set_dasa_valid <= 1'b1;
end else begin
set_dasa_addr <= '0;
Expand Down
2 changes: 1 addition & 1 deletion src/ctrl/controller.sv
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ module controller
output logic ibi_status_we_o,

output logic [7:0] rst_action_o,
output logic [7:0] set_dasa_o,
output logic [6:0] set_dasa_o,
output logic set_dasa_valid_o,
output logic rstdaa_o,

Expand Down
2 changes: 1 addition & 1 deletion src/ctrl/controller_standby_i3c.sv
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ module controller_standby_i3c

output logic [7:0] rst_action_o,
output logic tx_host_nack_o,
output logic [7:0] set_dasa_o,
output logic [6:0] set_dasa_o,
output logic set_dasa_valid_o,
output logic rstdaa_o,

Expand Down
17 changes: 10 additions & 7 deletions src/hci/hci.sv
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ module hci
output I3CCSR_pkg::I3CCSR__out_t hwif_out_o,

input logic [7:0] rst_action_i,
input logic [7:0] set_dasa_i,
input logic [6:0] set_dasa_i,
input logic set_dasa_valid_i,
input logic rstdaa_i
);
Expand Down Expand Up @@ -294,10 +294,11 @@ module hci
end : wire_hwif_ccc

always_comb begin : wire_address_setting
hwif_in.I3CBase.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR_VALID.we = set_dasa_valid_i | rstdaa_i;
hwif_in.I3CBase.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR.we = set_dasa_valid_i | rstdaa_i;
hwif_in.I3CBase.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR_VALID.next = rstdaa_i ? '0: set_dasa_valid_i;
hwif_in.I3CBase.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR.next = rstdaa_i ? 1'b0 : set_dasa_i;
// Target address
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID.we = set_dasa_valid_i | rstdaa_i;
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID.next = rstdaa_i ? '0: set_dasa_valid_i;
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR.we = set_dasa_valid_i | rstdaa_i;
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR.next = rstdaa_i ? 1'b0 : set_dasa_i;
end

I3CCSR i3c_csr (
Expand Down Expand Up @@ -502,8 +503,6 @@ module hci
);

always_comb begin : wire_unconnected_regs
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID.we = '0;
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR.we = '0;
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.STATIC_ADDR_VALID.we = '0;
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.STATIC_ADDR.we = '0;
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_CONTROL.PENDING_RX_NACK.next = '0;
Expand Down Expand Up @@ -570,6 +569,10 @@ module hci

hwif_in.I3C_EC.CtrlCfg.CONTROLLER_CONFIG.OPERATION_MODE.we = '0;

hwif_in.I3CBase.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR_VALID.we = '0;
hwif_in.I3CBase.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR.we = '0;
hwif_in.I3CBase.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR_VALID.next = '0;
hwif_in.I3CBase.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR.next = '0;
hwif_in.I3CBase.HC_CONTROL.RESUME.we = '0;
hwif_in.I3CBase.HC_CONTROL.RESUME.next = '0;
hwif_in.I3CBase.HC_CONTROL.BUS_ENABLE.we = '0;
Expand Down
2 changes: 1 addition & 1 deletion src/i3c.sv
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ module i3c
logic [7:0] rx_bus_addr;
logic rx_bus_addr_valid;
logic [7:0] rst_action;
logic [7:0] set_dasa;
logic [6:0] set_dasa;
logic set_dasa_valid;
logic rstdaa;

Expand Down
27 changes: 14 additions & 13 deletions verification/cocotb/top/lib_i3c_top/test_ccc.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ async def test_setup(dut):

@cocotb.test()
async def test_ccc_getstatus(dut):
I3C_DIRECT_GETSTATUS = 0x90
PENDING_INTERRUPT = 7
PENDING_INTERRUPT_MASK = 0b1111

Expand All @@ -67,7 +66,7 @@ async def test_ccc_getstatus(dut):
pending_interrupt == PENDING_INTERRUPT
), "Unexpected pending interrupt value read from CSR"

status = await i3c_controller.i3c_ccc_read(ccc=I3C_DIRECT_GETSTATUS, addr=TGT_ADR, count=2)
status = await i3c_controller.i3c_ccc_read(ccc=CCC.DIRECT.GETSTATUS, addr=TGT_ADR, count=2)
print("status", status)
pending_interrupt = (
int.from_bytes(status, byteorder="big", signed=False) & PENDING_INTERRUPT_MASK
Expand All @@ -84,15 +83,16 @@ async def test_ccc_setdasa(dut):

STATIC_ADDR = 0x5A
DYNAMIC_ADDR = 0x52
I3C_DIRECT_SETDASA = 0x87
i3c_controller, i3c_target, tb = await test_setup(dut)
await ClockCycles(tb.clk, 50)
await i3c_controller.i3c_ccc_write(
ccc=I3C_DIRECT_SETDASA, directed_data=[(STATIC_ADDR, [DYNAMIC_ADDR])]
ccc=CCC.DIRECT.SETDASA, directed_data=[(STATIC_ADDR, [DYNAMIC_ADDR << 1])]
)
dynamic_address_reg_addr = tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.base_addr
dynamic_address_reg_value = tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR
dynamic_address_reg_valid = (
tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID
)
dynamic_address_reg_addr = tb.reg_map.I3CBASE.CONTROLLER_DEVICE_ADDR.base_addr
dynamic_address_reg_value = tb.reg_map.I3CBASE.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR
dynamic_address_reg_valid = tb.reg_map.I3CBASE.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR_VALID
dynamic_address = await tb.read_csr_field(dynamic_address_reg_addr, dynamic_address_reg_value)
dynamic_address_valid = await tb.read_csr_field(
dynamic_address_reg_addr, dynamic_address_reg_valid
Expand All @@ -105,12 +105,13 @@ async def test_ccc_setdasa(dut):
async def test_ccc_rstdaa(dut):

DYNAMIC_ADDR = 0x52
I3C_DIRECT_RSTDAA = 0x06
i3c_controller, i3c_target, tb = await test_setup(dut)
await ClockCycles(tb.clk, 50)
dynamic_address_reg_addr = tb.reg_map.I3CBASE.CONTROLLER_DEVICE_ADDR.base_addr
dynamic_address_reg_value = tb.reg_map.I3CBASE.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR
dynamic_address_reg_valid = tb.reg_map.I3CBASE.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR_VALID
dynamic_address_reg_addr = tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.base_addr
dynamic_address_reg_value = tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR
dynamic_address_reg_valid = (
tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID
)

# set dynamic address CSR
await tb.write_csr_field(dynamic_address_reg_addr, dynamic_address_reg_value, DYNAMIC_ADDR)
Expand All @@ -125,7 +126,7 @@ async def test_ccc_rstdaa(dut):
assert dynamic_address_valid == 1, "New DYNAMIC ADDRESS is not set as valid"

# reset Dynamic Address
await i3c_controller.i3c_ccc_write(ccc=I3C_DIRECT_RSTDAA)
await i3c_controller.i3c_ccc_write(ccc=CCC.BCAST.RSTDAA)

# check if the address was reset
dynamic_address = await tb.read_csr_field(dynamic_address_reg_addr, dynamic_address_reg_value)
Expand Down Expand Up @@ -212,7 +213,7 @@ async def test_ccc_setaasa(dut):
I3C_BCAST_SETAASA = 0x29
i3c_controller, i3c_target, tb = await test_setup(dut)
await ClockCycles(tb.clk, 50)
dynamic_address_reg_addr = tb.reg_map.I3CBASE.CONTROLLER_DEVICE_ADDR.base_addr
dynamic_address_reg_addr = tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.base_addr
dynamic_address_reg_value = tb.reg_map.I3CBASE.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR
dynamic_address_reg_valid = tb.reg_map.I3CBASE.CONTROLLER_DEVICE_ADDR.DYNAMIC_ADDR_VALID

Expand Down

0 comments on commit c3ff246

Please sign in to comment.