spec_mode_feature_tb.vhd 11.2 KB
Newer Older
1
--------------------------------------------------------------------------------
2
-- 
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
3
-- CTU CAN FD IP Core
4 5 6 7
-- Copyright (C) 2015-2018
-- 
-- Authors:
--     Ondrej Ille <ondrej.ille@gmail.com>
8
--     Martin Jerabek <martin.jerabek01@gmail.com>
9 10
-- 
-- Project advisors: 
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
11 12
-- 	Jiri Novak <jnovak@fel.cvut.cz>
-- 	Pavel Pisa <pisa@cmp.felk.cvut.cz>
13
-- 
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
14 15 16
-- Department of Measurement         (http://meas.fel.cvut.cz/)
-- Faculty of Electrical Engineering (http://www.fel.cvut.cz)
-- Czech Technical University        (http://www.cvut.cz/)
17
-- 
18 19 20 21 22
-- 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
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
23
-- Component is furnished to do so, subject to the following conditions:
24
-- 
25
-- The above copyright notice and this permission notice shall be included in
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
26
-- all copies or substantial portions of the Component.
27
-- 
28 29 30 31
-- 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
32
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33
-- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
34
-- IN THE COMPONENT.
35
-- 
36 37
-- 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
38
-- protocol license from Bosch.
39
-- 
40
--------------------------------------------------------------------------------
41

42
--------------------------------------------------------------------------------
43
-- Purpose:
44 45
--  Special modes feature testbench. Verifies behaviour of Self-test mode,
--  Acknowledge forbidden mode and Listen only mode.
46
--
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
--  Test sequence:
--      1. Part 1:
--          1.1 Set STM in Node 1, STM and ACF in Node 2.
--          1.2 Read traffic counters in both nodes.
--          1.3 Start Transmission by Node 1.
--          1.4 Wait until "delim_ack" protocol state of Node 2.
--          1.5 Monitor that all three bits of this state (CRC Delim, ACK,
--              ACK Delim) are recessive on bus (no ACK is sent).
--          1.6 Wait till end of frame. Read traffic counters again.
--          1.7 Check that TX counter was incremented in Node 1 and RX counter
--              was incremented in Node 2.
--      2. Part 2:
--          1.1 Set STM in Node 1, LOM in Node 2.
--          1.2 Read traffic counters in both nodes.
--          1.3 Start Transmission by Node 1.
--          1.4 Wait until "delim_ack" protocol state of Node 2.
--          1.5 Monitor that all three bits of this state (CRC Delim, ACK,
--              ACK Delim) are recessive on bus (no ACK is sent).
--          1.6 Wait till end of frame. Read traffic counters again.
--          1.7 Check that TX counter was incremented in Node 1 and RX counter
--              was incremented in Node 2.
68
--
69 70 71
--------------------------------------------------------------------------------
-- Revision History:
--    24.6.2016   Created file
72
--    06.02.2018  Modified to work with the IP-XACT generated memory map
73 74
--     12.6.2018  Modified to use CAN Test lib functions instead of direct
--                register access.
75
--------------------------------------------------------------------------------
76

77 78
context work.ctu_can_synth_context;
context work.ctu_can_test_context;
79

80
use lib.pkg_feature_exec_dispath.all;
81 82

package spec_mode_feature is
83
    procedure spec_mode_feature_exec(
84
        variable    o               : out    feature_outputs_t;
85
        signal      so              : out    feature_signal_outputs_t;
86
        signal      rand_ctr        : inout  natural range 0 to RAND_POOL_SIZE;
87
        signal      iout            : in     instance_outputs_arr_t;
88 89
        signal      mem_bus         : inout  mem_bus_arr_t;
        signal      bus_level       : in     std_logic
90
    );
91 92 93 94
end package;


package body spec_mode_feature is
95
    procedure spec_mode_feature_exec(
96
        variable    o               : out    feature_outputs_t;
97
        signal      so              : out    feature_signal_outputs_t;
98
        signal      rand_ctr        : inout  natural range 0 to RAND_POOL_SIZE;
99
        signal      iout            : in     instance_outputs_arr_t;
100 101 102
        signal      mem_bus         : inout  mem_bus_arr_t;
        signal      bus_level       : in     std_logic
    ) is
103 104 105 106
        variable ID_1           	:       natural := 1;
        variable ID_2           	:       natural := 2;
        variable CAN_frame          :       SW_CAN_frame_type;
        variable frame_sent         :       boolean := false;
107
        variable mode               :       SW_mode := SW_mode_rst_val;
108 109 110 111
        variable ctr_1_1            :       SW_traffic_counters;
        variable ctr_1_2            :       SW_traffic_counters;
        variable ctr_2_1            :       SW_traffic_counters;
        variable ctr_2_2            :       SW_traffic_counters;
112
        variable pc_state           :       SW_PC_Debug;
113
    begin
114
        o.outcome := true;
115 116 117 118 119 120 121 122

        ------------------------------------------------------------------------
        -- Part 1
        ------------------------------------------------------------------------
        ------------------------------------------------------------------------
        -- Set STM in node 1 and STM, ACF in node 2
        ------------------------------------------------------------------------
        mode.self_test := true;
123
        set_core_mode(mode, ID_1, mem_bus(1));
124 125

        mode.acknowledge_forbidden := true;
126
        set_core_mode(mode, ID_2, mem_bus(2));
127 128 129

        mode.self_test := false;
        mode.acknowledge_forbidden := false;
130

131 132 133
        ------------------------------------------------------------------------
        -- Check the TX RX counters
        ------------------------------------------------------------------------
134 135
        read_traffic_counters(ctr_1_1, ID_1, mem_bus(1));
        read_traffic_counters(ctr_1_2, ID_2, mem_bus(2));
136

137 138 139 140
        ------------------------------------------------------------------------
        -- Send frame by node 1
        ------------------------------------------------------------------------
        CAN_generate_frame(rand_ctr, CAN_frame);
141
        CAN_send_frame(CAN_frame, 1, ID_1, mem_bus(1), frame_sent);
142

143
        ------------------------------------------------------------------------
144 145 146
        -- Wait until Node 2 is in CRC Delimiter. Transmitted bit might still
        -- be DOMINANT since last bit of CRC might be dominant. TX Bit is
        -- updated in SYNC segment. Wait for rising edge on bus_level if so!
147
        ------------------------------------------------------------------------
148
        CAN_wait_pc_state(pc_deb_crc_delim, ID_2, mem_bus(2));
149 150 151
        if (bus_level = DOMINANT) then
            wait until rising_edge(bus_level);
        end if;
152

153 154
        ------------------------------------------------------------------------
        -- Now monitor the bus level to see if it is recessive during whole
155 156 157
        -- CRC Delimim, ACK and ACK Delim. Monitor always on reciever! IN FD
        -- transciever workaround is used for state switching in TX trigger 
        -- just slightly delayed!!!
158
        ------------------------------------------------------------------------
159 160 161
        CAN_read_pc_debug(pc_state, ID_2, mem_bus(2));
        while (pc_state = pc_deb_crc_delim or pc_state = pc_deb_ack or 
               pc_state = pc_deb_ack_delim)
162
        loop
163 164 165
            check(bus_level = RECESSIVE,
                  "CRC Delim, ACK and ACK Delim should be recessive now!");
            CAN_read_pc_debug(pc_state, ID_2, mem_bus(2));
166 167
        end loop;

168
        CAN_wait_bus_idle(ID_1, mem_bus(1));
169 170 171 172

        ------------------------------------------------------------------------
        -- Check the TX RX counters
        ------------------------------------------------------------------------
173 174
        read_traffic_counters(ctr_2_1, ID_1, mem_bus(1));
        read_traffic_counters(ctr_2_2, ID_2, mem_bus(2));
175

176 177
        check(ctr_1_1.tx_frames + 1 = ctr_2_1.tx_frames,
              "TX Frames counter incremented unexpectedly!");
178

179 180
        check(ctr_1_2.rx_frames + 1 = ctr_2_2.rx_frames,
              "RX Frames counter incremented unexpectedly!");
181 182 183 184 185 186 187 188 189 190 191

        ------------------------------------------------------------------------
        -- Part 2
        ------------------------------------------------------------------------
        ------------------------------------------------------------------------
        -- Set STM in node 1 and LOM mode in Node 2. Thisway node 1 does not
        -- expect acknowledge and node 2 reroutes the acknowledge to itself
        -- internally so it gets the acknowledge from itself but it is not on
        -- the bus!
        ------------------------------------------------------------------------
        mode.self_test := true;
192
        set_core_mode(mode, ID_1, mem_bus(1));
193 194 195
        mode.self_test := false;

        mode.listen_only := true;
196
        set_core_mode(mode, ID_2, mem_bus(2));
197 198 199 200 201 202
        mode.listen_only := false;

        ------------------------------------------------------------------------
        -- Send frame by node 1
        ------------------------------------------------------------------------
        CAN_generate_frame(rand_ctr, CAN_frame);
203
        CAN_send_frame(CAN_frame, 1, ID_1, mem_bus(1), frame_sent);
204 205

        ------------------------------------------------------------------------
206 207
        -- Wait until node 2 is in CRC Delimiter field since bus is delayed we
        -- have to wait until the first rising edge on income data!
208
        ------------------------------------------------------------------------
209
        CAN_wait_pc_state(pc_deb_crc_delim, ID_2, mem_bus(2));
210 211 212 213 214 215
        if (bus_level = DOMINANT) then
            wait until rising_edge(bus_level);
        end if;

        ------------------------------------------------------------------------
        -- Now monitor the bus level to see if it is recessive during whole
216
        -- CRC Delim, ACK and ACK Delim field.
217
        ------------------------------------------------------------------------
218 219
        while (pc_state = pc_deb_crc_delim or pc_state = pc_deb_ack or 
               pc_state = pc_deb_ack_delim)
220
        loop
221 222 223
            check(bus_level = RECESSIVE,
                  "CRC Delim, ACK and ACK Delim should be recessive now!");
            CAN_read_pc_debug(pc_state, ID_2, mem_bus(2));
224
        end loop;
225
        CAN_wait_bus_idle(ID_1, mem_bus(1));
226

227 228 229
        ------------------------------------------------------------------------
        -- Check the TX RX counters
        ------------------------------------------------------------------------
230 231
        read_traffic_counters(ctr_2_1, ID_1, mem_bus(1));
        read_traffic_counters(ctr_2_2, ID_2, mem_bus(2));
232

233 234
        check(ctr_1_1.tx_frames + 2 = ctr_2_1.tx_frames,
              "TX Frames counter incremented unexpectedly!");
235

236 237
        check(ctr_1_2.rx_frames + 2 = ctr_2_2.rx_frames,
              "RX Frames counter incremented unexpectedly!");
238

239
  end procedure;
240

241
end package body;