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 3

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

powered by: WebSVN 2.1.0

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