@@ -20,6 +20,7 @@ use work.sync_pkg.all;
2020
2121library osvvm;
2222use osvvm.RandomPkg.all ;
23+ use osvvm.CoveragePkg.all ;
2324
2425entity tb_axi_stream is
2526 generic (
@@ -133,6 +134,7 @@ begin
133134 variable previous_inactive_policy : inactive_bus_policy_t := 'X' ;
134135 variable inactive_policy_read_back : inactive_bus_policy_t;
135136 variable loop_count : natural := 0 ;
137+ variable cov : CoverageIDType;
136138
137139 impure function select_policy(
138140 modified_signal, signal_to_check : axi_stream_signal_t;
@@ -154,33 +156,86 @@ begin
154156 check(is_already_handled(msg_type));
155157 end ;
156158
157- procedure check(inactive_data, packet_data : std_logic_vector ; inactive_policy : inactive_bus_policy_t) is
159+ function to_sl(policy : inactive_bus_policy_t) return std_logic is
158160 begin
159- if inactive_policy = '0' then
160- check_equal(inactive_data, std_logic_vector '((inactive_data'range => '0' )));
161- elsif inactive_policy = '1' then
162- check_equal(inactive_data, std_logic_vector '((inactive_data'range => '1' )));
163- elsif inactive_policy = 'X' then
164- check_equal(inactive_data, std_logic_vector '((inactive_data'range => 'X' )));
165- elsif inactive_policy = hold then
161+ if policy = '0' then
162+ return '0' ;
163+ elsif policy = '1' then
164+ return '1' ;
165+ elsif policy = 'X' then
166+ return 'X' ;
167+ end if ;
168+
169+ check_failed(" Cannot convert inactive_bus_policy " & inactive_bus_policy_t'image (policy) & " to std_logic." );
170+ return 'U' ;
171+ end ;
172+
173+ procedure check(
174+ add_to_coverage : boolean ;
175+ inactive_data, packet_data : std_logic ;
176+ inactive_policy : inactive_bus_policy_t
177+ ) is
178+ begin
179+ if inactive_policy = hold then
166180 check_equal(inactive_data, packet_data);
181+ elsif inactive_policy = rand01 then
182+ check_not_unknown(inactive_data);
167183 else
168- check_failed;
184+ check_equal(inactive_data, to_sl(inactive_policy));
185+ end if ;
186+
187+ if add_to_coverage then
188+ if inactive_policy = rand01 then
189+ -- Randomized bits should cover '0' (bin 0) and '1' (bin 1).
190+ ICover(cov, to_integer (inactive_data));
191+ else
192+ -- Non-randomized bits are immediately covered.
193+ ICover(cov, 0 );
194+ ICover(cov, 1 );
195+ end if ;
169196 end if ;
170197 end ;
171198
172- procedure check(inactive_data, packet_data : std_logic ; inactive_policy : inactive_bus_policy_t) is
199+ procedure check(
200+ add_to_coverage : boolean ;
201+ inactive_data, packet_data : std_logic_vector ;
202+ inactive_policy : inactive_bus_policy_t
203+ ) is
173204 begin
174- if inactive_policy = '0' then
175- check_equal(inactive_data, '0' );
176- elsif inactive_policy = '1' then
177- check_equal(inactive_data, '1' );
178- elsif inactive_policy = 'X' then
179- check_equal(inactive_data, 'X' );
180- elsif inactive_policy = hold then
205+ if inactive_data'length = 1 then
206+ check(
207+ add_to_coverage,
208+ inactive_data(inactive_data'left ),
209+ packet_data(packet_data'left ),
210+ inactive_policy
211+ );
212+ return ;
213+ end if ;
214+
215+ if inactive_policy = hold then
181216 check_equal(inactive_data, packet_data);
217+ elsif inactive_policy = rand01 then
218+ check_not_unknown(inactive_data);
182219 else
183- check_failed;
220+ check_equal(inactive_data, std_logic_vector '((inactive_data'range => to_sl(inactive_policy))));
221+ end if ;
222+
223+ if add_to_coverage then
224+ if inactive_policy = rand01 then
225+ -- Randomized vectors should cover values whose bits are not all the same (bin 0), and
226+ -- not the packet data (bin 1).
227+ if inactive_data /= (inactive_data'range => '0' ) and inactive_data /= (inactive_data'range => '1' ) then
228+ ICover(cov, 0 );
229+ end if ;
230+
231+ if inactive_data /= packet_data then
232+ ICover(cov, 1 );
233+ end if ;
234+ else
235+ -- Non-randomized vectors are immediately covered.
236+ ICover(cov, 0 );
237+ ICover(cov, 1 );
238+ end if ;
184239 end if ;
185240 end ;
186241
@@ -777,6 +832,7 @@ begin
777832 disable(get_logger(" monitor:rule 10" ), error );
778833 disable(get_logger(" master:rule 10" ), error );
779834 disable(get_logger(" slave:rule 10" ), error );
835+
780836 for inactive_policy in inactive_bus_policy_t'left to inactive_bus_policy_t'right loop
781837 for axi_stream_signal in work.axi_stream_pkg.tuser downto work.axi_stream_pkg.tdata loop
782838 set_inactive_axi_stream_policy(net, master_axi_stream, inactive_policy, axi_stream_signal);
@@ -788,71 +844,76 @@ begin
788844 tid => x"11" , tdest => x"22" , tuser => x"33"
789845 );
790846 last := '1' when axi_stream_transaction.tlast else '0' ;
791- push_axi_stream(
792- net,
793- master_axi_stream,
794- tdata => axi_stream_transaction.tdata,
795- tlast => last,
796- tkeep => axi_stream_transaction.tkeep,
797- tstrb => axi_stream_transaction.tstrb,
798- tid => axi_stream_transaction.tid,
799- tdest => axi_stream_transaction.tdest,
800- tuser => axi_stream_transaction.tuser
801- );
802847
803- pop_axi_stream(net, slave_axi_stream, data, last, keep, strb, id, dest, user);
804- wait until rising_edge (aclk);
805- for sig in work.axi_stream_pkg.tdata to work.axi_stream_pkg.tuser loop
806- case sig is
807- when work.axi_stream_pkg.tdata =>
808- check(
809- tdata,
810- axi_stream_transaction.tdata,
811- select_policy(axi_stream_signal, work.axi_stream_pkg.tdata, inactive_policy, previous_inactive_policy)
812- );
813- when work.axi_stream_pkg.tlast =>
814- check(
815- tlast,
816- last,
817- select_policy(axi_stream_signal, work.axi_stream_pkg.tlast, inactive_policy, previous_inactive_policy)
818- );
819- when work.axi_stream_pkg.tkeep =>
820- check(
821- tkeep,
822- axi_stream_transaction.tkeep,
823- select_policy(axi_stream_signal, work.axi_stream_pkg.tkeep, inactive_policy, previous_inactive_policy)
824- );
825- when work.axi_stream_pkg.tstrb =>
826- check(
827- tstrb,
828- axi_stream_transaction.tstrb,
829- select_policy(axi_stream_signal, work.axi_stream_pkg.tstrb, inactive_policy, previous_inactive_policy)
830- );
831- when work.axi_stream_pkg.tid =>
832- check(
833- tid,
834- axi_stream_transaction.tid,
835- select_policy(axi_stream_signal, work.axi_stream_pkg.tid, inactive_policy, previous_inactive_policy)
836- );
837- when work.axi_stream_pkg.tdest =>
838- check(
839- tdest,
840- axi_stream_transaction.tdest,
841- select_policy(axi_stream_signal, work.axi_stream_pkg.tdest, inactive_policy, previous_inactive_policy)
842- );
843- when work.axi_stream_pkg.tuser =>
844- check(
845- tuser,
846- axi_stream_transaction.tuser,
847- select_policy(axi_stream_signal, work.axi_stream_pkg.tuser, inactive_policy, previous_inactive_policy)
848- );
849- end case ;
850- loop_count := loop_count + 1 ;
848+ cov := NewID(
849+ axi_stream_signal_t'image (axi_stream_signal) & "_" &
850+ inactive_bus_policy_t'image (inactive_policy)
851+ );
852+ AddBins(cov, GenBin(0 ,1 ));
853+
854+ while not IsCovered(cov) loop
855+ push_axi_stream(
856+ net,
857+ master_axi_stream,
858+ tdata => axi_stream_transaction.tdata,
859+ tlast => last,
860+ tkeep => axi_stream_transaction.tkeep,
861+ tstrb => axi_stream_transaction.tstrb,
862+ tid => axi_stream_transaction.tid,
863+ tdest => axi_stream_transaction.tdest,
864+ tuser => axi_stream_transaction.tuser
865+ );
866+ pop_axi_stream(net, slave_axi_stream, data, last, keep, strb, id, dest, user);
867+ wait until rising_edge (aclk);
868+
869+ check(
870+ axi_stream_signal = work.axi_stream_pkg.tdata,
871+ tdata,
872+ axi_stream_transaction.tdata,
873+ select_policy(axi_stream_signal, work.axi_stream_pkg.tdata, inactive_policy, previous_inactive_policy)
874+ );
875+ check(
876+ axi_stream_signal = work.axi_stream_pkg.tlast,
877+ tlast,
878+ last,
879+ select_policy(axi_stream_signal, work.axi_stream_pkg.tlast, inactive_policy, previous_inactive_policy)
880+ );
881+ check(
882+ axi_stream_signal = work.axi_stream_pkg.tkeep,
883+ tkeep,
884+ axi_stream_transaction.tkeep,
885+ select_policy(axi_stream_signal, work.axi_stream_pkg.tkeep, inactive_policy, previous_inactive_policy)
886+ );
887+ check(
888+ axi_stream_signal = work.axi_stream_pkg.tstrb,
889+ tstrb,
890+ axi_stream_transaction.tstrb,
891+ select_policy(axi_stream_signal, work.axi_stream_pkg.tstrb, inactive_policy, previous_inactive_policy)
892+ );
893+ check(
894+ axi_stream_signal = work.axi_stream_pkg.tid,
895+ tid,
896+ axi_stream_transaction.tid,
897+ select_policy(axi_stream_signal, work.axi_stream_pkg.tid, inactive_policy, previous_inactive_policy)
898+ );
899+ check(
900+ axi_stream_signal = work.axi_stream_pkg.tdest,
901+ tdest,
902+ axi_stream_transaction.tdest,
903+ select_policy(axi_stream_signal, work.axi_stream_pkg.tdest, inactive_policy, previous_inactive_policy)
904+ );
905+ check(
906+ axi_stream_signal = work.axi_stream_pkg.tuser,
907+ tuser,
908+ axi_stream_transaction.tuser,
909+ select_policy(axi_stream_signal, work.axi_stream_pkg.tuser, inactive_policy, previous_inactive_policy)
910+ );
851911 end loop ;
912+ loop_count := loop_count + 1 ;
852913 end loop ;
853914 previous_inactive_policy := inactive_policy;
854915 end loop ;
855- check_equal(loop_count, 4 * 7 * 7 );
916+ check_equal(loop_count, 5 * 7 );
856917
857918 elsif run(" test global inactive bus policy" ) then
858919 for inactive_policy in inactive_bus_policy_t' (' 0 ') to inactive_bus_policy_t' (' 1 ') loop
@@ -878,27 +939,16 @@ begin
878939
879940 pop_axi_stream(net, slave_axi_stream, data, last, keep, strb, id, dest, user);
880941 wait until rising_edge (aclk);
881- for sig in work.axi_stream_pkg.tdata to work.axi_stream_pkg.tuser loop
882- case sig is
883- when work.axi_stream_pkg.tdata =>
884- check(tdata, " " , inactive_policy);
885- when work.axi_stream_pkg.tlast =>
886- check(tlast, '-' , inactive_policy);
887- when work.axi_stream_pkg.tkeep =>
888- check(tkeep, " " , inactive_policy);
889- when work.axi_stream_pkg.tstrb =>
890- check(tstrb, " " , inactive_policy);
891- when work.axi_stream_pkg.tid =>
892- check(tid, " " , inactive_policy);
893- when work.axi_stream_pkg.tdest =>
894- check(tdest, " " , inactive_policy);
895- when work.axi_stream_pkg.tuser =>
896- check(tuser, " " , inactive_policy);
897- end case ;
898- loop_count := loop_count + 1 ;
899- end loop ;
942+ check(false , tdata, " " , inactive_policy);
943+ check(false , tlast, '-' , inactive_policy);
944+ check(false , tkeep, " " , inactive_policy);
945+ check(false , tstrb, " " , inactive_policy);
946+ check(false , tid, " " , inactive_policy);
947+ check(false , tdest, " " , inactive_policy);
948+ check(false , tuser, " " , inactive_policy);
949+ loop_count := loop_count + 1 ;
900950 end loop ;
901- check_equal(loop_count, 2 * 7 );
951+ check_equal(loop_count, 2 );
902952 end if ;
903953 test_runner_cleanup(runner, allow_disabled_errors => running_test_case = " test signal inactive bus policy" );
904954 end process ;
0 commit comments