OpenCores
URL https://opencores.org/ocsvn/pcie_ds_dma/pcie_ds_dma/trunk

Subversion Repositories pcie_ds_dma

[/] [pcie_ds_dma/] [trunk/] [core/] [ds_dma64/] [pcie_src/] [pcie_core64_m1/] [source_artix7/] [cl_a7pcie_x4_axi_basic_tx_thrtl_ctl.vhd] - Blame information for rev 49

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 46 dsmv
-------------------------------------------------------------------------------
2
--
3
-- (c) Copyright 2010-2011 Xilinx, Inc. All rights reserved.
4
--
5
-- This file contains confidential and proprietary information
6
-- of Xilinx, Inc. and is protected under U.S. and
7
-- international copyright and other intellectual property
8
-- laws.
9
--
10
-- DISCLAIMER
11
-- This disclaimer is not a license and does not grant any
12
-- rights to the materials distributed herewith. Except as
13
-- otherwise provided in a valid license issued to you by
14
-- Xilinx, and to the maximum extent permitted by applicable
15
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
16
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
17
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
18
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
19
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
20
-- (2) Xilinx shall not be liable (whether in contract or tort,
21
-- including negligence, or under any other theory of
22
-- liability) for any loss or damage of any kind or nature
23
-- related to, arising under or in connection with these
24
-- materials, including for any direct, or any indirect,
25
-- special, incidental, or consequential loss or damage
26
-- (including loss of data, profits, goodwill, or any type of
27
-- loss or damage suffered as a result of any action brought
28
-- by a third party) even if such damage or loss was
29
-- reasonably foreseeable or Xilinx had been advised of the
30
-- possibility of the same.
31
--
32
-- CRITICAL APPLICATIONS
33
-- Xilinx products are not designed or intended to be fail-
34
-- safe, or for use in any application requiring fail-safe
35
-- performance, such as life-support or safety devices or
36
-- systems, Class III medical devices, nuclear facilities,
37
-- applications related to the deployment of airbags, or any
38
-- other applications that could lead to death, personal
39
-- injury, or severe property or environmental damage
40
-- (individually and collectively, "Critical
41
-- Applications"). Customer assumes the sole risk and
42
-- liability of any use of Xilinx products in Critical
43
-- Applications, subject only to applicable laws and
44
-- regulations governing limitations on product liability.
45
--
46
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
47
-- PART OF THIS FILE AT ALL TIMES.
48
--
49
-------------------------------------------------------------------------------
50
-- Project    : Series-7 Integrated Block for PCI Express
51
-- File       : cl_a7pcie_x4_axi_basic_tx_thrtl_ctl.vhd
52 49 dsmv
-- Version    : 1.11
53 46 dsmv
--
54
-- Description:
55
--    TX throttle controller. Anticipates back-pressure from PCIe block and
56
--      preemptively back-pressures user design (packet boundary throttling).
57
--
58
--      Notes:
59
--      Optional notes section.
60
--
61
--      Hierarchical:
62
--        axi_basic_top
63
--          axi_basic_tx
64
--            axi_basic_tx_thrtl_ctl
65
--------------------------------------------------------------------------------
66
-- Library Declarations
67
--------------------------------------------------------------------------------
68
 
69
LIBRARY ieee;
70
  USE ieee.std_logic_1164.all;
71
  USE ieee.std_logic_unsigned.all;
72
 
73
 
74
ENTITY cl_a7pcie_x4_axi_basic_tx_thrtl_ctl IS
75
  GENERIC (
76
    C_DATA_WIDTH              : INTEGER := 128;      -- RX/TX interface data width
77
    C_FAMILY                  : STRING := "X7";      -- Targeted FPGA family
78
    C_ROOT_PORT               : BOOLEAN := FALSE;   -- PCIe block is in root port mode
79
    TCQ                       : INTEGER := 1         -- Clock to Q time
80
  );
81
  PORT (
82
    -- AXI TX
83
    -------------
84
    S_AXIS_TX_TDATA           : IN STD_LOGIC_VECTOR(C_DATA_WIDTH - 1 DOWNTO 0)  := (OTHERS=>'0'); -- TX data from user
85
    S_AXIS_TX_TVALID          : IN STD_LOGIC                     := '0';    -- TX data is valid
86
    S_AXIS_TX_TUSER           : IN STD_LOGIC_VECTOR(3 DOWNTO 0)  := "0000"; -- TX user signals
87
    S_AXIS_TX_TLAST           : IN STD_LOGIC                     := '0';    -- TX data is last
88
 
89
    -- User Misc.
90
    -------------
91
    USER_TURNOFF_OK           : IN STD_LOGIC                     := '0';    -- Turnoff OK from user
92
    USER_TCFG_GNT             : IN STD_LOGIC                     := '0';    -- Send cfg OK from user
93
 
94
    -- TRN TX
95
    -------------
96
    TRN_TBUF_AV               : IN STD_LOGIC_VECTOR(5 DOWNTO 0)  := "000000"; -- TX buffers available
97
    TRN_TDST_RDY              : IN STD_LOGIC                     := '0';     -- TX destination ready
98
 
99
    -- TRN Misc.
100
    -------------
101
    TRN_TCFG_REQ              : IN STD_LOGIC                     := '0';     -- TX config request
102
    TRN_TCFG_GNT              : OUT STD_LOGIC                    ;--:= '0';     -- TX config grant
103
    TRN_LNK_UP                : IN STD_LOGIC                     := '0';     -- PCIe link up
104
 
105
    -- 7 Series/Virtex6 PM
106
    -------------
107
    CFG_PCIE_LINK_STATE       : IN STD_LOGIC_VECTOR(2 DOWNTO 0)  := "000";    -- Encoded PCIe link state
108
 
109
    -- Virtex6 PM
110
    -------------
111
    CFG_PM_SEND_PME_TO        : IN STD_LOGIC                     := '0';              -- PM send PME turnoff msg
112
    CFG_PMCSR_POWERSTATE      : IN STD_LOGIC_VECTOR(1 DOWNTO 0)  := "00";             -- PMCSR power state
113
    TRN_RDLLP_DATA            : IN STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00000000";      -- RX DLLP data
114
    TRN_RDLLP_SRC_RDY         : IN STD_LOGIC                     := '0';              -- RX DLLP source ready
115
 
116
    -- Virtex6/Spartan6 PM
117
    -------------
118
    CFG_TO_TURNOFF            : IN STD_LOGIC                     := '0';    -- Turnoff request
119
    CFG_TURNOFF_OK            : OUT STD_LOGIC                    ;--:= '0';    -- Turnoff grant
120
 
121
    -- System
122
    -------------
123
    TREADY_THRTL              : OUT STD_LOGIC                    ;--:= '0';   -- TREADY to pipeline
124
    USER_CLK                  : IN STD_LOGIC                     := '0';   -- user clock from block
125
    USER_RST                  : IN STD_LOGIC                     := '0'    -- user reset from block
126
  );
127
END cl_a7pcie_x4_axi_basic_tx_thrtl_ctl;
128
 
129
ARCHITECTURE trans OF cl_a7pcie_x4_axi_basic_tx_thrtl_ctl IS
130
 
131
  function tbuf_av_min_fn (
132
    constant wdt   : integer)
133
    return integer is
134
    variable buf_min : integer := 1;
135
  begin  -- tbuf_av_min_fn
136
 
137
    if (wdt = 128) then
138
      buf_min := 5;
139
    elsif (wdt = 64) then
140
      buf_min := 1;
141
    else
142
      buf_min := 0;
143
    end if;
144
    return buf_min;
145
  end tbuf_av_min_fn;
146
 
147
  function tbuf_gap_time_fn (
148
    constant wdt   : integer)
149
    return integer is
150
    variable gap_time : integer := 1;
151
  begin  -- tbuf_gap_time_fn
152
 
153
    if (wdt = 128) then
154
      gap_time := 4;
155
    else
156
      gap_time := 1;
157
    end if;
158
    return gap_time;
159
  end tbuf_gap_time_fn;
160
 
161
  -- Thrtl user when TBUF hits this val
162
  CONSTANT TBUF_AV_MIN               : INTEGER :=  tbuf_av_min_fn(C_DATA_WIDTH);
163
 
164
  -- Pause user when TBUF hits this val
165
  CONSTANT TBUF_AV_GAP               : INTEGER :=  TBUF_AV_MIN + 1;
166
 
167
  -- GAP pause time - the latency from the time a packet is accepted on the TRN
168
  -- interface to the time trn_tbuf_av from the Block will decrement.
169
  CONSTANT TBUF_GAP_TIME             : INTEGER :=  tbuf_gap_time_fn(C_DATA_WIDTH);
170
 
171
  -- Latency time from when tcfg_gnt is asserted to when PCIe block will throttle
172
  CONSTANT TCFG_LATENCY_TIME         : INTEGER :=  2;
173
 
174
  -- Number of pipeline stages to delay trn_tcfg_gnt. For V6 128-bit only
175
  CONSTANT TCFG_GNT_PIPE_STAGES      : INTEGER :=  3;
176
 
177
  CONSTANT LINKSTATE_L0              : INTEGER := 0;
178
  CONSTANT LINKSTATE_PPM_L1          : INTEGER := 1;
179
  CONSTANT LINKSTATE_PPM_L1_TRANS    : INTEGER := 5;
180
  CONSTANT LINKSTATE_PPM_L23R_TRANS  : INTEGER := 6;
181
  CONSTANT PM_ENTER_L1               : INTEGER := 32;
182
  CONSTANT POWERSTATE_D0             : INTEGER := 0;
183
 
184 49 dsmv
  SIGNAL lnk_up_thrtl           : STD_LOGIC:= '0';
185
  SIGNAL lnk_up_trig            : STD_LOGIC:= '0';
186
  SIGNAL lnk_up_exit            : STD_LOGIC:= '0';
187
  SIGNAL tbuf_av_min_thrtl      : STD_LOGIC:= '0';
188
  SIGNAL tbuf_av_min_trig       : STD_LOGIC:= '0';
189
  SIGNAL tbuf_av_gap_thrtl      : STD_LOGIC:= '0';
190
  SIGNAL tbuf_gap_cnt           : STD_LOGIC_VECTOR(2 DOWNTO 0):= (others => '0');
191
  SIGNAL tbuf_gap_cnt_t         : STD_LOGIC_VECTOR(2 DOWNTO 0):= (others => '0');
192
  SIGNAL tbuf_av_gap_trig       : STD_LOGIC:= '0';
193
  SIGNAL tbuf_av_gap_exit       : STD_LOGIC:= '0';
194
  SIGNAL gap_trig_tlast         : STD_LOGIC:= '0';
195
  SIGNAL gap_trig_tlast_1       : STD_LOGIC:= '0';
196
  SIGNAL gap_trig_decr          : STD_LOGIC:= '0';
197
  SIGNAL gap_trig_decr_1        : STD_LOGIC:= '0';
198
  SIGNAL gap_trig_decr_2        : STD_LOGIC:= '0';
199
  SIGNAL tbuf_av_d              : STD_LOGIC_VECTOR(5 DOWNTO 0):= (others => '0');
200
  SIGNAL tcfg_req_thrtl         : STD_LOGIC:= '0';
201
  SIGNAL tcfg_req_cnt           : STD_LOGIC_VECTOR(1 DOWNTO 0):= (others => '0');
202
  SIGNAL trn_tdst_rdy_d         : STD_LOGIC:= '0';
203
  SIGNAL tcfg_req_trig          : STD_LOGIC:= '0';
204
  SIGNAL tcfg_req_exit          : STD_LOGIC:= '0';
205
  SIGNAL tcfg_gnt_log           : STD_LOGIC:= '0';
206
  SIGNAL tcfg_gnt_pipe          : STD_LOGIC_VECTOR(TCFG_GNT_PIPE_STAGES-1 DOWNTO 0):= (others => '0');
207
  SIGNAL pre_throttle           : STD_LOGIC:= '0';
208
  SIGNAL reg_throttle           : STD_LOGIC:= '0';
209
  SIGNAL exit_crit              : STD_LOGIC:= '0';
210
  SIGNAL reg_tcfg_gnt           : STD_LOGIC:= '0';
211
  SIGNAL trn_tcfg_req_d         : STD_LOGIC:= '0';
212
  SIGNAL tcfg_gnt_pending       : STD_LOGIC:= '0';
213
  SIGNAL wire_to_turnoff        : STD_LOGIC:= '0';
214
  SIGNAL reg_turnoff_ok         : STD_LOGIC:= '0';
215
  SIGNAL tready_thrtl_mux       : STD_LOGIC:= '0';
216
  SIGNAL ppm_L1_thrtl           : STD_LOGIC:= '0';
217
  SIGNAL ppm_L1_trig            : STD_LOGIC:= '0';
218
  SIGNAL ppm_L1_exit            : STD_LOGIC:= '0';
219
  SIGNAL cfg_pcie_link_state_d  : STD_LOGIC_VECTOR(2 DOWNTO 0):= (others => '0');
220
  SIGNAL trn_rdllp_src_rdy_d    : STD_LOGIC:= '0';
221
  SIGNAL ppm_L23_thrtl          : STD_LOGIC:= '0';
222
  SIGNAL ppm_L23_trig           : STD_LOGIC:= '0';
223
  SIGNAL cfg_turnoff_ok_pending : STD_LOGIC:= '0';
224
  SIGNAL reg_tlast              : STD_LOGIC:= '0';
225
  SIGNAL cur_state              : STD_LOGIC:= '0';
226
  SIGNAL next_state             : STD_LOGIC:= '0';
227 46 dsmv
 
228 49 dsmv
  SIGNAL reg_axi_in_pkt         : STD_LOGIC:= '0';
229
  SIGNAL axi_in_pkt             : STD_LOGIC:= '0';
230
  SIGNAL axi_pkt_ending         : STD_LOGIC:= '0';
231
  SIGNAL axi_throttled          : STD_LOGIC:= '0';
232
  SIGNAL axi_thrtl_ok           : STD_LOGIC:= '0';
233
  SIGNAL tx_ecrc_pause          : STD_LOGIC:= '0';
234 46 dsmv
 
235 49 dsmv
  SIGNAL gap_trig_tcfg          : STD_LOGIC:= '0';
236
  SIGNAL reg_to_turnoff         : STD_LOGIC:= '0';
237
  SIGNAL reg_tx_ecrc_pkt        : STD_LOGIC:= '0';
238 46 dsmv
 
239 49 dsmv
  SIGNAL tx_ecrc_pkt            : STD_LOGIC:= '0';
240
  SIGNAL packet_fmt             : STD_LOGIC_VECTOR(1 DOWNTO 0):= (others => '0');
241
  SIGNAL packet_td              : STD_LOGIC:= '0';
242
  SIGNAL header_len             : STD_LOGIC_VECTOR(2 DOWNTO 0):= (others => '0');
243
  SIGNAL payload_len            : STD_LOGIC_VECTOR(9 DOWNTO 0):= (others => '0');
244
  SIGNAL packet_len             : STD_LOGIC_VECTOR(13 DOWNTO 0):= (others => '0');
245
  SIGNAL pause_needed           : STD_LOGIC:= '0';
246 46 dsmv
 
247
  -- Declare intermediate signals for referenced outputs
248 49 dsmv
  SIGNAL cfg_turnoff_ok_xhdl0   : STD_LOGIC:= '0';
249
  SIGNAL tready_thrtl_xhdl1     : STD_LOGIC:= '0';
250 46 dsmv
--   TYPE T_STATE is  (IDLE_A,THROTTLE);
251
--   SIGNAL CUR_STATE_A, NEXT_STATE_A : T_STATE;
252 49 dsmv
  SIGNAL CUR_STATE_A, NEXT_STATE_A : STD_LOGIC := '0';
253 46 dsmv
 
254
  constant IDLE : std_logic := '0';
255
  constant THROTTLE : std_logic := '1';
256
 
257
BEGIN
258
  -- Drive referenced outputs
259
  CFG_TURNOFF_OK   <= cfg_turnoff_ok_xhdl0;
260
  TREADY_THRTL     <= tready_thrtl_xhdl1;
261
   --------------------------------------------------------------------------------
262
   -- THROTTLE REASON: PCIe link is down                                         --
263
   --   - When to throttle: trn_lnk_up deasserted                                --
264
   --   - When to stop: trn_tdst_rdy assesrted                                   --
265
   --------------------------------------------------------------------------------
266
  lnk_up_trig      <= NOT(TRN_LNK_UP);
267
  lnk_up_exit      <= TRN_TDST_RDY;
268
 
269
  PROCESS (USER_CLK)
270
  BEGIN
271
    IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
272
      IF (USER_RST = '1') THEN
273
        lnk_up_thrtl <= '1'  AFTER (TCQ)*1 ps;
274
      ELSE
275
        IF (lnk_up_trig = '1') THEN
276
          lnk_up_thrtl <= '1'   AFTER (TCQ)*1 ps;
277
        ELSIF (lnk_up_exit = '1') THEN
278
          lnk_up_thrtl <= '0'   AFTER (TCQ)*1 ps;
279
        END IF;
280
      END IF;
281
    END IF;
282
  END PROCESS;
283
 
284
  --------------------------------------------------------------------------------
285
  -- THROTTLE REASON: Transmit buffers depleted                                 --
286
  --   - When to throttle: trn_tbuf_av falls to 0                               --
287
  --   - When to stop: trn_tbuf_av rises above 0 again                          --
288
  --------------------------------------------------------------------------------
289
  tbuf_av_min_trig <= '1' WHEN (TRN_TBUF_AV <= TBUF_AV_MIN) ELSE '0';
290
 
291
  PROCESS (USER_CLK)
292
  BEGIN
293
    IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
294
      IF (USER_RST = '1') THEN
295
        tbuf_av_min_thrtl <= '0'   AFTER (TCQ)*1 ps;
296
      ELSE
297
        IF (tbuf_av_min_trig = '1') THEN
298
          tbuf_av_min_thrtl <= '1'  AFTER (TCQ)*1 ps;
299
          -- The exit condition for tbuf_av_min_thrtl is !tbuf_av_min_trig
300
        ELSE
301
          tbuf_av_min_thrtl <= '0'  AFTER (TCQ)*1 ps;
302
        END IF;
303
      END IF;
304
    END IF;
305
  END PROCESS;
306
 
307
  ------------------------------------------------------------------------------//
308
  -- THROTTLE REASON: Transmit buffers getting low                              //
309
  --   - When to throttle: trn_tbuf_av falls below "gap" threshold TBUF_AV_GAP  //
310
  --   - When to stop: after TBUF_GAP_TIME cycles elapse                        //
311
  --                                                                            //
312
  -- If we're about to run out of transmit buffers, throttle the user for a     //
313
  -- few clock cycles to give the PCIe block time to catch up. This is          //
314
  -- needed to compensate for latency in decrementing trn_tbuf_av in the PCIe   //
315
  -- Block transmit path.                                                       //
316
  ------------------------------------------------------------------------------//
317
 
318
  -- Detect two different scenarios for buffers getting low:
319
  -- 1) If we see a TLAST. a new packet has been inserted into the buffer, and
