Skip to content

Commit fbe6bba

Browse files
committed
Improve TE support
Signed-off-by: Maciej Dudek <mdudek@antmicro.com>
1 parent 9fbd49b commit fbe6bba

File tree

5 files changed

+336
-46
lines changed

5 files changed

+336
-46
lines changed

src/ctrl/ccc.sv

Lines changed: 89 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ module ccc
9696
input logic ccc_valid_i,
9797

9898
output logic done_fsm_o,
99+
output logic invalid_ccc_o,
99100
output logic next_ccc_o,
100101

101102
// Bus Monitor interface
@@ -344,6 +345,9 @@ module ccc
344345

345346
logic get_status_in_progress;
346347

348+
logic ccc_expected_parity;
349+
assign ccc_expected_parity = ^{ccc_i, 1'b1};
350+
347351
always_ff @(posedge clk_i or negedge rst_ni) begin : report_get_status_done
348352
if (~rst_ni) begin
349353
get_status_in_progress <= '0;
@@ -428,7 +432,8 @@ module ccc
428432
DoneCCC,
429433
HandleENTDAA,
430434
HandleTargetENTDAA,
431-
HandleVirtualTargetENTDAA
435+
HandleVirtualTargetENTDAA,
436+
CCCError
432437
} state_e;
433438

434439
state_e state_q, state_d;
@@ -468,6 +473,13 @@ module ccc
468473
logic is_byte_rsvd_addr;
469474
assign is_byte_rsvd_addr = (rx_data == {7'h7E, 1'b0}) | (command_addr == 7'h7E);
470475

476+
logic is_incorrect_byte_match;
477+
assign is_incorrect_byte_match = (rx_data inside {
478+
8'h7C, 8'hBC, 8'hDC, 8'hEC, 8'hF4, 8'hF8, 8'hFE, 8'hFD
479+
}) | (command_addr inside {
480+
8'h7C, 8'hBC, 8'hDC, 8'hEC, 8'hF4, 8'hF8, 8'hFE, 8'hFD
481+
});
482+
471483
logic is_byte_our_dynamic_addr;
472484
logic is_byte_our_virtual_dynamic_addr;
473485
logic is_byte_our_static_addr;
@@ -488,7 +500,6 @@ module ccc
488500
assign is_byte_virtual_addr = is_byte_our_virtual_dynamic_addr | is_byte_our_virtual_static_addr;
489501

490502
logic supported_direct_command_code;
491-
492503
assign supported_direct_command_code = command_code inside {
493504
// Setters
494505
`I3C_DIRECT_SETDASA,
@@ -509,8 +520,32 @@ module ccc
509520
`I3C_DIRECT_GETCAPS
510521
};
511522

512-
logic unsupported_def_byte;
523+
logic read_only_command;
524+
assign read_only_command = command_code inside {
525+
`I3C_DIRECT_GETSTATUS,
526+
`I3C_DIRECT_GETCAPS,
527+
`I3C_DIRECT_GETBCR,
528+
`I3C_DIRECT_GETDCR,
529+
`I3C_DIRECT_GETMWL,
530+
`I3C_DIRECT_GETMRL,
531+
`I3C_DIRECT_GETPID
532+
};
533+
534+
logic write_only_command;
535+
assign write_only_command = command_code inside {
536+
`I3C_DIRECT_SETDASA,
537+
`I3C_DIRECT_SETNEWDA,
538+
`I3C_DIRECT_SETXTIME,
539+
`I3C_DIRECT_SETMWL,
540+
`I3C_DIRECT_SETMRL,
541+
`I3C_DIRECT_ENEC,
542+
`I3C_DIRECT_DISEC
543+
};
544+
545+
logic direction_error;
546+
assign direction_error = (read_only_command & ~command_rnw) | (write_only_command & command_rnw);
513547

548+
logic unsupported_def_byte;
514549
assign unsupported_def_byte = have_defining_byte & valid_defining_byte & (
515550
(command_code == `I3C_DIRECT_RSTACT) & ~(defining_byte inside {8'h00, 8'h01, 8'h02, 8'h81, 8'h82})
516551
| (command_code == `I3C_DIRECT_GETCAPS) & ~(defining_byte inside {8'h00, 8'h93}));
@@ -519,10 +554,11 @@ module ccc
519554
assign supported_direct_command = supported_direct_command_code & ~unsupported_def_byte;
520555

521556
logic direct_addr_ack;
522-
523-
assign direct_addr_ack = (command_code == `I3C_DIRECT_SETDASA) ?
524-
((is_byte_our_static_addr && ~target_dyn_address_valid_i) | (is_byte_our_virtual_static_addr && ~virtual_target_dyn_address_valid_i)) :
525-
((is_byte_our_addr | is_byte_virtual_addr) & supported_direct_command | is_byte_rsvd_addr );
557+
assign direct_addr_ack = ~direction_error & ((command_code == `I3C_DIRECT_SETDASA) ?
558+
((is_byte_our_static_addr && ~target_dyn_address_valid_i) |
559+
(is_byte_our_virtual_static_addr && ~virtual_target_dyn_address_valid_i)) :
560+
((is_byte_our_addr | is_byte_virtual_addr) & supported_direct_command |
561+
is_byte_rsvd_addr ));
526562

