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

Subversion Repositories epc_rfid_transponder

[/] [epc_rfid_transponder/] [trunk/] [tagfsm.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 erwing
-------------------------------------------------------------------------------
2
--     Politecnico di Torino                                              
3
--     Dipartimento di Automatica e Informatica             
4
-------------------------------------------------------------------------------
5
-------------------------------------------------------------------------------     
6
--
7
--     Title          : EPC Class1 Gen2 RFID Tag - Tag main FSM
8
--
9
--     File name      : TagFSM.vhd 
10
--
11
--     Description    : Tag finite state machine (Mealy).     
12
--
13
--     Authors        : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
14
--
15
--     Rev. History   : 28 June 06 - First Draft 
16
--                                 
17
-------------------------------------------------------------------------------            
18
-------------------------------------------------------------------------------
19
-------------------------------------------------------------------------------
20
-------------------------------------------------------------------------------
21
-- Tag Finite State Machine based on EPC Class 1 Gen 2 Air interface
22
--
23
-- The following requirements of the EPC document are not fully implemented.
24
--     -In the "Select" command, the comparison between the mask and any
25
--      portion of the memory does not work with bit precision. According        
26
--      to the EPC document, the comparison may start at any bit of any
27
--      portion of the memory. In this implementation, the comparison starts
28
--      with a word. It may, however, be of any length.
29
--     -In the "Select" command, the truncate bit is not currently
30
--      implemented and does not cause any effect.
31
--     -Kill and Access passwords are not implemented. So, the tag behaves
32
--      as though it had zero-valued passwords.
33
--     -Access command is not implemented.
34
--     -Kill and Lock commands are currently unavailable.
35
--      
36
-------------------------------------------------------------------------------   
37
-------------------------------------------------------------------------------
38
library IEEE;
39
use IEEE.STD_LOGIC_1164.all;
40
use IEEE.std_logic_unsigned.all;
41
use IEEE.STD_LOGIC_ARITH.all;
42
library work;
43
use work.epc_tag.all;
44
 
45
 
46
entity TagFSM is
47
  generic(
48
    WordsRSV : integer := 8;
49
    WordsEPC : integer := 16;
50
    WordsTID : integer := 8;
51
    WordsUSR : integer := 256;
52
    AddrUSR  : integer := 5;            -- 1/2 memory address pins (maximum)
53
    Data     : integer := 16);          -- memory data width
54
  port (
55
    clk       : in  std_logic;
56
    rst_n     : in  std_logic;
57
    -- Receiver
58
    CommDone  : in  CommandInternalCode_t;
59
    Data_r    : in  std_logic_vector(31 downto 0);
60
    Pointer_r : in  std_logic_vector(15 downto 0);
61
    RN16_r    : in  std_logic_vector(15 downto 0);
62
    Length_r  : in  std_logic_vector(7 downto 0);
63
    Mask_r    : in  std_logic_vector(MASKLENGTH-1 downto 0);
64
--  -- MCU
65
--    MCUComm    : out CommandMCU_t;
66
--    MCUCommVal : out std_logic;
67
--    MCURdy     : in  std_logic;
68
    -- Inventoried and Select flags
69
    SInvD     : out std_logic_vector(3 downto 0);  -- Flag input
70
    SelD      : out std_logic;
71
    SInvQ     : in  std_logic_vector(3 downto 0);  -- Flag output
72
    SelQ      : in  std_logic;
73
    SInvCE    : out std_logic_vector(3 downto 0);  -- Flag enable
74
    SelCE     : out std_logic;
75
    -- Random Number Generator
76
    rng_init  : out std_logic;
77
    rng_cin   : out std_logic_vector(30 downto 0);
78
    rng_ce    : out std_logic;
79
    rng_cout  : in  std_logic_vector(30 downto 0);
80
    -- Memory
81
    mem_WR    : out std_logic;
82
    mem_RD    : out std_logic;
83
    mem_RB    : in  std_logic;
84
    mem_BANK  : out std_logic_vector(1 downto 0);
85
    mem_ADR   : out std_logic_vector((2*AddrUSR)-1 downto 0);
86
    mem_DTI   : out std_logic_vector(Data-1 downto 0);
87
    mem_DTO   : in  std_logic_vector(Data-1 downto 0);
88
    -- Interrogator Response Timer Flag (T2) - see EPC Standard 1.09 p.34
89
    T2ExpFlag : in  std_logic;
90
    -- Transmitter Command and Output buffer
91
    trm_cmd   : out std_logic_vector(2 downto 0);
92
    trm_buf   : out std_logic_vector(15 downto 0)
93
    );
94
 
95
end TagFSM;
96
 
97
architecture TagFSM1 of TagFSM is
98
 
99
-------------------------------------------------------------------------------
100
-- DATA_r values according to received command
101
-------------------------------------------------------------------------------
102
  -- QUERY
103
  --    ___________________________________________________________
104
  --   |__DR__|__M__|__TRext__|__Sel__|__Session__|__Target__|__Q__|
105
  --    12     11    9         8       6           4          3    0
106
 
107
  -- QUERYREP
108
  --    ___________
109
  --   |__Session__|
110
  --    1          0    
111
 
112
  -- QUERYADJUST
113
  --    ____________________
114
  --   |__Session__|__UpDn__|
115
  --    4           2       0
116
 
117
  -- SELECT
118
  --    ______________________________________________
119
  --   |__Target__|__Action__|__MemBank__|__Truncate__|
120
  --    8          5          2            0
121
 
122
  -- READ
123
  --    ___________
124
  --   |__MemBank__|
125
  --    1          0
126
 
127
  -- WRITE
128
  --    _____________________________
129
  --   |__MemBank__|__Data xor RN16__|
130
  --    17          15               0
131
 
132
 
133
-------------------------------------------------------------------------------
134
-- Signals
135
-------------------------------------------------------------------------------
136
 
137
  -- Kill Flag & RNG initialization address (MSB)
138
  -- (LSB = MEMORY_KILL_RNG_ADDRESS_MSB + 1)
139
  constant MEMORY_KILL_RNG_ADDRESS_MSB : std_logic_vector((2*AddrUSR)-1 downto 0)   := (others => '0');
140
  constant RESERVED_MEMORY_BANK        : std_logic_vector(1 downto 0)               := "00";
141
  constant EPC_MEMORY_BANK             : std_logic_vector(1 downto 0)               := "01";
142
  constant MEMORY_PC_ADDRESS_16b       : std_logic_vector(15 downto 0)              := conv_std_logic_vector(1, 16);
143
  constant MEMORY_CRC16_ADDRESS        : std_logic_vector((2 * AddrUSR)-1 downto 0) := (others => '0');
144
 
145
  -- Error Codes
146
  constant NON_SPECIFIC_ERROR : std_logic_vector(15 downto 0) := X"00F0";
147
 
148
  -- Finite State Machine. [ st_STATE_COMMAND_DESCRIPTION ]
149
  type TagFSM_t is (st_PowerUp, st_PowerUp_GetFlagMSB, st_PowerUp_GetFlagLSB, st_PowerUp_LoadRNG,
150
                    -- Ready
151
                    st_Ready, st_Ready_QRY_LoadSlot_AND_SaveRN, st_Ready_QRY_CheckSlot_AND_SaveRN,
152
                    st_Ready_QRY_LoadRN16Handler_AND_SaveRN, st_Ready_QRY_BackscatterRN16_AND_SaveRN,
153
                    st_Ready_SEL_GetWord, st_Ready_SEL_NonMatchingTag, st_Ready_SEL_CompareWords,
154
                    st_Ready_SEL_CompareBits, st_Ready_SEL_PrepareComparison, st_Ready_SEL_MatchingTag,
155
                    -- Arbitrate
156
                    st_Arbitrate, st_Arbitrate_QRYQRA_LoadSlot_AND_SaveRN, st_Arbitrate_QRR_CheckSlot,
157
                    st_Arbitrate_QRYQRA_CheckSlot_AND_SaveRN,
158
                    -- Reply
159
                    st_Reply, st_Reply_ACK_SendPC_AND_DecodeEPCLength, st_Reply_ACK_GetPC,
160
                    st_Reply_ACK_GetAndSendEPC, st_Reply_ACK_GetAndSendCRC16,
161
                    -- Acknoledged
162
                    st_Acknowledged, st_Acknowledged_QRY_CheckFlags, st_Acknowledged_RRN_LoadHandler_AND_SaveRN,
163
                    st_Acknowledged_RRN_BackscatterHandler_AND_SaveRN,
164
                    -- Open
165
                    st_Open, st_Open_ACK_GetPC, st_Open_ACK_SendPC_AND_DecodeEPCLength,
166
                    st_Open_ACK_GetAndSendEPC, st_Open_ACK_GetAndSendCRC16,
167
                    st_Open_RRN_LoadHandler_AND_SaveRN, st_Open_RRN_BackscatterHandler_AND_SaveRN,
168
                    -- Secured
169
                    st_Secured, st_Secured_ACK_GetPC, st_Secured_ACK_SendPC_AND_DecodeEPCLength,
170
                    st_Secured_ACK_GetAndSendEPC, st_Secured_ACK_GetAndSendCRC16,
171
                    st_Secured_RRN_LoadHandler_AND_SaveRN, st_Secured_RRN_BackscatterHandler_AND_SaveRN,
172
                    st_Secured_WR_CheckMemoryBounds, st_Secured_WR_WriteWord, st_Secured_WR_WriteIsDone,
173
                    st_Secured_RD_CheckMemoryBounds, st_Secured_RD_ReadMemory, st_Secured_RD_Read_AND_Send,
174
                    st_Secured_RD_SendLast, st_Secured_RD_SendHandle,
175
                    -- Killed
176
                    st_Killed);
177
  signal StTag, NextStTag                 : TagFSM_t;
178
  signal KillFlag, SlotIsZero             : std_logic;
179
  signal Query_InventoryFlag_Match        : std_logic;
180
  signal Query_SelectFlag_Match           : std_logic;
181
  signal Slot, Slot_i                     : std_logic_vector(15 downto 0);
182
  signal GPR, GPR_i                       : std_logic_vector(31 downto 0);  -- general purpose register
183
  signal RN16Handler, RN16Handler_i       : std_logic_vector(15 downto 0);
184
  signal CurrSession, CurrSession_i       : std_logic_vector(1 downto 0);
185
  signal CurrQ, CurrQ_i                   : std_logic_vector(3 downto 0);
186
  signal Select_Address_Pointer_Length_OK : std_logic;
187
  signal Select_Address_Bounds_OK         : std_logic;
188
  signal Write_Address_Pointer_Length_OK  : std_logic;
189
  signal Write_Address_Bounds_OK          : std_logic;
190
  signal Read_Address_Pointer_Length_OK   : std_logic;
191
  signal Read_Address_Bounds_OK           : std_logic;
192
  signal GCounter, GCounter_i             : std_logic_vector(7 downto 0);
193
  signal GCounter2, Gcounter2_i           : std_logic_vector(7 downto 0);
194
  signal FirstCompWord, FirstCompWord_i   : std_logic;
195
  signal ComparisonReg, ComparisonReg_i   : std_logic_vector(Data-1 downto 0);
196
  signal ADRint, ADRint_i                 : std_logic_vector(15 downto 0);
197
 
198
  signal GPR_AFTER_COMPARISON_MUX       : std_logic_vector(15 downto 0);
199
  signal MASK_AFTER_COMPARISON_BIT_MUX      : std_logic_vector(15 downto 0);
200
  signal MASK_AFTER_FIRSTCOMPARISON_MUX : std_logic_vector(15 downto 0);
201
  signal SLOT_VALUE : std_logic_vector(15 downto 0);
202
 
203
  signal SelD_i, SelCE_i   : std_logic;
204
  signal SInvD_i, SInvCE_i : std_logic_vector(3 downto 0);
205
 
206
  signal trm_cmd_i : std_logic_vector(2 downto 0);
207
  signal trm_buf_i : std_logic_vector(15 downto 0);
208
 
209
  -- Memory Signals
210
  signal mem_WR_i, mem_RD_i   : std_logic;
211
  signal mem_ADR_i            : std_logic_vector((2*AddrUSR)-1 downto 0);
212
  signal mem_DTI_i            : std_logic_vector(Data-1 downto 0);
213
  signal mem_BANK_i           : std_logic_vector(1 downto 0);
214
  -- RNG signals
215
  signal rng_cin_i            : std_logic_vector(30 downto 0);
216
  signal rng_init_i, rng_ce_i : std_logic;
217
 
218
 
219
begin  -- TagFSM1
220
 
221
  SYNCRO : process (clk, rst_n)
222
  begin  -- process SYNCRO
223
    if rst_n = '0' then                 -- asynchronous reset (active low)
224
      -- FSM
225
      StTag         <= st_PowerUp;
226
      -- General Purpose Register
227
      GPR           <= (others => '0');
228
      -- Slot Register
229
      Slot          <= (others => '1');
230
      -- RN16 & Handler Register
231
      RN16Handler   <= (others => '0');
232
      -- Memory signals
233
      mem_WR        <= '0';
234
      mem_RD        <= '0';
235
      mem_ADR       <= (others => '0');
236
      mem_DTI       <= (others => '0');
237
      mem_BANK      <= (others => '0');
238
      ADRint        <= (others => '0');
239
      -- RNG signals
240
      rng_cin       <= (others => '0');
241
      rng_init      <= '0';
242
      rng_ce        <= '0';
243
      -- Internal signals and Flags
244
      CurrSession   <= "00";
245
      CurrQ         <= (others => '0');
246
      FirstCompWord <= '0';
247
      ComparisonReg <= (others => '0');
248
      -- Counters
249
      GCounter      <= (others => '0');
250
      GCounter2     <= (others => '0');
251
      -- Transmitter
252
      trm_cmd       <= trmcmd_Null;
253
      trm_buf       <= (others => '0');
254
    elsif clk'event and clk = '1' then  -- rising clock edge
255
      -- FSM
256
      StTag         <= NextStTag;
257
      -- General Purpose Register
258
      GPR           <= GPR_i;
259
      -- Slot Register
260
      Slot          <= Slot_i;
261
      -- RN16 & Handler Register
262
      RN16Handler   <= RN16Handler_i;
263
      -- Memory signals
264
      mem_WR        <= mem_WR_i;
265
      mem_RD        <= mem_RD_i;
266
      mem_ADR       <= mem_ADR_i;
267
      mem_DTI       <= mem_DTI_i;
268
      mem_BANK      <= mem_BANK_i;
269
      ADRint        <= ADRint_i;
270
      -- RNG signals
271
      rng_init      <= rng_init_i;
272
      rng_cin       <= rng_cin_i;
273
      rng_ce        <= rng_ce_i;
274
      -- Internal signals and Flags
275
      CurrSession   <= CurrSession_i;
276
      CurrQ         <= CurrQ_i;
277
      FirstCompWord <= FirstCompWord_i;
278
      ComparisonReg <= ComparisonReg_i;
279
      -- Counters
280
      GCounter      <= GCounter_i;
281
      GCounter2     <= GCounter2_i;
282
      -- Transmitter
283
      trm_cmd       <= trm_cmd_i;
284
      trm_buf       <= trm_buf_i;
285
    end if;
286
  end process SYNCRO;
287
 
288
 
289
-------------------------------------------------------------------------------
290
-----------------------------------------------------------------------------
291
-- NEXT STATE PROCESS
292
-----------------------------------------------------------------------------
293
-------------------------------------------------------------------------------
294
  NEXT_ST : process (StTag, CommDone, mem_RB, mem_DTO, Query_SelectFlag_Match, Query_InventoryFlag_Match, SlotIsZero,
295
                     Select_Address_Pointer_Length_OK, GPR, T2ExpFlag, RN16Handler, Write_Address_Pointer_Length_OK,
296
                     Read_Address_Pointer_Length_OK, GCounter, MASK_AFTER_FIRSTCOMPARISON_MUX, MASK_AFTER_COMPARISON_BIT_MUX,
297
                     GPR_AFTER_COMPARISON_MUX, CurrSession, Data_r, RN16_r)
298
  begin  -- process NEXT_ST
299
    NextStTag <= StTag;
300
    case StTag is
301
      -------------------------------------------------------------------------
302
      -- POWERUP        (in next state process)
303
      -------------------------------------------------------------------------
304
      when st_PowerUp =>
305
        if mem_RB = '1' then
306
          NextStTag <= st_PowerUp_GetFlagMSB;
307
        end if;
308
      when st_PowerUp_GetFlagMSB =>
309
        if mem_RB = '1' then
310
          if mem_DTO(15) = '1' then     -- KILL flag!
311
            NextStTag <= st_Killed;
312
          else
313
            NextStTag <= st_PowerUp_GetFlagLSB;
314
          end if;
315
        end if;
316
      when st_PowerUp_GetFlagLSB =>
317
        if mem_RB = '1' then
318
          NextStTag <= st_PowerUp_LoadRNG;
319
        end if;
320
      when st_PowerUp_LoadRNG =>
321
        NextStTag <= st_Ready;
322
        -----------------------------------------------------------------------
323
        -- READY        (in next state process)       
324
        -----------------------------------------------------------------------
325
      when st_Ready =>
326
        if CommDone = cmd_Query then
327
          -- Check for matching Inventoried and SL flags
328
          if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1'then
329
            NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
330
          end if;
331
        elsif CommDone = cmd_Select then
332
          if Select_Address_Pointer_Length_OK = '1' then
333
            NextStTag <= st_Ready_SEL_GetWord;
334
          else
335
            NextStTag <= st_Ready_SEL_NonMatchingTag;
336
          end if;
337
        end if;
338
 
339
      when st_Ready_QRY_LoadSlot_AND_SaveRN =>
340
        if mem_RB = '1' then
341
          NextStTag <= st_Ready_QRY_CheckSlot_AND_SaveRN;
342
        end if;
343
 
344
      when st_Ready_QRY_CheckSlot_AND_SaveRN =>
345
        if mem_RB = '1' then
346
          if SlotIsZero = '1' then
347
            NextStTag <= st_Ready_QRY_LoadRN16Handler_AND_SaveRN;
348
          else
349
            NextStTag <= st_Arbitrate;
350
          end if;
351
        end if;
352
 
353
      when st_Ready_QRY_LoadRN16Handler_AND_SaveRN =>
354
        if mem_RB = '1' then
355
          NextStTag <= st_Ready_QRY_BackscatterRN16_AND_SaveRN;
356
        end if;
357
 
358
      when st_Ready_QRY_BackscatterRN16_AND_SaveRN =>
359
        if mem_RB = '1' then
360
          NextStTag <= st_Reply;
361
        end if;
362
 
363
        -- NOTE: Select command does not support
364
        -- "bit" comparison. Comparison starts at
365
        -- the beginning of a Word!!  
366
      when st_Ready_SEL_GetWord =>
367
        if mem_RB = '1' then
368
          NextStTag <= st_Ready_SEL_CompareWords;
369
        end if;
370
 
371
      when st_Ready_SEL_PrepareComparison =>
372
        if mem_RB = '1' then
373
          if unsigned(GCounter) < Data then
374
            NextStTag <= st_Ready_SEL_CompareBits;
375
          else
376
            NextStTag <= st_Ready_SEL_CompareWords;
377
          end if;
378
        end if;
379
 
380
      when st_Ready_SEL_CompareWords =>
381
   --if Mask_r((GCounter2)+15 downto conv_integer(unsigned(GCounter2))) = GPR(15 downto 0) then       
382
        if MASK_AFTER_FIRSTCOMPARISON_MUX = GPR(15 downto 0) then
383
          NextStTag <= st_Ready_SEL_GetWord;
384
        else
385
          NextStTag <= st_Ready_SEL_NonMatchingTag;
386
        end if;
387
 
388
      when st_Ready_SEL_CompareBits =>
389
--        if Mask_r(conv_integer(unsigned(GCounter2))+conv_integer(unsigned(GCounter))-1 downto conv_integer(unsigned(GCounter2))) = GPR(conv_integer(unsigned(GCounter))-1 downto 0) then
390
        if MASK_AFTER_COMPARISON_BIT_MUX = GPR_AFTER_COMPARISON_MUX then
391
          NextStTag <= st_Ready_SEL_MatchingTag;
392
        else
393
          NextStTag <= st_Ready_SEL_NonMatchingTag;
394
        end if;
395
 
396
      when st_Ready_SEL_NonMatchingTag =>
397
        NextStTag <= st_Ready;
398
 
399
      when st_Ready_SEL_MatchingTag =>
400
        NextStTag <= st_Ready;
401
 
402
        -----------------------------------------------------------------------
403
        -- ARBITRATE    (in next state process)
404
        -----------------------------------------------------------------------
405
      when st_Arbitrate =>
406
        -- Query command, in the Arbitrate state, behaves as in the Ready state
407
        if CommDone = cmd_Query then
408
          if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1'then
409
            NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
410
          else
411
            NextStTag <= st_Ready;
412
          end if;
413
        elsif CommDone = cmd_QueryRep then
414
          if CurrSession = Data_r(1 downto 0) then
415
            NextStTag <= st_Arbitrate_QRR_CheckSlot;
416
          end if;
417
          -- After Adjusting Q, the behavior of a QueryAdjust command
418
          -- is the same as the Query Command.
419
        elsif CommDone = cmd_QueryAdjust then
420
          if CurrSession = Data_r(4 downto 3) then
421
            if Data_r(2 downto 0) = "000" or Data_r(2 downto 0) = "110" or Data_r(2 downto 0) = "011" then
422
              NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
423
            end if;
424
          end if;
425
          -- Select Command behaves always as in the Ready state!
426
        elsif CommDone = cmd_Select then
427
          if Select_Address_Pointer_Length_OK = '1' then
428
            NextStTag <= st_Ready_SEL_GetWord;
429
          else
430
            NextStTag <= st_Ready_SEL_NonMatchingTag;
431
          end if;
432
        end if;
433
 
434
      when st_Arbitrate_QRR_CheckSlot =>
435
        if SlotIsZero = '1' then
436
          NextStTag <= st_Ready_QRY_LoadRN16Handler_AND_SaveRN;
437
        else
438
          NextStTag <= st_Arbitrate;
439
        end if;
440
 
441
        -----------------------------------------------------------------------
442
        -- REPLY    (in next state process)
443
        -----------------------------------------------------------------------
444
      when st_Reply =>
445
        -- If interrogator reponse time expires, tag exits the Reply state
446
        if T2ExpFlag = '1' then
447
          NextStTag <= st_Arbitrate;
448
        end if;
449
        -- Query command, in the Reply state, behaves as in the Ready state
450
        if CommDone = cmd_Query then
451
          if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1'then
452
            NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
453
          else
454
            NextStTag <= st_Ready;
455
          end if;
456
          -- QueryRep behaves as in the Arbitrate state
457
        elsif CommDone = cmd_QueryRep then
458
          if CurrSession = Data_r(1 downto 0) then
459
            NextStTag <= st_Arbitrate_QRR_CheckSlot;
460
          end if;
461
          -- After Adjusting Q, the behavior of a QueryAdjust command
462
          -- is the same as the Query Command.
463
        elsif CommDone = cmd_QueryAdjust then
464
          if CurrSession = Data_r(4 downto 3) then
465
            if Data_r(2 downto 0) = "000" or Data_r(2 downto 0) = "110" or Data_r(2 downto 0) = "011" then
466
              NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
467
            end if;
468
          end if;
469
        elsif CommDone = cmd_Ack then
470
          if RN16_r = RN16Handler then
471
            NextStTag <= st_Reply_ACK_GetPC;
472
          else
473
            NextStTag <= st_Arbitrate;
474
          end if;
475
        elsif CommDone = cmd_Nak then
476
          NextStTag <= st_Arbitrate;
477
          -- Select Command behaves always as in the Ready state!
478
        elsif CommDone = cmd_Select then
479
          if Select_Address_Pointer_Length_OK = '1' then
480
            NextStTag <= st_Ready_SEL_GetWord;
481
          else
482
            NextStTag <= st_Ready_SEL_NonMatchingTag;
483
          end if;
484
        elsif (CommDone = cmd_Invalid) or (CommDone = cmd_NULL) then
485
          NextStTag <= st_Reply;
486
        else
487
          NextStTag <= st_Arbitrate;
488
        end if;
489
 
490
      when st_Reply_ACK_GetPC =>
491
        if mem_RB = '1' then
492
          NextStTag <= st_Reply_ACK_SendPC_AND_DecodeEPCLength;
493
        end if;
494
 
495
      when st_Reply_ACK_SendPC_AND_DecodeEPCLength =>
496
        if mem_RB = '1' then
497
          NextStTag <= st_Reply_ACK_GetAndSendEPC;
498
        end if;
499
 
500
      when st_Reply_ACK_GetAndSendEPC =>
501
        if mem_RB = '1' then
502
          if unsigned(GPR) /= 0 then
503
            NextStTag <= st_Reply_ACK_GetAndSendEPC;
504
          else
505
            NextStTag <= st_Reply_ACK_GetAndSendCRC16;
506
          end if;
507
        end if;
508
 
509
      when st_Reply_ACK_GetAndSendCRC16 =>
510
        if mem_RB = '1' then
511
          NextStTag <= st_Acknowledged;
512
        end if;
513
 
514
        -----------------------------------------------------------------------
515
        -- ACKNOWLEDGED    (in next state process)
516
        -----------------------------------------------------------------------
517
      when st_Acknowledged =>
518
        -- If interrogator reponse time expires, tag exits the Acknowledged state
519
        if T2ExpFlag = '1' then
520
          NextStTag <= st_Arbitrate;
521
        end if;
522
        if CommDone = cmd_Query then
523
          NextStTag <= st_Acknowledged_QRY_CheckFlags;
524
        elsif CommDone = cmd_QueryRep then
525
          if CurrSession = Data_r(1 downto 0) then
526
            NextStTag <= st_Ready;
527
          end if;
528
        elsif CommDone = cmd_QueryAdjust then
529
          if CurrSession = Data_r(4 downto 3) then
530
            NextStTag <= st_Ready;
531
          end if;
532
          -- Ack Command is the same as in the Reply state.
533
        elsif CommDone = cmd_Ack then
534
          if RN16_r = RN16Handler then
535
            NextStTag <= st_Reply_ACK_GetPC;
536
          else
537
            NextStTag <= st_Arbitrate;
538
          end if;
539
        elsif CommDone = cmd_Nak then
540
          NextStTag <= st_Arbitrate;
541
        elsif CommDone = cmd_ReqRN then
542
          if RN16_r = RN16Handler then
543
            NextStTag <= st_Acknowledged_RRN_LoadHandler_AND_SaveRN;
544
          end if;
545
          -- Select Command behaves always as in the Ready state!
546
        elsif CommDone = cmd_Select then
547
          if Select_Address_Pointer_Length_OK = '1' then
548
            NextStTag <= st_Ready_SEL_GetWord;
549
          else
550
            NextStTag <= st_Ready_SEL_NonMatchingTag;
551
          end if;
552
        elsif (CommDone = cmd_Invalid) or (CommDone = cmd_NULL) then
553
          NextStTag <= st_Acknowledged;
554
        else
555
          NextStTag <= st_Arbitrate;
556
        end if;
557
 
558
      when st_Acknowledged_QRY_CheckFlags =>
559
        -- Query Command in the Acknowledged state is almost the same as in the
560
        -- Ready state. The difference is that the inventoried flags may change
561
        -- (if the session is the same) before evaluating the Query condition.
562
        if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1'then
563
          NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
564
        else
565
          NextStTag <= st_Ready;
566
        end if;
567
 
568
      when st_Acknowledged_RRN_LoadHandler_AND_SaveRN =>
569
        if mem_RB = '1' then
570
          NextStTag <= st_Acknowledged_RRN_BackscatterHandler_AND_SaveRN;
571
        end if;
572
 
573
      when st_Acknowledged_RRN_BackscatterHandler_AND_SaveRN =>
574
        if mem_RB = '1' then
575
          NextStTag <= st_Secured;
576
        end if;
577
 
578
        -----------------------------------------------------------------------
579
        -- OPEN         (in next state process)
580
        -----------------------------------------------------------------------
581
      when st_Open =>
582
        -- Query in Open = Query in Acknowledged
583
        if CommDone = cmd_Query then
584
          NextStTag <= st_Acknowledged_QRY_CheckFlags;
585
        elsif CommDone = cmd_QueryRep then
586
          if CurrSession = Data_r(1 downto 0) then
587
            NextStTag <= st_Ready;
588
          end if;
589
        elsif CommDone = cmd_QueryAdjust then
590
          if CurrSession = Data_r(4 downto 3) then
591
            NextStTag <= st_Ready;
592
          end if;
593
        elsif CommDone = cmd_Ack then
594
          if RN16_r = RN16Handler then
595
            NextStTag <= st_Open_ACK_GetPC;
596
          else
597
            NextStTag <= st_Arbitrate;
598
          end if;
599
        elsif CommDone = cmd_Nak then
600
          NextStTag <= st_Arbitrate;
601
        elsif CommDone = cmd_ReqRN then
602
          if RN16_r = RN16Handler then
603
            NextStTag <= st_Open_RRN_LoadHandler_AND_SaveRN;
604
          end if;
605
          -- Select Command behaves always as in the Ready state!
606
        elsif CommDone = cmd_Select then
607
          if Select_Address_Pointer_Length_OK = '1' then
608
            NextStTag <= st_Ready_SEL_GetWord;
609
          else
610
            NextStTag <= st_Ready_SEL_NonMatchingTag;
611
          end if;
612
-- elsif CommDone = cmd_Kill then       -- See kill flowchart pg.60 (EPC Standard)
613
--          if "Valid handle" then
614
--            if "Kill Password != 0" then
615
--              if "Valid Kill Password" then
616
--                NextStTag <= st_Killed;
617
--              else
618
--                NextStTag <= st_Arbitrate;
619
--              end if;
620
--            end if;
621
--          end if;
622
--        elsif CommDone = cmd_Access then  -- See Access flowchart pg.63 (EPC Standard)
623
--          if "Valid Handle" then
624
--            if "Valid Access Password" then
625
--              NextStTag <= st_Secured;
626
--            else
627
--              NextStTag <= st_Arbitrate;
628
--            end if;
629
--          end if;
630
        elsif CommDone = cmd_Invalid then  -- See state & note pg.73
631
          NextStTag <= st_Arbitrate;
632
        end if;
633
 
634
      when st_Open_RRN_LoadHandler_AND_SaveRN =>
635
        if mem_RB = '1' then
636
          NextStTag <= st_Open_RRN_BackscatterHandler_AND_SaveRN;
637
        end if;
638
 
639
      when st_Open_RRN_BackscatterHandler_AND_SaveRN =>
640
        if mem_RB = '1' then
641
          NextStTag <= st_Open;
642
        end if;
643
 
644
      when st_Open_ACK_GetPC =>
645
        if mem_RB = '1' then
646
          NextStTag <= st_Open_ACK_SendPC_AND_DecodeEPCLength;
647
        end if;
648
 
649
      when st_Open_ACK_SendPC_AND_DecodeEPCLength =>
650
        if mem_RB = '1' then
651
          NextStTag <= st_Open_ACK_GetAndSendEPC;
652
        end if;
653
 
654
      when st_Open_ACK_GetAndSendEPC =>
655
        if mem_RB = '1' then
656
          if unsigned(GPR) /= 0 then
657
            NextStTag <= st_Open_ACK_GetAndSendEPC;
658
          else
659
            NextStTag <= st_Open_ACK_GetAndSendCRC16;
660
          end if;
661
        end if;
662
 
663
      when st_Open_ACK_GetAndSendCRC16 =>
664
        if mem_RB = '1' then
665
          NextStTag <= st_Open;
666
        end if;
667
 
668
        -----------------------------------------------------------------------
669
        -- SECURED    (in next state process)
670
        -----------------------------------------------------------------------
671
      when st_Secured =>
672
        -- Query in Secured = Query in Acknowledged
673
        if CommDone = cmd_Query then
674
          NextStTag <= st_Acknowledged_QRY_CheckFlags;
675
        elsif CommDone = cmd_QueryRep then
676
          if CurrSession = Data_r(1 downto 0) then
677
            NextStTag <= st_Ready;
678
          end if;
679
        elsif CommDone = cmd_QueryAdjust then
680
          if CurrSession = Data_r(4 downto 3) then
681
            NextStTag <= st_Ready;
682
          end if;
683
        elsif CommDone = cmd_Ack then
684
          if RN16_r = RN16Handler then
685
            NextStTag <= st_Secured_ACK_GetPC;
686
          else
687
            NextStTag <= st_Arbitrate;
688
          end if;
689
        elsif CommDone = cmd_Nak then
690
          NextStTag <= st_Arbitrate;
691
        elsif CommDone = cmd_ReqRN then
692
          if RN16_r = RN16Handler then
693
            NextStTag <= st_Secured_RRN_LoadHandler_AND_SaveRN;
694
          end if;
695
          -- Select Command behaves always as in the Ready state!
696
        elsif CommDone = cmd_Select then
697
          if Select_Address_Pointer_Length_OK = '1' then
698
            NextStTag <= st_Ready_SEL_GetWord;
699
          else
700
            NextStTag <= st_Ready_SEL_NonMatchingTag;
701
          end if;
702
        elsif CommDone = cmd_Write then
703
          if RN16_r = RN16Handler then
704
            NextStTag <= st_Secured_WR_CheckMemoryBounds;
705
          end if;
706
        elsif CommDone = cmd_Read then
707
          if RN16_r = RN16Handler then
708
            NextStTag <= st_Secured_RD_CheckMemoryBounds;
709
          end if;
710
-- elsif CommDone = cmd_Kill then       -- See kill flowchart pg.60 (EPC Standard)
711
--          if "Valid handle" then
712
--            if "Kill Password != 0" then
713
--              if "Valid Kill Password" then
714
--                NextStTag <= st_Killed;
715
--              else
716
--                NextStTag <= st_Arbitrate;
717
--              end if;
718
--            end if;
719
--          end if;
720
--        elsif CommDone = cmd_Access then  -- See Access flowchart pg.63 (EPC Standard)
721
--          if "Valid Handle" then
722
--            if "Valid Access Password" then
723
--              NextStTag <= st_Secured;
724
--            else
725
--              NextStTag <= st_Arbitrate;
726
--            end if;
727
--          end if;
728
        elsif CommDone = cmd_Invalid then  -- See state & note pg.74
729
          NextStTag <= st_Arbitrate;
730
        end if;
731
 
732
      when st_Secured_RRN_LoadHandler_AND_SaveRN =>
733
        if mem_RB = '1' then
734
          NextStTag <= st_Secured_RRN_BackscatterHandler_AND_SaveRN;
735
        end if;
736
 
737
      when st_Secured_RRN_BackscatterHandler_AND_SaveRN =>
738
        if mem_RB = '1' then
739
          NextStTag <= st_Secured;
740
        end if;
741
 
742
      when st_Secured_ACK_GetPC =>
743
        if mem_RB = '1' then
744
          NextStTag <= st_Secured_ACK_SendPC_AND_DecodeEPCLength;
745
        end if;
746
 
747
      when st_Secured_ACK_SendPC_AND_DecodeEPCLength =>
748
        if mem_RB = '1' then
749
          NextStTag <= st_Secured_ACK_GetAndSendEPC;
750
        end if;
751
 
752
      when st_Secured_ACK_GetAndSendEPC =>
753
        if mem_RB = '1' then
754
          if unsigned(GPR) /= 0 then
755
            NextStTag <= st_Secured_ACK_GetAndSendEPC;
756
          else
757
            NextStTag <= st_Secured_ACK_GetAndSendCRC16;
758
          end if;
759
        end if;
760
 
761
      when st_Secured_ACK_GetAndSendCRC16 =>
762
        if mem_RB = '1' then
763
          NextStTag <= st_Secured;
764
        end if;
765
 
766
      when st_Secured_WR_CheckMemoryBounds =>
767
        if Write_Address_Pointer_Length_OK = '1' then
768
          NextStTag <= st_Secured_WR_WriteWord;
769
        else
770
          NextStTag <= st_Secured;
771
        end if;
772
 
773
      when st_Secured_WR_WriteWord =>
774
        if mem_RB = '1' then
775
          NextStTag <= st_Secured_WR_WriteIsDone;
776
        end if;
777
 
778
      when st_Secured_WR_WriteIsDone =>
779
        if mem_RB = '1' then
780
          NextStTag <= st_Secured;
781
        end if;
782
 
783
      when st_Secured_RD_CheckMemoryBounds =>
784
        if Read_Address_Pointer_Length_OK = '1' then
785
          NextStTag <= st_Secured_RD_ReadMemory;
786
        else
787
          NextStTag <= st_Secured;
788
        end if;
789
 
790
      when st_Secured_RD_ReadMemory =>
791
        if mem_RB = '1' then
792
          NextStTag <= st_Secured_RD_Read_AND_Send;
793
        end if;
794
 
795
      when st_Secured_RD_Read_AND_Send =>
796
        if mem_RB = '1' then
797
          if unsigned(GPR) /= 0 then
798
            NextStTag <= st_Secured_RD_Read_AND_Send;
799
          else
800
            NextStTag <= st_Secured_RD_SendLast;
801
          end if;
802
        end if;
803
 
804
      when st_Secured_RD_SendLast =>
805
        if mem_RB = '1' then
806
          NextStTag <= st_Secured_RD_SendHandle;
807
        end if;
808
 
809
      when st_Secured_RD_SendHandle =>
810
        NextStTag <= st_Secured;
811
 
812
        -----------------------------------------------------------------------
813
        -- KILLED    (in next state process)
814
        -----------------------------------------------------------------------
815
      when st_Killed =>
816
        NextStTag <= st_Killed;
817
 
818
      when others => null;
819
    end case;
820
  end process NEXT_ST;
821
 
822
 
823
-------------------------------------------------------------------------------
824
-------------------------------------------------------------------------------
825
-- OUTPUT DECODER PROCESS
826
-------------------------------------------------------------------------------
827
-------------------------------------------------------------------------------
828
  OUTPUT_DEC : process (StTag, CommDone, mem_RB, RN16Handler, GPR, Slot, CurrSession, CurrQ, mem_DTO, Query_SelectFlag_Match,
829
                        Query_InventoryFlag_Match, Select_Address_Pointer_Length_OK, SlotIsZero, Write_Address_Pointer_Length_OK,
830
                        Read_Address_Pointer_Length_OK, Data_r, Pointer_r, Length_r, SLOT_VALUE, rng_cout, GCounter2, GCounter,
831
                        ADRint, SelQ, RN16_r, SInvQ)
832
  begin  -- process OUTPUT_DEC
833
    RN16Handler_i   <= RN16Handler;
834
    GPR_i           <= GPR;
835
    Slot_i          <= Slot;
836
    mem_DTI_i       <= (others => '0');
837
    mem_WR_i        <= '0';
838
    mem_RD_i        <= '0';
839
    mem_ADR_i       <= (others => '0');
840
    mem_BANK_i      <= (others => '0');
841
    rng_cin_i       <= (others => '0');
842
    rng_init_i      <= '0';
843
    rng_ce_i        <= '0';
844
    CurrSession_i   <= CurrSession;
845
    CurrQ_i         <= CurrQ;
846
    FirstCompWord_i <= '0';
847
    GCounter_i      <= (others => '0');
848
    GCounter2_i     <= (others => '0');
849
    ADRint_i        <= (others => '0');
850
    -- SEL & Inventory Flags
851
    SelD            <= '0';
852
    SelCE           <= '0';
853
    SInvD           <= (others => '0');
854
    SInvCE          <= (others => '0');
855
    -- Transmitter
856
    trm_cmd_i       <= trmcmd_Null;
857
    trm_buf_i       <= (others => '0');
858
 
859
    case StTag is
860
      -----------------------------------------------------------------------
861
      -- POWERUP    (in output process)
862
      -----------------------------------------------------------------------
863
      when st_PowerUp =>
864
        if mem_RB = '1' then
865
          mem_ADR_i  <= MEMORY_KILL_RNG_ADDRESS_MSB;
866
          mem_BANK_i <= RESERVED_MEMORY_BANK;
867
          mem_RD_i   <= '1';
868
        end if;
869
 
870
      when st_PowerUp_GetFlagMSB =>
871
        if mem_RB = '1' then
872
          GPR_i(31 downto 16) <= mem_DTO;
873
          mem_ADR_i           <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
874
          mem_BANK_i          <= RESERVED_MEMORY_BANK;
875
          mem_RD_i            <= '1';
876
        end if;
877
 
878
      when st_PowerUp_GetFlagLSB =>
879
        if mem_RB = '1' then
880
          GPR_i(15 downto 0) <= mem_DTO;
881
        end if;
882
 
883
      when st_PowerUp_LoadRNG =>
884
        rng_init_i <= '1';
885
        rng_cin_i  <= GPR(30 downto 0);
886
        -----------------------------------------------------------------------
887
        -- READY    (in output process)
888
        -----------------------------------------------------------------------
889
      when st_Ready =>
890
        if CommDone = cmd_Query then
891
          if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1' then
892
            rng_ce_i      <= '1';       -- Prepare new RN
893
            CurrSession_i <= Data_r(6 downto 5);
894
            CurrQ_i       <= Data_r(3 downto 0);
895
          end if;
896
        elsif CommDone = cmd_Select then
897
          if Select_Address_Pointer_Length_OK = '1' then
898
            ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
899
            --       CompLSBit_i <= Pointer_r(3 downto 0);
900
            GCounter_i            <= Length_r;
901
          end if;
902
        end if;
903
 
904
      when st_Ready_QRY_LoadSlot_AND_SaveRN =>
905
        if mem_RB = '1' then
906
          Slot_i     <= SLOT_VALUE;
907
          mem_DTI_i  <= rng_cout(15 downto 0);
908
          mem_ADR_i  <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
909
          mem_BANK_i <= RESERVED_MEMORY_BANK;
910
          mem_WR_i   <= '1';
911
        end if;
912
 
913
      when st_Ready_QRY_CheckSlot_AND_SaveRN =>
914
        if mem_RB = '1' then
915
          mem_DTI_i  <= '0' & rng_cout(30 downto 16);
916
          mem_ADR_i  <= MEMORY_KILL_RNG_ADDRESS_MSB;
917
          mem_BANK_i <= RESERVED_MEMORY_BANK;
918
          mem_WR_i   <= '1';
919
          if SlotIsZero = '1' then
920
            rng_ce_i <= '1';            -- Prepare new RN
921
          end if;
922
        end if;
923
 
924
      when st_Ready_QRY_LoadRN16Handler_AND_SaveRN =>
925
        if mem_RB = '1' then
926
          RN16Handler_i <= rng_cout(15 downto 0);
927
          mem_DTI_i     <= rng_cout(15 downto 0);
928
          mem_ADR_i     <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
929
          mem_BANK_i    <= RESERVED_MEMORY_BANK;
930
          mem_WR_i      <= '1';
931
        end if;
932
 
933
      when st_Ready_QRY_BackscatterRN16_AND_SaveRN =>
934
        if mem_RB = '1' then
935
          mem_DTI_i  <= '0' & rng_cout(30 downto 16);
936
          mem_ADR_i  <= MEMORY_KILL_RNG_ADDRESS_MSB;
937
          mem_BANK_i <= RESERVED_MEMORY_BANK;
938
          mem_WR_i   <= '1';
939
          -- Backscatter RN16
940
          trm_cmd_i  <= trmcmd_Send;
941
          trm_buf_i  <= RN16Handler;
942
        end if;
943
 
944
        -- NOTE: Select command does not support
945
        -- "bit" comparison. Comparison starts at
946
        -- the beginning of a Word!!  
947
      when st_Ready_SEL_GetWord =>
948
        GCounter2_i <= GCounter2;       -- Number of bits already compared
949
        GCounter_i  <= GCounter;        -- Number of bits to compare
950
        ADRint_i    <= ADRint;
951
-- CompLSBit_i <= CompLSBit;            -- Starting bits (unused within this version)
952
        if mem_RB = '1' then
953
          mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
954
          mem_BANK_i <= Data_r(2 downto 1);
955
          mem_RD_i   <= '1';
956
        end if;
957
 
958
      when st_Ready_SEL_PrepareComparison =>
959
        GCounter2_i <= GCounter2;            -- Number of bits already compared
960
        GCounter_i  <= GCounter;             -- Number of bits to compare
961
        ADRint_i    <= ADRint;
962
        if mem_RB = '1' then
963
          ADRint_i           <= ADRint + 1;  -- prepare next word address
964
          GPR_i(15 downto 0) <= mem_DTO;
965
        end if;
966
 
967
      when st_Ready_SEL_CompareWords =>
968
        GCounter2_i <= GCounter2 + conv_std_logic_vector(16, 8);  -- Number of bits already compared
969
        GCounter_i  <= GCounter - conv_std_logic_vector(16, 8);  -- Number of Bits to compare
970
        ADRint_i    <= ADRint;
971
 
972
      when st_Ready_SEL_CompareBits =>
973
        GCounter2_i <= GCounter2 + conv_std_logic_vector(unsigned(GCounter), 8);  -- Number of bits already compared
974
        GCounter_i  <= GCounter - conv_std_logic_vector(unsigned(GCounter), 8);  -- Number of Bits to compare
975
        ADRint_i    <= ADRint;
976
 
977
      when st_Ready_SEL_MatchingTag =>
978
        case Data_r(5 downto 3) is      -- Action
979
          when "000" =>
980
            if Data_r(8) = '1' then
981
              if Data_r(7 downto 6) = "00" then
982
                SelD  <= '1';
983
                SelCE <= '1';
984
              end if;
985
            else
986
              SInvD(conv_integer(Data_r(7 downto 6)))  <= '0';  -- -> A
987
              SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
988
            end if;
989
          when "001" =>
990
            if Data_r(8) = '1' then
991
              if Data_r(7 downto 6) = "00" then
992
                SelD  <= '1';
993
                SelCE <= '1';
994
              end if;
995
            else
996
              SInvD(conv_integer(Data_r(7 downto 6)))  <= '0';  -- -> A
997
              SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
998
            end if;
999
          when "011" =>
1000
            if Data_r(8) = '1' then
1001
              if Data_r(7 downto 6) = "00" then
1002
                SelD  <= not(SelQ);
1003
                SelCE <= '1';
1004
              end if;
1005
            else
1006
              SInvD(conv_integer(Data_r(7 downto 6)))  <= not(SInvQ(conv_integer(Data_r(7 downto 6))));  -- -> negate
1007
              SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
1008
            end if;
1009
          when "100" =>
1010
            if Data_r(8) = '1' then
1011
              if Data_r(7 downto 6) = "00" then
1012
                SelD  <= '0';
1013
                SelCE <= '1';
1014
              end if;
1015
            else
1016
              SInvD(conv_integer(Data_r(7 downto 6)))  <= '1';  -- -> B
1017
              SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
1018
            end if;
1019
          when "101" =>
1020
            if Data_r(8) = '1' then
1021
              if Data_r(7 downto 6) = "00" then
1022
                SelD  <= '0';
1023
                SelCE <= '1';
1024
              end if;
1025
            else
1026
              SInvD(conv_integer(Data_r(7 downto 6)))  <= '1';  -- -> B
1027
              SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
1028
            end if;
1029
          when others => null;
1030
        end case;
1031
 
1032
      when st_Ready_SEL_NonMatchingTag =>
1033
        case Data_r(5 downto 3) is      -- Action
1034
          when "000" =>
1035
            if Data_r(8) = '1' then
1036
              if Data_r(7 downto 6) = "00" then
1037
                SelD  <= '0';
1038
                SelCE <= '1';
1039
              end if;
1040
            else
1041
              SInvD(conv_integer(Data_r(7 downto 6)))  <= '1';  -- -> B
1042
              SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
1043
            end if;
1044
          when "010" =>
1045
            if Data_r(8) = '1' then
1046
              if Data_r(7 downto 6) = "00" then
1047
                SelD  <= '0';
1048
                SelCE <= '1';
1049
              end if;
1050
            else
1051
              SInvD(conv_integer(Data_r(7 downto 6)))  <= '1';  -- -> B
1052
              SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
1053
            end if;
1054
          when "100" =>
1055
            if Data_r(8) = '1' then
1056
              if Data_r(7 downto 6) = "00" then
1057
                SelD  <= '1';
1058
                SelCE <= '1';
1059
              end if;
1060
            else
1061
              SInvD(conv_integer(Data_r(7 downto 6)))  <= '0';  -- -> A
1062
              SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
1063
            end if;
1064
          when "110" =>
1065
            if Data_r(8) = '1' then
1066
              if Data_r(7 downto 6) = "00" then
1067
                SelD  <= '1';
1068
                SelCE <= '1';
1069
              end if;
1070
            else
1071
              SInvD(conv_integer(Data_r(7 downto 6)))  <= '0';  -- -> A
1072
              SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
1073
            end if;
1074
          when "111" =>
1075
            if Data_r(8) = '1' then
1076
              if Data_r(7 downto 6) = "00" then
1077
                SelD  <= not(SelQ);
1078
                SelCE <= '1';
1079
              end if;
1080
            else
1081
              SInvD(conv_integer(Data_r(7 downto 6)))  <= not(SInvQ(conv_integer(Data_r(7 downto 6))));  -- -> negate
1082
              SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
1083
            end if;
1084
          when others => null;
1085
        end case;
1086
        -----------------------------------------------------------------------
1087
        -- ARBITRATE    (in output process)
1088
        -----------------------------------------------------------------------
1089
      when st_Arbitrate =>
1090
        if CommDone = cmd_Query then
1091
          if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1' then
1092
            rng_ce_i      <= '1';       -- Prepare new RN
1093
            CurrSession_i <= Data_r(6 downto 5);
1094
            CurrQ_i       <= Data_r(3 downto 0);
1095
          end if;
1096
        elsif CommDone = cmd_QueryRep then
1097
          if CurrSession = Data_r(1 downto 0) then
1098
            Slot_i <= Slot - '1';
1099
          end if;
1100
        elsif CommDone = cmd_QueryAdjust then
1101
          if CurrSession = Data_r(4 downto 3) then
1102
            if Data_r(2 downto 0) = "000" then                  -- Q = Q
1103
              rng_ce_i <= '1';          -- Prepare new RN
1104
            elsif Data_r(2 downto 0) = "110"then                -- Q = Q + 1
1105
              rng_ce_i <= '1';          -- Prepare new RN
1106
              if CurrQ /= "1111" then
1107
                CurrQ_i <= CurrQ + '1';
1108
              end if;
1109
            elsif Data_r(2 downto 0) = "011" then               -- Q = Q - 1
1110
              rng_ce_i <= '1';          -- Prepare new RN
1111
              if CurrQ /= "0000" then
1112
                CurrQ_i <= CurrQ - '1';
1113
              end if;
1114
            end if;
1115
          end if;
1116
        elsif CommDone = cmd_Select then
1117
          if Select_Address_Pointer_Length_OK = '1' then
1118
            ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
1119
            --     CompLSBit_i <= Pointer_r(3 downto 0);
1120
            GCounter_i            <= Length_r;
1121
          end if;
1122
        end if;
1123
 
1124
      when st_Arbitrate_QRR_CheckSlot =>
1125
        if SlotIsZero = '1' then
1126
          rng_ce_i <= '1';              -- Prepare new RN
1127
        end if;
1128
 
1129
        -----------------------------------------------------------------------
1130
        -- REPLY    (in output process)
1131
        -----------------------------------------------------------------------
1132
      when st_Reply =>
1133
        if CommDone = cmd_Query then
1134
          if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1' then
1135
            rng_ce_i      <= '1';                  -- Prepare new RN
1136
            CurrSession_i <= Data_r(6 downto 5);
1137
            CurrQ_i       <= Data_r(3 downto 0);
1138
          end if;
1139
        elsif CommDone = cmd_QueryRep then
1140
          if CurrSession = Data_r(1 downto 0) then
1141
            Slot_i <= Slot - '1';
1142
          end if;
1143
        elsif CommDone = cmd_QueryAdjust then
1144
          if CurrSession = Data_r(4 downto 3) then
1145
            if Data_r(2 downto 0) = "000" then     -- Q = Q
1146
              rng_ce_i <= '1';                     -- Prepare new RN
1147
            elsif Data_r(2 downto 0) = "110"then   -- Q = Q + 1
1148
              rng_ce_i <= '1';                     -- Prepare new RN
1149
              if CurrQ /= "1111" then
1150
                CurrQ_i <= CurrQ + '1';
1151
              end if;
1152
            elsif Data_r(2 downto 0) = "011" then  -- Q = Q - 1
1153
              rng_ce_i <= '1';                     -- Prepare new RN
1154
              if CurrQ /= "0000" then
1155
                CurrQ_i <= CurrQ - '1';
1156
              end if;
1157
            end if;
1158
          end if;
1159
        elsif CommDone = cmd_Select then
1160
          if Select_Address_Pointer_Length_OK = '1' then
1161
            ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
1162
            -- CompLSBit_i <= Pointer_r(3 downto 0);
1163
            GCounter_i            <= Length_r;
1164
          end if;
1165
        elsif CommDone = cmd_Ack then
1166
          if RN16_r = RN16Handler then
1167
            ADRint_i <= MEMORY_PC_ADDRESS_16b;
1168
          end if;
1169
        end if;
1170
 
1171
      when st_Reply_ACK_GetPC =>
1172
        ADRint_i <= ADRint;
1173
        if mem_RB = '1' then
1174
          mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1175
          mem_BANK_i <= EPC_MEMORY_BANK;
1176
          mem_RD_i   <= '1';
1177
          ADRint_i   <= ADRint + '1';
1178
          GPR_i      <= (others => '0');
1179
        end if;
1180
 
1181
      when st_Reply_ACK_SendPC_AND_DecodeEPCLength =>
1182
        ADRint_i <= ADRint;
1183
        if mem_RB = '1' then
1184
          mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1185
          mem_BANK_i <= EPC_MEMORY_BANK;
1186
          ADRint_i   <= ADRint + '1';
1187
          mem_RD_i   <= '1';
1188
-- GPR_i(4 downto 0) <= mem_DTO(0 to 4);  --Length of the PC+EPC (in words)
1189
          GPR_i(4)   <= mem_DTO(0);
1190
          GPR_i(3)   <= mem_DTO(1);
1191
          GPR_i(2)   <= mem_DTO(2);
1192
          GPR_i(1)   <= mem_DTO(3);
1193
          GPR_i(0)   <= mem_DTO(4);
1194
          trm_cmd_i  <= trmcmd_Send;
1195
          trm_buf_i  <= mem_DTO;
1196
        end if;
1197
 
1198
      when st_Reply_ACK_GetAndSendEPC =>
1199
        ADRint_i <= ADRint;
1200
        if mem_RB = '1' then
1201
          if unsigned(GPR) /= 0 then
1202
            mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1203
            mem_BANK_i <= EPC_MEMORY_BANK;
1204
            ADRint_i   <= ADRint + '1';
1205
            mem_RD_i   <= '1';
1206
            GPR_i      <= GPR - '1';
1207
            trm_cmd_i  <= trmcmd_Send;
1208
            trm_buf_i  <= mem_DTO;
1209
          else
1210
            mem_ADR_i  <= MEMORY_CRC16_ADDRESS;
1211
            mem_BANK_i <= EPC_MEMORY_BANK;
1212
            mem_RD_i   <= '1';
1213
          end if;
1214
        end if;
1215
 
1216
      when st_Reply_ACK_GetAndSendCRC16 =>
1217
        if mem_RB = '1' then
1218
          trm_cmd_i <= trmcmd_Send;
1219
          trm_buf_i <= mem_DTO;
1220
        end if;
1221
 
1222
        -----------------------------------------------------------------------
1223
        -- ACKNOWLEDGED    (in output process)
1224
        -----------------------------------------------------------------------
1225
      when st_Acknowledged =>
1226
        if CommDone = cmd_Query then
1227
          if Data_r(6 downto 5) = CurrSession then  --TODO: Verify flags refresh in one clockcycle.  -- Toggle inventoried flag
1228
            case CurrSession is
1229
              when "00" =>
1230
                SInvD(0)  <= not(SInvQ(0));
1231
                SInvCE(0) <= '1';
1232
              when "01" =>
1233
                SInvD(1)  <= not(SInvQ(1));
1234
                SInvCE(1) <= '1';
1235
              when "10" =>
1236
                SInvD(2)  <= not(SInvQ(2));
1237
                SInvCE(2) <= '1';
1238
              when "11" =>
1239
                SInvD(3)  <= not(SInvQ(3));
1240
                SInvCE(3) <= '1';
1241
              when others => null;
1242
            end case;
1243
          end if;
1244
        elsif CommDone = cmd_QueryRep then
1245
          if CurrSession = Data_r(1 downto 0) then
1246
            -- Toggle inventoried flag
1247
            case CurrSession is
1248
              when "00" =>
1249
                SInvD(0)  <= not(SInvQ(0));
1250
                SInvCE(0) <= '1';
1251
              when "01" =>
1252
                SInvD(1)  <= not(SInvQ(1));
1253
                SInvCE(1) <= '1';
1254
              when "10" =>
1255
                SInvD(2)  <= not(SInvQ(2));
1256
                SInvCE(2) <= '1';
1257
              when "11" =>
1258
                SInvD(3)  <= not(SInvQ(3));
1259
                SInvCE(3) <= '1';
1260
              when others => null;
1261
            end case;
1262
          end if;
1263
        elsif CommDone = cmd_QueryAdjust then
1264
          if CurrSession = Data_r(4 downto 3) then
1265
            -- Toggle inventoried flag
1266
            case CurrSession is
1267
              when "00" =>
1268
                SInvD(0)  <= not(SInvQ(0));
1269
                SInvCE(0) <= '1';
1270
              when "01" =>
1271
                SInvD(1)  <= not(SInvQ(1));
1272
                SInvCE(1) <= '1';
1273
              when "10" =>
1274
                SInvD(2)  <= not(SInvQ(2));
1275
                SInvCE(2) <= '1';
1276
              when "11" =>
1277
                SInvD(3)  <= not(SInvQ(3));
1278
                SInvCE(3) <= '1';
1279
              when others => null;
1280
            end case;
1281
          end if;
1282
        elsif CommDone = cmd_Ack then
1283
          if RN16_r = RN16Handler then
1284
            ADRint_i <= MEMORY_PC_ADDRESS_16b;
1285
          end if;
1286
        elsif CommDone = cmd_ReqRN then
1287
          if RN16_r = RN16Handler then
1288
            rng_ce_i <= '1';            -- Prepare new RN
1289
          end if;
1290
        elsif CommDone = cmd_Select then
1291
          if Select_Address_Pointer_Length_OK = '1' then
1292
            ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
1293
            --  CompLSBit_i <= Pointer_r(3 downto 0);
1294
            GCounter_i            <= Length_r;
1295
          end if;
1296
        end if;
1297
 
1298
      when st_Acknowledged_QRY_CheckFlags =>
1299
        if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1' then
1300
          rng_ce_i      <= '1';         -- Prepare new RN
1301
          CurrSession_i <= Data_r(6 downto 5);
1302
          CurrQ_i       <= Data_r(3 downto 0);
1303
        end if;
1304
 
1305
      when st_Acknowledged_RRN_LoadHandler_AND_SaveRN =>
1306
        if mem_RB = '1' then
1307
          RN16Handler_i <= rng_cout(15 downto 0);
1308
          mem_DTI_i     <= rng_cout(15 downto 0);
1309
          mem_ADR_i     <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
1310
          mem_BANK_i    <= RESERVED_MEMORY_BANK;
1311
          mem_WR_i      <= '1';
1312
        end if;
1313
 
1314
      when st_Acknowledged_RRN_BackscatterHandler_AND_SaveRN =>
1315
        if mem_RB = '1' then
1316
          mem_DTI_i  <= '0' & rng_cout(30 downto 16);
1317
          mem_ADR_i  <= MEMORY_KILL_RNG_ADDRESS_MSB;
1318
          mem_BANK_i <= RESERVED_MEMORY_BANK;
1319
          mem_WR_i   <= '1';
1320
          -- Backscatter RN16
1321
          trm_cmd_i  <= trmcmd_Send;
1322
          trm_buf_i  <= RN16Handler;
1323
        end if;
1324
 
1325
        -----------------------------------------------------------------------
1326
        -- OPEN            (in output process)
1327
        -----------------------------------------------------------------------
1328
      when st_Open =>
1329
        if CommDone = cmd_Query then
1330
          if Data_r(6 downto 5) = CurrSession then  --TODO: Verify flags refresh in one clockcycle.                                                    
1331
            -- Toggle inventoried flag
1332
            case CurrSession is
1333
              when "00" =>
1334
                SInvD(0)  <= not(SInvQ(0));
1335
                SInvCE(0) <= '1';
1336
              when "01" =>
1337
                SInvD(1)  <= not(SInvQ(1));
1338
                SInvCE(1) <= '1';
1339
              when "10" =>
1340
                SInvD(2)  <= not(SInvQ(2));
1341
                SInvCE(2) <= '1';
1342
              when "11" =>
1343
                SInvD(3)  <= not(SInvQ(3));
1344
                SInvCE(3) <= '1';
1345
              when others => null;
1346
            end case;
1347
          end if;
1348
        elsif CommDone = cmd_QueryRep then
1349
          if CurrSession = Data_r(1 downto 0) then
1350
            -- Toggle inventoried flag
1351
            case CurrSession is
1352
              when "00" =>
1353
                SInvD(0)  <= not(SInvQ(0));
1354
                SInvCE(0) <= '1';
1355
              when "01" =>
1356
                SInvD(1)  <= not(SInvQ(1));
1357
                SInvCE(1) <= '1';
1358
              when "10" =>
1359
                SInvD(2)  <= not(SInvQ(2));
1360
                SInvCE(2) <= '1';
1361
              when "11" =>
1362
                SInvD(3)  <= not(SInvQ(3));
1363
                SInvCE(3) <= '1';
1364
              when others => null;
1365
            end case;
1366
          end if;
1367
        elsif CommDone = cmd_QueryAdjust then
1368
          if CurrSession = Data_r(4 downto 3) then
1369
            -- Toggle inventoried flag
1370
            case CurrSession is
1371
              when "00" =>
1372
                SInvD(0)  <= not(SInvQ(0));
1373
                SInvCE(0) <= '1';
1374
              when "01" =>
1375
                SInvD(1)  <= not(SInvQ(1));
1376
                SInvCE(1) <= '1';
1377
              when "10" =>
1378
                SInvD(2)  <= not(SInvQ(2));
1379
                SInvCE(2) <= '1';
1380
              when "11" =>
1381
                SInvD(3)  <= not(SInvQ(3));
1382
                SInvCE(3) <= '1';
1383
              when others => null;
1384
            end case;
1385
          end if;
1386
        elsif CommDone = cmd_Ack then
1387
          if RN16_r = RN16Handler then
1388
            ADRint_i <= MEMORY_PC_ADDRESS_16b;
1389
          end if;
1390
        elsif CommDone = cmd_ReqRN then
1391
          if RN16_r = RN16Handler then
1392
            rng_ce_i <= '1';            -- Prepare new RN
1393
          end if;
1394
        elsif CommDone = cmd_Select then
1395
          if Select_Address_Pointer_Length_OK = '1' then
1396
            ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
1397
-- CompLSBit_i <= Pointer_r(3 downto 0);
1398
            GCounter_i            <= Length_r;
1399
          end if;
1400
        end if;
1401
 
1402
      when st_Open_ACK_GetPC =>
1403
        ADRint_i <= ADRint;
1404
        if mem_RB = '1' then
1405
          mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1406
          mem_BANK_i <= EPC_MEMORY_BANK;
1407
          ADRint_i   <= ADRint + '1';
1408
          mem_RD_i   <= '1';
1409
          GPR_i      <= (others => '0');
1410
        end if;
1411
 
1412
      when st_Open_ACK_SendPC_AND_DecodeEPCLength =>
1413
        ADRint_i <= ADRint;
1414
        if mem_RB = '1' then
1415
          mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1416
          mem_BANK_i <= EPC_MEMORY_BANK;
1417
          ADRint_i   <= ADRint + '1';
1418
          mem_RD_i   <= '1';
1419
-- GPR_i(4 downto 0) <= mem_DTO(0 to 4);  --Length of the PC+EPC (in words)
1420
          GPR_i(4)   <= mem_DTO(0);
1421
          GPR_i(3)   <= mem_DTO(1);
1422
          GPR_i(2)   <= mem_DTO(2);
1423
          GPR_i(1)   <= mem_DTO(3);
1424
          GPR_i(0)   <= mem_DTO(4);
1425
          trm_cmd_i  <= trmcmd_Send;
1426
          trm_buf_i  <= mem_DTO;
1427
        end if;
1428
 
1429
      when st_Open_ACK_GetAndSendEPC =>
1430
        ADRint_i <= ADRint;
1431
        if mem_RB = '1' then
1432
          if unsigned(GPR) /= 0 then
1433
            mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1434
            mem_BANK_i <= EPC_MEMORY_BANK;
1435
            ADRint_i   <= ADRint + '1';
1436
            mem_RD_i   <= '1';
1437
            GPR_i      <= GPR - '1';
1438
            trm_cmd_i  <= trmcmd_Send;
1439
            trm_buf_i  <= mem_DTO;
1440
          else
1441
            mem_ADR_i  <= MEMORY_CRC16_ADDRESS;
1442
            mem_BANK_i <= EPC_MEMORY_BANK;
1443
            mem_RD_i   <= '1';
1444
          end if;
1445
        end if;
1446
 
1447
      when st_Open_ACK_GetAndSendCRC16 =>
1448
        if mem_RB = '1' then
1449
          trm_cmd_i <= trmcmd_Send;
1450
          trm_buf_i <= mem_DTO;
1451
        end if;
1452
 
1453
      when st_Open_RRN_LoadHandler_AND_SaveRN =>
1454
        if mem_RB = '1' then
1455
          RN16Handler_i <= rng_cout(15 downto 0);
1456
          mem_DTI_i     <= rng_cout(15 downto 0);
1457
          mem_ADR_i     <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
1458
          mem_BANK_i    <= RESERVED_MEMORY_BANK;
1459
          mem_WR_i      <= '1';
1460
        end if;
1461
 
1462
      when st_Open_RRN_BackscatterHandler_AND_SaveRN =>
1463
        if mem_RB = '1' then
1464
          mem_DTI_i  <= '0' & rng_cout(30 downto 16);
1465
          mem_ADR_i  <= MEMORY_KILL_RNG_ADDRESS_MSB;
1466
          mem_BANK_i <= RESERVED_MEMORY_BANK;
1467
          mem_WR_i   <= '1';
1468
          -- Backscatter RN16
1469
          trm_cmd_i  <= trmcmd_Send;
1470
          trm_buf_i  <= RN16Handler;
1471
        end if;
1472
 
1473
 
1474
 
1475
        -----------------------------------------------------------------------
1476
        -- SECURED      (in output process)
1477
        -----------------------------------------------------------------------      
1478
      when st_Secured =>
1479
        if CommDone = cmd_Query then
1480
          if Data_r(6 downto 5) = CurrSession then  --TODO: Verify flags refresh in one clockcycle.                                                    
1481
            -- Toggle inventoried flag
1482
            case CurrSession is
1483
              when "00" =>
1484
                SInvD(0)  <= not(SInvQ(0));
1485
                SInvCE(0) <= '1';
1486
              when "01" =>
1487
                SInvD(1)  <= not(SInvQ(1));
1488
                SInvCE(1) <= '1';
1489
              when "10" =>
1490
                SInvD(2)  <= not(SInvQ(2));
1491
                SInvCE(2) <= '1';
1492
              when "11" =>
1493
                SInvD(3)  <= not(SInvQ(3));
1494
                SInvCE(3) <= '1';
1495
              when others => null;
1496
            end case;
1497
          end if;
1498
        elsif CommDone = cmd_QueryRep then
1499
          if CurrSession = Data_r(1 downto 0) then
1500
            -- Toggle inventoried flag
1501
            case CurrSession is
1502
              when "00" =>
1503
                SInvD(0)  <= not(SInvQ(0));
1504
                SInvCE(0) <= '1';
1505
              when "01" =>
1506
                SInvD(1)  <= not(SInvQ(1));
1507
                SInvCE(1) <= '1';
1508
              when "10" =>
1509
                SInvD(2)  <= not(SInvQ(2));
1510
                SInvCE(2) <= '1';
1511
              when "11" =>
1512
                SInvD(3)  <= not(SInvQ(3));
1513
                SInvCE(3) <= '1';
1514
              when others => null;
1515
            end case;
1516
          end if;
1517
        elsif CommDone = cmd_QueryAdjust then
1518
          if CurrSession = Data_r(4 downto 3) then
1519
            -- Toggle inventoried flag
1520
            case CurrSession is
1521
              when "00" =>
1522
                SInvD(0)  <= not(SInvQ(0));
1523
                SInvCE(0) <= '1';
1524
              when "01" =>
1525
                SInvD(1)  <= not(SInvQ(1));
1526
                SInvCE(1) <= '1';
1527
              when "10" =>
1528
                SInvD(2)  <= not(SInvQ(2));
1529
                SInvCE(2) <= '1';
1530
              when "11" =>
1531
                SInvD(3)  <= not(SInvQ(3));
1532
                SInvCE(3) <= '1';
1533
              when others => null;
1534
            end case;
1535
          end if;
1536
        elsif CommDone = cmd_Ack then
1537
          if RN16_r = RN16Handler then
1538
            ADRint_i <= MEMORY_PC_ADDRESS_16b;
1539
          end if;
1540
        elsif CommDone = cmd_ReqRN then
1541
          if RN16_r = RN16Handler then
1542
            rng_ce_i <= '1';            -- Prepare new RN
1543
          end if;
1544
        elsif CommDone = cmd_Select then
1545
          if Select_Address_Pointer_Length_OK = '1' then
1546
            ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
1547
-- CompLSBit_i <= Pointer_r(3 downto 0);
1548
            GCounter_i            <= Length_r;
1549
          end if;
1550
        elsif CommDone = cmd_Read then
1551
          if RN16_r = RN16Handler then
1552
            GPR_i <= (others => '0');
1553
          end if;
1554
          -- Write command does not cause any FSM output at this point (see next_state_process)
1555
        end if;
1556
 
1557
      when st_Secured_ACK_GetPC =>
1558
        ADRint_i <= ADRint;
1559
        if mem_RB = '1' then
1560
          mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1561
          mem_BANK_i <= EPC_MEMORY_BANK;
1562
          ADRint_i   <= ADRint + '1';
1563
          mem_RD_i   <= '1';
1564
          GPR_i      <= (others => '0');
1565
        end if;
1566
 
1567
      when st_Secured_ACK_SendPC_AND_DecodeEPCLength =>
1568
        ADRint_i <= ADRint;
1569
        if mem_RB = '1' then
1570
          mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1571
          mem_BANK_i <= EPC_MEMORY_BANK;
1572
          ADRint_i   <= ADRint + '1';
1573
          mem_RD_i   <= '1';
1574
-- GPR_i(4 downto 0) <= mem_DTO(0 to 4);  --Length of the PC+EPC (in words)
1575
          GPR_i(4)   <= mem_DTO(0);
1576
          GPR_i(3)   <= mem_DTO(1);
1577
          GPR_i(2)   <= mem_DTO(2);
1578
          GPR_i(1)   <= mem_DTO(3);
1579
          GPR_i(0)   <= mem_DTO(4);
1580
          trm_cmd_i  <= trmcmd_Send;
1581
          trm_buf_i  <= mem_DTO;
1582
        end if;
1583
 
1584
      when st_Secured_ACK_GetAndSendEPC =>
1585
        ADRint_i <= ADRint;
1586
        if mem_RB = '1' then
1587
          if unsigned(GPR) /= 0 then
1588
            mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1589
            mem_BANK_i <= EPC_MEMORY_BANK;
1590
            ADRint_i   <= ADRint + '1';
1591
            mem_RD_i   <= '1';
1592
            GPR_i      <= GPR - '1';
1593
            trm_cmd_i  <= trmcmd_Send;
1594
            trm_buf_i  <= mem_DTO;
1595
          else
1596
            mem_ADR_i  <= MEMORY_CRC16_ADDRESS;
1597
            mem_BANK_i <= EPC_MEMORY_BANK;
1598
            mem_RD_i   <= '1';
1599
          end if;
1600
        end if;
1601
 
1602
      when st_Secured_ACK_GetAndSendCRC16 =>
1603
        if mem_RB = '1' then
1604
          trm_cmd_i <= trmcmd_Send;
1605
          trm_buf_i <= mem_DTO;
1606
        end if;
1607
 
1608
      when st_Secured_RRN_LoadHandler_AND_SaveRN =>
1609
        if mem_RB = '1' then
1610
          RN16Handler_i <= rng_cout(15 downto 0);
1611
          mem_DTI_i     <= rng_cout(15 downto 0);
1612
          mem_ADR_i     <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
1613
          mem_BANK_i    <= RESERVED_MEMORY_BANK;
1614
          mem_WR_i      <= '1';
1615
        end if;
1616
 
1617
      when st_Secured_RRN_BackscatterHandler_AND_SaveRN =>
1618
        if mem_RB = '1' then
1619
          mem_DTI_i  <= '0' & rng_cout(30 downto 16);
1620
          mem_ADR_i  <= MEMORY_KILL_RNG_ADDRESS_MSB;
1621
          mem_BANK_i <= RESERVED_MEMORY_BANK;
1622
          mem_WR_i   <= '1';
1623
          -- Backscatter RN16
1624
          trm_cmd_i  <= trmcmd_Send;
1625
          trm_buf_i  <= RN16Handler;
1626
        end if;
1627
 
1628
      when st_Secured_WR_CheckMemoryBounds =>
1629
        if Write_Address_Pointer_Length_OK = '1' then
1630
          ADRint_i           <= Pointer_r;
1631
          GPR_i(15 downto 0) <= Data_r(15 downto 0) xor RN16Handler;
1632
        else
1633
          trm_cmd_i <= trmcmd_SendError;
1634
          trm_buf_i <= NON_SPECIFIC_ERROR;  -- X"0F"
1635
        end if;
1636
 
1637
      when st_Secured_WR_WriteWord =>
1638
        ADRint_i <= ADRint;
1639
        if mem_RB = '1' then
1640
          mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1641
          mem_DTI_i  <= GPR(15 downto 0);
1642
          mem_BANK_i <= Data_r(17 downto 16);
1643
          mem_WR_i   <= '1';
1644
        end if;
1645
 
1646
      when st_Secured_WR_WriteIsDone =>
1647
        if mem_RB = '1' then
1648
          -- Backscatter Handler
1649
          trm_cmd_i <= trmcmd_Send;
1650
          trm_buf_i <= RN16Handler;
1651
        end if;
1652
 
1653
      when st_Secured_RD_CheckMemoryBounds =>
1654
        if Read_Address_Pointer_Length_OK = '1' then
1655
          ADRint_i          <= Pointer_r;
1656
          GPR_i(7 downto 0) <= Length_r;
1657
        else
1658
          trm_cmd_i <= trmcmd_SendError;
1659
          trm_buf_i <= NON_SPECIFIC_ERROR;  -- X"0F"
1660
        end if;
1661
 
1662
      when st_Secured_RD_ReadMemory =>
1663
        ADRint_i <= ADRint;
1664
        if mem_RB = '1' then
1665
          if unsigned(GPR) /= 0 then
1666
            mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1667
            mem_BANK_i <= Data_r(1 downto 0);
1668
            mem_RD_i   <= '1';
1669
            ADRint_i   <= ADRint + '1';
1670
            GPR_i      <= GPR - '1';
1671
          else  -- Backscatter the whole memory (TODO:check when MEMBANK="01" (EPC))
1672
            mem_ADR_i                  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1673
            mem_BANK_i                 <= Data_r(1 downto 0);
1674
            mem_RD_i                   <= '1';
1675
            ADRint_i                   <= ADRint + '1';
1676
--            GPR_i(31 downto 2*AddrUSR) <= (others => '0');
1677
            case Data_r(1 downto 0) is
1678
              when "00" =>              --Reserved Memory
1679
                --  GPR_i((2*AddrUSR)-1 downto 0) <= conv_std_logic_vector(WordsRSV-1, 2*AddrUSR);
1680
                GPR_i <= EXT(conv_std_logic_vector(WordsRSV-1, 2 * AddrUSR), 32);
1681
              when "01" =>              -- EPC Memory
1682
--                GPR_i((2*AddrUSR)-1 downto 0) <= conv_std_logic_vector(WordsEPC-1, 2*AddrUSR);
1683
                 GPR_i <= EXT(conv_std_logic_vector(WordsEPC-1, 2 * AddrUSR), 32);
1684
              when "10" =>              --TID Memory
1685
--                GPR_i((2*AddrUSR)-1 downto 0) <= conv_std_logic_vector(WordsTID-1, 2*AddrUSR);
1686
                 GPR_i <= EXT(conv_std_logic_vector(WordsTID-1, 2 * AddrUSR), 32);
1687
              when "11" =>              -- User Memory
1688
--                GPR_i((2*AddrUSR)-1 downto 0) <= conv_std_logic_vector(WordsUSR-1, 2*AddrUSR);
1689
                 GPR_i <= EXT(conv_std_logic_vector(WordsUSR-1, 2 * AddrUSR), 32);
1690
              when others => null;
1691
            end case;
1692
          end if;
1693
        end if;
1694
 
1695
      when st_Secured_RD_Read_AND_Send =>
1696
        ADRint_i <= ADRint;
1697
        if mem_RB = '1' then
1698
          if unsigned(GPR) /= 0 then
1699
            mem_ADR_i  <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
1700
            mem_BANK_i <= Data_r(1 downto 0);
1701
            mem_RD_i   <= '1';
1702
            ADRint_i   <= ADRint + '1';
1703
            GPR_i      <= GPR - '1';
1704
            --backscatter data
1705
            trm_cmd_i  <= trmcmd_SendRData;
1706
            trm_buf_i  <= mem_DTO;
1707
          end if;
1708
        end if;
1709
 
1710
      when st_Secured_RD_SendLast =>
1711
        if mem_RB = '1' then
1712
          --backscatter data
1713
          trm_cmd_i <= trmcmd_SendRData;
1714
          trm_buf_i <= mem_DTO;
1715
        end if;
1716
 
1717
      when st_Secured_RD_SendHandle =>
1718
        trm_cmd_i <= trmcmd_SendRHandler;
1719
        trm_buf_i <= RN16Handler;
1720
 
1721
 
1722
 
1723
        -----------------------------------------------------------------------
1724
        -- KILLED    (in output process)
1725
        -----------------------------------------------------------------------
1726
      when st_Killed => null;
1727
 
1728
 
1729
      when others => null;
1730
    end case;
1731
 
1732
 
1733
  end process OUTPUT_DEC;
1734
 
1735
 
1736
 
1737
 
1738
  -----------------------------------------------------------------------------
1739
  -- Inventory and Select Flag Comparison
1740
  -----------------------------------------------------------------------------
1741
  Query_InventoryFlag_Match <= '1' when Data_r(8 downto 7) = "00" else
1742
                               '1' when Data_r(8 downto 7) = "01"                  else
1743
                               '1' when (Data_r(8 downto 7) = "10" and SelQ = '0') else
1744
                               '1' when (Data_r(8 downto 7) = "11" and SelQ = '1') else
1745
                               '0';
1746
  Query_SelectFlag_Match <= '1' when (Data_r(6 downto 5) = "00" and Data_r(4) = SInvQ(0)) else
1747
                            '1' when (Data_r(6 downto 5) = "01" and Data_r(4) = SInvQ(1)) else
1748
                            '1' when (Data_r(6 downto 5) = "10" and Data_r(4) = SInvQ(2)) else
1749
                            '1' when (Data_r(6 downto 5) = "11" and Data_r(4) = SInvQ(3)) else
1750
                            '0';
1751
 
1752
  -----------------------------------------------------------------------------
1753
  -- Slot Zero comparison
1754
  -----------------------------------------------------------------------------
1755
  SlotIsZero <= '1' when conv_integer(Slot) = 0 else
1756
                '0';
1757
 
1758
  -----------------------------------------------------------------------------
1759
  -- Adress Pointer & Length Control (Select Command)
1760
  -----------------------------------------------------------------------------
1761
 
1762
  Select_Address_Pointer_Length_OK <= '1' when Select_Address_Bounds_OK = '1' and conv_integer(Length_r) /= 0 else
1763
                                      '0';
1764
 
1765
  Select_Address_Bounds_OK <= '1' when (Data_r(2 downto 1) = "00") and ((conv_integer(Pointer_r(15 downto 4))+ conv_integer(Length_r)) < WordsRSV) else
1766
                              '1' when (Data_r(2 downto 1) = "01") and ((conv_integer(Pointer_r(15 downto 4))+ conv_integer(Length_r)) < WordsEPC) else
1767
                              '1' when (Data_r(2 downto 1) = "10") and ((conv_integer(Pointer_r(15 downto 4))+ conv_integer(Length_r)) < WordsTID) else
1768
                              '1' when (Data_r(2 downto 1) = "11") and ((conv_integer(Pointer_r(15 downto 4))+ conv_integer(Length_r)) < WordsUSR) else
1769
                              '0';
1770
 
1771
  -----------------------------------------------------------------------------
1772
  -- Adress Pointer & Length Control (Read Command)
1773
  -----------------------------------------------------------------------------
1774
 
1775
  Read_Address_Pointer_Length_OK <= '1' when Read_Address_Bounds_OK = '1' and conv_integer(Length_r) /= 0 else
1776
                                    '0';
1777
 
1778
  Read_Address_Bounds_OK <= '1' when (Data_r(1 downto 0) = "00") and ((conv_integer(Pointer_r)+ conv_integer(Length_r)) < WordsRSV) else
1779
                            '1' when (Data_r(1 downto 0) = "01") and ((conv_integer(Pointer_r)+ conv_integer(Length_r)) < WordsEPC) else
1780
                            '1' when (Data_r(1 downto 0) = "10") and ((conv_integer(Pointer_r)+ conv_integer(Length_r)) < WordsTID) else
1781
                            '1' when (Data_r(1 downto 0) = "11") and ((conv_integer(Pointer_r)+ conv_integer(Length_r)) < WordsUSR) else
1782
                            '0';
1783
 
1784
  -----------------------------------------------------------------------------
1785
  -- Adress Pointer & Length Control (Write Command)
1786
  -----------------------------------------------------------------------------
1787
 
1788
  Write_Address_Pointer_Length_OK <= '1' when Write_Address_Bounds_OK = '1' else
1789
                                     '0';
1790
 
1791
  Write_Address_Bounds_OK <= '1' when (Data_r(17 downto 16) = "00") and (conv_integer(Pointer_r) < WordsRSV) else
1792
                             '1' when (Data_r(17 downto 16) = "01") and (conv_integer(Pointer_r) < WordsEPC) else
1793
                             '1' when (Data_r(17 downto 16) = "10") and (conv_integer(Pointer_r) < WordsTID) else
1794
                             '1' when (Data_r(17 downto 16) = "11") and (conv_integer(Pointer_r) < WordsUSR) else
1795
                             '0';
1796
 
1797
 
1798
  -----------------------------------------------------------------------------
1799
  -- MASK Comparison (Select Command)
1800
  -----------------------------------------------------------------------------
1801
  GPR_AFTER_COMPARISON_MUX <= X"000" & "000" & GPR(0) when unsigned(GCounter(3 downto 0)) = 0 else
1802
                              EXT(GPR(1 downto 0), 16)  when unsigned(GCounter(3 downto 0)) = 1  else
1803
                              EXT(GPR(2 downto 0), 16)  when unsigned(GCounter(3 downto 0)) = 2  else
1804
                              EXT(GPR(3 downto 0), 16)  when unsigned(GCounter(3 downto 0)) = 3  else
1805
                              EXT(GPR(4 downto 0), 16)  when unsigned(GCounter(3 downto 0)) = 4  else
1806
                              EXT(GPR(5 downto 0), 16)  when unsigned(GCounter(3 downto 0)) = 5  else
1807
                              EXT(GPR(6 downto 0), 16)  when unsigned(GCounter(3 downto 0)) = 6  else
1808
                              EXT(GPR(7 downto 0), 16)  when unsigned(GCounter(3 downto 0)) = 7  else
1809
                              EXT(GPR(8 downto 0), 16)  when unsigned(GCounter(3 downto 0)) = 8  else
1810
                              EXT(GPR(9 downto 0), 16)  when unsigned(GCounter(3 downto 0)) = 9  else
1811
                              EXT(GPR(10 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 10 else
1812
                              EXT(GPR(11 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 11 else
1813
                              EXT(GPR(12 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 12 else
1814
                              EXT(GPR(13 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 13 else
1815
                              EXT(GPR(14 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 14 else
1816
                              GPR(15 downto 0);
1817
 
1818
  MASK_AFTER_FIRSTCOMPARISON_MUX <= Mask_r(15 downto 0) when unsigned(GCounter2) = 0 else
1819
                                    Mask_r(16 downto 1)  when unsigned(GCounter2) = 1  else
1820
                                    Mask_r(17 downto 2)  when unsigned(GCounter2) = 2  else
1821
                                    Mask_r(18 downto 3)  when unsigned(GCounter2) = 3  else
1822
                                    Mask_r(19 downto 4)  when unsigned(GCounter2) = 4  else
1823
                                    Mask_r(20 downto 5)  when unsigned(GCounter2) = 5  else
1824
                                    Mask_r(21 downto 6)  when unsigned(GCounter2) = 6  else
1825
                                    Mask_r(22 downto 7)  when unsigned(GCounter2) = 7  else
1826
                                    Mask_r(23 downto 8)  when unsigned(GCounter2) = 8  else
1827
                                    Mask_r(24 downto 9)  when unsigned(GCounter2) = 9  else
1828
                                    Mask_r(25 downto 10) when unsigned(GCounter2) = 10 else
1829
                                    Mask_r(26 downto 11) when unsigned(GCounter2) = 11 else
1830
                                    Mask_r(27 downto 12) when unsigned(GCounter2) = 12 else
1831
                                    Mask_r(28 downto 13) when unsigned(GCounter2) = 13 else
1832
                                    Mask_r(29 downto 14) when unsigned(GCounter2) = 14 else
1833
                                    Mask_r(30 downto 15) when unsigned(GCounter2) = 15 else
1834
                                    Mask_r(31 downto 16) when unsigned(GCounter2) = 16 else
1835
                                    Mask_r(32 downto 17) when unsigned(GCounter2) = 17 else
1836
                                    Mask_r(33 downto 18) when unsigned(GCounter2) = 18 else
1837
                                    Mask_r(34 downto 19) when unsigned(GCounter2) = 19 else
1838
                                    Mask_r(35 downto 20) when unsigned(GCounter2) = 20 else
1839
                                    Mask_r(36 downto 21);
1840
 
1841
  MASK_AFTER_COMPARISON_BIT_MUX <= MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000000001" when unsigned(GCounter(3 downto 0)) = 0 else
1842
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000000011" when unsigned(GCounter(3 downto 0)) = 1  else
1843
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000000111" when unsigned(GCounter(3 downto 0)) = 2  else
1844
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000001111" when unsigned(GCounter(3 downto 0)) = 3  else
1845
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000011111" when unsigned(GCounter(3 downto 0)) = 4  else
1846
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000111111" when unsigned(GCounter(3 downto 0)) = 5  else
1847
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000001111111" when unsigned(GCounter(3 downto 0)) = 6  else
1848
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000011111111" when unsigned(GCounter(3 downto 0)) = 7  else
1849
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000111111111" when unsigned(GCounter(3 downto 0)) = 8  else
1850
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000001111111111" when unsigned(GCounter(3 downto 0)) = 9  else
1851
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000011111111111" when unsigned(GCounter(3 downto 0)) = 10 else
1852
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0000111111111111" when unsigned(GCounter(3 downto 0)) = 11 else
1853
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0001111111111111" when unsigned(GCounter(3 downto 0)) = 12 else
1854
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0011111111111111" when unsigned(GCounter(3 downto 0)) = 13 else
1855
                               MASK_AFTER_FIRSTCOMPARISON_MUX and "0111111111111111" when unsigned(GCounter(3 downto 0)) = 14 else
1856
                               MASK_AFTER_FIRSTCOMPARISON_MUX;
1857
 
1858
  -----------------------------------------------------------------------------
1859
  -- SLOT VALUE (Query Command)
1860
  -----------------------------------------------------------------------------
1861
  SLOT_VALUE <= X"0000" when unsigned(CurrQ) = 0 else
1862
                X"000" & "000" & rng_cout(0) when unsigned(CurrQ) = 1 else
1863
                EXT(rng_cout(1 downto 0), 16) when unsigned(CurrQ) = 2 else
1864
                EXT(rng_cout(2 downto 0), 16) when unsigned(CurrQ) = 3 else
1865
                EXT(rng_cout(3 downto 0), 16) when unsigned(CurrQ) = 4 else
1866
                EXT(rng_cout(4 downto 0), 16) when unsigned(CurrQ) = 5 else
1867
                EXT(rng_cout(5 downto 0), 16) when unsigned(CurrQ) = 6 else
1868
                EXT(rng_cout(6 downto 0), 16) when unsigned(CurrQ) = 7 else
1869
                EXT(rng_cout(7 downto 0), 16) when unsigned(CurrQ) = 8 else
1870
                EXT(rng_cout(8 downto 0), 16) when unsigned(CurrQ) = 9 else
1871
                EXT(rng_cout(9 downto 0), 16) when unsigned(CurrQ) = 10 else
1872
                EXT(rng_cout(10 downto 0), 16) when unsigned(CurrQ) = 11 else
1873
                EXT(rng_cout(11 downto 0), 16) when unsigned(CurrQ) = 12 else
1874
                EXT(rng_cout(12 downto 0), 16) when unsigned(CurrQ) = 13 else
1875
                EXT(rng_cout(13 downto 0), 16) when unsigned(CurrQ) = 14 else
1876
                EXT(rng_cout(14 downto 0), 16);
1877
 
1878
 
1879
 
1880
end TagFSM1;

powered by: WebSVN 2.1.0

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