320
  --    we need to pause and let that packet "soak in"
321
  gap_trig_tlast_1 <=  '1' WHEN (TRN_TBUF_AV <= TBUF_AV_GAP) ELSE '0';
322
  gap_trig_tlast   <=  (gap_trig_tlast_1 AND S_AXIS_TX_TVALID AND tready_thrtl_xhdl1 AND S_AXIS_TX_TLAST );
323
 
324
  -- 2) Any time tbug_avail decrements to the TBUF_AV_GAP threshold, we need to
325
  --    pause and make sure no other packets are about to soak in and cause the
326
  --    buffer availability to drop further.
327
  gap_trig_decr_1    <=  '1' WHEN ( TRN_TBUF_AV = TBUF_AV_GAP) ELSE '0' ;
328
  gap_trig_decr_2  <=  '1' WHEN (tbuf_av_d = TBUF_AV_GAP + 1) ELSE '0' ;
329
 
330
  gap_trig_decr    <= ( gap_trig_decr_1 AND gap_trig_decr_2);
331
 
332
  gap_trig_tcfg    <= ((tcfg_req_thrtl AND tcfg_req_exit));
333
  tbuf_av_gap_trig <= (gap_trig_tlast OR gap_trig_decr OR gap_trig_tcfg) ;
334
  tbuf_av_gap_exit <= '1' WHEN (tbuf_gap_cnt = "000") ELSE '0' ;
