txtb_state_feature_tb.vhd 16.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
--------------------------------------------------------------------------------
--
-- CTU CAN FD IP Core
-- Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com>
--
-- Project advisors and co-authors:
-- 	Jiri Novak <jnovak@fel.cvut.cz>
-- 	Pavel Pisa <pisa@cmp.felk.cvut.cz>
-- 	Martin Jerabek <jerabma7@fel.cvut.cz>
-- Department of Measurement         (http://meas.fel.cvut.cz/)
-- Faculty of Electrical Engineering (http://www.fel.cvut.cz)
-- Czech Technical University        (http://www.cvut.cz/)
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this VHDL component and associated documentation files (the "Component"),
-- to deal in the Component without restriction, including without limitation
-- the rights to use, copy, modify, merge, publish, distribute, sublicense,
-- and/or sell copies of the Component, and to permit persons to whom the
-- Component is furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Component.
--
-- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS
-- IN THE COMPONENT.
--
-- The CAN protocol is developed by Robert Bosch GmbH and protected by patents.
-- Anybody who wants to implement this IP core on silicon has to obtain a CAN
-- protocol license from Bosch.
--
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
-- Purpose:
--  Buffer operation feature test. Verifies states of TXT Buffer and application
--  of "set_ready", "set_empty" and "set_abort" commands on TXT Buffer.
--
--  Test sequence:
--      Part 1 (set_empty):
--          1. Generate CAN Frame and insert to Node 1 for transmission.
--          2. Wait till transmission starts. Check that TXT Buffer is in
--             "TX in progress".
--          3. Wait till transmission ends. Check that TXT Buffer is in "Done".
--          4. Send "set_empty" command.
--          5. Verify that TXT Buffer ends up "Empty" state!
--      Part 2 (set_abort):
--          1. Insert CAN Frame to Node 1 and send "set_ready" command.
--          2. Wait till Transmission starts.
--          3. Send "set_abort" command.
--          4. Verify that TX Buffer is in "Abort in Progress".
--          5. Wait till transmission ends.
--          6. Verify that TX Buffer ended up in "Aborted".
--      Part 3 (set_ready, set_abort):
--          1. Insert 1 frame to TXT Buffer "n" of Node 1.
--          2. Send "set_ready" command on TXT Buffer "n".
--          3. Wait till transmission starts.
--          4. Insert the frame into "n+1" TXT Buffer.
--          5. Send "set_ready" command on TXT Buffer "n+1".
--          6. Verify that TXT Buffer "n+1" is in "TX Ready".
--          7. Send "send_abort" command to TXT Buffer "n+1".
--          8. Verify that TXT Buffer is "Aborted". Wait till bus is idle.
--      Part 4 (Error state):
--          1. Configure Retransmitt limit to e.g. 5 on Node 1.
--          2. Forbid Acknowledge on Node 2.
--          3. Erase error counters on Node 1 and Node 2.
--          4. Insert Frame to TXT Buffer of Node 1.
--          4. Give "set_ready" command to Node 1.
--          5. Wait till transmission starts and ends for 5 times. After this
--             amount TXT Buffer with the frame should be in "TX Error".
--      Part 5 (Different TXT Buffers):
--          Repeat Parts 1 to 4 for all TXT Buffers via simple for loop!
--
--      One iteration of this test is enough. This test is namely to improve
--      code coverage for TXT Buffer registers!
--
--------------------------------------------------------------------------------
-- Revision History:
--    11.9.2018   Created file
--------------------------------------------------------------------------------

Library ieee;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.ALL;
USE ieee.math_real.ALL;
use work.CANconstants.all;
USE work.CANtestLib.All;
use work.CAN_FD_frame_format.all;
USE work.randomLib.All;
use work.pkg_feature_exec_dispath.all;

use work.CAN_FD_register_map.all;

package txtb_state_feature is
    procedure txtb_state_feature_exec(
        variable    o               : out    feature_outputs_t;
        signal      so              : out    feature_signal_outputs_t;
        signal      rand_ctr        : inout  natural range 0 to RAND_POOL_SIZE;
        signal      iout            : in     instance_outputs_arr_t;
        signal      mem_bus         : inout  mem_bus_arr_t;
        signal      bus_level       : in     std_logic
    );
end package;


package body txtb_state_feature is
    procedure txtb_state_feature_exec(
        variable    o               : out    feature_outputs_t;
        signal      so              : out    feature_signal_outputs_t;
        signal      rand_ctr        : inout  natural range 0 to RAND_POOL_SIZE;
        signal      iout            : in     instance_outputs_arr_t;
        signal      mem_bus         : inout  mem_bus_arr_t;
        signal      bus_level       : in     std_logic
    ) is
        variable ID_1           	:       natural := 1;
        variable ID_2           	:       natural := 2;
        variable CAN_frame          :       SW_CAN_frame_type;
        variable frame_sent         :       boolean := false;
        variable mode               :       SW_mode := (false, false, false,
                                                false, true, false, false,
                                                false, false, false);
        variable rx_state           :       SW_RX_Buffer_info;
        variable txt_state          :       SW_TXT_Buffer_state_type;
        variable error_counters     :       SW_error_counters := (0, 0, 0, 0);
        variable nxt_buffer         :       natural := 0;
    begin
        o.outcome := true;

        ------------------------------------------------------------------------
        -- Generate CAN Frame to be used during the whole test.
        -- Use RTR frame to make the test shorter.
        -- Wait till the end of unit integration!
137 138
        -- Disable Retransmitt limit Enable, so that TXT Buffers can end up
        -- also in "TX Aborted" state!
139 140 141 142 143
        ------------------------------------------------------------------------
        CAN_generate_frame(rand_ctr, CAN_frame);
        CAN_frame.rtr := RTR_FRAME;
        CAN_frame.frame_format := NORMAL_CAN;
        wait_rand_cycles(rand_ctr, mem_bus(1).clk_sys, 1600, 1601);
144
        CAN_enable_retr_limit(false, 0, ID_1, mem_bus(1));
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223

        for i in 1 to TXT_BUFFER_COUNT loop

            report "Starting TXT Buffer " & integer'image(i) & " test!";

            --------------------------------------------------------------------
            -- Part 1 (set_empty)
            --------------------------------------------------------------------
            report "Starting " & integer'image(i) & ".1";

            --------------------------------------------------------------------
            -- Insert frame to Node 1, Wait until it starts transmitting
            --------------------------------------------------------------------
            CAN_send_frame(CAN_frame, i, ID_1, mem_bus(1), frame_sent);
            CAN_wait_tx_rx_start(true, false, ID_1, mem_bus(1));

            --------------------------------------------------------------------
            -- Check that TXT Buffer state is "TX in progress"
            --------------------------------------------------------------------
            get_tx_buf_state(i, txt_state, ID_1, mem_bus(1));
            if (txt_state /= buf_tx_progress) then
                 -- LCOV_EXCL_START
                o.outcome := false;
                report "TXT Buffer " & integer'image(i) & " is not " &
                       "'TX in Progress' as expected!" severity error;
                -- LCOV_EXCL_STOP
            end if;
            CAN_wait_bus_idle(ID_1, mem_bus(1));

            --------------------------------------------------------------------
            -- Check that TXT Buffer state is "TX Done" after the transmission!
            --------------------------------------------------------------------
            get_tx_buf_state(i, txt_state, ID_1, mem_bus(1));
            if (txt_state /= buf_done) then
                 -- LCOV_EXCL_START
                o.outcome := false;
                report "TXT Buffer " & integer'image(i) & " is not " &
                       "'TX Done' as expected!" severity error;
                -- LCOV_EXCL_STOP
            end if;

            --------------------------------------------------------------------
            -- Issue "set_empty" command and check that buffer is in "Empty"!
            --------------------------------------------------------------------
            send_TXT_buf_cmd(buf_set_empty, i, ID_1, mem_bus(1));
            get_tx_buf_state(i, txt_state, ID_1, mem_bus(1));
            if (txt_state /= buf_empty) then
                 -- LCOV_EXCL_START
                o.outcome := false;
                report "TXT Buffer " & integer'image(i) & " is not " &
                       "'Empty' as expected!" severity error;
                -- LCOV_EXCL_STOP
            end if;


            --------------------------------------------------------------------
            -- Part 2 (set_abort)
            --------------------------------------------------------------------
            report "Starting " & integer'image(i) & ".2";
            --------------------------------------------------------------------
            -- Insert CAN Frame and wait till transmission starts.
            --------------------------------------------------------------------
            CAN_send_frame(CAN_frame, i, ID_1, mem_bus(1), frame_sent);
            CAN_wait_tx_rx_start(true, false, ID_1, mem_bus(1));

            --------------------------------------------------------------------
            -- Send "set_abort" command
            --------------------------------------------------------------------
            send_TXT_buf_cmd(buf_set_abort, i, ID_1, mem_bus(1));
            get_tx_buf_state(i, txt_state, ID_1, mem_bus(1));
            if (txt_state /= buf_ab_progress) then
                 -- LCOV_EXCL_START
                o.outcome := false;
                report "TXT Buffer " & integer'image(i) & " is not " &
                       "'Abort in progress' as expected!" severity error;
                -- LCOV_EXCL_STOP
            end if;

            --------------------------------------------------------------------
224
            -- Forbid ACK on Node 2 (not to end up in TXT OK)!
225 226
            -- Wait till transmission end, check that TXT Buffer is in "Aborted"
            --------------------------------------------------------------------
227 228 229 230
            get_core_mode(mode, ID_2, mem_bus(2));
            mode.acknowledge_forbidden := true;
            set_core_mode(mode, ID_2, mem_bus(2));
            
231 232 233 234 235 236 237 238 239 240
            CAN_wait_bus_idle(ID_1, mem_bus(1));
            get_tx_buf_state(i, txt_state, ID_1, mem_bus(1));
            if (txt_state /= buf_aborted) then
                 -- LCOV_EXCL_START
                o.outcome := false;
                report "TXT Buffer " & integer'image(i) & " is not " &
                       "'Aborted' as expected!" severity error;
                -- LCOV_EXCL_STOP
            end if;

241 242 243 244 245 246 247
            --------------------------------------------------------------------
            -- Allow ACK Again for Node 2.
            --------------------------------------------------------------------
            mode.acknowledge_forbidden := false;
            set_core_mode(mode, ID_2, mem_bus(2));
            

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337

            --------------------------------------------------------------------
            -- Part 3 (set_ready)
            --------------------------------------------------------------------
            report "Starting " & integer'image(i) & ".3";
            --------------------------------------------------------------------
            -- Send CAN Frame by Node 1, TXT Buffer i.
            -- Wait till transmission starts!
            --------------------------------------------------------------------
            CAN_send_frame(CAN_frame, i, ID_1, mem_bus(1), frame_sent);
            CAN_wait_tx_rx_start(true, false, ID_1, mem_bus(1));

            --------------------------------------------------------------------
            -- Insert CAN Frame to Node 1, TXT Buffer i + 1.
            -- Send "set_ready" command.
            --------------------------------------------------------------------
            nxt_buffer := ((i + 1) mod TXT_BUFFER_COUNT) + 1;
            CAN_insert_TX_frame(CAN_frame, nxt_buffer, ID_1, mem_bus(1));
            send_TXT_buf_cmd(buf_set_ready, nxt_buffer, ID_1, mem_bus(1));

            --------------------------------------------------------------------
            -- Check that Buffer "n+1" is in "TX Ready"!
            --------------------------------------------------------------------
            get_tx_buf_state(nxt_buffer, txt_state, ID_1, mem_bus(1));
            if (txt_state /= buf_ready) then
                 -- LCOV_EXCL_START
                o.outcome := false;
                report "TXT Buffer " &
                        integer'image(nxt_buffer) &
                       " is not 'TX Ready' as expected!" severity error;
                -- LCOV_EXCL_STOP
            end if;

            --------------------------------------------------------------------
            -- Send "set_abort" command on Buffer "n+1" and check that
            -- TXT Buffer ends up in "Aborted" state. 
            --------------------------------------------------------------------
            send_TXT_buf_cmd(buf_set_abort, nxt_buffer, ID_1, mem_bus(1));
            if (txt_state /= buf_aborted) then
                 -- LCOV_EXCL_START
                o.outcome := false;
                report "TXT Buffer " &
                       integer'image(nxt_buffer) &
                       " is not 'Aborted' as expected!" severity error;
                -- LCOV_EXCL_STOP
            end if;
            CAN_wait_bus_idle(ID_1, mem_bus(1));



            --------------------------------------------------------------------
            -- Part 4 (Error state)
            --------------------------------------------------------------------
            report "Starting " & integer'image(i) & ".4";
            --------------------------------------------------------------------
            -- Set "ACF" - Acknowledge forbidden on Node 2.
            -- Set Retransmitt limit to 5 on Node 1.
            --------------------------------------------------------------------
            get_core_mode(mode, ID_2, mem_bus(2));
            mode.acknowledge_forbidden := true;
            set_core_mode(mode, ID_2, mem_bus(2));
            CAN_enable_retr_limit(true, 5, ID_1, mem_bus(1));
        
            --------------------------------------------------------------------
            -- Erase error counters on both nodes.
            --------------------------------------------------------------------
            set_error_counters(error_counters, ID_1, mem_bus(1));
            set_error_counters(error_counters, ID_2, mem_bus(2));

            --------------------------------------------------------------------
            -- Send frame from Node 1. Wait till the frame is retransmitted
            -- 5 times!
            --------------------------------------------------------------------
            CAN_send_frame(CAN_frame, i, ID_1, mem_bus(1), frame_sent);
            for i in 0 to 4 loop
                CAN_wait_tx_rx_start(true, false, ID_1, mem_bus(1));
                CAN_wait_bus_idle(ID_1, mem_bus(1));
            end loop;

            --------------------------------------------------------------------
            -- Check that state of TXT Buffer is "TX Failed".
            --------------------------------------------------------------------
            get_tx_buf_state(i, txt_state, ID_1, mem_bus(1));
            if (txt_state /= buf_failed) then
                 -- LCOV_EXCL_START
                o.outcome := false;
                report "TXT Buffer " & integer'image(i) &
                       " is not 'TX Failed' as expected!" severity error;
                -- LCOV_EXCL_STOP
            end if;
338 339 340 341 342 343 344

            --------------------------------------------------------------------
            -- Allow ACK Again for Node 2.
            --------------------------------------------------------------------
            mode.acknowledge_forbidden := false;
            set_core_mode(mode, ID_2, mem_bus(2));

345 346 347 348 349
        end loop;

  end procedure;

end package body;