527563
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_addr
528564
if (~rst_ni) begin
@@ -561,34 +597,36 @@ module ccc
561597
ent_hdr_6_o <= '0;
562598
ent_hdr_7_o <= '0;
563599
end else begin
564-
unique case(command_code)
565-
`I3C_BCAST_ENTHDR0:
566-
ent_hdr_0_o <= '1;
567-
`I3C_BCAST_ENTHDR1:
568-
ent_hdr_1_o <= '1;
569-
`I3C_BCAST_ENTHDR2:
570-
ent_hdr_2_o <= '1;
571-
`I3C_BCAST_ENTHDR3:
572-
ent_hdr_3_o <= '1;
573-
`I3C_BCAST_ENTHDR4:
574-
ent_hdr_4_o <= '1;
575-
`I3C_BCAST_ENTHDR5:
576-
ent_hdr_5_o <= '1;
577-
`I3C_BCAST_ENTHDR6:
578-
ent_hdr_6_o <= '1;
579-
`I3C_BCAST_ENTHDR7:
580-
ent_hdr_7_o <= '1;
581-
default: begin
582-
ent_hdr_0_o <= '0;
583-
ent_hdr_1_o <= '0;
584-
ent_hdr_2_o <= '0;
585-
ent_hdr_3_o <= '0;
586-
ent_hdr_4_o <= '0;
587-
ent_hdr_5_o <= '0;
588-
ent_hdr_6_o <= '0;
589-
ent_hdr_7_o <= '0;
590-
end
591-
endcase
600+
if (bus_tx_done_i & (state_q == RxTbit) & (ccc_expected_parity == bus_rx_data_i[0])) begin
601+
unique case(command_code)
602+
`I3C_BCAST_ENTHDR0:
603+
ent_hdr_0_o <= '1;
604+
`I3C_BCAST_ENTHDR1:
605+
ent_hdr_1_o <= '1;
606+
`I3C_BCAST_ENTHDR2:
607+
ent_hdr_2_o <= '1;
608+
`I3C_BCAST_ENTHDR3:
609+
ent_hdr_3_o <= '1;
610+
`I3C_BCAST_ENTHDR4:
611+
ent_hdr_4_o <= '1;
612+
`I3C_BCAST_ENTHDR5:
613+
ent_hdr_5_o <= '1;
614+
`I3C_BCAST_ENTHDR6:
615+
ent_hdr_6_o <= '1;
616+
`I3C_BCAST_ENTHDR7:
617+
ent_hdr_7_o <= '1;
618+
default: begin
619+
ent_hdr_0_o <= '0;
620+
ent_hdr_1_o <= '0;
621+
ent_hdr_2_o <= '0;
622+
ent_hdr_3_o <= '0;
623+
ent_hdr_4_o <= '0;
624+
ent_hdr_5_o <= '0;
625+
ent_hdr_6_o <= '0;
626+
ent_hdr_7_o <= '0;
627+
end
628+
endcase
629+
end
592630
end
593631
end
594632