335
 
336
  tbuf_gap_cnt_t   <= "100" WHEN (C_DATA_WIDTH = 128) ELSE "001";
337
  PROCESS (USER_CLK)
338
  BEGIN
339
    IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
340
      IF (USER_RST = '1') THEN
341
        tbuf_av_gap_thrtl <= '0'       AFTER (TCQ)*1 ps;
342
        tbuf_gap_cnt      <= "000"     AFTER (TCQ)*1 ps;
343
        tbuf_av_d         <= "000000"  AFTER (TCQ)*1 ps;
344
      ELSE
345
        IF (tbuf_av_gap_trig = '1') THEN
346
          tbuf_av_gap_thrtl <= '1'   AFTER (TCQ)*1 ps;
347
        ELSIF (tbuf_av_gap_exit = '1') THEN
348
          tbuf_av_gap_thrtl <= '0'   AFTER (TCQ)*1 ps;
349
        END IF;
350
        -- tbuf gap counter:
351
        -- This logic controls the length of the throttle condition when tbufs are
352
        -- getting low.
353
        IF (tbuf_av_gap_thrtl = '1' AND (CUR_STATE_A = THROTTLE)) THEN
354
          IF (tbuf_gap_cnt > "000") THEN
355
            tbuf_gap_cnt <= tbuf_gap_cnt - "001"  AFTER (TCQ)*1 ps;
