@@ -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
0 commit comments