Skip to content

Commit 4593dec

Browse files
committed
ccc: handle setnewda
1 parent 2e91c3f commit 4593dec

File tree

3 files changed

+93
-26
lines changed

3 files changed

+93
-26
lines changed

src/ctrl/ccc.sv

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ module ccc
323323
logic set_aasa_valid;
324324
logic [6:0] set_aasa_addr;
325325

326+
logic set_newda_valid;
327+
logic [6:0] set_newda_addr;
326328
logic entdaa_addres_valid;
327329
logic [6:0] entdaa_address;
328330
logic entdaa_process_virtual;
@@ -441,32 +443,24 @@ module ccc
441443
logic is_byte_rsvd_addr;
442444
assign is_byte_rsvd_addr = (rx_data == {7'h7E, 1'b0}) | (command_addr == 7'h7E);
443445

446+
logic is_byte_our_dynamic_addr;
447+
logic is_byte_our_virtual_dynamic_addr;
448+
logic is_byte_our_static_addr;
449+
logic is_byte_our_virtual_static_addr;
444450
logic is_byte_our_addr;
445451
logic is_byte_virtual_addr;
446452

447453
logic [7:0] rx_data_count;
448454

449455
logic entdaa_start, entdaa_done;
450456

451-
always_comb begin : addr_matching
452-
if (target_dyn_address_valid_i) begin
453-
is_byte_our_addr = command_addr == target_dyn_address_i;
454-
end else if (target_sta_address_valid_i) begin
455-
is_byte_our_addr = command_addr == target_sta_address_i;
456-
end else begin
457-
is_byte_our_addr = '0;
458-
end
459-
end
457+
assign is_byte_our_dynamic_addr = ((command_addr == target_dyn_address_i) && target_dyn_address_valid_i);
458+
assign is_byte_our_static_addr = ((command_addr == target_sta_address_i) && target_sta_address_valid_i);
459+
assign is_byte_our_addr = is_byte_our_dynamic_addr | is_byte_our_static_addr;
460460

461-
always_comb begin : virtual_addr_matching
462-
if (virtual_target_dyn_address_valid_i) begin
463-
is_byte_virtual_addr = command_addr == virtual_target_dyn_address_i;
464-
end else if (virtual_target_sta_address_valid_i) begin
465-
is_byte_virtual_addr = command_addr == virtual_target_sta_address_i;
466-
end else begin
467-
is_byte_virtual_addr = '0;
468-
end
469-
end
461+
assign is_byte_our_virtual_dynamic_addr = ((command_addr == virtual_target_dyn_address_i) && virtual_target_dyn_address_valid_i);
462+
assign is_byte_our_virtual_static_addr = ((command_addr == virtual_target_sta_address_i) && virtual_target_sta_address_valid_i);
463+
assign is_byte_virtual_addr = is_byte_our_virtual_dynamic_addr | is_byte_our_virtual_static_addr;
470464

471465
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_addr
472466
if (~rst_ni) begin
@@ -598,7 +592,6 @@ module ccc
598592
RxDataTbit: begin
599593
if (bus_rx_done_i) state_d = RxData;
600594
end
601-
602595
TxData: begin
603596
if (bus_rstart_det_i) state_d = RxDirectAddr;
604597
else if (bus_tx_done_i) state_d = TxDataTbit;
@@ -805,16 +798,18 @@ module ccc
805798

806799
// connect entdaa/setnewda
807800
always_comb begin: entdaa_setnewda_mux
808-
set_newda_o = entdaa_addres_valid && (state_q == HandleTargetENTDAA);
809-
set_newda_virtual_device_o = entdaa_addres_valid && (state_q == HandleVirtualTargetENTDAA);
810-
newda_o = entdaa_address;
801+
set_newda_o = set_newda_valid | (entdaa_addres_valid && ((state_q == HandleTargetENTDAA) || (state_q == HandleVirtualTargetENTDAA)));
802+
set_newda_virtual_device_o = set_newda_valid ? is_byte_our_virtual_dynamic_addr : (entdaa_addres_valid && (state_q == HandleVirtualTargetENTDAA));
803+
newda_o = set_newda_valid ? set_newda_addr : entdaa_address;
811804
end
812805

813806
// Handle DIRECT SET CCCs
814807
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_set_direct
815808
if (~rst_ni) begin
816809
set_dasa_valid <= 1'b0;
817810
set_dasa_addr <= '0;
811+
set_newda_valid <= 1'b0;
812+
set_newda_addr <= '0;
818813
end else begin
819814
case (command_code)
820815
// setdasa has only one data byte - dynamic address
@@ -827,6 +822,15 @@ module ccc
827822
set_dasa_valid <= 1'b0;
828823
end
829824
end
825+
`I3C_DIRECT_SETNEWDA: begin
826+
if (state_q == RxDataTbit && bus_rx_done_i && ~is_byte_rsvd_addr &&
827+
rx_data_count == 8'd0) begin
828+
set_newda_addr <= rx_data[7:1];
829+
set_newda_valid <= 1'b1;
830+
end else begin
831+
set_newda_valid <= 1'b0;
832+
end
833+
end
830834
default: begin
831835
end
832836
endcase

src/hci/hci.sv

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,14 @@ module hci
321321
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR.we = (set_dasa_valid_i | rstdaa_i) && (set_dasa_virtual_device_i);
322322
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR.next = rstdaa_i && set_dasa_virtual_device_i ? 1'b0 : set_dasa_i;
323323
end else if (set_newda_i | set_newda_virtual_device_i) begin
324-
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID.we = set_newda_i;
324+
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID.we = set_newda_i && ~(set_newda_virtual_device_i);
325325
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID.next = 1'b1;
326-
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR.we = set_newda_i;
326+
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR.we = set_newda_i && ~(set_newda_virtual_device_i);
327327
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR.next = newda_i;
328328
// Virtual device address
329-
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR_VALID.we = set_newda_virtual_device_i;
329+
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR_VALID.we = set_newda_i && set_newda_virtual_device_i;
330330
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR_VALID.next = 1'b1;
331-
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR.we = set_newda_virtual_device_i;
331+
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR.we = set_newda_i && set_newda_virtual_device_i;
332332
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR.next = newda_i;
333333
end else begin
334334
hwif_in.I3C_EC.StdbyCtrlMode.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID.we = 1'b0;

verification/cocotb/top/lib_i3c_top/test_ccc.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,69 @@ async def test_ccc_setdasa(dut):
129129
assert virt_dynamic_address_valid == 1, "New VIRT DYNAMIC ADDRESS is not set as valid"
130130

131131

132+
@cocotb.test()
133+
async def test_ccc_setnewda(dut):
134+
135+
STATIC_ADDR = 0x5A
136+
VIRT_STATIC_ADDR = 0x5B
137+
DYNAMIC_ADDR = 0x52
138+
VIRT_DYNAMIC_ADDR = 0x53
139+
NEW_DYNAMIC_ADDR = 0x0C
140+
NEW_VIRT_DYNAMIC_ADDR = 0x21
141+
142+
i3c_controller, i3c_target, tb = await test_setup(dut)
143+
await ClockCycles(tb.clk, 50)
144+
145+
dynamic_address_reg_addr = tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.base_addr
146+
dynamic_address_reg_value = tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR
147+
virtual_dynamic_address_reg_addr = (
148+
tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_VIRT_DEVICE_ADDR.base_addr
149+
)
150+
virtual_dynamic_address_reg_value = (
151+
tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR
152+
)
153+
dynamic_address_reg_valid = (
154+
tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID
155+
)
156+
virtual_dynamic_address_reg_valid = (
157+
tb.reg_map.I3C_EC.STDBYCTRLMODE.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR_VALID
158+
)
159+
160+
# set dynamic addresses
161+
await tb.write_csr_field(dynamic_address_reg_addr, dynamic_address_reg_value, DYNAMIC_ADDR)
162+
await tb.write_csr_field(dynamic_address_reg_addr, dynamic_address_reg_valid, 1)
163+
await tb.write_csr_field(virtual_dynamic_address_reg_addr, virtual_dynamic_address_reg_value, VIRT_DYNAMIC_ADDR)
164+
await tb.write_csr_field(virtual_dynamic_address_reg_addr, virtual_dynamic_address_reg_valid, 1)
165+
166+
# change regular device dynamic address
167+
await i3c_controller.i3c_ccc_write(
168+
ccc=CCC.DIRECT.SETNEWDA, directed_data=[(DYNAMIC_ADDR, [NEW_DYNAMIC_ADDR << 1])], stop=False
169+
)
170+
# change virtual device dynamic address
171+
await i3c_controller.i3c_ccc_write(
172+
ccc=CCC.DIRECT.SETNEWDA, directed_data=[(VIRT_DYNAMIC_ADDR, [NEW_VIRT_DYNAMIC_ADDR << 1])]
173+
)
174+
175+
# read addresses
176+
dynamic_address = await tb.read_csr_field(dynamic_address_reg_addr, dynamic_address_reg_value)
177+
dynamic_address_valid = await tb.read_csr_field(
178+
dynamic_address_reg_addr, dynamic_address_reg_valid
179+
)
180+
virt_dynamic_address = await tb.read_csr_field(
181+
virtual_dynamic_address_reg_addr, virtual_dynamic_address_reg_value
182+
)
183+
virt_dynamic_address_valid = await tb.read_csr_field(
184+
virtual_dynamic_address_reg_addr, virtual_dynamic_address_reg_valid
185+
)
186+
187+
assert dynamic_address == NEW_DYNAMIC_ADDR, "Unexpected DYNAMIC ADDRESS read from the CSR"
188+
assert dynamic_address_valid == 1, "New DYNAMIC ADDRESS is not set as valid"
189+
190+
assert (
191+
virt_dynamic_address == NEW_VIRT_DYNAMIC_ADDR
192+
), "Unexpected VIRT DYNAMIC ADDRESS read from the CSR"
193+
assert virt_dynamic_address_valid == 1, "New VIRT DYNAMIC ADDRESS is not set as valid"
194+
132195
@cocotb.test()
133196
async def test_ccc_rstdaa(dut):
134197

0 commit comments

Comments
 (0)