356
          END IF;
357
        ELSE
358
          tbuf_gap_cnt <= tbuf_gap_cnt_t AFTER (TCQ)*1 ps;
359
        END IF;
360
        tbuf_av_d <= TRN_TBUF_AV  AFTER (TCQ)*1 ps;
361
      END IF;
362
    END IF;
363
  END PROCESS;
364
 
365
  ------------------------------------------------------------------------------
366
  -- THROTTLE REASON: Block needs to send a CFG response
367
  --   - When to throttle: trn_tcfg_req and user_tcfg_gnt asserted
368
  --   - When to stop: after trn_tdst_rdy transitions to unasserted
369
  --
370
  -- If the block needs to send a response to a CFG packet, this will cause
371
  -- the subsequent deassertion of trn_tdst_rdy. When the user design permits,
372
  -- grant permission to the block to service request and throttle the user.
373
  ------------------------------------------------------------------------------
374
 
375
  tcfg_req_trig <= (TRN_TCFG_REQ AND reg_tcfg_gnt);
376
  tcfg_req_exit <= '1' WHEN (tcfg_req_cnt = "00" AND trn_tdst_rdy_d = '0' AND  TRN_TDST_RDY ='1') ELSE '0';
377
 
378
  PROCESS (USER_CLK)
379
  BEGIN
380
    IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
381
      IF (USER_RST = '1') THEN
382
        tcfg_req_thrtl   <= '0'   AFTER (TCQ)*1 ps;
383
        trn_tcfg_req_d   <= '0'   AFTER (TCQ)*1 ps;
384
        trn_tdst_rdy_d   <= '1'   AFTER (TCQ)*1 ps;
385
        reg_tcfg_gnt     <= '0'   AFTER (TCQ)*1 ps;
386
        tcfg_req_cnt     <= "00"  AFTER (TCQ)*1 ps;
387
        tcfg_gnt_pending <= '0'   AFTER (TCQ)*1 ps;
388
      ELSE
389
        IF (tcfg_req_trig = '1') THEN
390
          tcfg_req_thrtl <= '1'  AFTER (TCQ)*1 ps;
391
        ELSIF (tcfg_req_exit = '1') THEN
392
          tcfg_req_thrtl <= '0'  AFTER (TCQ)*1 ps;
393
        END IF;
394
        -- We need to wait the appropriate amount of time for the tcfg_gnt to
395
        -- "sink in" to the PCIe block. After that, we know that the PCIe block will
396
        -- not reassert trn_tdst_rdy until the CFG request has been serviced. If a
397
        -- new request is being service (tcfg_gnt_log == 1), then reset the timer.
