@@ -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 ;
@@ -427,7 +431,8 @@ module ccc
427431 DoneCCC,
428432 HandleENTDAA,
429433 HandleTargetENTDAA,
430- HandleVirtualTargetENTDAA
434+ HandleVirtualTargetENTDAA,
435+ CCCError
431436 } state_e ;
432437
433438 state_e state_q, state_d;
@@ -467,6 +472,13 @@ module ccc
467472 logic is_byte_rsvd_addr;
468473 assign is_byte_rsvd_addr = (rx_data == { 7'h7E , 1'b0 } ) | (command_addr == 7'h7E );
469474
475+ logic is_incorrect_byte_match;
476+ assign is_incorrect_byte_match = (rx_data inside {
477+ 8'h7C , 8'hBC , 8'hDC , 8'hEC , 8'hF4 , 8'hF8 , 8'hFE , 8'hFD
478+ } ) | (command_addr inside {
479+ 8'h7C , 8'hBC , 8'hDC , 8'hEC , 8'hF4 , 8'hF8 , 8'hFE , 8'hFD
480+ } );
481+
470482 logic is_byte_our_dynamic_addr;
471483 logic is_byte_our_virtual_dynamic_addr;
472484 logic is_byte_our_static_addr;
@@ -487,7 +499,6 @@ module ccc
487499 assign is_byte_virtual_addr = is_byte_our_virtual_dynamic_addr | is_byte_our_virtual_static_addr;
488500
489501 logic supported_direct_command_code;
490-
491502 assign supported_direct_command_code = command_code inside {
492503 // Setters
493504 `I3C_DIRECT_SETDASA ,
@@ -508,8 +519,32 @@ module ccc
508519 `I3C_DIRECT_GETCAPS
509520 } ;
510521
511- logic unsupported_def_byte;
522+ logic read_only_command;
523+ assign read_only_command = command_code inside {
524+ `I3C_DIRECT_GETSTATUS ,
525+ `I3C_DIRECT_GETCAPS ,
526+ `I3C_DIRECT_GETBCR ,
527+ `I3C_DIRECT_GETDCR ,
528+ `I3C_DIRECT_GETMWL ,
529+ `I3C_DIRECT_GETMRL ,
530+ `I3C_DIRECT_GETPID
531+ } ;
512532
533+ logic write_only_command;
534+ assign write_only_command = command_code inside {
535+ `I3C_DIRECT_SETDASA ,
536+ `I3C_DIRECT_SETNEWDA ,
537+ `I3C_DIRECT_SETXTIME ,
538+ `I3C_DIRECT_SETMWL ,
539+ `I3C_DIRECT_SETMRL ,
540+ `I3C_DIRECT_ENEC ,
541+ `I3C_DIRECT_DISEC
542+ } ;
543+
544+ logic direction_error;
545+ assign direction_error = (read_only_command & ~ command_rnw) | (write_only_command & command_rnw);
546+
547+ logic unsupported_def_byte;
513548 assign unsupported_def_byte = have_defining_byte & valid_defining_byte & (
514549 (command_code == `I3C_DIRECT_RSTACT ) & ~ (defining_byte inside { 8'h00 , 8'h01 , 8'h02 , 8'h81 , 8'h82 } )
515550 | (command_code == `I3C_DIRECT_GETCAPS ) & ~ (defining_byte inside { 8'h00 , 8'h93 } ));
@@ -518,10 +553,11 @@ module ccc
518553 assign supported_direct_command = supported_direct_command_code & ~ unsupported_def_byte;
519554
520555 logic direct_addr_ack;
521-
522- assign direct_addr_ack = (command_code == `I3C_DIRECT_SETDASA ) ?
523- ((is_byte_our_static_addr && ~ target_dyn_address_valid_i) | (is_byte_our_virtual_static_addr && ~ virtual_target_dyn_address_valid_i)) :
524- ((is_byte_our_addr | is_byte_virtual_addr) & supported_direct_command | is_byte_rsvd_addr );
556+ assign direct_addr_ack = ~ direction_error & ((command_code == `I3C_DIRECT_SETDASA ) ?
557+ ((is_byte_our_static_addr && ~ target_dyn_address_valid_i) |
558+ (is_byte_our_virtual_static_addr && ~ virtual_target_dyn_address_valid_i)) :
559+ ((is_byte_our_addr | is_byte_virtual_addr) & supported_direct_command |
560+ is_byte_rsvd_addr ));
525561
526562 always_ff @ (posedge clk_i or negedge rst_ni) begin : proc_addr
527563 if (~ rst_ni) begin
@@ -560,34 +596,45 @@ module ccc
560596 ent_hdr_6_o <= '0 ;
561597 ent_hdr_7_o <= '0 ;
562598 end else begin
563- unique case (command_code)
564- `I3C_BCAST_ENTHDR0 :
565- ent_hdr_0_o <= '1 ;
566- `I3C_BCAST_ENTHDR1 :
567- ent_hdr_1_o <= '1 ;
568- `I3C_BCAST_ENTHDR2 :
569- ent_hdr_2_o <= '1 ;
570- `I3C_BCAST_ENTHDR3 :
571- ent_hdr_3_o <= '1 ;
572- `I3C_BCAST_ENTHDR4 :
573- ent_hdr_4_o <= '1 ;
574- `I3C_BCAST_ENTHDR5 :
575- ent_hdr_5_o <= '1 ;
576- `I3C_BCAST_ENTHDR6 :
577- ent_hdr_6_o <= '1 ;
578- `I3C_BCAST_ENTHDR7 :
579- ent_hdr_7_o <= '1 ;
580- default : begin
581- ent_hdr_0_o <= '0 ;
582- ent_hdr_1_o <= '0 ;
583- ent_hdr_2_o <= '0 ;
584- ent_hdr_3_o <= '0 ;
585- ent_hdr_4_o <= '0 ;
586- ent_hdr_5_o <= '0 ;
587- ent_hdr_6_o <= '0 ;
588- ent_hdr_7_o <= '0 ;
589- end
590- endcase
599+ if (bus_rx_done_i & (state_q == RxTbit) & (ccc_expected_parity == bus_rx_data_i[0 ])) begin
600+ unique case (command_code)
601+ `I3C_BCAST_ENTHDR0 :
602+ ent_hdr_0_o <= '1 ;
603+ `I3C_BCAST_ENTHDR1 :
604+ ent_hdr_1_o <= '1 ;
605+ `I3C_BCAST_ENTHDR2 :
606+ ent_hdr_2_o <= '1 ;
607+ `I3C_BCAST_ENTHDR3 :
608+ ent_hdr_3_o <= '1 ;
609+ `I3C_BCAST_ENTHDR4 :
610+ ent_hdr_4_o <= '1 ;
611+ `I3C_BCAST_ENTHDR5 :
612+ ent_hdr_5_o <= '1 ;
613+ `I3C_BCAST_ENTHDR6 :
614+ ent_hdr_6_o <= '1 ;
615+ `I3C_BCAST_ENTHDR7 :
616+ ent_hdr_7_o <= '1 ;
617+ default : begin
618+ ent_hdr_0_o <= '0 ;
619+ ent_hdr_1_o <= '0 ;
620+ ent_hdr_2_o <= '0 ;
621+ ent_hdr_3_o <= '0 ;
622+ ent_hdr_4_o <= '0 ;
623+ ent_hdr_5_o <= '0 ;
624+ ent_hdr_6_o <= '0 ;
625+ ent_hdr_7_o <= '0 ;
626+ end
627+ endcase
628+ end else if (exit_hdr_i) begin
629+ ent_hdr_0_o <= '0 ;
630+ ent_hdr_1_o <= '0 ;
631+ ent_hdr_2_o <= '0 ;
632+ ent_hdr_3_o <= '0 ;
633+ ent_hdr_4_o <= '0 ;
634+ ent_hdr_5_o <= '0 ;
635+ ent_hdr_6_o <= '0 ;
636+ ent_hdr_7_o <= '0 ;
637+ end
591638 end
592639 end
593640
@@ -605,8 +652,11 @@ module ccc
605652 end
606653 RxTbit: begin
607654 if (bus_rx_done_i) begin
655+ // Check T-bit
656+ if (ccc_expected_parity != bus_rx_data_i[0 ]) begin
657+ state_d = CCCError;
608658 // have defining byte
609- if (have_defining_byte && command_code == `I3C_DIRECT_GETCAPS ) state_d = RxDefByteOrBusCond;
659+ end else if (have_defining_byte && command_code == `I3C_DIRECT_GETCAPS ) state_d = RxDefByteOrBusCond;
610660 else if (have_defining_byte) state_d = RxDefByte;
611661 else begin
612662 // ENTDAA is special
@@ -689,9 +739,10 @@ module ccc
689739 else state_d = WaitForBusCond;
690740 end
691741 else begin
692- if (is_byte_rsvd_addr) state_d = NextCCC;
693- else if ((is_byte_our_addr || is_byte_virtual_addr) && command_rnw && supported_direct_command) state_d = TxData;
694- else if ((is_byte_our_addr || is_byte_virtual_addr) && ~ command_rnw && supported_direct_command) begin
742+ if (is_incorrect_byte_match) state_d = CCCError;
743+ else if (is_byte_rsvd_addr) state_d = NextCCC;
744+ else if ((is_byte_our_addr || is_byte_virtual_addr) && command_rnw && supported_direct_command && ~ direction_error) state_d = TxData;
745+ else if ((is_byte_our_addr || is_byte_virtual_addr) && ~ command_rnw && supported_direct_command && ~ direction_error) begin
695746 if (command_code == `I3C_DIRECT_SETXTIME ) state_d = RxSubCmdByte;
696747 else state_d = RxData;
697748 end else state_d = WaitForBusCond;
@@ -730,6 +781,9 @@ module ccc
730781 DoneCCC: begin
731782 state_d = Idle;
732783 end
784+ CCCError: begin
785+ state_d = Idle;
786+ end
733787 default : begin
734788 end
735789 endcase
@@ -747,6 +801,7 @@ module ccc
747801
748802 done_fsm_o = '0 ;
749803 next_ccc_o = '0 ;
804+ invalid_ccc_o = '0 ;
750805 unique case (state_q)
751806 Idle: begin
752807
@@ -818,6 +873,10 @@ module ccc
818873 DoneCCC: begin
819874 done_fsm_o = '1 ;
820875 end
876+ CCCError: begin
877+ invalid_ccc_o = '1 ;
878+ done_fsm_o = '1 ;
879+ end
821880 default : begin
822881 end
823882 endcase
0 commit comments