@@ -606,8 +644,11 @@ module ccc
606644
end
607645
RxTbit: begin
608646
if (bus_rx_done_i) begin
647+
// Check T-bit
648+
if (ccc_expected_parity != bus_rx_data_i[0]) begin
649+
state_d = CCCError;
609650
// have defining byte
610-
if (have_defining_byte && command_code == `I3C_DIRECT_GETCAPS) state_d = RxDefByteOrBusCond;
651+
end else if (have_defining_byte && command_code == `I3C_DIRECT_GETCAPS) state_d = RxDefByteOrBusCond;
611652
else if (have_defining_byte) state_d = RxDefByte;
612653
else begin
613654
// ENTDAA is special
@@ -690,9 +731,10 @@ module ccc
690731
else state_d = WaitForBusCond;
691732
end
692733
else begin
693-
if (is_byte_rsvd_addr) state_d = NextCCC;
694-
else if ((is_byte_our_addr || is_byte_virtual_addr) && command_rnw && supported_direct_command) state_d = TxData;
695-
else if ((is_byte_our_addr || is_byte_virtual_addr) && ~command_rnw && supported_direct_command) begin
734+
if (is_incorrect_byte_match) state_d = CCCError;
735+
else if (is_byte_rsvd_addr) state_d = NextCCC;
736+
else if ((is_byte_our_addr || is_byte_virtual_addr) && command_rnw && supported_direct_command && ~direction_error) state_d = TxData;
737+
else if ((is_byte_our_addr || is_byte_virtual_addr) && ~command_rnw && supported_direct_command && ~direction_error) begin
696738
if (command_code == `I3C_DIRECT_SETXTIME) state_d = RxSubCmdByte;
697739
else state_d = RxData;
698740
end else state_d = WaitForBusCond;
@@ -731,6 +773,9 @@ module ccc
731773
DoneCCC: begin
732774
state_d = Idle;
733775
end
776+
CCCError: begin
777+
state_d = Idle;
778+
end
734779
default: begin
735780
end
736781
endcase
@@ -748,6 +793,7 @@ module ccc
748793

749794
done_fsm_o = '0;
750795
next_ccc_o = '0;
796+
invalid_ccc_o = '0;
751797
unique case (state_q)
752798
Idle: begin
753799

@@ -819,6 +865,10 @@ module ccc
819865
DoneCCC: begin
820866
done_fsm_o = '1;
821867
end
868+
CCCError: begin
869+
invalid_ccc_o = '1;
870+
done_fsm_o = '1;
871+
end
822872
default: begin
823873
end
824874
endcase

src/ctrl/controller_standby_i3c.sv

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ module controller_standby_i3c
240240
logic target_reset_detect;
241241
logic hdr_exit_detect;
242242
logic is_in_hdr_mode;
243+
logic te0_detected;
243244

244245
// SubFSMs status
245246
logic ibi_pending;
@@ -249,6 +250,7 @@ module controller_standby_i3c
249250
logic [7:0] ccc;
250251
logic ccc_valid;
251252
logic is_ccc_done;
253+
logic invalid_ccc;
252254
logic is_next_ccc;
253255
logic is_hotjoin_done;
254256

@@ -447,13 +449,15 @@ module controller_standby_i3c
447449
.target_reset_detect_i (target_reset_detect),
448450
.hdr_exit_detect_i (hdr_exit_detect),
449451
.is_in_hdr_mode_i (is_in_hdr_mode),
452+
.te0_detected_o (te0_detected),
450453
.ibi_enable_i (ibi_enable_i),
451454
.ibi_pending_i (ibi_pending),
452455
.ibi_begin_o (ibi_begin),
453456
.ibi_done_i (ibi_done),
454457
.ccc_o (ccc),
455458
.ccc_valid_o (ccc_valid),
456459
.is_ccc_done_i (is_ccc_done),
460+
.invalid_ccc_i (invalid_ccc),
457461
.is_next_ccc_i (is_next_ccc),
458462
.is_hotjoin_done_i (is_hotjoin_done),
459463
.last_addr_o (bus_addr_o),
@@ -463,6 +467,7 @@ module controller_standby_i3c
463467
.sda_negedge_i (ctrl_bus_i.sda.neg_edge),
464468
.sda_posedge_i (ctrl_bus_i.sda.pos_edge),
465469
.bus_free_i (bus_free),
470+
.bus_idle_i (bus_idle),
466471
.parity_err_o,
467472
.rx_overflow_err_o (rx_overflow_err),
468473
.virtual_device_sel_o (virtual_device_sel_o),
@@ -476,6 +481,7 @@ module controller_standby_i3c
476481
.ccc_i (ccc),
477482
.ccc_valid_i (ccc_valid),
478483
.done_fsm_o (is_ccc_done),
484+
.invalid_ccc_o (invalid_ccc),
479485
.next_ccc_o (is_next_ccc),
480486
.bus_start_det_i (ctrl_bus_i.start_det),
481487
.bus_rstart_det_i (ctrl_bus_i.rstart_det),
@@ -637,12 +643,15 @@ module controller_standby_i3c
637643
.rx_idle_o (bus_rx_idle)
638644
);
639645

646+
logic hdr_exit_trigger;
647+
assign hdr_exit_trigger = is_in_hdr_mode | te0_detected;
648+
640649
i3c_bus_monitor xbus_monitor (
641650
.clk_i,
642651
.rst_ni,
643652
.enable_i (i3c_standby_en),
644653
.bus_i (ctrl_bus_i),
645-
.is_in_hdr_mode_i (is_in_hdr_mode),
654+
.is_in_hdr_mode_i (hdr_exit_trigger),
646655
.hdr_exit_detect_o (hdr_exit_detect),
647656
.target_reset_detect_o(target_reset_detect)
648657
);

0 commit comments

Comments
 (0)