398
        IF ((NOT(trn_tcfg_req_d = '1' ) AND TRN_TCFG_REQ = '1' ) OR tcfg_gnt_pending = '1') THEN
399
          -- As TCFG_LATENCY_TIME value is 2
400
          tcfg_req_cnt <= "10"  AFTER (TCQ)*1 ps;
401
        ELSE
402
          IF (tcfg_req_cnt > "00") THEN
403
            tcfg_req_cnt <= tcfg_req_cnt - "01"  AFTER (TCQ)*1 ps;
404
          END IF;
405
        END IF;
406
        -- Make sure tcfg_gnt_log pulses once for one clock cycle for every
407
        -- cfg packet request.
408
        IF (TRN_TCFG_REQ = '1' AND NOT(trn_tcfg_req_d = '1' )) THEN
409
          tcfg_gnt_pending   <= '1' AFTER (TCQ)*1 ps;
410
        ELSIF (tcfg_gnt_log = '1') THEN
411
          tcfg_gnt_pending   <= '0' AFTER (TCQ)*1 ps;
412
        END IF;
413
 
414
        trn_tcfg_req_d   <= TRN_TCFG_REQ   AFTER (TCQ)*1 ps;
415
        trn_tdst_rdy_d   <= TRN_TDST_RDY   AFTER (TCQ)*1 ps;
416
        reg_tcfg_gnt     <= USER_TCFG_GNT  AFTER (TCQ)*1 ps;
417
      END IF;
418
    END IF;
419
  END PROCESS;
420
 
421
  ------------------------------------------------------------------------------
422
  -- THROTTLE REASON: Block needs to transition to low power state PPM L1
423
  --   - When to throttle: appropriate low power state signal asserted
424
  --     (architecture dependent)
425
  --   - When to stop: cfg_pcie_link_state goes to proper value (C_ROOT_PORT
426
  --     dependent)
427
  --
428
  -- If the block needs to transition to PM state PPM L1, we need to finish
429
  -- up what we're doing and throttle immediately.
430
  ------------------------------------------------------------------------------
431
  xhdl3 : IF ((C_FAMILY = "X7") AND (C_ROOT_PORT)) GENERATE
432
    -- PPM L1 signals for 7 Series in RC mode
433
    ppm_L1_trig <=  '1' WHEN ((cfg_pcie_link_state_d = "000") AND (CFG_PCIE_LINK_STATE = "101")) ELSE '0';
434
    ppm_L1_exit <= '1' WHEN (CFG_PCIE_LINK_STATE = "001") ELSE '0';
435
  END GENERATE;
436
 
437
  -- PPM L1 signals for 7 Series in EP mode
438
  xhdl4 : IF (NOT((C_FAMILY = ("X7")) AND (C_ROOT_PORT))) GENERATE
439
    xhdl5 : IF ((C_FAMILY = ("X7")) AND (NOT(C_ROOT_PORT))) GENERATE
440
      ppm_L1_trig <= '1' WHEN ((cfg_pcie_link_state_d = "000") AND (CFG_PCIE_LINK_STATE = "101")) ELSE '0';
441
      ppm_L1_exit <= '1' WHEN (CFG_PCIE_LINK_STATE = "000") ELSE '0';
442
    END GENERATE;
443
    -- PPM L1 signals for V6 in RC mode
444
    xhdl6 : IF (NOT((C_FAMILY = ("X7")) AND (NOT(C_ROOT_PORT)))) GENERATE
445
      xhdl7 : IF ((C_FAMILY = ("V6")) AND (C_ROOT_PORT)) GENERATE
446
        ppm_L1_trig <= '1' WHEN ((TRN_RDLLP_DATA(31 DOWNTO 24) = x"20") AND TRN_RDLLP_SRC_RDY = '1' AND trn_rdllp_src_rdy_d = '0')
447
                       ELSE '0';
448
        ppm_L1_exit <= '1' WHEN (CFG_PCIE_LINK_STATE = "001") ELSE '0';
449
      END GENERATE;
450
      -- PPM L1 signals for V6 in EP mode
451
      xhdl8 : IF (NOT((C_FAMILY = ("V6")) AND (C_ROOT_PORT))) GENERATE
452
        xhdl9 : IF ((C_FAMILY = ("V6")) AND (NOT(C_ROOT_PORT))) GENERATE
453
          ppm_L1_trig <= '1' WHEN (CFG_PMCSR_POWERSTATE /= "000") ELSE '0';
454
          ppm_L1_exit <= '1' WHEN (CFG_PCIE_LINK_STATE = "000") ELSE '0';
455
        END GENERATE;
456
        -- PPM L1 detection not supported for S6
457
        xhdl10 : IF (NOT((C_FAMILY = ("V6")) AND (NOT(C_ROOT_PORT)))) GENERATE
458
          ppm_L1_trig <= '0';
459
          ppm_L1_exit <= '1';
460
        END GENERATE;
461
      END GENERATE;
462
    END GENERATE;
463
  END GENERATE;
464
 
465
  PROCESS (USER_CLK)
466
  BEGIN
467
    IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
468
      IF (USER_RST = '1') THEN
469
        ppm_L1_thrtl          <= '0'   AFTER (TCQ)*1 ps;
470
        cfg_pcie_link_state_d <= "000" AFTER (TCQ)*1 ps;
471
        trn_rdllp_src_rdy_d   <= '0'   AFTER (TCQ)*1 ps;
472
      ELSE
473
        IF (ppm_L1_trig = '1') THEN
474
          ppm_L1_thrtl  <= '1'   AFTER (TCQ)*1 ps;
475
        ELSIF (ppm_L1_exit = '1') THEN
476
          ppm_L1_thrtl  <= '0'   AFTER (TCQ)*1 ps;
477
        END IF;
478
        cfg_pcie_link_state_d <= CFG_PCIE_LINK_STATE  AFTER (TCQ)*1 ps;
479
        trn_rdllp_src_rdy_d <= TRN_RDLLP_SRC_RDY      AFTER (TCQ)*1 ps;
480
      END IF;
481
    END IF;
482
  END PROCESS;
483
 
484
  ------------------------------------------------------------------------------
