22// Licensed under the Apache License, Version 2.0, see LICENSE for details.
33// SPDX-License-Identifier: Apache-2.0
44
5+ // Base sequence from which all other sequences must be derived. It contains the instantiation of
6+ // the "dut_cfg" class which itself contains all variables relating to the DUT configuration.
7+ // By default, we keep TL transactions random, as this can easily be overridden by derived
8+ // sequences if required, as the constraints are declared "soft".
59class ac_range_check_base_vseq extends cip_base_vseq # (
610 .RAL_T (ac_range_check_reg_block),
711 .CFG_T (ac_range_check_env_cfg),
@@ -13,15 +17,39 @@ class ac_range_check_base_vseq extends cip_base_vseq #(
1317 // Various knobs to enable certain routines
1418 bit do_ac_range_check_init = 1'b1 ;
1519
20+ // Randomized variables
21+ rand tl_main_vars_t tl_main_vars;
22+ rand bit [TL_DW - 1 : 0 ] range_base[NUM_RANGES ]; // Granularity is 32-bit words, 2-LSBs are ignored
23+ rand bit [TL_DW - 1 : 0 ] range_limit[NUM_RANGES ]; // Granularity is 32-bit words, 2-LSBs are ignored
24+ rand range_perm_t range_perm[NUM_RANGES ];
25+ rand racl_policy_t range_racl_policy[NUM_RANGES ];
26+
27+ // Constraints
28+ extern constraint tl_main_vars_c ;
29+
1630 // Standard SV/UVM methods
1731 extern function new (string name= " " );
1832
1933 // Class specific methods
2034 extern task dut_init (string reset_kind = " HARD" );
2135 extern task ac_range_check_init ();
36+ extern task cfg_range_base ();
37+ extern task cfg_range_limit ();
38+ extern task cfg_range_perm ();
39+ extern task cfg_range_racl_policy ();
40+ extern task send_single_tl_unfilt_tr (tl_main_vars_t main_vars);
41+ extern task tl_filt_device_auto_resp (int min_rsp_delay = 0 , int max_rsp_delay = 80 ,
42+ int rsp_abort_pct = 25 , int d_error_pct = 0 , int d_chan_intg_err_pct = 0 );
2243endclass : ac_range_check_base_vseq
2344
2445
46+ constraint ac_range_check_base_vseq :: tl_main_vars_c {
47+ soft tl_main_vars.rand_write == 1 ;
48+ soft tl_main_vars.rand_addr == 1 ;
49+ soft tl_main_vars.rand_mask == 1 ;
50+ soft tl_main_vars.rand_data == 1 ;
51+ }
52+
2553function ac_range_check_base_vseq::new (string name= " " );
2654 super .new (name);
2755endfunction : new
@@ -31,11 +59,88 @@ task ac_range_check_base_vseq::dut_init(string reset_kind = "HARD");
3159 if (do_ac_range_check_init) begin
3260 ac_range_check_init ();
3361 end
62+
63+ // Spawns off a thread to auto-respond to incoming TL accesses on the Filtered host interface.
64+ // Note: the fork is required as the called sequence will loop indefinitely.
65+ fork
66+ tl_filt_device_auto_resp ();
67+ join_none
3468endtask : dut_init
3569
3670task ac_range_check_base_vseq::ac_range_check_init ();
37- bit [TL_DW - 1 : 0 ] tmp_test;
38- csr_wr (.ptr (ral.range_base[0 ]), .value (32'hABCD_1234 ));
39- csr_rd (.ptr (ral.range_base[0 ]), .value (tmp_test));
40- `uvm_info (`gfn , $sformatf (" tmp_test=%0h " , tmp_test), UVM_LOW )
71+ // This fork will ensure that configuration takes place in "disorder", as the TL register
72+ // sequencer will have to deal with parallel requests (and random delays).
73+ fork
74+ cfg_range_base ();
75+ cfg_range_limit ();
76+ cfg_range_perm ();
77+ cfg_range_racl_policy ();
78+ join
79+ // TODO lastly, randomly lock the configuration with RANGE_REGWEN
4180endtask : ac_range_check_init
81+
82+ // Only update registers whose value does not match the new one (usage of set+update instead write)
83+ task ac_range_check_base_vseq::cfg_range_base ();
84+ foreach (range_base[i]) begin
85+ ral.range_base[i].set (range_base[i]);
86+ csr_update (.csr (ral.range_base[i]));
87+ end
88+ endtask : cfg_range_base
89+
90+ task ac_range_check_base_vseq::cfg_range_limit ();
91+ foreach (range_limit[i]) begin
92+ ral.range_limit[i].set (range_limit[i]);
93+ csr_update (.csr (ral.range_limit[i]));
94+ end
95+ endtask : cfg_range_limit
96+
97+ task ac_range_check_base_vseq::cfg_range_perm ();
98+ foreach (range_perm[i]) begin
99+ ral.range_perm[i].set (mubi4_bool_to_mubi (range_perm[i].log_denied_access));
100+ ral.range_perm[i].set (mubi4_bool_to_mubi (range_perm[i].execute_access ));
101+ ral.range_perm[i].set (mubi4_bool_to_mubi (range_perm[i].write_access ));
102+ ral.range_perm[i].set (mubi4_bool_to_mubi (range_perm[i].read_access ));
103+ ral.range_perm[i].set (mubi4_bool_to_mubi (range_perm[i].enable ));
104+ csr_update (.csr (ral.range_perm[i]));
105+ end
106+ endtask : cfg_range_perm
107+
108+ task ac_range_check_base_vseq::cfg_range_racl_policy ();
109+ foreach (range_racl_policy[i]) begin
110+ ral.range_racl_policy_shadowed[i].set (range_racl_policy[i]);
111+ // Shadowed register: the 2 writes are automatically managed by the csr_utils_pkg
112+ csr_update (.csr (ral.range_racl_policy_shadowed[i]));
113+ end
114+ endtask : cfg_range_racl_policy
115+
116+ task ac_range_check_base_vseq::send_single_tl_unfilt_tr (tl_main_vars_t main_vars);
117+ tl_host_single_seq tl_unfilt_host_seq;
118+ `uvm_create_on (tl_unfilt_host_seq, p_sequencer.tl_unfilt_sqr)
119+ `DV_CHECK_RANDOMIZE_WITH_FATAL ( tl_unfilt_host_seq,
120+ (! main_vars.rand_write) - > (write == main_vars.write);
121+ (! main_vars.rand_addr ) - > (addr == main_vars.addr);
122+ (! main_vars.rand_mask ) - > (mask == main_vars.mask);
123+ (! main_vars.rand_data ) - > (data == main_vars.data);)
124+
125+ csr_utils_pkg :: increment_outstanding_access ();
126+ `uvm_info (`gfn , " Starting tl_unfilt_host_seq" , UVM_MEDIUM )
127+ `DV_SPINWAIT (`uvm_send (tl_unfilt_host_seq), " Timed out when sending fetch request" )
128+ csr_utils_pkg :: decrement_outstanding_access ();
129+ endtask : send_single_tl_unfilt_tr
130+
131+ task ac_range_check_base_vseq::tl_filt_device_auto_resp (int min_rsp_delay = 0 ,
132+ int max_rsp_delay = 80 ,
133+ int rsp_abort_pct = 25 ,
134+ int d_error_pct = 0 ,
135+ int d_chan_intg_err_pct = 0 );
136+ cip_tl_device_seq tl_filt_device_seq;
137+ tl_filt_device_seq = cip_tl_device_seq :: type_id :: create (" tl_filt_device_seq" );
138+ tl_filt_device_seq.min_rsp_delay = min_rsp_delay;
139+ tl_filt_device_seq.max_rsp_delay = max_rsp_delay;
140+ tl_filt_device_seq.rsp_abort_pct = rsp_abort_pct;
141+ tl_filt_device_seq.d_error_pct = d_error_pct;
142+ tl_filt_device_seq.d_chan_intg_err_pct = d_chan_intg_err_pct;
143+ `DV_CHECK_RANDOMIZE_FATAL (tl_filt_device_seq)
144+ `uvm_info (`gfn , " Starting tl_filt_device_seq" , UVM_MEDIUM )
145+ tl_filt_device_seq.start (p_sequencer.tl_filt_sqr);
146+ endtask : tl_filt_device_auto_resp
0 commit comments