485
  -- THROTTLE REASON: Block needs to transition to low power state PPM L2/3
486
  --   - When to throttle: appropriate PM signal indicates a transition to
487
  --     L2/3 is pending or in progress (family and role dependent)
488
  --   - When to stop: never (the only path out of L2/3 is a full reset)
489
  --
490
  -- If the block needs to transition to PM state PPM L2/3, we need to finish
491
  -- up what we're doing and throttle when the user gives permission.
492
  ------------------------------------------------------------------------------
493
  -- PPM L2/3 signals for 7 Series in RC mode
494
  xhdl11 : IF ((C_FAMILY = ("X7")) AND (C_ROOT_PORT)) GENERATE
495
    ppm_L23_trig <= '1' WHEN (cfg_pcie_link_state_d = "110") ELSE '0';
496
    wire_to_turnoff <= '0';
497
  END GENERATE;
498
 
499
  -- PPM L2/3 signals for V6 in RC mode
500
  xhdl12 : IF (NOT((C_FAMILY = ("X7")) AND (C_ROOT_PORT))) GENERATE
501
    xhdl13 : IF ((C_FAMILY = ("V6")) AND (C_ROOT_PORT)) GENERATE
502
      ppm_L23_trig <= CFG_PM_SEND_PME_TO;
503
      wire_to_turnoff <= '0';
504
    END GENERATE;
505
     -- PPM L2/3 signals in EP mode
506
    xhdl14 : IF (NOT((C_FAMILY = ("V6")) AND (C_ROOT_PORT))) GENERATE
507
      ppm_L23_trig <= (wire_to_turnoff AND reg_turnoff_ok);
508
       -- PPM L2/3 signals for 7 Series in EP mode
509
       -- For 7 Series, cfg_to_turnoff pulses once when a turnoff request is
510
       -- outstanding, so we need a "sticky" register that grabs the request.
511
      xhdl15 : IF (C_FAMILY = ("X7")) GENERATE
512
        PROCESS (USER_CLK)
513
        BEGIN
514
          IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
515
            IF (USER_RST = '1') THEN
516
              reg_to_turnoff <= '0' AFTER (TCQ)*1 ps;
517
            ELSE
518
              IF (CFG_TO_TURNOFF = '1') THEN
519
                reg_to_turnoff <= '1' AFTER (TCQ)*1 ps;
520
              END IF;
521
            END IF;
522
          END IF;
523
        END PROCESS;
524
        wire_to_turnoff <= reg_to_turnoff;
525
      END GENERATE;
526
       -- PPM L2/3 signals for V6/S6 in EP mode
527
       -- In V6 and S6, the to_turnoff signal asserts and remains asserted until
528
       -- turnoff_ok is asserted, so a sticky reg is not necessary.
529
      xhdl16 : IF (NOT(C_FAMILY = ("X7"))) GENERATE
530
        wire_to_turnoff <= CFG_TO_TURNOFF;
531
      END GENERATE;
532
 
533
    PROCESS (USER_CLK)
534
    BEGIN
535
      IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
536
        IF (USER_RST = '1') THEN
537
          reg_turnoff_ok <= '0' AFTER (TCQ)*1 ps;
538
        ELSE
539
          reg_turnoff_ok <= USER_TURNOFF_OK AFTER (TCQ)*1 ps;
540
        END IF;
541
      END IF;
542
    END PROCESS;
543
    END GENERATE;
544
  END GENERATE;
545
 
546
   PROCESS (USER_CLK)
547
   BEGIN
548
    IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
549
      IF (USER_RST = '1') THEN
550
        ppm_L23_thrtl <= '0' AFTER (TCQ)*1 ps;
551
        cfg_turnoff_ok_pending <= '0' AFTER (TCQ)*1 ps;
552
      ELSE
553
        -- Make sure cfg_turnoff_ok pulses once for one clock cycle for every
554
        -- turnoff request.
555
        IF (ppm_L23_trig = '1') THEN
556
          ppm_L23_thrtl <= '1' AFTER (TCQ)*1 ps;
557
        END IF;
558
        IF (ppm_L23_trig = '1' AND (ppm_L23_thrtl = '0')) THEN
559
          cfg_turnoff_ok_pending <= '1' AFTER (TCQ)*1 ps;
560
        ELSIF (cfg_turnoff_ok_xhdl0 = '1') THEN
561
          cfg_turnoff_ok_pending <= '0' AFTER (TCQ)*1 ps;
562
        END IF;
563
      END IF;
564
    END IF;
565
   END PROCESS;
566
 
567
   --------------------------------------------------------------------------------
568
   -- Create axi_thrtl_ok. This signal determines if it's OK to throttle the     --
569
   -- user design on the AXI interface. Since TREADY is registered, this signal  --
570
   -- needs to assert on the cycle ~before~ we actually intend to throttle.      --
571
   -- The only time it's OK to throttle when TVALID is asserted is on the first  --
572
   -- beat of a new packet. Therefore, assert axi_thrtl_ok if one of the         --
573
   -- is true:                                                                   --
574
   --    1) The user is not in a packet and is not starting one                  --
575
   --    2) The user is just finishing a packet                                  --
576
   --    3) We're already throttled, so it's OK to continue throttling           --
577
   --------------------------------------------------------------------------------
578
 
579
  PROCESS (USER_CLK)
580
  BEGIN
581
    IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
582
      IF (USER_RST = '1') THEN
583
        reg_axi_in_pkt <= '0' AFTER (TCQ)*1 ps;
584
      ELSE
585
        IF (S_AXIS_TX_TVALID = '1' AND S_AXIS_TX_TLAST  = '1') THEN
586
          reg_axi_in_pkt <= '0' AFTER (TCQ)*1 ps;
587
        ELSIF (tready_thrtl_xhdl1  = '1'  AND S_AXIS_TX_TVALID  = '1') THEN
588
          reg_axi_in_pkt <= '1' AFTER (TCQ)*1 ps;
589
        END IF;
590
      END IF;
591
    END IF;
592
  END PROCESS;
593
 
594
  axi_in_pkt     <= (S_AXIS_TX_TVALID OR reg_axi_in_pkt);
595
  axi_pkt_ending <= (S_AXIS_TX_TVALID AND S_AXIS_TX_TLAST);
596
  axi_throttled  <= NOT(tready_thrtl_xhdl1);
597
  axi_thrtl_ok   <= (NOT(axi_in_pkt) OR axi_pkt_ending OR axi_throttled);
598
  --------------------------------------------------------------------------------
599
  -- Throttle CTL State Machine:                                                --
600
  -- Throttle user design when a throttle trigger (or triggers) occur.          --
601
  -- Keep user throttled until all exit criteria have been met.                 --
602
  --------------------------------------------------------------------------------
603
 
604
  -- Immediate throttle signal. Used to "pounce" on a throttle opportunity when
605
  -- we're seeking one
606
  pre_throttle <= (tbuf_av_min_trig OR tbuf_av_gap_trig OR lnk_up_trig OR tcfg_req_trig OR ppm_L1_trig OR ppm_L23_trig);
607
 
608
  -- Registered throttle signals. Used to control throttle state machine
609
  reg_throttle <= (tbuf_av_min_thrtl OR tbuf_av_gap_thrtl OR lnk_up_thrtl OR tcfg_req_thrtl OR ppm_L1_thrtl OR ppm_L23_thrtl);
610
  exit_crit <= (NOT(tbuf_av_min_thrtl) AND NOT(tbuf_av_gap_thrtl) AND (NOT(lnk_up_thrtl)) AND (NOT(tcfg_req_thrtl)) and
611
               (NOT(ppm_L1_thrtl)) AND (NOT(ppm_L23_thrtl)));
612
 
613
  PROCESS (CUR_STATE_A,reg_throttle, axi_thrtl_ok, tcfg_req_thrtl, tcfg_gnt_pending, cfg_turnoff_ok_pending, pre_throttle,
614
           exit_crit, ppm_L23_thrtl)
615
  BEGIN
616
    CASE CUR_STATE_A IS
617
      -- IDLE: in this state we're waiting for a trigger event to occur. As
618
      -- soon as an event occurs and the user isn't transmitting a packet, we
619
      -- throttle the PCIe block and the user and next state is THROTTLE.
620
      WHEN (IDLE) =>
621
              IF (reg_throttle = '1' AND axi_thrtl_ok = '1') THEN
622
                tready_thrtl_mux <= '0';
623
                NEXT_STATE_A   <= (THROTTLE);
624
                -- Assert appropriate grant signal depending on the throttle type.
625
                IF (tcfg_req_thrtl  = '1') THEN
626
                  tcfg_gnt_log          <= '1';   -- For cfg request, grant the request
627
                  cfg_turnoff_ok_xhdl0  <= '0'; --
628
                ELSIF (ppm_L23_thrtl = '1') THEN
629
                  tcfg_gnt_log          <= '0';    --
630
                  cfg_turnoff_ok_xhdl0  <= '1';  -- For PM request, permit transition
631
                ELSE
632
                  tcfg_gnt_log          <= '0';  -- Otherwise do nothing
633
                  cfg_turnoff_ok_xhdl0  <= '0';--
634
                END IF;
635
              ELSE
636
                -- If there's not throttle event, do nothing
637
                -- Throttle user as soon as possible
638
                tready_thrtl_mux <= (NOT((axi_thrtl_ok AND pre_throttle)));
639
                NEXT_STATE_A <= IDLE;
640
                tcfg_gnt_log         <= '0';
641
                cfg_turnoff_ok_xhdl0 <= '0';
642
              END IF;
643
      -- THROTTLE: in this state the user is throttle and we're waiting for
644
      -- exit criteria, which tells us that the throttle event is over. When
645
      -- the exit criteria is satisfied, de-throttle the user and next state
646
      WHEN (THROTTLE) =>
647
              IF (exit_crit = '1') THEN
648
                -- Dethrottle user
649
                tready_thrtl_mux <= (NOT(pre_throttle));
650
                NEXT_STATE_A   <= IDLE;
651
              ELSE
652
                -- Throttle user
653
                tready_thrtl_mux <= '0';
654
                NEXT_STATE_A   <= (THROTTLE);
655
              END IF;
656
               -- Assert appropriate grant signal depending on the throttle type.
657
              IF (tcfg_req_thrtl = '1' AND tcfg_gnt_pending = '1') THEN
658
                tcfg_gnt_log           <= '1';   -- For cfg request, grant the request
659
                cfg_turnoff_ok_xhdl0   <= '0'; --
660
              ELSIF (cfg_turnoff_ok_pending = '1') THEN
661
                tcfg_gnt_log           <= '0';   --
662
                cfg_turnoff_ok_xhdl0   <= '1'; -- For PM request, permit transition
663
              ELSE
664
                tcfg_gnt_log           <= '0';   -- Otherwise do nothing
665
                cfg_turnoff_ok_xhdl0   <= '0'; --
666
              END IF;
667
      WHEN OTHERS =>
668
              tready_thrtl_mux     <= '0';
669
              NEXT_STATE_A         <= (IDLE);
670
              tcfg_gnt_log         <= '0' ;
671
              cfg_turnoff_ok_xhdl0 <= '0';
672
    END CASE;
673
  END PROCESS;
674
 
675
 
676
  -- Synchronous logic
677
  PROCESS (USER_CLK)
678
  BEGIN
679
    IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
680
      IF (USER_RST = '1') THEN
681
        -- Throttle user by default until link comes up
682
        CUR_STATE_A        <= (THROTTLE) AFTER (TCQ)*1 ps;
683
        reg_tlast          <= '0' AFTER (TCQ)*1 ps;
684
        tready_thrtl_xhdl1 <= '0' AFTER (TCQ)*1 ps;
685
      ELSE
686
        CUR_STATE_A        <= NEXT_STATE_A AFTER (TCQ)*1 ps;
687
        tready_thrtl_xhdl1 <= (tready_thrtl_mux AND NOT(tx_ecrc_pause)) AFTER (TCQ)*1 ps;
688
        reg_tlast          <= S_AXIS_TX_TLAST AFTER (TCQ)*1 ps;
689
      END IF;
690
    END IF;
691
  END PROCESS;
692
 
693
 
694
  -- For X7, the PCIe block will generate the ECRC for a packet if trn_tecrc_gen
695
  -- is asserted at SOF. In this case, the Block needs an extra data beat to
696
  -- calculate the ECRC, but only if the following conditions are met:
697
  --  1) there is no empty DWORDS at the end of the packet
698
  --     (i.e. packet length % C_DATA_WIDTH == 0)
699
  --
700
  --  2) There isn't a ECRC in the TLP already, as indicated by the TD bit in the
701
  --     TLP header
702
  --
703
  -- If both conditions are met, the Block will stall the TRN interface for one
704
  -- data beat after EOF. We need to predict this stall and preemptively stall the
705
  -- User for one beat.
706
  xhdl17 : IF (C_FAMILY = ("X7")) GENERATE
707
 
708
    -- Grab necessary packet fields
709
    packet_fmt <= S_AXIS_TX_TDATA(30 DOWNTO 29);
710
    packet_td  <= S_AXIS_TX_TDATA(15);
711
 
712
    -- Calculate total packet length
713
    header_len <= "100" WHEN packet_fmt(0) = '1' ELSE "011";
714
    payload_len <= S_AXIS_TX_TDATA(9 DOWNTO 0) WHEN packet_fmt(1) = '1' ELSE "0000000000";
715
    packet_len  <= ("0000000000" & header_len) + ("0000" & payload_len);
716
 
717
    -- Determine if an ECRC pause is needed
718
    PACKET_LEN_CHECK_128 : IF (C_DATA_WIDTH = 128) GENERATE
719
      pause_needed <= '1' WHEN (packet_len(1 DOWNTO 0) = "00" AND packet_td = '0') ELSE '0';
720
    END GENERATE;
721
 
722
    PACKET_LEN_CHECK_64 : IF (C_DATA_WIDTH /= 128) GENERATE
723
      pause_needed <= '1' WHEN (packet_len(0) = '0' AND packet_td = '0') ELSE '0';
724
    END GENERATE;
725
 
726
    -- Create flag to alert TX pipeline to insert a stall
727
    tx_ecrc_pkt <= S_AXIS_TX_TUSER(0) AND pause_needed AND tready_thrtl_xhdl1 AND S_AXIS_TX_TVALID AND not(reg_axi_in_pkt);
728
 
729
    PROCESS (USER_CLK)
730
    BEGIN
731
      IF (USER_CLK'EVENT AND USER_CLK = '1') THEN
732
        IF (USER_RST = '1') THEN
733
          reg_tx_ecrc_pkt <= '0' AFTER (TCQ)*1 ps;
734
        ELSE
735
          IF (tx_ecrc_pkt  = '1' AND S_AXIS_TX_TLAST = '0') THEN
736
            reg_tx_ecrc_pkt <= '1' AFTER (TCQ)*1 ps;
737
          ELSIF (tready_thrtl_xhdl1 = '1' AND S_AXIS_TX_TVALID = '1' AND S_AXIS_TX_TLAST = '1') THEN
738
            reg_tx_ecrc_pkt <= '0' AFTER (TCQ)*1 ps;
739
          END IF;
740
        END IF;
741
      END IF;
742
    END PROCESS;
743
 
744
--    tx_ecrc_pkt <= (S_AXIS_TX_TUSER(0) AND tready_thrtl_xhdl1 AND S_AXIS_TX_TVALID AND (NOT(reg_axi_in_pkt)));
745
    tx_ecrc_pause <= (((tx_ecrc_pkt OR reg_tx_ecrc_pkt) AND S_AXIS_TX_TLAST AND S_AXIS_TX_TVALID AND tready_thrtl_xhdl1));
746
  END GENERATE;
747
 
748
  xhdl18 : IF (NOT(C_FAMILY = ("X7"))) GENERATE
749
    tx_ecrc_pause <= '0';
750
  END GENERATE;
751
 
752
  -- Logic for 128-bit single cycle bug fix.
753
  -- This tcfg_gnt pipeline addresses an issue with 128-bit V6 designs where a
754
  -- single cycle packet transmitted simultaneously with an assertion of tcfg_gnt
755
  -- from AXI Basic causes the packet to be dropped. The packet drop occurs
756
  -- because the 128-bit shim doesn't know about the tcfg_req/gnt, and therefor
757
  -- isn't expecting trn_tdst_rdy to go low. Since the 128-bit shim does throttle
758
  -- prediction just as we do, it ignores the value of trn_tdst_rdy, and
759
  -- ultimately drops the packet when transmitting the packet to the block.
760
 
761
 
762
  TCFG_GNT_PIPELINE: if (C_DATA_WIDTH = 128 AND C_FAMILY = "V6") generate
763
    -- Create a configurable depth FF delay pipeline
764
    tcfg_gnt_pipeline_stage: for stage in 0 to TCFG_GNT_PIPE_STAGES -1 generate
765
      process (USER_CLK)
766
      begin  -- process
767
        if USER_CLK'event and USER_CLK = '1' then
768
          if USER_RST = '1' then
769
            tcfg_gnt_pipe(stage) <= '0' after (TCQ)*1 ps;
770
          else
771
            -- For stage 0, insert the actual tcfg_gnt signal from logic
772
           if stage = 0 then
773
             tcfg_gnt_pipe(stage) <= tcfg_gnt_log after (TCQ)*1 ps;
774
             -- For stages 1+, chain together
775
           else
776
             tcfg_gnt_pipe(stage) <= tcfg_gnt_pipe(stage - 1) after (TCQ)*1 ps;
777
           end if;
778
          end if;
779
        end if;
780
      end process;
781
 
782
      -- tcfg_gnt output to block assigned the last pipeline stage
783
      TRN_TCFG_GNT <= tcfg_gnt_pipe(TCFG_GNT_PIPE_STAGES - 1);
784
    end generate tcfg_gnt_pipeline_stage;
785
  end generate TCFG_GNT_PIPELINE;
786
 
787
  tcfg_gnt_no_pipeline: if (not(C_DATA_WIDTH = 128 AND C_FAMILY = "V6")) generate
788
    -- For all other architectures, no pipeline delay needed for tcfg_gnt
789
 
790
    TRN_TCFG_GNT <= tcfg_gnt_log;
791
 
792
  end generate tcfg_gnt_no_pipeline;
793
 
794
END trans;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.