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

Subversion Repositories epc_rfid_transponder

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /epc_rfid_transponder
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/TagCtrl.vhd
0,0 → 1,261
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- File name : tagCtrl.vhd
--
-- Description : top level of the tag control - Includes TagFSM.
--
-- Author : Erwing R. Sanchez Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Last change : 11 October 06 - Erwing Sanchez
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
library WORK;
use WORK.epc_tag.all;
 
entity TagCtrl is
generic(
WordsRSV : integer := 8;
WordsEPC : integer := 16;
WordsTID : integer := 8;
WordsUSR : integer := 256;
AddrRSV : integer := 2; -- 1/2 memory address pins
AddrEPC : integer := 3; -- 1/2 memory address pins
AddrTID : integer := 2; -- 1/2 memory address pins
AddrUSR : integer := 5; -- 1/2 memory address pins (maximum)
Data : integer := 16); -- memory data width
port (
clk : in std_logic;
rst_n : in std_logic;
-- Receiver
CommDone : in CommandInternalCode_t;
Data_r : in std_logic_vector(31 downto 0);
Pointer_r : in std_logic_vector(15 downto 0);
RN16_r : in std_logic_vector(15 downto 0);
Length_r : in std_logic_vector(7 downto 0);
Mask_r : in std_logic_vector(MASKLENGTH-1 downto 0);
-- Transmitter Command and Output buffer
trm_cmd : out std_logic_vector(2 downto 0);
trm_buf : out std_logic_vector(15 downto 0)
);
end TagCtrl;
 
 
architecture struct of TagCtrl is
 
component TagFSM
generic (
WordsRSV : integer;
WordsEPC : integer;
WordsTID : integer;
WordsUSR : integer;
AddrUSR : integer;
Data : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
CommDone : in CommandInternalCode_t;
Data_r : in std_logic_vector(31 downto 0);
Pointer_r : in std_logic_vector(15 downto 0);
RN16_r : in std_logic_vector(15 downto 0);
Length_r : in std_logic_vector(7 downto 0);
Mask_r : in std_logic_vector(MASKLENGTH-1 downto 0);
SInvD : out std_logic_vector(3 downto 0);
SelD : out std_logic;
SInvQ : in std_logic_vector(3 downto 0);
SelQ : in std_logic;
SInvCE : out std_logic_vector(3 downto 0);
SelCE : out std_logic;
rng_init : out std_logic;
rng_cin : out std_logic_vector(30 downto 0);
rng_ce : out std_logic;
rng_cout : in std_logic_vector(30 downto 0);
mem_WR : out std_logic;
mem_RD : out std_logic;
mem_RB : in std_logic;
mem_BANK : out std_logic_vector(1 downto 0);
mem_ADR : out std_logic_vector((2*AddrUSR)-1 downto 0);
mem_DTI : out std_logic_vector(Data-1 downto 0);
mem_DTO : in std_logic_vector(Data-1 downto 0);
T2ExpFlag : in std_logic;
trm_cmd : out std_logic_vector(2 downto 0);
trm_buf : out std_logic_vector(15 downto 0));
end component;
 
component Mem_ctrl
generic (
WordsRSV : integer;
WordsEPC : integer;
WordsTID : integer;
WordsUSR : integer;
AddrRSV : integer;
AddrEPC : integer;
AddrTID : integer;
AddrUSR : integer;
Data : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
BANK : in std_logic_vector(1 downto 0);
WR : in std_logic;
RD : in std_logic;
ADR : in std_logic_vector((2*AddrUSR)-1 downto 0);
DTI : in std_logic_vector(Data-1 downto 0);
DTO : out std_logic_vector(Data-1 downto 0);
RB : out std_logic);
end component;
 
component prng
port (
clk : in std_logic;
rst_n : in std_logic;
init : in std_logic;
cin : in std_logic_vector(30 downto 0);
ce : in std_logic;
cout : out std_logic_vector(30 downto 0));
end component;
 
component InvSelFlagCtrl
port (
clk : in std_logic;
rst_n : in std_logic;
S0in : in std_logic;
S1in : in std_logic;
S2in : in std_logic;
S3in : in std_logic;
SLin : in std_logic;
S0en : in std_logic;
S1en : in std_logic;
S2en : in std_logic;
S3en : in std_logic;
SLen : in std_logic;
S0out : out std_logic;
S1out : out std_logic;
S2out : out std_logic;
S3out : out std_logic;
SLout : out std_logic);
end component;
 
 
signal SInvD : std_logic_vector(3 downto 0);
signal SelD : std_logic;
signal SInvQ : std_logic_vector(3 downto 0);
signal SelQ : std_logic;
signal SInvCE : std_logic_vector(3 downto 0);
signal SelCE : std_logic;
signal rng_init : std_logic;
signal rng_cin : std_logic_vector(30 downto 0);
signal rng_ce : std_logic;
signal rng_cout : std_logic_vector(30 downto 0);
signal mem_WR : std_logic;
signal mem_RD : std_logic;
signal mem_RB : std_logic;
signal mem_BANK : std_logic_vector(1 downto 0);
signal mem_ADR : std_logic_vector((2*AddrUSR)-1 downto 0);
signal mem_DTI : std_logic_vector(Data-1 downto 0);
signal mem_DTO : std_logic_vector(Data-1 downto 0);
signal T2ExpFlag : std_logic := '0';
 
begin -- struct
 
 
TagFSM_i : TagFSM
generic map (
WordsRSV => WordsRSV,
WordsEPC => WordsEPC,
WordsTID => WordsTID,
WordsUSR => WordsUSR,
AddrUSR => AddrUSR,
Data => Data)
port map (
clk => clk,
rst_n => rst_n,
CommDone => CommDone,
Data_r => Data_r,
Pointer_r => Pointer_r,
RN16_r => RN16_r,
Length_r => Length_r,
Mask_r => Mask_r,
SInvD => SInvD,
SelD => SelD,
SInvQ => SInvQ,
SelQ => SelQ,
SInvCE => SInvCE,
SelCE => SelCE,
rng_init => rng_init,
rng_cin => rng_cin,
rng_ce => rng_ce,
rng_cout => rng_cout,
mem_WR => mem_WR,
mem_RD => mem_RD,
mem_RB => mem_RB,
mem_BANK => mem_BANK,
mem_ADR => mem_ADR,
mem_DTI => mem_DTI,
mem_DTO => mem_DTO,
T2ExpFlag => T2ExpFlag,
trm_cmd => trm_cmd,
trm_buf => trm_buf);
 
 
Mem_ctrl_i : Mem_ctrl
generic map (
WordsRSV => WordsRSV,
WordsEPC => WordsEPC,
WordsTID => WordsTID,
WordsUSR => WordsUSR,
AddrRSV => AddrRSV,
AddrEPC => AddrEPC,
AddrTID => AddrTID,
AddrUSR => AddrUSR,
Data => Data)
port map (
clk => clk,
rst_n => rst_n,
BANK => mem_BANK,
WR => mem_WR,
RD => mem_RD,
ADR => mem_ADR,
DTI => mem_DTI,
DTO => mem_DTO,
RB => mem_RB);
 
prng_i : prng
port map (
clk => clk,
rst_n => rst_n,
init => rng_init,
cin => rng_cin,
ce => rng_ce,
cout => rng_cout);
 
InvSelFlagCtrl_i : InvSelFlagCtrl
port map (
clk => clk,
rst_n => rst_n,
S0in => SInvD(0),
S1in => SInvD(1),
S2in => SInvD(2),
S3in => SInvD(3),
SLin => SelD,
S0en => SInvCE(0),
S1en => SInvCE(1),
S2en => SInvCE(2),
S3en => SInvCE(3),
SLen => SelCE,
S0out => SInvQ(0),
S1out => SInvQ(1),
S2out => SInvQ(2),
S3out => SInvQ(3),
SLout => SelQ);
 
end struct;
/trunk/epc_tag.vhd
0,0 → 1,67
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag constants
--
-- File name : epc_tag.vhd
--
-- Description : EPC tag package
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 21 july 06 - First Draft
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
 
 
package EPC_TAG is
 
constant MASKLENGTH : integer := 256;
 
subtype Rec_Out_T is std_logic_vector(31 downto 0);
 
 
 
-- type CommandInternalCode_t is (cmd_NULL, cmd_QueryRep, cmd_Ack, cmd_Query, cmd_QueryAdjust,
-- cmd_Select, cmd_Nak, cmd_ReqRN, cmd_Read, cmd_Write, cmd_Kill,
-- cmd_Lock, cmd_Access, cmd_BlockWrite, cmd_BlockErase, cmd_Invalid);
 
subtype CommandInternalCode_t is std_logic_vector(3 downto 0);
 
constant cmd_NULL : std_logic_vector(3 downto 0) := "0000";
constant cmd_QueryRep : std_logic_vector(3 downto 0) := "0001";
constant cmd_Ack : std_logic_vector(3 downto 0) := "0010";
constant cmd_Query : std_logic_vector(3 downto 0) := "0011";
constant cmd_QueryAdjust : std_logic_vector(3 downto 0) := "0100";
constant cmd_Select : std_logic_vector(3 downto 0) := "0101";
constant cmd_Nak : std_logic_vector(3 downto 0) := "0110";
constant cmd_ReqRN : std_logic_vector(3 downto 0) := "0111";
constant cmd_Read : std_logic_vector(3 downto 0) := "1000";
constant cmd_Write : std_logic_vector(3 downto 0) := "1001";
constant cmd_Kill : std_logic_vector(3 downto 0) := "1010";
constant cmd_Lock : std_logic_vector(3 downto 0) := "1011";
constant cmd_Access : std_logic_vector(3 downto 0) := "1100";
constant cmd_BlockWrite : std_logic_vector(3 downto 0) := "1101";
constant cmd_BlockErase : std_logic_vector(3 downto 0) := "1110";
constant cmd_Invalid : std_logic_vector(3 downto 0) := "1111";
 
 
-- subtype CommandTransmitter_t is std_logic_vector(2 downto 0)
constant trmcmd_Null : std_logic_vector(2 downto 0) := "000";
constant trmcmd_Send : std_logic_vector(2 downto 0) := "001";
constant trmcmd_SendError : std_logic_vector(2 downto 0) := "010";
constant trmcmd_SendRData : std_logic_vector(2 downto 0) := "011";
constant trmcmd_SendRHandler : std_logic_vector(2 downto 0) := "100";
 
end EPC_TAG;
 
/trunk/InvSelFlagsCtrl.vhd
0,0 → 1,163
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag - Inventoried and Selected Flags Controller
--
-- File name : InvSelFlagsCtrl.vhd
--
-- Description : Inventoried and Selected flag controller. It provides a
-- suitable interface with the flag model and deals with
-- refreshing procedures.
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 29 June 06
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
 
 
entity InvSelFlagCtrl is
generic (
REFRESHING_CLK_CYC : integer := 255); -- Number of clock cycles to refresh flags
port (
clk : in std_logic;
rst_n : in std_logic;
S0in : in std_logic;
S1in : in std_logic;
S2in : in std_logic;
S3in : in std_logic;
SLin : in std_logic;
S0en : in std_logic;
S1en : in std_logic;
S2en : in std_logic;
S3en : in std_logic;
SLen : in std_logic;
S0out : out std_logic;
S1out : out std_logic;
S2out : out std_logic;
S3out : out std_logic;
SLout : out std_logic);
 
end InvSelFlagCtrl;
 
 
architecture FlagController1 of InvSelFlagCtrl is
 
component InvSelFlag
port (
S1i : in std_logic;
S2i : in std_logic;
S3i : in std_logic;
SLi : in std_logic;
S1o : out std_logic;
S2o : out std_logic;
S3o : out std_logic;
SLo : out std_logic);
end component;
-- synopsys synthesis_off
signal S0out_i, S1out_i, S2out_i, S3out_i, SLout_i : std_logic;
signal S1i, S2i, S3i, SLi : std_logic;
signal S1o, S2o, S3o, SLo : std_logic;
signal RefCnt : integer;
-- synopsys synthesis_on
begin -- FlagController1
-- synopsys synthesis_off
-- OUTPUT WIRES
S0out <= S0out_i;
S1out <= S1out_i;
S2out <= S2out_i;
S3out <= S3out_i;
SLout <= SLout_i;
 
REGISTERS : process (clk, rst_n)
begin -- process REGISTERS
if rst_n = '0' then -- asynchronous reset (active low)
S0out_i <= '0';
S1out_i <= '0';
S2out_i <= '0';
S3out_i <= '0';
SLout_i <= '0';
elsif clk'event and clk = '1' then -- rising clock edge
if S0en = '1' then
S0out_i <= S0in;
else
S0out_i <= S0out_i;
end if;
 
-- Flag Model Input Registers
--S1
if S1en = '1' then
S1i <= S1in;
elsif RefCnt = REFRESHING_CLK_CYC then
S1i <= S1out_i;
else
S1i <= 'Z';
end if;
--S2
if S2en = '1' then
S2i <= S2in;
elsif RefCnt = REFRESHING_CLK_CYC then
S2i <= S2out_i;
else
S2i <= 'Z';
end if;
--S3
if S3en = '1' then
S3i <= S3in;
elsif RefCnt = REFRESHING_CLK_CYC then
S3i <= S3out_i;
else
S3i <= 'Z';
end if;
--SL
if SLen = '1' then
SLi <= SLin;
elsif RefCnt = REFRESHING_CLK_CYC then
SLi <= SLout_i;
else
SLi <= 'Z';
end if;
 
-- Flag Model Output Registers
S1out_i <= S1o;
S2out_i <= S2o;
S3out_i <= S3o;
SLout_i <= SLo;
end if;
end process REGISTERS;
 
REF_COUNTER : process (clk, rst_n)
begin -- process REF_COUNTER
if rst_n = '0' then -- asynchronous reset (active low)
RefCnt <= 0;
elsif clk'event and clk = '1' then -- rising clock edge
if RefCnt = REFRESHING_CLK_CYC then
RefCnt <= 0;
else
RefCnt <= RefCnt + 1;
end if;
end if;
end process REF_COUNTER;
 
InvSelFlag_i : InvSelFlag
port map (
S1i => S1i,
S2i => S2i,
S3i => S3i,
SLi => SLi,
S1o => S1o,
S2o => S2o,
S3o => S3o,
SLo => SLo);
-- synopsys synthesis_on
end FlagController1;
 
 
/trunk/memctrl.vhd
0,0 → 1,422
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : Memory Controller
--
-- File name : MemCtrl.vhd
--
-- Description : Flash memory controller.
--
-- Authors : Erwing Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : Erwing Sanchez -- 17/07/06
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- EPC Memory Map
--
-- _______________________
-- | | RESERVED MEMORY (Bank 00)
-- | |
-- |_______________________|
-- | | EPC MEMORY (Bank 01)
-- | |
-- |_______________________|
-- | | TID MEMORY (Bank 10)
-- | |
-- |_______________________|
-- | | USER MEMORY (Bank 11)
-- | |
-- |_______________________|
--
 
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
 
 
entity Mem_ctrl is
generic (
WordsRSV : integer := 8;
WordsEPC : integer := 16;
WordsTID : integer := 8;
WordsUSR : integer := 256;
--Address are loaded in two steps, so only half of address pins are needed.
AddrRSV : integer := 2; -- 1/2address pins
AddrEPC : integer := 3; -- 1/2address pins
AddrTID : integer := 2; -- 1/2address pins
AddrUSR : integer := 5; -- 1/2address pins
Data : integer := 16);
port (
clk : in std_logic;
rst_n : in std_logic;
BANK : in std_logic_vector(1 downto 0);
WR : in std_logic; -- Write signal
RD : in std_logic; -- Read signal
ADR : in std_logic_vector((2*AddrUSR)-1 downto 0);
DTI : in std_logic_vector(Data-1 downto 0);
DTO : out std_logic_vector(Data-1 downto 0);
RB : out std_logic -- Ready/nBusy signal(unbuffered!)
);
end Mem_ctrl;
 
 
architecture Mem_Ctrl_arch of Mem_ctrl is
 
component Flash_MeM_EPC
generic (
Words : integer;
Addr : integer;
Data : integer);
port (
A : in std_logic_vector(Addr-1 downto 0);
D : in std_logic_vector(Data-1 downto 0);
Q : out std_logic_vector(Data-1 downto 0);
G : in std_logic;
W : in std_logic;
RC : in std_logic;
st : out std_logic);
end component;
 
component Flash_MeM_TID
generic (
Words : integer;
Addr : integer;
Data : integer);
port (
A : in std_logic_vector(Addr-1 downto 0);
D : in std_logic_vector(Data-1 downto 0);
Q : out std_logic_vector(Data-1 downto 0);
G : in std_logic;
W : in std_logic;
RC : in std_logic;
st : out std_logic);
end component;
 
component Flash_MeM_USR
generic (
Words : integer;
Addr : integer;
Data : integer);
port (
A : in std_logic_vector(Addr-1 downto 0);
D : in std_logic_vector(Data-1 downto 0);
Q : out std_logic_vector(Data-1 downto 0);
G : in std_logic;
W : in std_logic;
RC : in std_logic;
st : out std_logic);
end component;
 
component Flash_MeM_RSV
generic (
Words : integer;
Addr : integer;
Data : integer);
port (
A : in std_logic_vector(Addr-1 downto 0);
D : in std_logic_vector(Data-1 downto 0);
Q : out std_logic_vector(Data-1 downto 0);
G : in std_logic;
W : in std_logic;
RC : in std_logic;
st : out std_logic);
end component;
 
 
-- Contants
constant WriteCommand : std_logic_vector(Data-1 downto 0) := conv_std_logic_vector(64, Data); --"01000000" Flash Write Code
-- FSM
type MemCtrl_t is (st_idle, st_read_LoadAddr1, st_read_LoadAddr2, st_read_LoadOutput, st_read_read, st_write_LoadAddr1, st_write_LoadAddr2, st_write_write);
signal StMCtrl, NextStMCtrl : MemCtrl_t;
-- Memory signals
signal A_RSV : std_logic_vector(AddrRSV-1 downto 0);
signal A_EPC : std_logic_vector(AddrEPC-1 downto 0);
signal A_TID : std_logic_vector(AddrTID-1 downto 0);
signal A_USR : std_logic_vector(AddrUSR-1 downto 0);
signal D : std_logic_vector(Data-1 downto 0);
signal Q : std_logic_vector(Data-1 downto 0);
signal G, G_i : std_logic;
signal W, W_i : std_logic;
signal RC, RC_i : std_logic;
signal st : std_logic;
signal W_RSV, W_EPC, W_TID, W_USR : std_logic;
signal G_RSV, G_EPC, G_TID, G_USR : std_logic;
signal Q_RSV, Q_EPC, Q_TID, Q_USR : std_logic_vector(Data-1 downto 0);
signal RC_RSV, RC_EPC, RC_TID, RC_USR : std_logic;
-- Internal regs
signal DTI_r : std_logic_vector(Data-1 downto 0);
signal DTO_r : std_logic_vector(Data-1 downto 0);
signal ADR_r : std_logic_vector((2*AddrUSR)-1 downto 0);
signal BNK_r : std_logic_vector(1 downto 0);
signal ADR_ce, DTI_ce, DTO_ce, BNK_ce : std_logic;
-- Internal Flags & other signals
signal AddrMux : std_logic;
signal WRCmdFlag, WRCmdFlag_i : std_logic;
 
begin -- Mem_Ctrl_arch
 
 
SYNC_MEMCTRL : process (clk, rst_n)
begin -- process SYNC
if rst_n = '0' then -- asynchronous reset (active low)
StMCtrl <= st_idle;
RC <= '1'; -- 1 -> 0 : Load LSB address
G <= '1'; -- 0: enable
W <= '0';
WRCmdFlag <= '0';
elsif clk'event and clk = '1' then -- rising clock edge
StMCtrl <= NextStMCtrl;
RC <= RC_i;
G <= G_i;
W <= W_i;
WRCmdFlag <= WRCmdFlag_i;
end if;
end process SYNC_MEMCTRL;
 
NEXTST_MEMCTRL : process (StMCtrl, WR, RD, ADR, DTI)
begin -- process NEXTST
 
NextStMCtrl <= StMCtrl;
 
case StMCtrl is
when st_idle =>
if WR = '1' then
NextStMCtrl <= st_write_LoadAddr1;
elsif RD = '1' then
NextStMCtrl <= st_read_LoadAddr1;
end if;
when st_read_LoadAddr1 =>
NextStMCtrl <= st_read_LoadAddr2;
when st_read_LoadAddr2 =>
NextStMCtrl <= st_read_read;
when st_read_read =>
NextStMCtrl <= st_read_LoadOutput;
when st_read_LoadOutput =>
NextStMCtrl <= st_idle;
 
when st_write_LoadAddr1 =>
NextStMCtrl <= st_write_LoadAddr2;
when st_write_LoadAddr2 =>
NextStMCtrl <= st_write_write;
when st_write_write =>
NextStMCtrl <= st_idle;
 
when others => null;
end case;
 
end process NEXTST_MEMCTRL;
 
 
OUTPUT_MEMCTRL : process (StMCtrl, WR, RD)
begin -- process OUTPUT_MEMCTRL
 
RB <= '0';
ADR_ce <= '0';
DTI_ce <= '0';
DTO_ce <= '0';
BNK_ce <= '0';
AddrMux <= '0';
WRCmdFlag_i <= '0';
-- Memory signals
RC_i <= '1';
G_i <= '1';
W_i <= '0';
 
case StMCtrl is
when st_idle =>
RB <= '1';
if WR = '1' then
ADR_ce <= '1'; -- load address
DTI_ce <= '1'; -- load data
BNK_ce <= '1'; -- load Bank
RB <= '0';
elsif RD = '1' then
ADR_ce <= '1'; -- load address
BNK_ce <= '1'; -- load Bank
RB <= '0';
end if;
 
when st_read_LoadAddr1 =>
RC_i <= '0'; -- Load Address LSB
 
when st_read_LoadAddr2 =>
AddrMux <= '1'; -- Load Address MSB
 
when st_read_read =>
G_i <= '0'; -- Read Command
 
when st_read_LoadOutput =>
DTO_ce <= '1'; -- Load output register
 
when st_write_LoadAddr1 =>
RC_i <= '0'; -- Load Address LSB
WRCmdFlag_i <= '1'; -- Load Write Command code
W_i <= '1';
 
when st_write_LoadAddr2 =>
AddrMux <= '1'; -- Load Address MSB
 
when st_write_write =>
W_i <= '1'; -- Write Data
 
when others => null;
end case;
end process OUTPUT_MEMCTRL;
 
 
 
INTREGS : process (clk, rst_n)
begin -- process INTREGS
if rst_n = '0' then -- asynchronous reset (active low)
ADR_r <= (others => '0');
DTI_r <= (others => '0');
DTO_r <= (others => '0');
BNK_r <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
if ADR_ce = '1' then
ADR_r <= ADR;
end if;
if DTI_ce = '1' then
DTI_r <= DTI;
end if;
if DTO_ce = '1' then
DTO_r <= Q;
end if;
if BNK_ce = '1' then
BNK_r <= BANK;
end if;
end if;
end process INTREGS;
 
 
DTO <= DTO_r;
 
 
-------------------------------------------------------------------------------
-- ADDRESS MUX
-------------------------------------------------------------------------------
 
A_RSV <= ADR_r(AddrRSV-1 downto 0) when AddrMux = '0' else
ADR_r((2*AddrRSV)-1 downto AddrRSV);
 
A_EPC <= ADR_r(AddrEPC-1 downto 0) when AddrMux = '0' else
ADR_r((2*AddrEPC)-1 downto AddrEPC);
 
A_TID <= ADR_r(AddrTID-1 downto 0) when AddrMux = '0' else
ADR_r((2*AddrTID)-1 downto AddrTID);
 
A_USR <= ADR_r(AddrUSR-1 downto 0) when AddrMux = '0' else
ADR_r((2*AddrUSR)-1 downto AddrUSR);
 
 
-------------------------------------------------------------------------------
-- DATA IN MUX
-------------------------------------------------------------------------------
 
D <= WriteCommand when WRCmdFlag = '1' else
DTI_r;
 
-------------------------------------------------------------------------------
-- CONTROL SIGNALS MUXs
-------------------------------------------------------------------------------
 
W_RSV <= W when BNK_r = "00" else
'0';
W_EPC <= W when BNK_r = "01" else
'0';
W_TID <= W when BNK_r = "10" else
'0';
W_USR <= W when BNK_r = "11" else
'0';
 
 
G_RSV <= G when BNK_r = "00" else
'1';
G_EPC <= G when BNK_r = "01" else
'1';
G_TID <= G when BNK_r = "10" else
'1';
G_USR <= G when BNK_r = "11" else
'1';
 
RC_RSV <= RC when BNK_r = "00" else
'1';
RC_EPC <= RC when BNK_r = "01" else
'1';
RC_TID <= RC when BNK_r = "10" else
'1';
RC_USR <= RC when BNK_r = "11" else
'1';
 
Q <= Q_RSV when BNK_r = "00" else
Q_EPC when BNK_r = "01" else
Q_TID when BNK_r = "10" else
Q_USR;
 
-------------------------------------------------------------------------------
-- MEMORIES
-------------------------------------------------------------------------------
 
Flash_MeM_RSV_i : Flash_MeM_RSV
generic map (
Words => WordsRSV,
Addr => AddrRSV,
Data => Data)
port map (
A => A_RSV,
D => D,
Q => Q_RSV,
G => G_RSV,
W => W_RSV,
RC => RC_RSV,
st => st);
 
Flash_MeM_EPC_i : Flash_MeM_EPC
generic map (
Words => WordsEPC,
Addr => AddrEPC,
Data => Data)
port map (
A => A_EPC,
D => D,
Q => Q_EPC,
G => G_EPC,
W => W_EPC,
RC => RC_EPC,
st => st);
 
Flash_MeM_TID_i : Flash_MeM_TID
generic map (
Words => WordsTID,
Addr => AddrTID,
Data => Data)
port map (
A => A_TID,
D => D,
Q => Q_TID,
G => G_TID,
W => W_TID,
RC => RC_TID,
st => st);
 
Flash_MeM_USR_i : Flash_MeM_USR
generic map (
Words => WordsUSR,
Addr => AddrUSR,
Data => Data)
port map (
A => A_USR,
D => D,
Q => Q_USR,
G => G_USR,
W => W_USR,
RC => RC_USR,
st => st);
 
end Mem_Ctrl_arch;
/trunk/receiver.vhd
0,0 → 1,97
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag - Receiver
--
-- File name : receiver.vhd
--
-- Description : Tag receiver detects valid frames decoding command
-- preambles and frame-syncs.
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 21 june 06 - First Draft
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.all;
use ieee.numeric_std.all;
library work;
use work.epc_tag.all;
 
 
entity receiver is
generic (
LOG2_10_TARI_CK_CYC : integer := 9; -- Log2(clock cycles for 10 maximum TARI value) (def:Log2(490) = 9 @TCk=520ns)
DELIMITIER_TIME_CK_CYC_MIN : integer := 22; -- Min Clock cycles for 12,5 us delimitier
DELIMITIER_TIME_CK_CYC_MAX : integer := 24); -- Max Clock cycles for 12,5 us delimitier
port (
clk : in std_logic;
rst_n : in std_logic;
tdi : in std_logic;
en : in std_logic;
CommDone : out CommandInternalCode_t;
Data_r : out std_logic_vector(31 downto 0);
CRC_r : out std_logic_vector(15 downto 0);
Pointer_r : out std_logic_vector(15 downto 0);
RN16_r : out std_logic_vector(15 downto 0);
Length_r : out std_logic_vector(7 downto 0);
Mask_r : out std_logic_vector(MASKLENGTH-1 downto 0));
 
 
end receiver;
 
 
architecture Receiver1 of receiver is
 
component CommandDecoder
generic (
LOG2_10_TARI_CK_CYC : integer;
DELIMITIER_TIME_CK_CYC_MIN : integer;
DELIMITIER_TIME_CK_CYC_MAX : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
tdi : in std_logic;
en : in std_logic;
CommDone : out CommandInternalCode_t;
Data_r : out std_logic_vector(31 downto 0);
CRC_r : out std_logic_vector(15 downto 0);
Pointer_r : out std_logic_vector(15 downto 0);
RN16_r : out std_logic_vector(15 downto 0);
Length_r : out std_logic_vector(7 downto 0);
Mask_r : out std_logic_vector(MASKLENGTH-1 downto 0));
end component;
 
 
begin
 
CommandDecoder_i : CommandDecoder
generic map (
LOG2_10_TARI_CK_CYC => LOG2_10_TARI_CK_CYC,
DELIMITIER_TIME_CK_CYC_MIN => DELIMITIER_TIME_CK_CYC_MIN,
DELIMITIER_TIME_CK_CYC_MAX => DELIMITIER_TIME_CK_CYC_MAX)
port map (
clk => clk,
rst_n => rst_n,
tdi => tdi,
en => en,
CommDone => CommDone,
Data_r => Data_r,
CRC_r => CRC_r,
Pointer_r => Pointer_r,
RN16_r => RN16_r,
Length_r => Length_r,
Mask_r => Mask_r);
 
 
end Receiver1;
 
 
/trunk/tb_counterclr.vhd
0,0 → 1,107
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 16:47:20 05/18/2009
-- Design Name:
-- Module Name: /home/erwing/Projects/vhdl/rfid/tb_counterclr.vhd
-- Project Name: rfid
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: COUNTERCLR
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY tb_counterclr IS
END tb_counterclr;
ARCHITECTURE behavior OF tb_counterclr IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT COUNTERCLR
PORT(
clk : IN std_logic;
rst_n : IN std_logic;
en : IN std_logic;
clear : IN std_logic;
outcnt : OUT std_logic_vector(7 downto 0)
);
END COMPONENT;
 
--Inputs
signal clk : std_logic := '0';
signal rst_n : std_logic := '0';
signal en : std_logic := '0';
signal clear : std_logic := '0';
 
--Outputs
signal outcnt : std_logic_vector(7 downto 0);
 
-- Clock period definitions
constant clk_period : time := 10us;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: COUNTERCLR PORT MAP (
clk => clk,
rst_n => rst_n,
en => en,
clear => clear,
outcnt => outcnt
);
 
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
 
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100ms.
wait for 100ms;
 
wait for clk_period*10;
 
rst_n <= '1';
en <= '1';
clear <= '0';
wait for 3ms;
clear <= '1';
wait for 30us;
clear <= '0';
wait for 5ms;
 
 
wait;
end process;
 
END;
/trunk/pseudoRNG.vhd
0,0 → 1,62
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag - 16-bit Pseudo-random Number Generator
--
-- File name : pseudoRNG.vhd
--
-- Description : Peudo-random number generator based on 31-bit LFSR.
-- LFSR primitive polynomial: 1 + X^28 + X^31
-- Better performance may be reached using a leap-forward
-- LFSR implementation...!!!
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 17 july 06 - First Draft
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.all;
 
 
entity prng is
port (
clk : in std_logic;
rst_n : in std_logic;
init : in std_logic;
cin : in std_logic_vector(30 downto 0);
ce : in std_logic;
cout : out std_logic_vector(30 downto 0));
end prng;
 
 
architecture prng_arch of prng is
 
signal lfsr31 : std_logic_vector(30 downto 0);
begin -- prng16_arch
 
LFSR : process (clk, rst_n)
begin -- process LFSR
if rst_n = '0' then -- asynchronous reset (active low)
lfsr31 <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
if init = '1' then
lfsr31 <= cin;
elsif ce = '1' then -- shift register;
lfsr31(30 downto 1) <= lfsr31(29 downto 0);
lfsr31(0) <= lfsr31(30) xor lfsr31(27);
end if;
end if;
end process LFSR;
 
cout <= lfsr31;
end prng_arch;
/trunk/shiftreg.vhd
0,0 → 1,57
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : Shift Register
--
-- File name : shiftreg.vhd
--
-- Description : Simple Shift Register
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 30 June 06
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
 
 
entity shiftreg is
generic (
REGWD : integer := 16);
 
port (
clk : in std_logic;
rst_n : in std_logic;
ce : in std_logic;
sin : in std_logic;
pout : out std_logic_vector(REGWD - 1 downto 0));
 
end shiftreg;
 
architecture shreg1 of shiftreg is
 
signal shreg : std_logic_vector(REGWD-1 downto 0);
begin -- shreg1
 
process (clk , rst_n)
begin
if rst_n = '0' then
shreg <= (others => '0');
elsif clk'event and clk = '1' then
if ce = '1' then
shreg <= shreg((REGWD - 2) downto 0) & sin;
end if;
end if;
pout <= shreg;
end process;
 
end shreg1;
/trunk/tag.vhd
0,0 → 1,191
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- File name : tag.vhd
--
-- Description : top level of the whole architecture
--
-- Author : Erwing R. Sanchez Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Last change : 20 July 06 - Erwing Sanchez
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
library WORK;
use WORK.epc_tag.all;
 
 
entity EPCTAG is
generic (
LOG2_10_TARI_CK_CYC : integer := 9; -- Log2(clock cycles for 10 maximum TARI value) (def: Log2(490) = 9 @TCk=520ns)
DELIMITIER_TIME_CK_CYC_MIN : integer := 22; -- Min Clock cycles for 12,5 us delimitier
DELIMITIER_TIME_CK_CYC_MAX : integer := 24; -- Max Clock cycles for 12,5 us delimitier
WordsRSV : integer := 8;
WordsEPC : integer := 16;
WordsTID : integer := 8;
WordsUSR : integer := 256;
AddrRSV : integer := 2; -- 1/2 memory address pins
AddrEPC : integer := 3; -- 1/2 memory address pins
AddrTID : integer := 2; -- 1/2 memory address pins
AddrUSR : integer := 5; -- 1/2 memory address pins (maximum)
Data : integer := 16); -- memory data width
port (
clk : in std_logic;
rst_n : in std_logic;
tdi : in std_logic;
tdo : out std_logic;
Data_r : out std_logic_vector(31 downto 0);
CRC_r : out std_logic_vector(15 downto 0);
Pointer_r : out std_logic_vector(15 downto 0);
RN16_r : out std_logic_vector(15 downto 0);
Length_r : out std_logic_vector(7 downto 0);
Mask_r : out std_logic_vector(MASKLENGTH-1 downto 0);
trm_cmd : out std_logic_vector(2 downto 0);
trm_buf : out std_logic_vector(15 downto 0));
end EPCTAG;
 
architecture STRUCTURAL of EPCTAG is
 
component receiver
generic (
LOG2_10_TARI_CK_CYC : integer;
DELIMITIER_TIME_CK_CYC_MIN : integer;
DELIMITIER_TIME_CK_CYC_MAX : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
tdi : in std_logic;
en : in std_logic;
CommDone : out CommandInternalCode_t;
Data_r : out std_logic_vector(31 downto 0);
CRC_r : out std_logic_vector(15 downto 0);
Pointer_r : out std_logic_vector(15 downto 0);
RN16_r : out std_logic_vector(15 downto 0);
Length_r : out std_logic_vector(7 downto 0);
Mask_r : out std_logic_vector(MASKLENGTH-1 downto 0));
end component;
 
component TagCtrl
generic (
WordsRSV : integer;
WordsEPC : integer;
WordsTID : integer;
WordsUSR : integer;
AddrRSV : integer;
AddrEPC : integer;
AddrTID : integer;
AddrUSR : integer;
Data : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
CommDone : in CommandInternalCode_t;
Data_r : in std_logic_vector(31 downto 0);
Pointer_r : in std_logic_vector(15 downto 0);
RN16_r : in std_logic_vector(15 downto 0);
Length_r : in std_logic_vector(7 downto 0);
Mask_r : in std_logic_vector(MASKLENGTH-1 downto 0);
trm_cmd : out std_logic_vector(2 downto 0);
trm_buf : out std_logic_vector(15 downto 0));
end component;
 
 
 
component transmitter
port (
clk : in std_logic;
rst_n : in std_logic;
trm_cmd : in std_logic_vector(2 downto 0);
trm_buf : in std_logic_vector(15 downto 0);
tdo : out std_logic);
end component;
 
 
signal Data_ri : std_logic_vector(31 downto 0);
signal CRC_ri : std_logic_vector(15 downto 0);
signal Pointer_ri : std_logic_vector(15 downto 0);
signal RN16_ri : std_logic_vector(15 downto 0);
signal Length_ri : std_logic_vector(7 downto 0);
signal Mask_ri : std_logic_vector(MASKLENGTH-1 downto 0);
 
signal rec_en : std_logic;
signal CommDone : CommandInternalCode_t;
signal trm_cmd_i : std_logic_vector(2 downto 0);
signal trm_buf_i : std_logic_vector(15 downto 0);
begin
 
-- Enabling signals
rec_en <= '1';
-- Output signals
Data_r <= Data_ri;
CRC_r <= CRC_ri;
Pointer_r <= Pointer_ri;
RN16_r <= RN16_ri;
Length_r <= Length_ri;
Mask_r <= Mask_ri;
trm_cmd <= trm_cmd_i;
trm_buf <= trm_buf_i;
 
 
receiver_i : receiver
generic map (
LOG2_10_TARI_CK_CYC => LOG2_10_TARI_CK_CYC,
DELIMITIER_TIME_CK_CYC_MIN => DELIMITIER_TIME_CK_CYC_MIN,
DELIMITIER_TIME_CK_CYC_MAX => DELIMITIER_TIME_CK_CYC_MAX)
port map (
clk => clk,
rst_n => rst_n,
tdi => tdi,
en => rec_en,
CommDone => CommDone,
Data_r => Data_ri,
CRC_r => CRC_ri,
Pointer_r => Pointer_ri,
RN16_r => RN16_ri,
Length_r => Length_ri,
Mask_r => Mask_ri);
 
TagCtrl_i : TagCtrl
generic map (
WordsRSV => WordsRSV,
WordsEPC => WordsEPC,
WordsTID => WordsTID,
WordsUSR => WordsUSR,
AddrRSV => AddrRSV,
AddrEPC => AddrEPC,
AddrTID => AddrTID,
AddrUSR => AddrUSR,
Data => Data)
port map (
clk => clk,
rst_n => rst_n,
CommDone => CommDone,
Data_r => Data_ri,
Pointer_r => Pointer_ri,
RN16_r => RN16_ri,
Length_r => Length_ri,
Mask_r => Mask_ri,
trm_cmd => trm_cmd_i,
trm_buf => trm_buf_i);
 
transmitter_i: transmitter
port map (
clk => clk,
rst_n => rst_n,
trm_cmd => trm_cmd_i,
trm_buf => trm_buf_i,
tdo => tdo);
 
end STRUCTURAL;
 
 
 
 
/trunk/transmitter.vhd
0,0 → 1,101
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- File name : transmitter.vhd
--
-- Description : Tag transmitter.
-- Currently is reduced to simple Parallel-Serial
-- converter.
--
-- Author : Erwing R. Sanchez Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Last change : 17 Oct 06 - Erwing Sanchez
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.all;
library work;
use work.epc_tag.all;
 
entity transmitter is
port (
clk : in std_logic;
rst_n : in std_logic;
trm_cmd : in std_logic_vector(2 downto 0);
trm_buf : in std_logic_vector(15 downto 0);
tdo : out std_logic);
 
end transmitter;
 
 
architecture trans of transmitter is
 
constant buffer_depth : integer := 3;
 
type BuffBlock_t is array (buffer_depth-1 downto 0) of std_logic_vector(15 downto 0);
signal buffblock : BuffBlock_t;
signal sendflag : std_logic_vector(buffer_depth-1 downto 0);
 
signal buffout_busy : std_logic;
signal buffout : std_logic_vector(15 downto 0);
 
signal counter : std_logic_vector(3 downto 0);
begin -- trans
 
buffer_shift : process (clk, rst_n)
begin -- process serial_conv
if rst_n = '0' then -- asynchronous reset (active low)
sendflag <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
if trm_cmd /= trmcmd_Null then
buffblock(buffer_depth-2 downto 0) <= buffblock(buffer_depth-1 downto 1);
sendflag(buffer_depth-2 downto 0) <= sendflag(buffer_depth-1 downto 1);
buffblock(buffer_depth-1) <= trm_buf;
sendflag(buffer_depth-1) <= '1';
elsif buffout_busy = '0' then
buffblock(buffer_depth-2 downto 0) <= buffblock(buffer_depth-1 downto 1);
sendflag(buffer_depth-2 downto 0) <= sendflag(buffer_depth-1 downto 1);
buffblock(buffer_depth-1) <= (others => '0');
sendflag(buffer_depth-1) <= '0';
end if;
end if;
end process buffer_shift;
 
 
buffout_shift : process (clk, rst_n)
begin -- process buffout_shift
if rst_n = '0' then -- asynchronous reset (active low)
buffout <= (others => '0');
buffout_busy <= '0';
counter <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
if buffout_busy = '1' then
if counter = X"F" then
counter <= (others => '0');
buffout_busy <= '0';
else
counter <= counter + '1';
end if;
buffout(14 downto 0) <= buffout(15 downto 1);
buffout(15) <= '0';
elsif sendflag(0) = '1' then
buffout <= buffblock(0);
buffout_busy <= '1';
end if;
end if;
end process buffout_shift;
 
 
tdo <= buffout(0);
 
end trans;
/trunk/InvSelFlags.vhd
0,0 → 1,145
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag - Inventoried and Selected Flags Model
--
-- File name : InvSelFlags.vhd
--
-- Description : Simulation model of Inventoried and Selected Flags. It
-- includes persistence time as described in the EPC
-- standard v. 1.09.
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 29 June 06
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
 
 
 
entity InvSelFlag is
port (
S1i : in std_logic;
S2i : in std_logic;
S3i : in std_logic;
SLi : in std_logic;
S1o : out std_logic;
S2o : out std_logic;
S3o : out std_logic;
SLo : out std_logic);
 
end InvSelFlag;
 
 
architecture Flags1 of InvSelFlag is
-- synopsys synthesis_off
constant S1INV_PERSISTENCE_TIME : time := 500 ms;
constant S2INV_PERSISTENCE_TIME : time := 2 sec;
constant S3INV_PERSISTENCE_TIME : time := 2 sec;
constant SL_PERSISTENCE_TIME : time := 2 sec;
 
constant TM_STEP : time := 10 ns;
signal S1_time_cnt : time := 1 ns;
signal S2_time_cnt : time := 1 ns;
signal S3_time_cnt : time := 1 ns;
signal SL_time_cnt : time := 1 ns;
signal S1_time_cnt_flag : std_logic := '0';
signal S2_time_cnt_flag : std_logic := '0';
signal S3_time_cnt_flag : std_logic := '0';
signal SL_time_cnt_flag : std_logic := '0';
 
 
 
-- synopsys synthesis_on
begin -- Flags1
-- synopsys synthesis_off
S1FLAG : process (S1_time_cnt_flag, S1i)
begin -- process S1FLAG
if S1i'event and (S1i = '0' or S1i = '1') then
S1o <= S1i;
S1_time_cnt <= 0 ns after TM_STEP;
elsif S1_time_cnt_flag'event then
if S1_time_cnt = S1INV_PERSISTENCE_TIME then
S1o <= 'X';
S1_time_cnt <= 0 ns after TM_STEP;
else
S1_time_cnt <= S1_time_cnt + TM_STEP after TM_STEP;
end if;
end if;
end process S1FLAG;
 
S1FLAG_flag : process (S1_time_cnt)
begin -- process S1FLAG_MIRROR
S1_time_cnt_flag <= not S1_time_cnt_flag;
end process S1FLAG_flag;
 
 
S2FLAG : process (S2_time_cnt_flag, S2i)
begin -- process S2FLAG
if S2i'event and (S2i = '0' or S2i = '1') then
S2o <= S2i;
S2_time_cnt <= 0 ns after TM_STEP;
elsif S2_time_cnt_flag'event then
if S2_time_cnt = S2INV_PERSISTENCE_TIME then
S2o <= 'X';
S2_time_cnt <= 0 ns after TM_STEP;
else
S2_time_cnt <= S2_time_cnt + TM_STEP after TM_STEP;
end if;
end if;
end process S2FLAG;
 
S2FLAG_flag : process (S2_time_cnt)
begin -- process S2FLAG_MIRROR
S2_time_cnt_flag <= not S2_time_cnt_flag;
end process S2FLAG_flag;
 
S3FLAG : process (S3_time_cnt_flag, S3i)
begin -- process S3FLAG
if S3i'event and (S3i = '0' or S3i = '1') then
S3o <= S3i;
S3_time_cnt <= 0 ns after TM_STEP;
elsif S3_time_cnt_flag'event then
if S3_time_cnt = S3INV_PERSISTENCE_TIME then
S3o <= 'X';
S3_time_cnt <= 0 ns after TM_STEP;
else
S3_time_cnt <= S3_time_cnt + TM_STEP after TM_STEP;
end if;
end if;
end process S3FLAG;
 
S3FLAG_flag : process (S3_time_cnt)
begin -- process S3FLAG_MIRROR
S3_time_cnt_flag <= not S3_time_cnt_flag;
end process S3FLAG_flag;
 
SLFLAG : process (SL_time_cnt_flag, SLi)
begin -- process SLFLAG
if SLi'event and (SLi = '0' or SLi = '1') then
SLo <= SLi;
SL_time_cnt <= 0 ns after TM_STEP;
elsif SL_time_cnt_flag'event then
if SL_time_cnt = SL_PERSISTENCE_TIME then
SLo <= 'X';
SL_time_cnt <= 0 ns after TM_STEP;
else
SL_time_cnt <= SL_time_cnt + TM_STEP after TM_STEP;
end if;
end if;
end process SLFLAG;
 
SLFLAG_flag : process (SL_time_cnt)
begin -- process SLFLAG_MIRROR
SL_time_cnt_flag <= not SL_time_cnt_flag;
end process SLFLAG_flag;
-- synopsys synthesis_on
end Flags1;
/trunk/tb_InvSelFlag.vhd
0,0 → 1,122
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag - Inventoried and Selected Flags
-- Test Bench
--
-- File name : tb_InvSelFlag.vhd
--
-- Description : Inventoried and Selected flag test bench.
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 16 Oct 06
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
 
entity tb_InvSelFlag is
end tb_InvSelFlag;
 
architecture stim of tb_InvSelFlag is
 
 
component InvSelFlag
generic (
S1INV_PERSISTENCE_TIME : time;
S2INV_PERSISTENCE_TIME : time;
S3INV_PERSISTENCE_TIME : time;
SL_PERSISTENCE_TIME : time);
port (
S1i : in std_logic;
S2i : in std_logic;
S3i : in std_logic;
SLi : in std_logic;
S1o : out std_logic;
S2o : out std_logic;
S3o : out std_logic;
SLo : out std_logic);
end component;
 
 
constant S1INV_PERSISTENCE_TIME : time := 500 ms;
constant S2INV_PERSISTENCE_TIME : time := 2 sec;
constant S3INV_PERSISTENCE_TIME : time := 2 sec;
constant SL_PERSISTENCE_TIME : time := 2 sec;
constant CKdiv2 : time := 260 ns;
 
signal Si : std_logic_vector(1 to 3);
signal Sli : std_logic;
signal So : std_logic_vector(1 to 3);
signal Slo : std_logic;
 
begin -- stim
 
 
process
 
begin -- process
 
Si <= (others => '0');
Sli <= '0';
 
wait for 20 * CKdiv2;
 
Si(1) <= '1';
wait for 2 * CKdiv2;
Si(1) <= '0';
wait for 2 * CKdiv2;
Si(1) <= '1';
wait for 2 * CKdiv2;
 
Si(2) <= '1';
wait for 2 * CKdiv2;
Si(2) <= '0';
wait for 2 * CKdiv2;
Si(2) <= '1';
wait for 2 * CKdiv2;
 
Si(3) <= '1';
wait for 2 * CKdiv2;
Si(3) <= '0';
wait for 2 * CKdiv2;
Si(3) <= '1';
wait for 2 * CKdiv2;
 
Sli <= '1';
wait for 2 * CKdiv2;
Sli <= '0';
wait for 2 * CKdiv2;
Sli <= '1';
wait for 2 * CKdiv2;
 
 
wait;
end process;
 
 
InvSelFlag_1 : InvSelFlag
generic map (
S1INV_PERSISTENCE_TIME => S1INV_PERSISTENCE_TIME,
S2INV_PERSISTENCE_TIME => S2INV_PERSISTENCE_TIME,
S3INV_PERSISTENCE_TIME => S3INV_PERSISTENCE_TIME,
SL_PERSISTENCE_TIME => SL_PERSISTENCE_TIME)
port map (
S1i => Si(1),
S2i => Si(2),
S3i => Si(3),
SLi => Sli,
S1o => So(1),
S2o => So(2),
S3o => So(3),
SLo => Slo);
 
end stim;
/trunk/tb_Invselflag.vhd
0,0 → 1,107
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15:58:53 05/18/2009
-- Design Name:
-- Module Name: /home/erwing/Projects/vhdl/rfid/tb_Invselflag.vhd
-- Project Name: rfid
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: InvSelFlag
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY tb_Invselflag IS
END tb_Invselflag;
ARCHITECTURE behavior OF tb_Invselflag IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT InvSelFlag
PORT(
S1i : IN std_logic;
S2i : IN std_logic;
S3i : IN std_logic;
SLi : IN std_logic;
S1o : OUT std_logic;
S2o : OUT std_logic;
S3o : OUT std_logic;
SLo : OUT std_logic
);
END COMPONENT;
 
--Inputs
signal S1i : std_logic := '0';
signal S2i : std_logic := '0';
signal S3i : std_logic := '0';
signal SLi : std_logic := '0';
 
--Outputs
signal S1o : std_logic;
signal S2o : std_logic;
signal S3o : std_logic;
signal SLo : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: InvSelFlag PORT MAP (
S1i => S1i,
S2i => S2i,
S3i => S3i,
SLi => SLi,
S1o => S1o,
S2o => S2o,
S3o => S3o,
SLo => SLo
);
-- No clocks detected in port list. Replace <clock> below with
-- appropriate port name
constant <clock>_period := 1ns;
<clock>_process :process
begin
<clock> <= '0';
wait for <clock>_period/2;
<clock> <= '1';
wait for <clock>_period/2;
end process;
 
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100ms.
wait for 100ms;
 
wait for <clock>_period*10;
 
-- insert stimulus here
 
wait;
end process;
 
END;
/trunk/crc16encdec.vhd
0,0 → 1,67
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag - CRC16 encoder/decoder
--
-- File name : crc16encdec.vhd
--
-- Description : Tag CRC16 encoder/decoder
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 10 July 06
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.all;
 
 
entity crc16encdec is
 
generic(
PRESET_CRC16 : integer := 65535); -- X"FFFF"
port (
clk : in std_logic;
rst_n : in std_logic;
init : in std_logic;
ce : in std_logic;
sdi : in std_logic;
cout : out std_logic_vector(15 downto 0));
 
end crc16encdec;
 
architecture CRC16beh of crc16encdec is
 
 
signal crc16reg : std_logic_vector(15 downto 0);
begin -- CRC16beh
 
process (clk, rst_n)
begin -- process
if rst_n = '0' then -- asynchronous reset (active low)
crc16reg <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
if init = '1' then
crc16reg <= conv_std_logic_vector(PRESET_CRC16,16);
elsif ce = '1' then
crc16reg(0) <= crc16reg(15) xor sdi;
crc16reg(4 downto 1) <= crc16reg(3 downto 0);
crc16reg(5) <= crc16reg(15) xor sdi xor crc16reg(4);
crc16reg(11 downto 6) <= crc16reg(10 downto 5);
crc16reg(12) <= crc16reg(15) xor sdi xor crc16reg(11);
crc16reg(15 downto 13) <= crc16reg(14 downto 12);
end if;
end if;
end process;
 
cout <= crc16reg;
end CRC16beh;
/trunk/tagfsm.vhd
0,0 → 1,1880
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag - Tag main FSM
--
-- File name : TagFSM.vhd
--
-- Description : Tag finite state machine (Mealy).
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 28 June 06 - First Draft
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Tag Finite State Machine based on EPC Class 1 Gen 2 Air interface
--
-- The following requirements of the EPC document are not fully implemented.
-- -In the "Select" command, the comparison between the mask and any
-- portion of the memory does not work with bit precision. According
-- to the EPC document, the comparison may start at any bit of any
-- portion of the memory. In this implementation, the comparison starts
-- with a word. It may, however, be of any length.
-- -In the "Select" command, the truncate bit is not currently
-- implemented and does not cause any effect.
-- -Kill and Access passwords are not implemented. So, the tag behaves
-- as though it had zero-valued passwords.
-- -Access command is not implemented.
-- -Kill and Lock commands are currently unavailable.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.all;
library work;
use work.epc_tag.all;
 
 
entity TagFSM is
generic(
WordsRSV : integer := 8;
WordsEPC : integer := 16;
WordsTID : integer := 8;
WordsUSR : integer := 256;
AddrUSR : integer := 5; -- 1/2 memory address pins (maximum)
Data : integer := 16); -- memory data width
port (
clk : in std_logic;
rst_n : in std_logic;
-- Receiver
CommDone : in CommandInternalCode_t;
Data_r : in std_logic_vector(31 downto 0);
Pointer_r : in std_logic_vector(15 downto 0);
RN16_r : in std_logic_vector(15 downto 0);
Length_r : in std_logic_vector(7 downto 0);
Mask_r : in std_logic_vector(MASKLENGTH-1 downto 0);
-- -- MCU
-- MCUComm : out CommandMCU_t;
-- MCUCommVal : out std_logic;
-- MCURdy : in std_logic;
-- Inventoried and Select flags
SInvD : out std_logic_vector(3 downto 0); -- Flag input
SelD : out std_logic;
SInvQ : in std_logic_vector(3 downto 0); -- Flag output
SelQ : in std_logic;
SInvCE : out std_logic_vector(3 downto 0); -- Flag enable
SelCE : out std_logic;
-- Random Number Generator
rng_init : out std_logic;
rng_cin : out std_logic_vector(30 downto 0);
rng_ce : out std_logic;
rng_cout : in std_logic_vector(30 downto 0);
-- Memory
mem_WR : out std_logic;
mem_RD : out std_logic;
mem_RB : in std_logic;
mem_BANK : out std_logic_vector(1 downto 0);
mem_ADR : out std_logic_vector((2*AddrUSR)-1 downto 0);
mem_DTI : out std_logic_vector(Data-1 downto 0);
mem_DTO : in std_logic_vector(Data-1 downto 0);
-- Interrogator Response Timer Flag (T2) - see EPC Standard 1.09 p.34
T2ExpFlag : in std_logic;
-- Transmitter Command and Output buffer
trm_cmd : out std_logic_vector(2 downto 0);
trm_buf : out std_logic_vector(15 downto 0)
);
 
end TagFSM;
 
architecture TagFSM1 of TagFSM is
 
-------------------------------------------------------------------------------
-- DATA_r values according to received command
-------------------------------------------------------------------------------
-- QUERY
-- ___________________________________________________________
-- |__DR__|__M__|__TRext__|__Sel__|__Session__|__Target__|__Q__|
-- 12 11 9 8 6 4 3 0
 
-- QUERYREP
-- ___________
-- |__Session__|
-- 1 0
 
-- QUERYADJUST
-- ____________________
-- |__Session__|__UpDn__|
-- 4 2 0
 
-- SELECT
-- ______________________________________________
-- |__Target__|__Action__|__MemBank__|__Truncate__|
-- 8 5 2 0
 
-- READ
-- ___________
-- |__MemBank__|
-- 1 0
 
-- WRITE
-- _____________________________
-- |__MemBank__|__Data xor RN16__|
-- 17 15 0
 
 
-------------------------------------------------------------------------------
-- Signals
-------------------------------------------------------------------------------
 
-- Kill Flag & RNG initialization address (MSB)
-- (LSB = MEMORY_KILL_RNG_ADDRESS_MSB + 1)
constant MEMORY_KILL_RNG_ADDRESS_MSB : std_logic_vector((2*AddrUSR)-1 downto 0) := (others => '0');
constant RESERVED_MEMORY_BANK : std_logic_vector(1 downto 0) := "00";
constant EPC_MEMORY_BANK : std_logic_vector(1 downto 0) := "01";
constant MEMORY_PC_ADDRESS_16b : std_logic_vector(15 downto 0) := conv_std_logic_vector(1, 16);
constant MEMORY_CRC16_ADDRESS : std_logic_vector((2 * AddrUSR)-1 downto 0) := (others => '0');
 
-- Error Codes
constant NON_SPECIFIC_ERROR : std_logic_vector(15 downto 0) := X"00F0";
 
-- Finite State Machine. [ st_STATE_COMMAND_DESCRIPTION ]
type TagFSM_t is (st_PowerUp, st_PowerUp_GetFlagMSB, st_PowerUp_GetFlagLSB, st_PowerUp_LoadRNG,
-- Ready
st_Ready, st_Ready_QRY_LoadSlot_AND_SaveRN, st_Ready_QRY_CheckSlot_AND_SaveRN,
st_Ready_QRY_LoadRN16Handler_AND_SaveRN, st_Ready_QRY_BackscatterRN16_AND_SaveRN,
st_Ready_SEL_GetWord, st_Ready_SEL_NonMatchingTag, st_Ready_SEL_CompareWords,
st_Ready_SEL_CompareBits, st_Ready_SEL_PrepareComparison, st_Ready_SEL_MatchingTag,
-- Arbitrate
st_Arbitrate, st_Arbitrate_QRYQRA_LoadSlot_AND_SaveRN, st_Arbitrate_QRR_CheckSlot,
st_Arbitrate_QRYQRA_CheckSlot_AND_SaveRN,
-- Reply
st_Reply, st_Reply_ACK_SendPC_AND_DecodeEPCLength, st_Reply_ACK_GetPC,
st_Reply_ACK_GetAndSendEPC, st_Reply_ACK_GetAndSendCRC16,
-- Acknoledged
st_Acknowledged, st_Acknowledged_QRY_CheckFlags, st_Acknowledged_RRN_LoadHandler_AND_SaveRN,
st_Acknowledged_RRN_BackscatterHandler_AND_SaveRN,
-- Open
st_Open, st_Open_ACK_GetPC, st_Open_ACK_SendPC_AND_DecodeEPCLength,
st_Open_ACK_GetAndSendEPC, st_Open_ACK_GetAndSendCRC16,
st_Open_RRN_LoadHandler_AND_SaveRN, st_Open_RRN_BackscatterHandler_AND_SaveRN,
-- Secured
st_Secured, st_Secured_ACK_GetPC, st_Secured_ACK_SendPC_AND_DecodeEPCLength,
st_Secured_ACK_GetAndSendEPC, st_Secured_ACK_GetAndSendCRC16,
st_Secured_RRN_LoadHandler_AND_SaveRN, st_Secured_RRN_BackscatterHandler_AND_SaveRN,
st_Secured_WR_CheckMemoryBounds, st_Secured_WR_WriteWord, st_Secured_WR_WriteIsDone,
st_Secured_RD_CheckMemoryBounds, st_Secured_RD_ReadMemory, st_Secured_RD_Read_AND_Send,
st_Secured_RD_SendLast, st_Secured_RD_SendHandle,
-- Killed
st_Killed);
signal StTag, NextStTag : TagFSM_t;
signal KillFlag, SlotIsZero : std_logic;
signal Query_InventoryFlag_Match : std_logic;
signal Query_SelectFlag_Match : std_logic;
signal Slot, Slot_i : std_logic_vector(15 downto 0);
signal GPR, GPR_i : std_logic_vector(31 downto 0); -- general purpose register
signal RN16Handler, RN16Handler_i : std_logic_vector(15 downto 0);
signal CurrSession, CurrSession_i : std_logic_vector(1 downto 0);
signal CurrQ, CurrQ_i : std_logic_vector(3 downto 0);
signal Select_Address_Pointer_Length_OK : std_logic;
signal Select_Address_Bounds_OK : std_logic;
signal Write_Address_Pointer_Length_OK : std_logic;
signal Write_Address_Bounds_OK : std_logic;
signal Read_Address_Pointer_Length_OK : std_logic;
signal Read_Address_Bounds_OK : std_logic;
signal GCounter, GCounter_i : std_logic_vector(7 downto 0);
signal GCounter2, Gcounter2_i : std_logic_vector(7 downto 0);
signal FirstCompWord, FirstCompWord_i : std_logic;
signal ComparisonReg, ComparisonReg_i : std_logic_vector(Data-1 downto 0);
signal ADRint, ADRint_i : std_logic_vector(15 downto 0);
 
signal GPR_AFTER_COMPARISON_MUX : std_logic_vector(15 downto 0);
signal MASK_AFTER_COMPARISON_BIT_MUX : std_logic_vector(15 downto 0);
signal MASK_AFTER_FIRSTCOMPARISON_MUX : std_logic_vector(15 downto 0);
signal SLOT_VALUE : std_logic_vector(15 downto 0);
 
signal SelD_i, SelCE_i : std_logic;
signal SInvD_i, SInvCE_i : std_logic_vector(3 downto 0);
 
signal trm_cmd_i : std_logic_vector(2 downto 0);
signal trm_buf_i : std_logic_vector(15 downto 0);
 
-- Memory Signals
signal mem_WR_i, mem_RD_i : std_logic;
signal mem_ADR_i : std_logic_vector((2*AddrUSR)-1 downto 0);
signal mem_DTI_i : std_logic_vector(Data-1 downto 0);
signal mem_BANK_i : std_logic_vector(1 downto 0);
-- RNG signals
signal rng_cin_i : std_logic_vector(30 downto 0);
signal rng_init_i, rng_ce_i : std_logic;
 
 
begin -- TagFSM1
 
SYNCRO : process (clk, rst_n)
begin -- process SYNCRO
if rst_n = '0' then -- asynchronous reset (active low)
-- FSM
StTag <= st_PowerUp;
-- General Purpose Register
GPR <= (others => '0');
-- Slot Register
Slot <= (others => '1');
-- RN16 & Handler Register
RN16Handler <= (others => '0');
-- Memory signals
mem_WR <= '0';
mem_RD <= '0';
mem_ADR <= (others => '0');
mem_DTI <= (others => '0');
mem_BANK <= (others => '0');
ADRint <= (others => '0');
-- RNG signals
rng_cin <= (others => '0');
rng_init <= '0';
rng_ce <= '0';
-- Internal signals and Flags
CurrSession <= "00";
CurrQ <= (others => '0');
FirstCompWord <= '0';
ComparisonReg <= (others => '0');
-- Counters
GCounter <= (others => '0');
GCounter2 <= (others => '0');
-- Transmitter
trm_cmd <= trmcmd_Null;
trm_buf <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
-- FSM
StTag <= NextStTag;
-- General Purpose Register
GPR <= GPR_i;
-- Slot Register
Slot <= Slot_i;
-- RN16 & Handler Register
RN16Handler <= RN16Handler_i;
-- Memory signals
mem_WR <= mem_WR_i;
mem_RD <= mem_RD_i;
mem_ADR <= mem_ADR_i;
mem_DTI <= mem_DTI_i;
mem_BANK <= mem_BANK_i;
ADRint <= ADRint_i;
-- RNG signals
rng_init <= rng_init_i;
rng_cin <= rng_cin_i;
rng_ce <= rng_ce_i;
-- Internal signals and Flags
CurrSession <= CurrSession_i;
CurrQ <= CurrQ_i;
FirstCompWord <= FirstCompWord_i;
ComparisonReg <= ComparisonReg_i;
-- Counters
GCounter <= GCounter_i;
GCounter2 <= GCounter2_i;
-- Transmitter
trm_cmd <= trm_cmd_i;
trm_buf <= trm_buf_i;
end if;
end process SYNCRO;
 
 
-------------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- NEXT STATE PROCESS
-----------------------------------------------------------------------------
-------------------------------------------------------------------------------
NEXT_ST : process (StTag, CommDone, mem_RB, mem_DTO, Query_SelectFlag_Match, Query_InventoryFlag_Match, SlotIsZero,
Select_Address_Pointer_Length_OK, GPR, T2ExpFlag, RN16Handler, Write_Address_Pointer_Length_OK,
Read_Address_Pointer_Length_OK, GCounter, MASK_AFTER_FIRSTCOMPARISON_MUX, MASK_AFTER_COMPARISON_BIT_MUX,
GPR_AFTER_COMPARISON_MUX, CurrSession, Data_r, RN16_r)
begin -- process NEXT_ST
NextStTag <= StTag;
case StTag is
-------------------------------------------------------------------------
-- POWERUP (in next state process)
-------------------------------------------------------------------------
when st_PowerUp =>
if mem_RB = '1' then
NextStTag <= st_PowerUp_GetFlagMSB;
end if;
when st_PowerUp_GetFlagMSB =>
if mem_RB = '1' then
if mem_DTO(15) = '1' then -- KILL flag!
NextStTag <= st_Killed;
else
NextStTag <= st_PowerUp_GetFlagLSB;
end if;
end if;
when st_PowerUp_GetFlagLSB =>
if mem_RB = '1' then
NextStTag <= st_PowerUp_LoadRNG;
end if;
when st_PowerUp_LoadRNG =>
NextStTag <= st_Ready;
-----------------------------------------------------------------------
-- READY (in next state process)
-----------------------------------------------------------------------
when st_Ready =>
if CommDone = cmd_Query then
-- Check for matching Inventoried and SL flags
if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1'then
NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
end if;
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
NextStTag <= st_Ready_SEL_GetWord;
else
NextStTag <= st_Ready_SEL_NonMatchingTag;
end if;
end if;
 
when st_Ready_QRY_LoadSlot_AND_SaveRN =>
if mem_RB = '1' then
NextStTag <= st_Ready_QRY_CheckSlot_AND_SaveRN;
end if;
 
when st_Ready_QRY_CheckSlot_AND_SaveRN =>
if mem_RB = '1' then
if SlotIsZero = '1' then
NextStTag <= st_Ready_QRY_LoadRN16Handler_AND_SaveRN;
else
NextStTag <= st_Arbitrate;
end if;
end if;
 
when st_Ready_QRY_LoadRN16Handler_AND_SaveRN =>
if mem_RB = '1' then
NextStTag <= st_Ready_QRY_BackscatterRN16_AND_SaveRN;
end if;
 
when st_Ready_QRY_BackscatterRN16_AND_SaveRN =>
if mem_RB = '1' then
NextStTag <= st_Reply;
end if;
 
-- NOTE: Select command does not support
-- "bit" comparison. Comparison starts at
-- the beginning of a Word!!
when st_Ready_SEL_GetWord =>
if mem_RB = '1' then
NextStTag <= st_Ready_SEL_CompareWords;
end if;
 
when st_Ready_SEL_PrepareComparison =>
if mem_RB = '1' then
if unsigned(GCounter) < Data then
NextStTag <= st_Ready_SEL_CompareBits;
else
NextStTag <= st_Ready_SEL_CompareWords;
end if;
end if;
 
when st_Ready_SEL_CompareWords =>
--if Mask_r((GCounter2)+15 downto conv_integer(unsigned(GCounter2))) = GPR(15 downto 0) then
if MASK_AFTER_FIRSTCOMPARISON_MUX = GPR(15 downto 0) then
NextStTag <= st_Ready_SEL_GetWord;
else
NextStTag <= st_Ready_SEL_NonMatchingTag;
end if;
 
when st_Ready_SEL_CompareBits =>
-- 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
if MASK_AFTER_COMPARISON_BIT_MUX = GPR_AFTER_COMPARISON_MUX then
NextStTag <= st_Ready_SEL_MatchingTag;
else
NextStTag <= st_Ready_SEL_NonMatchingTag;
end if;
 
when st_Ready_SEL_NonMatchingTag =>
NextStTag <= st_Ready;
 
when st_Ready_SEL_MatchingTag =>
NextStTag <= st_Ready;
 
-----------------------------------------------------------------------
-- ARBITRATE (in next state process)
-----------------------------------------------------------------------
when st_Arbitrate =>
-- Query command, in the Arbitrate state, behaves as in the Ready state
if CommDone = cmd_Query then
if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1'then
NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
else
NextStTag <= st_Ready;
end if;
elsif CommDone = cmd_QueryRep then
if CurrSession = Data_r(1 downto 0) then
NextStTag <= st_Arbitrate_QRR_CheckSlot;
end if;
-- After Adjusting Q, the behavior of a QueryAdjust command
-- is the same as the Query Command.
elsif CommDone = cmd_QueryAdjust then
if CurrSession = Data_r(4 downto 3) then
if Data_r(2 downto 0) = "000" or Data_r(2 downto 0) = "110" or Data_r(2 downto 0) = "011" then
NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
end if;
end if;
-- Select Command behaves always as in the Ready state!
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
NextStTag <= st_Ready_SEL_GetWord;
else
NextStTag <= st_Ready_SEL_NonMatchingTag;
end if;
end if;
 
when st_Arbitrate_QRR_CheckSlot =>
if SlotIsZero = '1' then
NextStTag <= st_Ready_QRY_LoadRN16Handler_AND_SaveRN;
else
NextStTag <= st_Arbitrate;
end if;
 
-----------------------------------------------------------------------
-- REPLY (in next state process)
-----------------------------------------------------------------------
when st_Reply =>
-- If interrogator reponse time expires, tag exits the Reply state
if T2ExpFlag = '1' then
NextStTag <= st_Arbitrate;
end if;
-- Query command, in the Reply state, behaves as in the Ready state
if CommDone = cmd_Query then
if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1'then
NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
else
NextStTag <= st_Ready;
end if;
-- QueryRep behaves as in the Arbitrate state
elsif CommDone = cmd_QueryRep then
if CurrSession = Data_r(1 downto 0) then
NextStTag <= st_Arbitrate_QRR_CheckSlot;
end if;
-- After Adjusting Q, the behavior of a QueryAdjust command
-- is the same as the Query Command.
elsif CommDone = cmd_QueryAdjust then
if CurrSession = Data_r(4 downto 3) then
if Data_r(2 downto 0) = "000" or Data_r(2 downto 0) = "110" or Data_r(2 downto 0) = "011" then
NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
end if;
end if;
elsif CommDone = cmd_Ack then
if RN16_r = RN16Handler then
NextStTag <= st_Reply_ACK_GetPC;
else
NextStTag <= st_Arbitrate;
end if;
elsif CommDone = cmd_Nak then
NextStTag <= st_Arbitrate;
-- Select Command behaves always as in the Ready state!
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
NextStTag <= st_Ready_SEL_GetWord;
else
NextStTag <= st_Ready_SEL_NonMatchingTag;
end if;
elsif (CommDone = cmd_Invalid) or (CommDone = cmd_NULL) then
NextStTag <= st_Reply;
else
NextStTag <= st_Arbitrate;
end if;
 
when st_Reply_ACK_GetPC =>
if mem_RB = '1' then
NextStTag <= st_Reply_ACK_SendPC_AND_DecodeEPCLength;
end if;
 
when st_Reply_ACK_SendPC_AND_DecodeEPCLength =>
if mem_RB = '1' then
NextStTag <= st_Reply_ACK_GetAndSendEPC;
end if;
 
when st_Reply_ACK_GetAndSendEPC =>
if mem_RB = '1' then
if unsigned(GPR) /= 0 then
NextStTag <= st_Reply_ACK_GetAndSendEPC;
else
NextStTag <= st_Reply_ACK_GetAndSendCRC16;
end if;
end if;
 
when st_Reply_ACK_GetAndSendCRC16 =>
if mem_RB = '1' then
NextStTag <= st_Acknowledged;
end if;
 
-----------------------------------------------------------------------
-- ACKNOWLEDGED (in next state process)
-----------------------------------------------------------------------
when st_Acknowledged =>
-- If interrogator reponse time expires, tag exits the Acknowledged state
if T2ExpFlag = '1' then
NextStTag <= st_Arbitrate;
end if;
if CommDone = cmd_Query then
NextStTag <= st_Acknowledged_QRY_CheckFlags;
elsif CommDone = cmd_QueryRep then
if CurrSession = Data_r(1 downto 0) then
NextStTag <= st_Ready;
end if;
elsif CommDone = cmd_QueryAdjust then
if CurrSession = Data_r(4 downto 3) then
NextStTag <= st_Ready;
end if;
-- Ack Command is the same as in the Reply state.
elsif CommDone = cmd_Ack then
if RN16_r = RN16Handler then
NextStTag <= st_Reply_ACK_GetPC;
else
NextStTag <= st_Arbitrate;
end if;
elsif CommDone = cmd_Nak then
NextStTag <= st_Arbitrate;
elsif CommDone = cmd_ReqRN then
if RN16_r = RN16Handler then
NextStTag <= st_Acknowledged_RRN_LoadHandler_AND_SaveRN;
end if;
-- Select Command behaves always as in the Ready state!
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
NextStTag <= st_Ready_SEL_GetWord;
else
NextStTag <= st_Ready_SEL_NonMatchingTag;
end if;
elsif (CommDone = cmd_Invalid) or (CommDone = cmd_NULL) then
NextStTag <= st_Acknowledged;
else
NextStTag <= st_Arbitrate;
end if;
 
when st_Acknowledged_QRY_CheckFlags =>
-- Query Command in the Acknowledged state is almost the same as in the
-- Ready state. The difference is that the inventoried flags may change
-- (if the session is the same) before evaluating the Query condition.
if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1'then
NextStTag <= st_Ready_QRY_LoadSlot_AND_SaveRN;
else
NextStTag <= st_Ready;
end if;
 
when st_Acknowledged_RRN_LoadHandler_AND_SaveRN =>
if mem_RB = '1' then
NextStTag <= st_Acknowledged_RRN_BackscatterHandler_AND_SaveRN;
end if;
 
when st_Acknowledged_RRN_BackscatterHandler_AND_SaveRN =>
if mem_RB = '1' then
NextStTag <= st_Secured;
end if;
 
-----------------------------------------------------------------------
-- OPEN (in next state process)
-----------------------------------------------------------------------
when st_Open =>
-- Query in Open = Query in Acknowledged
if CommDone = cmd_Query then
NextStTag <= st_Acknowledged_QRY_CheckFlags;
elsif CommDone = cmd_QueryRep then
if CurrSession = Data_r(1 downto 0) then
NextStTag <= st_Ready;
end if;
elsif CommDone = cmd_QueryAdjust then
if CurrSession = Data_r(4 downto 3) then
NextStTag <= st_Ready;
end if;
elsif CommDone = cmd_Ack then
if RN16_r = RN16Handler then
NextStTag <= st_Open_ACK_GetPC;
else
NextStTag <= st_Arbitrate;
end if;
elsif CommDone = cmd_Nak then
NextStTag <= st_Arbitrate;
elsif CommDone = cmd_ReqRN then
if RN16_r = RN16Handler then
NextStTag <= st_Open_RRN_LoadHandler_AND_SaveRN;
end if;
-- Select Command behaves always as in the Ready state!
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
NextStTag <= st_Ready_SEL_GetWord;
else
NextStTag <= st_Ready_SEL_NonMatchingTag;
end if;
-- elsif CommDone = cmd_Kill then -- See kill flowchart pg.60 (EPC Standard)
-- if "Valid handle" then
-- if "Kill Password != 0" then
-- if "Valid Kill Password" then
-- NextStTag <= st_Killed;
-- else
-- NextStTag <= st_Arbitrate;
-- end if;
-- end if;
-- end if;
-- elsif CommDone = cmd_Access then -- See Access flowchart pg.63 (EPC Standard)
-- if "Valid Handle" then
-- if "Valid Access Password" then
-- NextStTag <= st_Secured;
-- else
-- NextStTag <= st_Arbitrate;
-- end if;
-- end if;
elsif CommDone = cmd_Invalid then -- See state & note pg.73
NextStTag <= st_Arbitrate;
end if;
 
when st_Open_RRN_LoadHandler_AND_SaveRN =>
if mem_RB = '1' then
NextStTag <= st_Open_RRN_BackscatterHandler_AND_SaveRN;
end if;
 
when st_Open_RRN_BackscatterHandler_AND_SaveRN =>
if mem_RB = '1' then
NextStTag <= st_Open;
end if;
 
when st_Open_ACK_GetPC =>
if mem_RB = '1' then
NextStTag <= st_Open_ACK_SendPC_AND_DecodeEPCLength;
end if;
 
when st_Open_ACK_SendPC_AND_DecodeEPCLength =>
if mem_RB = '1' then
NextStTag <= st_Open_ACK_GetAndSendEPC;
end if;
 
when st_Open_ACK_GetAndSendEPC =>
if mem_RB = '1' then
if unsigned(GPR) /= 0 then
NextStTag <= st_Open_ACK_GetAndSendEPC;
else
NextStTag <= st_Open_ACK_GetAndSendCRC16;
end if;
end if;
 
when st_Open_ACK_GetAndSendCRC16 =>
if mem_RB = '1' then
NextStTag <= st_Open;
end if;
 
-----------------------------------------------------------------------
-- SECURED (in next state process)
-----------------------------------------------------------------------
when st_Secured =>
-- Query in Secured = Query in Acknowledged
if CommDone = cmd_Query then
NextStTag <= st_Acknowledged_QRY_CheckFlags;
elsif CommDone = cmd_QueryRep then
if CurrSession = Data_r(1 downto 0) then
NextStTag <= st_Ready;
end if;
elsif CommDone = cmd_QueryAdjust then
if CurrSession = Data_r(4 downto 3) then
NextStTag <= st_Ready;
end if;
elsif CommDone = cmd_Ack then
if RN16_r = RN16Handler then
NextStTag <= st_Secured_ACK_GetPC;
else
NextStTag <= st_Arbitrate;
end if;
elsif CommDone = cmd_Nak then
NextStTag <= st_Arbitrate;
elsif CommDone = cmd_ReqRN then
if RN16_r = RN16Handler then
NextStTag <= st_Secured_RRN_LoadHandler_AND_SaveRN;
end if;
-- Select Command behaves always as in the Ready state!
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
NextStTag <= st_Ready_SEL_GetWord;
else
NextStTag <= st_Ready_SEL_NonMatchingTag;
end if;
elsif CommDone = cmd_Write then
if RN16_r = RN16Handler then
NextStTag <= st_Secured_WR_CheckMemoryBounds;
end if;
elsif CommDone = cmd_Read then
if RN16_r = RN16Handler then
NextStTag <= st_Secured_RD_CheckMemoryBounds;
end if;
-- elsif CommDone = cmd_Kill then -- See kill flowchart pg.60 (EPC Standard)
-- if "Valid handle" then
-- if "Kill Password != 0" then
-- if "Valid Kill Password" then
-- NextStTag <= st_Killed;
-- else
-- NextStTag <= st_Arbitrate;
-- end if;
-- end if;
-- end if;
-- elsif CommDone = cmd_Access then -- See Access flowchart pg.63 (EPC Standard)
-- if "Valid Handle" then
-- if "Valid Access Password" then
-- NextStTag <= st_Secured;
-- else
-- NextStTag <= st_Arbitrate;
-- end if;
-- end if;
elsif CommDone = cmd_Invalid then -- See state & note pg.74
NextStTag <= st_Arbitrate;
end if;
 
when st_Secured_RRN_LoadHandler_AND_SaveRN =>
if mem_RB = '1' then
NextStTag <= st_Secured_RRN_BackscatterHandler_AND_SaveRN;
end if;
 
when st_Secured_RRN_BackscatterHandler_AND_SaveRN =>
if mem_RB = '1' then
NextStTag <= st_Secured;
end if;
 
when st_Secured_ACK_GetPC =>
if mem_RB = '1' then
NextStTag <= st_Secured_ACK_SendPC_AND_DecodeEPCLength;
end if;
 
when st_Secured_ACK_SendPC_AND_DecodeEPCLength =>
if mem_RB = '1' then
NextStTag <= st_Secured_ACK_GetAndSendEPC;
end if;
 
when st_Secured_ACK_GetAndSendEPC =>
if mem_RB = '1' then
if unsigned(GPR) /= 0 then
NextStTag <= st_Secured_ACK_GetAndSendEPC;
else
NextStTag <= st_Secured_ACK_GetAndSendCRC16;
end if;
end if;
 
when st_Secured_ACK_GetAndSendCRC16 =>
if mem_RB = '1' then
NextStTag <= st_Secured;
end if;
 
when st_Secured_WR_CheckMemoryBounds =>
if Write_Address_Pointer_Length_OK = '1' then
NextStTag <= st_Secured_WR_WriteWord;
else
NextStTag <= st_Secured;
end if;
 
when st_Secured_WR_WriteWord =>
if mem_RB = '1' then
NextStTag <= st_Secured_WR_WriteIsDone;
end if;
 
when st_Secured_WR_WriteIsDone =>
if mem_RB = '1' then
NextStTag <= st_Secured;
end if;
 
when st_Secured_RD_CheckMemoryBounds =>
if Read_Address_Pointer_Length_OK = '1' then
NextStTag <= st_Secured_RD_ReadMemory;
else
NextStTag <= st_Secured;
end if;
 
when st_Secured_RD_ReadMemory =>
if mem_RB = '1' then
NextStTag <= st_Secured_RD_Read_AND_Send;
end if;
 
when st_Secured_RD_Read_AND_Send =>
if mem_RB = '1' then
if unsigned(GPR) /= 0 then
NextStTag <= st_Secured_RD_Read_AND_Send;
else
NextStTag <= st_Secured_RD_SendLast;
end if;
end if;
 
when st_Secured_RD_SendLast =>
if mem_RB = '1' then
NextStTag <= st_Secured_RD_SendHandle;
end if;
 
when st_Secured_RD_SendHandle =>
NextStTag <= st_Secured;
 
-----------------------------------------------------------------------
-- KILLED (in next state process)
-----------------------------------------------------------------------
when st_Killed =>
NextStTag <= st_Killed;
 
when others => null;
end case;
end process NEXT_ST;
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- OUTPUT DECODER PROCESS
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
OUTPUT_DEC : process (StTag, CommDone, mem_RB, RN16Handler, GPR, Slot, CurrSession, CurrQ, mem_DTO, Query_SelectFlag_Match,
Query_InventoryFlag_Match, Select_Address_Pointer_Length_OK, SlotIsZero, Write_Address_Pointer_Length_OK,
Read_Address_Pointer_Length_OK, Data_r, Pointer_r, Length_r, SLOT_VALUE, rng_cout, GCounter2, GCounter,
ADRint, SelQ, RN16_r, SInvQ)
begin -- process OUTPUT_DEC
RN16Handler_i <= RN16Handler;
GPR_i <= GPR;
Slot_i <= Slot;
mem_DTI_i <= (others => '0');
mem_WR_i <= '0';
mem_RD_i <= '0';
mem_ADR_i <= (others => '0');
mem_BANK_i <= (others => '0');
rng_cin_i <= (others => '0');
rng_init_i <= '0';
rng_ce_i <= '0';
CurrSession_i <= CurrSession;
CurrQ_i <= CurrQ;
FirstCompWord_i <= '0';
GCounter_i <= (others => '0');
GCounter2_i <= (others => '0');
ADRint_i <= (others => '0');
-- SEL & Inventory Flags
SelD <= '0';
SelCE <= '0';
SInvD <= (others => '0');
SInvCE <= (others => '0');
-- Transmitter
trm_cmd_i <= trmcmd_Null;
trm_buf_i <= (others => '0');
 
case StTag is
-----------------------------------------------------------------------
-- POWERUP (in output process)
-----------------------------------------------------------------------
when st_PowerUp =>
if mem_RB = '1' then
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB;
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_RD_i <= '1';
end if;
 
when st_PowerUp_GetFlagMSB =>
if mem_RB = '1' then
GPR_i(31 downto 16) <= mem_DTO;
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_RD_i <= '1';
end if;
 
when st_PowerUp_GetFlagLSB =>
if mem_RB = '1' then
GPR_i(15 downto 0) <= mem_DTO;
end if;
 
when st_PowerUp_LoadRNG =>
rng_init_i <= '1';
rng_cin_i <= GPR(30 downto 0);
-----------------------------------------------------------------------
-- READY (in output process)
-----------------------------------------------------------------------
when st_Ready =>
if CommDone = cmd_Query then
if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1' then
rng_ce_i <= '1'; -- Prepare new RN
CurrSession_i <= Data_r(6 downto 5);
CurrQ_i <= Data_r(3 downto 0);
end if;
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
-- CompLSBit_i <= Pointer_r(3 downto 0);
GCounter_i <= Length_r;
end if;
end if;
 
when st_Ready_QRY_LoadSlot_AND_SaveRN =>
if mem_RB = '1' then
Slot_i <= SLOT_VALUE;
mem_DTI_i <= rng_cout(15 downto 0);
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_WR_i <= '1';
end if;
 
when st_Ready_QRY_CheckSlot_AND_SaveRN =>
if mem_RB = '1' then
mem_DTI_i <= '0' & rng_cout(30 downto 16);
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB;
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_WR_i <= '1';
if SlotIsZero = '1' then
rng_ce_i <= '1'; -- Prepare new RN
end if;
end if;
 
when st_Ready_QRY_LoadRN16Handler_AND_SaveRN =>
if mem_RB = '1' then
RN16Handler_i <= rng_cout(15 downto 0);
mem_DTI_i <= rng_cout(15 downto 0);
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_WR_i <= '1';
end if;
 
when st_Ready_QRY_BackscatterRN16_AND_SaveRN =>
if mem_RB = '1' then
mem_DTI_i <= '0' & rng_cout(30 downto 16);
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB;
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_WR_i <= '1';
-- Backscatter RN16
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= RN16Handler;
end if;
 
-- NOTE: Select command does not support
-- "bit" comparison. Comparison starts at
-- the beginning of a Word!!
when st_Ready_SEL_GetWord =>
GCounter2_i <= GCounter2; -- Number of bits already compared
GCounter_i <= GCounter; -- Number of bits to compare
ADRint_i <= ADRint;
-- CompLSBit_i <= CompLSBit; -- Starting bits (unused within this version)
if mem_RB = '1' then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= Data_r(2 downto 1);
mem_RD_i <= '1';
end if;
 
when st_Ready_SEL_PrepareComparison =>
GCounter2_i <= GCounter2; -- Number of bits already compared
GCounter_i <= GCounter; -- Number of bits to compare
ADRint_i <= ADRint;
if mem_RB = '1' then
ADRint_i <= ADRint + 1; -- prepare next word address
GPR_i(15 downto 0) <= mem_DTO;
end if;
 
when st_Ready_SEL_CompareWords =>
GCounter2_i <= GCounter2 + conv_std_logic_vector(16, 8); -- Number of bits already compared
GCounter_i <= GCounter - conv_std_logic_vector(16, 8); -- Number of Bits to compare
ADRint_i <= ADRint;
 
when st_Ready_SEL_CompareBits =>
GCounter2_i <= GCounter2 + conv_std_logic_vector(unsigned(GCounter), 8); -- Number of bits already compared
GCounter_i <= GCounter - conv_std_logic_vector(unsigned(GCounter), 8); -- Number of Bits to compare
ADRint_i <= ADRint;
 
when st_Ready_SEL_MatchingTag =>
case Data_r(5 downto 3) is -- Action
when "000" =>
if Data_r(8) = '1' then
if Data_r(7 downto 6) = "00" then
SelD <= '1';
SelCE <= '1';
end if;
else
SInvD(conv_integer(Data_r(7 downto 6))) <= '0'; -- -> A
SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
end if;
when "001" =>
if Data_r(8) = '1' then
if Data_r(7 downto 6) = "00" then
SelD <= '1';
SelCE <= '1';
end if;
else
SInvD(conv_integer(Data_r(7 downto 6))) <= '0'; -- -> A
SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
end if;
when "011" =>
if Data_r(8) = '1' then
if Data_r(7 downto 6) = "00" then
SelD <= not(SelQ);
SelCE <= '1';
end if;
else
SInvD(conv_integer(Data_r(7 downto 6))) <= not(SInvQ(conv_integer(Data_r(7 downto 6)))); -- -> negate
SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
end if;
when "100" =>
if Data_r(8) = '1' then
if Data_r(7 downto 6) = "00" then
SelD <= '0';
SelCE <= '1';
end if;
else
SInvD(conv_integer(Data_r(7 downto 6))) <= '1'; -- -> B
SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
end if;
when "101" =>
if Data_r(8) = '1' then
if Data_r(7 downto 6) = "00" then
SelD <= '0';
SelCE <= '1';
end if;
else
SInvD(conv_integer(Data_r(7 downto 6))) <= '1'; -- -> B
SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
end if;
when others => null;
end case;
 
when st_Ready_SEL_NonMatchingTag =>
case Data_r(5 downto 3) is -- Action
when "000" =>
if Data_r(8) = '1' then
if Data_r(7 downto 6) = "00" then
SelD <= '0';
SelCE <= '1';
end if;
else
SInvD(conv_integer(Data_r(7 downto 6))) <= '1'; -- -> B
SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
end if;
when "010" =>
if Data_r(8) = '1' then
if Data_r(7 downto 6) = "00" then
SelD <= '0';
SelCE <= '1';
end if;
else
SInvD(conv_integer(Data_r(7 downto 6))) <= '1'; -- -> B
SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
end if;
when "100" =>
if Data_r(8) = '1' then
if Data_r(7 downto 6) = "00" then
SelD <= '1';
SelCE <= '1';
end if;
else
SInvD(conv_integer(Data_r(7 downto 6))) <= '0'; -- -> A
SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
end if;
when "110" =>
if Data_r(8) = '1' then
if Data_r(7 downto 6) = "00" then
SelD <= '1';
SelCE <= '1';
end if;
else
SInvD(conv_integer(Data_r(7 downto 6))) <= '0'; -- -> A
SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
end if;
when "111" =>
if Data_r(8) = '1' then
if Data_r(7 downto 6) = "00" then
SelD <= not(SelQ);
SelCE <= '1';
end if;
else
SInvD(conv_integer(Data_r(7 downto 6))) <= not(SInvQ(conv_integer(Data_r(7 downto 6)))); -- -> negate
SInvCE(conv_integer(Data_r(7 downto 6))) <= '1';
end if;
when others => null;
end case;
-----------------------------------------------------------------------
-- ARBITRATE (in output process)
-----------------------------------------------------------------------
when st_Arbitrate =>
if CommDone = cmd_Query then
if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1' then
rng_ce_i <= '1'; -- Prepare new RN
CurrSession_i <= Data_r(6 downto 5);
CurrQ_i <= Data_r(3 downto 0);
end if;
elsif CommDone = cmd_QueryRep then
if CurrSession = Data_r(1 downto 0) then
Slot_i <= Slot - '1';
end if;
elsif CommDone = cmd_QueryAdjust then
if CurrSession = Data_r(4 downto 3) then
if Data_r(2 downto 0) = "000" then -- Q = Q
rng_ce_i <= '1'; -- Prepare new RN
elsif Data_r(2 downto 0) = "110"then -- Q = Q + 1
rng_ce_i <= '1'; -- Prepare new RN
if CurrQ /= "1111" then
CurrQ_i <= CurrQ + '1';
end if;
elsif Data_r(2 downto 0) = "011" then -- Q = Q - 1
rng_ce_i <= '1'; -- Prepare new RN
if CurrQ /= "0000" then
CurrQ_i <= CurrQ - '1';
end if;
end if;
end if;
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
-- CompLSBit_i <= Pointer_r(3 downto 0);
GCounter_i <= Length_r;
end if;
end if;
 
when st_Arbitrate_QRR_CheckSlot =>
if SlotIsZero = '1' then
rng_ce_i <= '1'; -- Prepare new RN
end if;
 
-----------------------------------------------------------------------
-- REPLY (in output process)
-----------------------------------------------------------------------
when st_Reply =>
if CommDone = cmd_Query then
if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1' then
rng_ce_i <= '1'; -- Prepare new RN
CurrSession_i <= Data_r(6 downto 5);
CurrQ_i <= Data_r(3 downto 0);
end if;
elsif CommDone = cmd_QueryRep then
if CurrSession = Data_r(1 downto 0) then
Slot_i <= Slot - '1';
end if;
elsif CommDone = cmd_QueryAdjust then
if CurrSession = Data_r(4 downto 3) then
if Data_r(2 downto 0) = "000" then -- Q = Q
rng_ce_i <= '1'; -- Prepare new RN
elsif Data_r(2 downto 0) = "110"then -- Q = Q + 1
rng_ce_i <= '1'; -- Prepare new RN
if CurrQ /= "1111" then
CurrQ_i <= CurrQ + '1';
end if;
elsif Data_r(2 downto 0) = "011" then -- Q = Q - 1
rng_ce_i <= '1'; -- Prepare new RN
if CurrQ /= "0000" then
CurrQ_i <= CurrQ - '1';
end if;
end if;
end if;
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
-- CompLSBit_i <= Pointer_r(3 downto 0);
GCounter_i <= Length_r;
end if;
elsif CommDone = cmd_Ack then
if RN16_r = RN16Handler then
ADRint_i <= MEMORY_PC_ADDRESS_16b;
end if;
end if;
 
when st_Reply_ACK_GetPC =>
ADRint_i <= ADRint;
if mem_RB = '1' then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= EPC_MEMORY_BANK;
mem_RD_i <= '1';
ADRint_i <= ADRint + '1';
GPR_i <= (others => '0');
end if;
 
when st_Reply_ACK_SendPC_AND_DecodeEPCLength =>
ADRint_i <= ADRint;
if mem_RB = '1' then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= EPC_MEMORY_BANK;
ADRint_i <= ADRint + '1';
mem_RD_i <= '1';
-- GPR_i(4 downto 0) <= mem_DTO(0 to 4); --Length of the PC+EPC (in words)
GPR_i(4) <= mem_DTO(0);
GPR_i(3) <= mem_DTO(1);
GPR_i(2) <= mem_DTO(2);
GPR_i(1) <= mem_DTO(3);
GPR_i(0) <= mem_DTO(4);
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= mem_DTO;
end if;
 
when st_Reply_ACK_GetAndSendEPC =>
ADRint_i <= ADRint;
if mem_RB = '1' then
if unsigned(GPR) /= 0 then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= EPC_MEMORY_BANK;
ADRint_i <= ADRint + '1';
mem_RD_i <= '1';
GPR_i <= GPR - '1';
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= mem_DTO;
else
mem_ADR_i <= MEMORY_CRC16_ADDRESS;
mem_BANK_i <= EPC_MEMORY_BANK;
mem_RD_i <= '1';
end if;
end if;
 
when st_Reply_ACK_GetAndSendCRC16 =>
if mem_RB = '1' then
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= mem_DTO;
end if;
 
-----------------------------------------------------------------------
-- ACKNOWLEDGED (in output process)
-----------------------------------------------------------------------
when st_Acknowledged =>
if CommDone = cmd_Query then
if Data_r(6 downto 5) = CurrSession then --TODO: Verify flags refresh in one clockcycle. -- Toggle inventoried flag
case CurrSession is
when "00" =>
SInvD(0) <= not(SInvQ(0));
SInvCE(0) <= '1';
when "01" =>
SInvD(1) <= not(SInvQ(1));
SInvCE(1) <= '1';
when "10" =>
SInvD(2) <= not(SInvQ(2));
SInvCE(2) <= '1';
when "11" =>
SInvD(3) <= not(SInvQ(3));
SInvCE(3) <= '1';
when others => null;
end case;
end if;
elsif CommDone = cmd_QueryRep then
if CurrSession = Data_r(1 downto 0) then
-- Toggle inventoried flag
case CurrSession is
when "00" =>
SInvD(0) <= not(SInvQ(0));
SInvCE(0) <= '1';
when "01" =>
SInvD(1) <= not(SInvQ(1));
SInvCE(1) <= '1';
when "10" =>
SInvD(2) <= not(SInvQ(2));
SInvCE(2) <= '1';
when "11" =>
SInvD(3) <= not(SInvQ(3));
SInvCE(3) <= '1';
when others => null;
end case;
end if;
elsif CommDone = cmd_QueryAdjust then
if CurrSession = Data_r(4 downto 3) then
-- Toggle inventoried flag
case CurrSession is
when "00" =>
SInvD(0) <= not(SInvQ(0));
SInvCE(0) <= '1';
when "01" =>
SInvD(1) <= not(SInvQ(1));
SInvCE(1) <= '1';
when "10" =>
SInvD(2) <= not(SInvQ(2));
SInvCE(2) <= '1';
when "11" =>
SInvD(3) <= not(SInvQ(3));
SInvCE(3) <= '1';
when others => null;
end case;
end if;
elsif CommDone = cmd_Ack then
if RN16_r = RN16Handler then
ADRint_i <= MEMORY_PC_ADDRESS_16b;
end if;
elsif CommDone = cmd_ReqRN then
if RN16_r = RN16Handler then
rng_ce_i <= '1'; -- Prepare new RN
end if;
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
-- CompLSBit_i <= Pointer_r(3 downto 0);
GCounter_i <= Length_r;
end if;
end if;
 
when st_Acknowledged_QRY_CheckFlags =>
if Query_SelectFlag_Match = '1' and Query_InventoryFlag_Match = '1' then
rng_ce_i <= '1'; -- Prepare new RN
CurrSession_i <= Data_r(6 downto 5);
CurrQ_i <= Data_r(3 downto 0);
end if;
 
when st_Acknowledged_RRN_LoadHandler_AND_SaveRN =>
if mem_RB = '1' then
RN16Handler_i <= rng_cout(15 downto 0);
mem_DTI_i <= rng_cout(15 downto 0);
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_WR_i <= '1';
end if;
 
when st_Acknowledged_RRN_BackscatterHandler_AND_SaveRN =>
if mem_RB = '1' then
mem_DTI_i <= '0' & rng_cout(30 downto 16);
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB;
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_WR_i <= '1';
-- Backscatter RN16
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= RN16Handler;
end if;
 
-----------------------------------------------------------------------
-- OPEN (in output process)
-----------------------------------------------------------------------
when st_Open =>
if CommDone = cmd_Query then
if Data_r(6 downto 5) = CurrSession then --TODO: Verify flags refresh in one clockcycle.
-- Toggle inventoried flag
case CurrSession is
when "00" =>
SInvD(0) <= not(SInvQ(0));
SInvCE(0) <= '1';
when "01" =>
SInvD(1) <= not(SInvQ(1));
SInvCE(1) <= '1';
when "10" =>
SInvD(2) <= not(SInvQ(2));
SInvCE(2) <= '1';
when "11" =>
SInvD(3) <= not(SInvQ(3));
SInvCE(3) <= '1';
when others => null;
end case;
end if;
elsif CommDone = cmd_QueryRep then
if CurrSession = Data_r(1 downto 0) then
-- Toggle inventoried flag
case CurrSession is
when "00" =>
SInvD(0) <= not(SInvQ(0));
SInvCE(0) <= '1';
when "01" =>
SInvD(1) <= not(SInvQ(1));
SInvCE(1) <= '1';
when "10" =>
SInvD(2) <= not(SInvQ(2));
SInvCE(2) <= '1';
when "11" =>
SInvD(3) <= not(SInvQ(3));
SInvCE(3) <= '1';
when others => null;
end case;
end if;
elsif CommDone = cmd_QueryAdjust then
if CurrSession = Data_r(4 downto 3) then
-- Toggle inventoried flag
case CurrSession is
when "00" =>
SInvD(0) <= not(SInvQ(0));
SInvCE(0) <= '1';
when "01" =>
SInvD(1) <= not(SInvQ(1));
SInvCE(1) <= '1';
when "10" =>
SInvD(2) <= not(SInvQ(2));
SInvCE(2) <= '1';
when "11" =>
SInvD(3) <= not(SInvQ(3));
SInvCE(3) <= '1';
when others => null;
end case;
end if;
elsif CommDone = cmd_Ack then
if RN16_r = RN16Handler then
ADRint_i <= MEMORY_PC_ADDRESS_16b;
end if;
elsif CommDone = cmd_ReqRN then
if RN16_r = RN16Handler then
rng_ce_i <= '1'; -- Prepare new RN
end if;
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
-- CompLSBit_i <= Pointer_r(3 downto 0);
GCounter_i <= Length_r;
end if;
end if;
 
when st_Open_ACK_GetPC =>
ADRint_i <= ADRint;
if mem_RB = '1' then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= EPC_MEMORY_BANK;
ADRint_i <= ADRint + '1';
mem_RD_i <= '1';
GPR_i <= (others => '0');
end if;
 
when st_Open_ACK_SendPC_AND_DecodeEPCLength =>
ADRint_i <= ADRint;
if mem_RB = '1' then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= EPC_MEMORY_BANK;
ADRint_i <= ADRint + '1';
mem_RD_i <= '1';
-- GPR_i(4 downto 0) <= mem_DTO(0 to 4); --Length of the PC+EPC (in words)
GPR_i(4) <= mem_DTO(0);
GPR_i(3) <= mem_DTO(1);
GPR_i(2) <= mem_DTO(2);
GPR_i(1) <= mem_DTO(3);
GPR_i(0) <= mem_DTO(4);
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= mem_DTO;
end if;
 
when st_Open_ACK_GetAndSendEPC =>
ADRint_i <= ADRint;
if mem_RB = '1' then
if unsigned(GPR) /= 0 then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= EPC_MEMORY_BANK;
ADRint_i <= ADRint + '1';
mem_RD_i <= '1';
GPR_i <= GPR - '1';
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= mem_DTO;
else
mem_ADR_i <= MEMORY_CRC16_ADDRESS;
mem_BANK_i <= EPC_MEMORY_BANK;
mem_RD_i <= '1';
end if;
end if;
 
when st_Open_ACK_GetAndSendCRC16 =>
if mem_RB = '1' then
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= mem_DTO;
end if;
 
when st_Open_RRN_LoadHandler_AND_SaveRN =>
if mem_RB = '1' then
RN16Handler_i <= rng_cout(15 downto 0);
mem_DTI_i <= rng_cout(15 downto 0);
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_WR_i <= '1';
end if;
 
when st_Open_RRN_BackscatterHandler_AND_SaveRN =>
if mem_RB = '1' then
mem_DTI_i <= '0' & rng_cout(30 downto 16);
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB;
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_WR_i <= '1';
-- Backscatter RN16
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= RN16Handler;
end if;
 
 
 
-----------------------------------------------------------------------
-- SECURED (in output process)
-----------------------------------------------------------------------
when st_Secured =>
if CommDone = cmd_Query then
if Data_r(6 downto 5) = CurrSession then --TODO: Verify flags refresh in one clockcycle.
-- Toggle inventoried flag
case CurrSession is
when "00" =>
SInvD(0) <= not(SInvQ(0));
SInvCE(0) <= '1';
when "01" =>
SInvD(1) <= not(SInvQ(1));
SInvCE(1) <= '1';
when "10" =>
SInvD(2) <= not(SInvQ(2));
SInvCE(2) <= '1';
when "11" =>
SInvD(3) <= not(SInvQ(3));
SInvCE(3) <= '1';
when others => null;
end case;
end if;
elsif CommDone = cmd_QueryRep then
if CurrSession = Data_r(1 downto 0) then
-- Toggle inventoried flag
case CurrSession is
when "00" =>
SInvD(0) <= not(SInvQ(0));
SInvCE(0) <= '1';
when "01" =>
SInvD(1) <= not(SInvQ(1));
SInvCE(1) <= '1';
when "10" =>
SInvD(2) <= not(SInvQ(2));
SInvCE(2) <= '1';
when "11" =>
SInvD(3) <= not(SInvQ(3));
SInvCE(3) <= '1';
when others => null;
end case;
end if;
elsif CommDone = cmd_QueryAdjust then
if CurrSession = Data_r(4 downto 3) then
-- Toggle inventoried flag
case CurrSession is
when "00" =>
SInvD(0) <= not(SInvQ(0));
SInvCE(0) <= '1';
when "01" =>
SInvD(1) <= not(SInvQ(1));
SInvCE(1) <= '1';
when "10" =>
SInvD(2) <= not(SInvQ(2));
SInvCE(2) <= '1';
when "11" =>
SInvD(3) <= not(SInvQ(3));
SInvCE(3) <= '1';
when others => null;
end case;
end if;
elsif CommDone = cmd_Ack then
if RN16_r = RN16Handler then
ADRint_i <= MEMORY_PC_ADDRESS_16b;
end if;
elsif CommDone = cmd_ReqRN then
if RN16_r = RN16Handler then
rng_ce_i <= '1'; -- Prepare new RN
end if;
elsif CommDone = cmd_Select then
if Select_Address_Pointer_Length_OK = '1' then
ADRint_i(11 downto 0) <= Pointer_r(15 downto 4);
-- CompLSBit_i <= Pointer_r(3 downto 0);
GCounter_i <= Length_r;
end if;
elsif CommDone = cmd_Read then
if RN16_r = RN16Handler then
GPR_i <= (others => '0');
end if;
-- Write command does not cause any FSM output at this point (see next_state_process)
end if;
 
when st_Secured_ACK_GetPC =>
ADRint_i <= ADRint;
if mem_RB = '1' then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= EPC_MEMORY_BANK;
ADRint_i <= ADRint + '1';
mem_RD_i <= '1';
GPR_i <= (others => '0');
end if;
 
when st_Secured_ACK_SendPC_AND_DecodeEPCLength =>
ADRint_i <= ADRint;
if mem_RB = '1' then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= EPC_MEMORY_BANK;
ADRint_i <= ADRint + '1';
mem_RD_i <= '1';
-- GPR_i(4 downto 0) <= mem_DTO(0 to 4); --Length of the PC+EPC (in words)
GPR_i(4) <= mem_DTO(0);
GPR_i(3) <= mem_DTO(1);
GPR_i(2) <= mem_DTO(2);
GPR_i(1) <= mem_DTO(3);
GPR_i(0) <= mem_DTO(4);
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= mem_DTO;
end if;
 
when st_Secured_ACK_GetAndSendEPC =>
ADRint_i <= ADRint;
if mem_RB = '1' then
if unsigned(GPR) /= 0 then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= EPC_MEMORY_BANK;
ADRint_i <= ADRint + '1';
mem_RD_i <= '1';
GPR_i <= GPR - '1';
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= mem_DTO;
else
mem_ADR_i <= MEMORY_CRC16_ADDRESS;
mem_BANK_i <= EPC_MEMORY_BANK;
mem_RD_i <= '1';
end if;
end if;
 
when st_Secured_ACK_GetAndSendCRC16 =>
if mem_RB = '1' then
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= mem_DTO;
end if;
 
when st_Secured_RRN_LoadHandler_AND_SaveRN =>
if mem_RB = '1' then
RN16Handler_i <= rng_cout(15 downto 0);
mem_DTI_i <= rng_cout(15 downto 0);
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB + '1';
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_WR_i <= '1';
end if;
 
when st_Secured_RRN_BackscatterHandler_AND_SaveRN =>
if mem_RB = '1' then
mem_DTI_i <= '0' & rng_cout(30 downto 16);
mem_ADR_i <= MEMORY_KILL_RNG_ADDRESS_MSB;
mem_BANK_i <= RESERVED_MEMORY_BANK;
mem_WR_i <= '1';
-- Backscatter RN16
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= RN16Handler;
end if;
 
when st_Secured_WR_CheckMemoryBounds =>
if Write_Address_Pointer_Length_OK = '1' then
ADRint_i <= Pointer_r;
GPR_i(15 downto 0) <= Data_r(15 downto 0) xor RN16Handler;
else
trm_cmd_i <= trmcmd_SendError;
trm_buf_i <= NON_SPECIFIC_ERROR; -- X"0F"
end if;
 
when st_Secured_WR_WriteWord =>
ADRint_i <= ADRint;
if mem_RB = '1' then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_DTI_i <= GPR(15 downto 0);
mem_BANK_i <= Data_r(17 downto 16);
mem_WR_i <= '1';
end if;
 
when st_Secured_WR_WriteIsDone =>
if mem_RB = '1' then
-- Backscatter Handler
trm_cmd_i <= trmcmd_Send;
trm_buf_i <= RN16Handler;
end if;
 
when st_Secured_RD_CheckMemoryBounds =>
if Read_Address_Pointer_Length_OK = '1' then
ADRint_i <= Pointer_r;
GPR_i(7 downto 0) <= Length_r;
else
trm_cmd_i <= trmcmd_SendError;
trm_buf_i <= NON_SPECIFIC_ERROR; -- X"0F"
end if;
 
when st_Secured_RD_ReadMemory =>
ADRint_i <= ADRint;
if mem_RB = '1' then
if unsigned(GPR) /= 0 then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= Data_r(1 downto 0);
mem_RD_i <= '1';
ADRint_i <= ADRint + '1';
GPR_i <= GPR - '1';
else -- Backscatter the whole memory (TODO:check when MEMBANK="01" (EPC))
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= Data_r(1 downto 0);
mem_RD_i <= '1';
ADRint_i <= ADRint + '1';
-- GPR_i(31 downto 2*AddrUSR) <= (others => '0');
case Data_r(1 downto 0) is
when "00" => --Reserved Memory
-- GPR_i((2*AddrUSR)-1 downto 0) <= conv_std_logic_vector(WordsRSV-1, 2*AddrUSR);
GPR_i <= EXT(conv_std_logic_vector(WordsRSV-1, 2 * AddrUSR), 32);
when "01" => -- EPC Memory
-- GPR_i((2*AddrUSR)-1 downto 0) <= conv_std_logic_vector(WordsEPC-1, 2*AddrUSR);
GPR_i <= EXT(conv_std_logic_vector(WordsEPC-1, 2 * AddrUSR), 32);
when "10" => --TID Memory
-- GPR_i((2*AddrUSR)-1 downto 0) <= conv_std_logic_vector(WordsTID-1, 2*AddrUSR);
GPR_i <= EXT(conv_std_logic_vector(WordsTID-1, 2 * AddrUSR), 32);
when "11" => -- User Memory
-- GPR_i((2*AddrUSR)-1 downto 0) <= conv_std_logic_vector(WordsUSR-1, 2*AddrUSR);
GPR_i <= EXT(conv_std_logic_vector(WordsUSR-1, 2 * AddrUSR), 32);
when others => null;
end case;
end if;
end if;
 
when st_Secured_RD_Read_AND_Send =>
ADRint_i <= ADRint;
if mem_RB = '1' then
if unsigned(GPR) /= 0 then
mem_ADR_i <= conv_std_logic_vector(conv_integer(ADRint), 2*AddrUSR);
mem_BANK_i <= Data_r(1 downto 0);
mem_RD_i <= '1';
ADRint_i <= ADRint + '1';
GPR_i <= GPR - '1';
--backscatter data
trm_cmd_i <= trmcmd_SendRData;
trm_buf_i <= mem_DTO;
end if;
end if;
 
when st_Secured_RD_SendLast =>
if mem_RB = '1' then
--backscatter data
trm_cmd_i <= trmcmd_SendRData;
trm_buf_i <= mem_DTO;
end if;
 
when st_Secured_RD_SendHandle =>
trm_cmd_i <= trmcmd_SendRHandler;
trm_buf_i <= RN16Handler;
 
 
 
-----------------------------------------------------------------------
-- KILLED (in output process)
-----------------------------------------------------------------------
when st_Killed => null;
 
 
when others => null;
end case;
 
 
end process OUTPUT_DEC;
 
 
 
 
-----------------------------------------------------------------------------
-- Inventory and Select Flag Comparison
-----------------------------------------------------------------------------
Query_InventoryFlag_Match <= '1' when Data_r(8 downto 7) = "00" else
'1' when Data_r(8 downto 7) = "01" else
'1' when (Data_r(8 downto 7) = "10" and SelQ = '0') else
'1' when (Data_r(8 downto 7) = "11" and SelQ = '1') else
'0';
Query_SelectFlag_Match <= '1' when (Data_r(6 downto 5) = "00" and Data_r(4) = SInvQ(0)) else
'1' when (Data_r(6 downto 5) = "01" and Data_r(4) = SInvQ(1)) else
'1' when (Data_r(6 downto 5) = "10" and Data_r(4) = SInvQ(2)) else
'1' when (Data_r(6 downto 5) = "11" and Data_r(4) = SInvQ(3)) else
'0';
 
-----------------------------------------------------------------------------
-- Slot Zero comparison
-----------------------------------------------------------------------------
SlotIsZero <= '1' when conv_integer(Slot) = 0 else
'0';
 
-----------------------------------------------------------------------------
-- Adress Pointer & Length Control (Select Command)
-----------------------------------------------------------------------------
 
Select_Address_Pointer_Length_OK <= '1' when Select_Address_Bounds_OK = '1' and conv_integer(Length_r) /= 0 else
'0';
 
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
'1' when (Data_r(2 downto 1) = "01") and ((conv_integer(Pointer_r(15 downto 4))+ conv_integer(Length_r)) < WordsEPC) else
'1' when (Data_r(2 downto 1) = "10") and ((conv_integer(Pointer_r(15 downto 4))+ conv_integer(Length_r)) < WordsTID) else
'1' when (Data_r(2 downto 1) = "11") and ((conv_integer(Pointer_r(15 downto 4))+ conv_integer(Length_r)) < WordsUSR) else
'0';
 
-----------------------------------------------------------------------------
-- Adress Pointer & Length Control (Read Command)
-----------------------------------------------------------------------------
 
Read_Address_Pointer_Length_OK <= '1' when Read_Address_Bounds_OK = '1' and conv_integer(Length_r) /= 0 else
'0';
 
Read_Address_Bounds_OK <= '1' when (Data_r(1 downto 0) = "00") and ((conv_integer(Pointer_r)+ conv_integer(Length_r)) < WordsRSV) else
'1' when (Data_r(1 downto 0) = "01") and ((conv_integer(Pointer_r)+ conv_integer(Length_r)) < WordsEPC) else
'1' when (Data_r(1 downto 0) = "10") and ((conv_integer(Pointer_r)+ conv_integer(Length_r)) < WordsTID) else
'1' when (Data_r(1 downto 0) = "11") and ((conv_integer(Pointer_r)+ conv_integer(Length_r)) < WordsUSR) else
'0';
 
-----------------------------------------------------------------------------
-- Adress Pointer & Length Control (Write Command)
-----------------------------------------------------------------------------
 
Write_Address_Pointer_Length_OK <= '1' when Write_Address_Bounds_OK = '1' else
'0';
 
Write_Address_Bounds_OK <= '1' when (Data_r(17 downto 16) = "00") and (conv_integer(Pointer_r) < WordsRSV) else
'1' when (Data_r(17 downto 16) = "01") and (conv_integer(Pointer_r) < WordsEPC) else
'1' when (Data_r(17 downto 16) = "10") and (conv_integer(Pointer_r) < WordsTID) else
'1' when (Data_r(17 downto 16) = "11") and (conv_integer(Pointer_r) < WordsUSR) else
'0';
 
 
-----------------------------------------------------------------------------
-- MASK Comparison (Select Command)
-----------------------------------------------------------------------------
GPR_AFTER_COMPARISON_MUX <= X"000" & "000" & GPR(0) when unsigned(GCounter(3 downto 0)) = 0 else
EXT(GPR(1 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 1 else
EXT(GPR(2 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 2 else
EXT(GPR(3 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 3 else
EXT(GPR(4 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 4 else
EXT(GPR(5 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 5 else
EXT(GPR(6 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 6 else
EXT(GPR(7 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 7 else
EXT(GPR(8 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 8 else
EXT(GPR(9 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 9 else
EXT(GPR(10 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 10 else
EXT(GPR(11 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 11 else
EXT(GPR(12 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 12 else
EXT(GPR(13 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 13 else
EXT(GPR(14 downto 0), 16) when unsigned(GCounter(3 downto 0)) = 14 else
GPR(15 downto 0);
 
MASK_AFTER_FIRSTCOMPARISON_MUX <= Mask_r(15 downto 0) when unsigned(GCounter2) = 0 else
Mask_r(16 downto 1) when unsigned(GCounter2) = 1 else
Mask_r(17 downto 2) when unsigned(GCounter2) = 2 else
Mask_r(18 downto 3) when unsigned(GCounter2) = 3 else
Mask_r(19 downto 4) when unsigned(GCounter2) = 4 else
Mask_r(20 downto 5) when unsigned(GCounter2) = 5 else
Mask_r(21 downto 6) when unsigned(GCounter2) = 6 else
Mask_r(22 downto 7) when unsigned(GCounter2) = 7 else
Mask_r(23 downto 8) when unsigned(GCounter2) = 8 else
Mask_r(24 downto 9) when unsigned(GCounter2) = 9 else
Mask_r(25 downto 10) when unsigned(GCounter2) = 10 else
Mask_r(26 downto 11) when unsigned(GCounter2) = 11 else
Mask_r(27 downto 12) when unsigned(GCounter2) = 12 else
Mask_r(28 downto 13) when unsigned(GCounter2) = 13 else
Mask_r(29 downto 14) when unsigned(GCounter2) = 14 else
Mask_r(30 downto 15) when unsigned(GCounter2) = 15 else
Mask_r(31 downto 16) when unsigned(GCounter2) = 16 else
Mask_r(32 downto 17) when unsigned(GCounter2) = 17 else
Mask_r(33 downto 18) when unsigned(GCounter2) = 18 else
Mask_r(34 downto 19) when unsigned(GCounter2) = 19 else
Mask_r(35 downto 20) when unsigned(GCounter2) = 20 else
Mask_r(36 downto 21);
 
MASK_AFTER_COMPARISON_BIT_MUX <= MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000000001" when unsigned(GCounter(3 downto 0)) = 0 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000000011" when unsigned(GCounter(3 downto 0)) = 1 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000000111" when unsigned(GCounter(3 downto 0)) = 2 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000001111" when unsigned(GCounter(3 downto 0)) = 3 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000011111" when unsigned(GCounter(3 downto 0)) = 4 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000000111111" when unsigned(GCounter(3 downto 0)) = 5 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000001111111" when unsigned(GCounter(3 downto 0)) = 6 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000011111111" when unsigned(GCounter(3 downto 0)) = 7 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000000111111111" when unsigned(GCounter(3 downto 0)) = 8 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000001111111111" when unsigned(GCounter(3 downto 0)) = 9 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000011111111111" when unsigned(GCounter(3 downto 0)) = 10 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0000111111111111" when unsigned(GCounter(3 downto 0)) = 11 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0001111111111111" when unsigned(GCounter(3 downto 0)) = 12 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0011111111111111" when unsigned(GCounter(3 downto 0)) = 13 else
MASK_AFTER_FIRSTCOMPARISON_MUX and "0111111111111111" when unsigned(GCounter(3 downto 0)) = 14 else
MASK_AFTER_FIRSTCOMPARISON_MUX;
-----------------------------------------------------------------------------
-- SLOT VALUE (Query Command)
-----------------------------------------------------------------------------
SLOT_VALUE <= X"0000" when unsigned(CurrQ) = 0 else
X"000" & "000" & rng_cout(0) when unsigned(CurrQ) = 1 else
EXT(rng_cout(1 downto 0), 16) when unsigned(CurrQ) = 2 else
EXT(rng_cout(2 downto 0), 16) when unsigned(CurrQ) = 3 else
EXT(rng_cout(3 downto 0), 16) when unsigned(CurrQ) = 4 else
EXT(rng_cout(4 downto 0), 16) when unsigned(CurrQ) = 5 else
EXT(rng_cout(5 downto 0), 16) when unsigned(CurrQ) = 6 else
EXT(rng_cout(6 downto 0), 16) when unsigned(CurrQ) = 7 else
EXT(rng_cout(7 downto 0), 16) when unsigned(CurrQ) = 8 else
EXT(rng_cout(8 downto 0), 16) when unsigned(CurrQ) = 9 else
EXT(rng_cout(9 downto 0), 16) when unsigned(CurrQ) = 10 else
EXT(rng_cout(10 downto 0), 16) when unsigned(CurrQ) = 11 else
EXT(rng_cout(11 downto 0), 16) when unsigned(CurrQ) = 12 else
EXT(rng_cout(12 downto 0), 16) when unsigned(CurrQ) = 13 else
EXT(rng_cout(13 downto 0), 16) when unsigned(CurrQ) = 14 else
EXT(rng_cout(14 downto 0), 16);
 
end TagFSM1;
/trunk/flashmemEPC.vhd
0,0 → 1,245
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : Flash Memory EPC
--
-- File name : flashmemEPC.vhd
--
-- Description : Flash memory model.
--
-- Author : Paolo Bernardi <paolo.bernardi@polito.it>
--
-- Rev. History : Erwing Sanchez -- 17/07/06
-- - Ready/busy input removed because not used
-- - "Bits" generic removed
-- - RP input removed
-- - Command codes changed to work with Data = 16
-- E.R. Sanchez -- 13/10/06
-- - Include Parameters & Initialization
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.std_logic_textio.all;
use STD.TEXTIO.all;
 
 
 
entity Flash_MeM_EPC is
generic (
Words : integer := 16; -- number of addresses
Addr : integer := 3; -- number of pins reserved for addresses
Data : integer := 16
);
port (
A : in std_logic_vector(Addr-1 downto 0); -- Address inputs
D : in std_logic_vector(Data-1 downto 0); -- Data input
Q : out std_logic_vector(Data-1 downto 0); -- Data output
G : in std_logic; -- Output enable
W : in std_logic; -- Write enable
RC : in std_logic; -- Row/Column address select
st : out std_logic -- Interface reset
);
 
end Flash_MeM_EPC;
 
 
architecture Behavioural of Flash_MeM_EPC is
 
--synopsys synthesis_off
 
type Flash_Type is array (0 to Words-1) of std_logic_vector(Data-1 downto 0);
signal Mem : Flash_Type := ("0100000000000000",
"0000000111111000",
"0011111111110000",
"0000001111000000",
"0100000000000000",
"0010000000000000",
"0001000000000000",
"0000100000000000",
"0000110000000000",
"0000101000000000",
"0000100100000000",
"0000100010000000",
"0000100001000000",
"0000100000100000",
"0000100000010000",
"0000100000001000");
 
 
signal Addr_int : std_logic_vector((2*Addr)-1 downto 0);
signal Data_int : std_logic_vector(Data-1 downto 0);
 
signal program : std_logic := '0';
signal erase : std_logic := '0';
signal i : natural range Words-1 downto 0;
signal status_register : std_logic_vector(Data-1 downto 0);
signal status : std_logic;
signal InitIsDoneFlag : std_logic := '0';
 
function resetVector (dim : natural) return std_logic_vector is
 
variable vectorOut : std_logic_vector(dim -1 downto 0);
variable i : natural range dim downto 0;
 
 
begin
 
 
for i in 0 to dim-1 loop
vectorOut(i) := '0';
end loop;
return vectorOut;
end resetVector;
 
function erase_mem (mem : Flash_Type) return Flash_Type is
 
variable mem_out : Flash_Type;
variable i : natural range Words-1 downto 0;
 
begin
for i in 0 to Words-1 loop
Mem_out(i) := (others => '1'); --"11111111";
end loop;
return mem_out;
 
end erase_mem;
 
--synopsys synthesis_on
begin --BEHAVIOURAL
 
--synopsys synthesis_off
write_first : process (RC)
begin
if RC'event and RC = '0' then
Addr_int(Addr-1 downto 0) <= A;
end if;
end process write_first;
 
write_second : process (RC)
begin
if RC'event and RC = '1' then
Addr_int((2*Addr)-1 downto Addr) <= A;
end if;
end process write_second;
 
w_data : process (W)
begin
if W'event and W = '1' then
if program = '1' then
Mem(conv_integer(unsigned(Addr_int))) <= D after 50 ns;
status_register <= conv_std_logic_vector(64, Data); --"01000000"
Data_int <= resetVector(Data_int'length);
st <= '0';
elsif erase = '1' then
Mem <= erase_mem(Mem) after 750000000 ns;
Data_int <= resetVector(Data_int'length);
st <= '1' after 750000000 ns;
else
Data_int <= D;
status_register <= (others => '0'); --"00000000";
st <= '0';
end if;
end if;
end process w_data;
 
read_data : process (G)
begin
if G'event and G = '0' then
if status = '0' then
Q <= Mem(conv_integer(unsigned(Addr_int))) after 50 ns;
else
Q <= status_register after 750000000 ns;
end if;
elsif G'event and G = '1' then
Q <= (others => 'U') after 50 ns; -- "UUUUUUUU"
end if;
end process read_data;
 
decode : process (Data_int)
begin
case conv_integer(Data_int) is
when 64 => -- "01000000" program
program <= '1';
erase <= '0';
status <= '0';
when 32 => -- "00100000" erase
program <= '0';
erase <= '1';
status <= '0';
when 112 => -- "01110000" read status reg
program <= '0';
erase <= '0';
status <= '1';
when others =>
program <= '0';
erase <= '0';
status <= '0';
end case;
end process decode;
 
 
-- -- purpose: Load Memory from file
-- load_memory : process(A, D, G, W, RC, InitIsDoneFlag)
-- file init_mem_file : text open read_mode is "meminit.txt";
-- variable inline, outline : line;
-- variable add : natural;
-- variable c : character;
-- variable Mem_var : Flash_Type;
-- begin -- process load_memory
-- if InitIsDoneFlag = '0' then
-- -- Clear Memory
-- for i in 0 to Words-1 loop
-- Mem_var(i) := (others => '0');
-- end loop; -- i
-- -- Load
-- while not endfile(init_mem_file) loop
-- readline(init_mem_file, inline);
-- read(inline, add);
-- read(inline, c);
-- if c /= ':' then
-- write(outline, string'("Syntax Error"));
-- writeline(output, outline);
-- assert false report "Mem Loader Aborted" severity failure;
-- end if;
-- for i in (Data-1) downto 0 loop
-- read(inline, c);
-- if c = '1' then
-- Mem_var(add)(i) := '1';
-- elsif c = '0' then
-- Mem_var(add)(i) := '0';
-- else
-- write(outline, string'("Invalid Character-Set to '0'"));
-- writeline(output, outline);
-- Mem_var(add)(i) := '0';
-- end if;
-- end loop; -- i
-- end loop;
-- Mem <= Mem_var;
-- InitIsDoneFlag <= '1';
-- end if;
-- end process load_memory;
 
--synopsys synthesis_on
 
end Behavioural;
 
--synopsys synthesis_off
 
configuration CFG_Flash_MeM_EPC of Flash_MeM_EPC is
for Behavioural
end for;
end CFG_Flash_MeM_EPC;
 
--synopsys synthesis_on
/trunk/flashmemUSR.vhd
0,0 → 1,218
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : Flash Memory USR
--
-- File name : flashmemUSR.vhd
--
-- Description : Flash memory model.
--
-- Author : Paolo Bernardi <paolo.bernardi@polito.it>
--
-- Rev. History : Erwing Sanchez -- 17/07/06
-- - Ready/busy input removed because not used
-- - "Bits" generic removed
-- - RP input removed
-- - Command codes changed to work with Data = 16
-- E.R. Sanchez -- 13/10/06
-- - Include Parameters & Initialization
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.std_logic_textio.all;
use STD.TEXTIO.all;
 
 
entity Flash_MeM_USR is
generic (
Words : integer := 256; -- number of addresses
Addr : integer := 5; -- number of pins reserved for addresses
Data : integer := 16
);
port (
A : in std_logic_vector(Addr-1 downto 0); -- Address inputs
D : in std_logic_vector(Data-1 downto 0); -- Data input
Q : out std_logic_vector(Data-1 downto 0); -- Data output
G : in std_logic; -- Output enable
W : in std_logic; -- Write enable
RC : in std_logic; -- Row/Column address select
st : out std_logic -- Interface reset
);
 
end Flash_MeM_USR;
 
--synopsys synthesis_on
architecture Behavioural of Flash_MeM_USR is
--synopsys synthesis_off
 
type Flash_Type is array (0 to Words-1) of std_logic_vector(Data-1 downto 0);
signal Mem : Flash_Type := (others => (others => '1'));
 
 
signal Addr_int : std_logic_vector((2*Addr)-1 downto 0);
signal Data_int : std_logic_vector(Data-1 downto 0);
 
signal program : std_logic := '0';
signal erase : std_logic := '0';
signal i : natural range Words-1 downto 0;
signal status_register : std_logic_vector(Data-1 downto 0);
signal status : std_logic;
signal InitIsDoneFlag : std_logic := '0';
 
function resetVector (dim : natural) return std_logic_vector is
 
variable vectorOut : std_logic_vector(dim -1 downto 0);
variable i : natural range dim downto 0;
 
begin
for i in 0 to dim-1 loop
vectorOut(i) := '0';
end loop;
return vectorOut;
end resetVector;
 
function erase_mem (mem : Flash_Type) return Flash_Type is
 
variable mem_out : Flash_Type;
variable i : natural range Words-1 downto 0;
 
begin
for i in 0 to Words-1 loop
Mem_out(i) := (others => '1'); --"11111111";
end loop;
return mem_out;
 
end erase_mem;
--synopsys synthesis_on
begin --BEHAVIOURAL
--synopsys synthesis_off
write_first : process (RC)
begin
if RC'event and RC = '0' then
Addr_int(Addr-1 downto 0) <= A;
end if;
end process write_first;
 
write_second : process (RC)
begin
if RC'event and RC = '1' then
Addr_int((2*Addr)-1 downto Addr) <= A;
end if;
end process write_second;
 
w_data : process (W)
begin
if W'event and W = '1' then
if program = '1' then
Mem(conv_integer(unsigned(Addr_int))) <= D after 50 ns;
status_register <= conv_std_logic_vector(64, Data); --"01000000"
Data_int <= resetVector(Data_int'length);
st <= '0';
elsif erase = '1' then
Mem <= erase_mem(Mem) after 750000000 ns;
Data_int <= resetVector(Data_int'length);
st <= '1' after 750000000 ns;
else
Data_int <= D;
status_register <= (others => '0'); --"00000000";
st <= '0';
end if;
end if;
end process w_data;
 
read_data : process (G)
begin
if G'event and G = '0' then
if status = '0' then
Q <= Mem(conv_integer(unsigned(Addr_int))) after 50 ns;
else
Q <= status_register after 750000000 ns;
end if;
elsif G'event and G = '1' then
Q <= (others => 'U') after 50 ns; -- "UUUUUUUU"
end if;
end process read_data;
 
decode : process (Data_int)
begin
case conv_integer(Data_int) is
when 64 => -- "01000000" program
program <= '1';
erase <= '0';
status <= '0';
when 32 => -- "00100000" erase
program <= '0';
erase <= '1';
status <= '0';
when 112 => -- "01110000" read status reg
program <= '0';
erase <= '0';
status <= '1';
when others =>
program <= '0';
erase <= '0';
status <= '0';
end case;
end process decode;
 
 
-- -- purpose: Load Memory from file
-- load_memory : process(A, D, G, W, RC, InitIsDoneFlag)
-- file init_mem_file : text open read_mode is "meminit.txt";
-- variable inline, outline : line;
-- variable add : natural;
-- variable c : character;
-- variable Mem_var : Flash_Type;
-- begin -- process load_memory
-- if InitIsDoneFlag = '0' then
-- -- Clear Memory
-- for i in 0 to Words-1 loop
-- Mem_var(i) := (others => '0');
-- end loop; -- i
-- -- Load
-- while not endfile(init_mem_file) loop
-- readline(init_mem_file, inline);
-- read(inline, add);
-- read(inline, c);
-- if c /= ':' then
-- write(outline, string'("Syntax Error"));
-- writeline(output, outline);
-- assert false report "Mem Loader Aborted" severity failure;
-- end if;
-- for i in (Data-1) downto 0 loop
-- read(inline, c);
-- if c = '1' then
-- Mem_var(add)(i) := '1';
-- elsif c = '0' then
-- Mem_var(add)(i) := '0';
-- else
-- write(outline, string'("Invalid Character-Set to '0'"));
-- writeline(output, outline);
-- Mem_var(add)(i) := '0';
-- end if;
-- end loop; -- i
-- end loop;
-- Mem <= Mem_var;
-- InitIsDoneFlag <= '1';
-- end if;
-- end process load_memory;
 
--synopsys synthesis_on
end Behavioural;
--synopsys synthesis_off
 
 
configuration CFG_Flash_MeM_USR of Flash_MeM_USR is
for Behavioural
end for;
end CFG_Flash_MeM_USR;
 
--synopsys synthesis_on
/trunk/counterclear.vhd
0,0 → 1,59
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : Simple Counter with clear
--
-- File name : counterclear.vhd
--
-- Description : Counter with clear.
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 22 july 06
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
 
entity COUNTERCLR is
generic (
width : integer := 8);
 
port (
clk : in std_logic;
rst_n : in std_logic;
en : in std_logic;
clear : in std_logic;
outcnt : out std_logic_vector(width-1 downto 0));
end COUNTERCLR;
 
architecture COUNTERCLR1 of COUNTERCLR is
 
signal cnt : std_logic_vector(width-1 downto 0);
begin -- COUNTERCLR1
 
process (clk, rst_n)
begin -- process
if rst_n = '0' then -- asynchronous reset (active low)
cnt <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
if en = '1' then
cnt <= conv_std_logic_vector(CONV_INTEGER(cnt) + 1, width);
elsif clear = '1' then
cnt <= (others => '0');
end if;
end if;
end process;
 
outcnt <= cnt;
end COUNTERCLR1;
/trunk/symbdec.vhd
0,0 → 1,377
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag - Symbol Decoder
--
-- File name : symbdec.vhd
--
-- Description : Tag symbol decoder detects valid frames decoding command
-- preambles and frame-syncs.
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 21 june 06 - First Draft
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.all;
use ieee.numeric_std.all;
library work;
use work.epc_tag.all;
 
 
entity SymbolDecoder is
generic (
LOG2_10_TARI_CK_CYC : integer := 9; -- Log2(clock cycles for 10 maximum TARI value) (def:
-- Log2(490) = 9 @TCk=520ns)
DELIMITIER_TIME_CK_CYC_MIN : integer := 22; -- Min Clock cycles for 12,5 us delimitier
DELIMITIER_TIME_CK_CYC_MAX : integer := 24); -- Max Clock cycles for 12,5 us delimitier
 
port (
clk : in std_logic;
rst_n : in std_logic;
tdi : in std_logic;
en : in std_logic;
start : in std_logic;
sserror : out std_logic;
ssovalid : out std_logic;
sso : out std_logic); -- serial symbol output
 
end SymbolDecoder;
 
 
architecture symbdec1 of SymbolDecoder is
 
component COUNTERCLR
generic (
width : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
en : in std_logic;
clear : in std_logic;
outcnt : out std_logic_vector(width-1 downto 0));
end component;
 
type RecFSM_t is (st0_Start, st0b_Delimitier, st1_Dat0H, st2_Dat0L, st3_RTcalH, st4_RTcalL, st5_Sym0H, st6_Sym0L, st6b_Sym0L_TR, st7_SymH, st8_SymL, st9_SymH_TR, st10_SymL_TR);
 
signal StRec, NextStRec : RecFSM_t;
signal CntEn, CntClr : std_logic;
signal CntEn_i, CntClr_i : std_logic;
signal TRCalEn, RTCalEn : std_logic;
signal TRCalEn_i, RTCalEn_i : std_logic;
signal TARI4En, TARI4En_i : std_logic;
signal CntReg, RTCalReg, TRCalReg : std_logic_vector(LOG2_10_TARI_CK_CYC-1 downto 0);
signal RTCaldiv2Reg, TARI4Reg : std_logic_vector(LOG2_10_TARI_CK_CYC-1 downto 0);
signal RTCal_GRTH_TRCal, Symb_GRTH_RTCaldiv2 : std_logic;
signal Symb_GRTH_TARI4 : std_logic;
signal ssovalid_i, sso_i, sserror_i : std_logic;
signal DelimitierComparisoOK : std_logic;
begin -- Receiver1
 
RTCaldiv2Reg <= '0' & RTCalReg(LOG2_10_TARI_CK_CYC-1 downto 1);
 
SYNCRO : process(clk, rst_n)
begin -- process
if clk'event and clk = '1' then
if rst_n = '0' then
CntEn <= '0';
TRCalEn <= '0';
RTCalEn <= '0';
TARI4En <= '0';
sserror <= '0';
ssovalid <= '0';
sso <= '0';
StRec <= st0_start;
else
if en = '1' then
StRec <= NextStRec;
CntEn <= CntEn_i;
TRCalEn <= TRCalEn_i;
RTCalEn <= RTCalEn_i;
TARI4En <= TARI4En_i;
CntClr <= CntClr_i;
sserror <= sserror_i;
ssovalid <= ssovalid_i;
sso <= sso_i;
end if;
end if;
end if;
end process;
 
 
NEXT_ST : process (StRec, tdi, start, TRCalEn, Symb_GRTH_TARI4, DelimitierComparisoOK)
begin -- process NEXT_ST
NextStRec <= StRec;
case StRec is
when st0_Start =>
if tdi = '0' then
NextStRec <= st0b_Delimitier;
end if;
when st0b_Delimitier =>
if tdi = '1' then
if DelimitierComparisoOK = '1' then
NextStRec <= st1_Dat0H;
else
NextStRec <= st0_Start;
end if;
end if;
when st1_Dat0H =>
if tdi = '0' then
NextStRec <= st2_Dat0L;
end if;
when st2_Dat0L =>
if tdi = '1' then
NextStRec <= st3_RTcalH;
end if;
when st3_RTcalH =>
if tdi = '0' then
NextStRec <= st4_RTcalL;
end if;
when st4_RTcalL =>
if tdi = '1' then
NextStRec <= st5_Sym0H;
end if;
when st5_Sym0H =>
if tdi = '0' then
NextStRec <= st6_Sym0L;
end if;
when st6_Sym0L =>
if TRCalEn = '1' then
NextStRec <= st6b_Sym0L_TR;
elsif tdi = '1' then
NextStRec <= st7_SymH;
end if;
when st6b_Sym0L_TR =>
if tdi = '1' then
NextStRec <= st9_SymH_TR;
end if;
when st9_SymH_TR =>
if tdi = '0' then
NextStRec <= st10_SymL_TR;
end if;
when st10_SymL_TR =>
if tdi = '1' then
NextStRec <= st7_SymH;
end if;
when st7_SymH =>
if Symb_GRTH_TARI4 = '1' then
NextStRec <= st0_Start;
elsif start = '1'then
NextStRec <= st0_Start;
elsif tdi = '0' then
NextStRec <= st8_SymL;
end if;
when st8_SymL =>
if Symb_GRTH_TARI4 = '1' then
NextStRec <= st0_Start;
elsif start = '1' then
NextStRec <= st0_Start;
elsif tdi = '1' then
NextStRec <= st7_SymH;
end if;
when others =>
NextStRec <= st0_start;
end case;
end process NEXT_ST;
 
 
OUTPUT_DEC : process (StRec, tdi, RTCal_GRTH_TRCal, Symb_GRTH_RTCaldiv2, Symb_GRTH_TARI4)
begin -- process OUTPUT_DEC
CntEn_i <= '0';
TRCalEn_i <= '0';
RTCalEn_i <= '0';
TARI4En_i <= '0';
CntClr_i <= '0';
sserror_i <= '0';
ssovalid_i <= '0';
sso_i <= '0';
 
case StRec is
when st0_Start =>
CntClr_i <= '1';
when st0b_Delimitier =>
if tdi = '0' then
CntEn_i <= '1';
else
CntClr_i <= '1';
end if;
when st1_Dat0H =>
CntEn_i <= '1';
when st2_Dat0L =>
if tdi = '0' then
CntEn_i <= '1';
else
CntClr_i <= '1';
TARI4En_i <= '1';
end if;
when st3_RTcalH =>
if tdi = '1' then
CntEn_i <= '1';
else
-- Load RTCal value
CntClr_i <= '1';
RTCalEn_i <= '1';
end if;
when st4_RTcalL =>
if tdi = '1' then
CntEn_i <= '1';
end if;
when st5_Sym0H =>
if tdi = '1' then
CntEn_i <= '1';
else
CntClr_i <= '1';
if RTCal_GRTH_TRCal = '1' then
-- Send valid Symbol
ssovalid_i <= '1';
if Symb_GRTH_RTCaldiv2 = '1' then
sso_i <= '1';
else
sso_i <= '0';
end if;
else
-- Load TRCal value (Preamble detected ("Query" comm.))
TRCalEn_i <= '1';
end if;
end if;
when st6_Sym0L =>
if tdi = '1' then
CntEn_i <= '1';
end if;
when st6b_Sym0L_TR =>
if tdi = '1' then
CntEn_i <= '1';
end if;
when st7_SymH =>
if Symb_GRTH_TARI4 = '1' then
sserror_i <= '1';
elsif tdi = '1' then
CntEn_i <= '1';
else
-- Send valid Symbol
-- CntClr_i <= '1';
ssovalid_i <= '1';
if Symb_GRTH_RTCaldiv2 = '1' then
sso_i <= '1';
else
sso_i <= '0';
end if;
end if;
when st8_SymL =>
if Symb_GRTH_TARI4 = '1' then
sserror_i <= '1';
elsif tdi = '1' then
CntClr_i <= '1';
end if;
when st9_SymH_TR =>
if tdi = '1' then
CntEn_i <= '1';
else
-- Send valid Symbol
CntClr_i <= '1';
ssovalid_i <= '1';
if Symb_GRTH_RTCaldiv2 = '1' then
sso_i <= '1';
else
sso_i <= '0';
end if;
end if;
when st10_SymL_TR =>
if tdi = '1' then
CntEn_i <= '1';
end if;
when others => null;
end case;
end process OUTPUT_DEC;
 
 
GRTH1 : process (RTCalReg, CntReg)
begin -- process EQUAL
if RTCalReg > CntReg then
RTCal_GRTH_TRCal <= '1';
else
RTCal_GRTH_TRCal <= '0';
end if;
end process GRTH1;
 
GRTH2 : process (CntReg, RTCaldiv2Reg)
begin -- process EQUAL
if CntReg > RTCaldiv2Reg then
Symb_GRTH_RTCaldiv2 <= '1';
else
Symb_GRTH_RTCaldiv2 <= '0';
end if;
end process GRTH2;
 
GRTH3 : process (CntReg, TARI4Reg)
begin -- process EQUAL
if CntReg > TARI4Reg then
Symb_GRTH_TARI4 <= '1';
else
Symb_GRTH_TARI4 <= '0';
end if;
end process GRTH3;
 
DELIMITIER_COMPARISON : process (CntReg)
begin -- process DELIMITIER_COMPARISON
if conv_integer(CntReg) > DELIMITIER_TIME_CK_CYC_MIN or conv_integer(CntReg) = DELIMITIER_TIME_CK_CYC_MIN then
if conv_integer(CntReg) < DELIMITIER_TIME_CK_CYC_MAX or conv_integer(CntReg) = DELIMITIER_TIME_CK_CYC_MAX then
DelimitierComparisoOK <= '1';
else
DelimitierComparisoOK <= '0';
end if;
else
DelimitierComparisoOK <= '0';
end if;
end process DELIMITIER_COMPARISON;
 
RTCALR : process (clk, rst_n)
begin -- process RTCALREG
if rst_n = '0' then -- asynchronous reset (active low)
RTCalReg <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
if RTCalEn = '1' then
RTCalReg <= CntReg;
end if;
end if;
end process RTCALR;
 
TRCALR : process (clk, rst_n)
begin -- process RTCALREG
if rst_n = '0' then -- asynchronous reset (active low)
TRCalReg <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
if TRCalEn = '1' then
TRCalReg <= CntReg;
end if;
end if;
end process TRCALR;
 
TARI4R : process (clk, rst_n)
begin -- process TARI4R
if rst_n = '0' then -- asynchronous reset (active low)
TARI4Reg <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
if TARI4En = '1' then
TARI4Reg <= CntReg(LOG2_10_TARI_CK_CYC-3 downto 0) & "00"; --Multiplied by 4
end if;
end if;
end process TARI4R;
 
COUNTERCLR_1 : COUNTERCLR
generic map (
width => LOG2_10_TARI_CK_CYC)
port map (
clk => clk,
rst_n => rst_n,
en => CntEn,
clear => CntClr,
outcnt => CntReg);
 
end symbdec1;
/trunk/flashmemRSV.vhd
0,0 → 1,226
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : Flash Memory RSV
--
-- File name : flashmemRSV.vhd
--
-- Description : Flash memory model.
--
-- Author : Paolo Bernardi <paolo.bernardi@polito.it>
--
-- Rev. History : Erwing Sanchez -- 17/07/06
-- - Ready/busy input removed because not used
-- - "Bits" generic removed
-- - RP input removed
-- - Command codes changed to work with Data = 16
-- E.R. Sanchez -- 13/10/06
-- - Include Parameters & Initialization
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.std_logic_textio.all;
use STD.TEXTIO.all;
 
 
entity Flash_MeM_RSV is
generic (
Words : integer := 8; -- number of addresses
Addr : integer := 2; -- number of pins reserved for addresses
Data : integer := 16
);
port (
A : in std_logic_vector(Addr-1 downto 0); -- Address inputs
D : in std_logic_vector(Data-1 downto 0); -- Data input
Q : out std_logic_vector(Data-1 downto 0); -- Data output
G : in std_logic; -- Output enable
W : in std_logic; -- Write enable
RC : in std_logic; -- Row/Column address select
st : out std_logic -- Interface reset
);
 
end Flash_MeM_RSV;
 
 
architecture Behavioural of Flash_MeM_RSV is
--synopsys synthesis_off
 
type Flash_Type is array (0 to Words-1) of std_logic_vector(Data-1 downto 0);
signal Mem : Flash_Type := ("0100000000000000",
"0000000000011000",
"0000000000000000",
"0000000000000000",
"0000000000000000",
"0000000000000000",
"0000000000000000",
"0000000000000000");
 
 
signal Addr_int : std_logic_vector((2*Addr)-1 downto 0);
signal Data_int : std_logic_vector(Data-1 downto 0);
 
signal program : std_logic := '0';
signal erase : std_logic := '0';
signal i : natural range Words-1 downto 0;
signal status_register : std_logic_vector(Data-1 downto 0);
signal status : std_logic;
signal InitIsDoneFlag : std_logic := '0';
 
function resetVector (dim : natural) return std_logic_vector is
 
variable vectorOut : std_logic_vector(dim -1 downto 0);
variable i : natural range dim downto 0;
 
begin
for i in 0 to dim-1 loop
vectorOut(i) := '0';
end loop;
return vectorOut;
end resetVector;
 
function erase_mem (mem : Flash_Type) return Flash_Type is
 
variable mem_out : Flash_Type;
variable i : natural range Words-1 downto 0;
 
begin
for i in 0 to Words-1 loop
Mem_out(i) := (others => '1'); --"11111111";
end loop;
return mem_out;
 
end erase_mem;
--synopsys synthesis_on
begin --BEHAVIOURAL
--synopsys synthesis_off
write_first : process (RC)
begin
if RC'event and RC = '0' then
Addr_int(Addr-1 downto 0) <= A;
end if;
end process write_first;
 
write_second : process (RC)
begin
if RC'event and RC = '1' then
Addr_int((2*Addr)-1 downto Addr) <= A;
end if;
end process write_second;
 
w_data : process (W)
begin
if W'event and W = '1' then
if program = '1' then
Mem(conv_integer(unsigned(Addr_int))) <= D after 50 ns;
status_register <= conv_std_logic_vector(64, Data); --"01000000"
Data_int <= resetVector(Data_int'length);
st <= '0';
elsif erase = '1' then
Mem <= erase_mem(Mem) after 750000000 ns;
Data_int <= resetVector(Data_int'length);
st <= '1' after 750000000 ns;
else
Data_int <= D;
status_register <= (others => '0'); --"00000000";
st <= '0';
end if;
end if;
end process w_data;
 
read_data : process (G)
begin
if G'event and G = '0' then
if status = '0' then
Q <= Mem(conv_integer(unsigned(Addr_int))) after 50 ns;
else
Q <= status_register after 750000000 ns;
end if;
elsif G'event and G = '1' then
Q <= (others => 'U') after 50 ns; -- "UUUUUUUU"
end if;
end process read_data;
 
decode : process (Data_int)
begin
case conv_integer(Data_int) is
when 64 => -- "01000000" program
program <= '1';
erase <= '0';
status <= '0';
when 32 => -- "00100000" erase
program <= '0';
erase <= '1';
status <= '0';
when 112 => -- "01110000" read status reg
program <= '0';
erase <= '0';
status <= '1';
when others =>
program <= '0';
erase <= '0';
status <= '0';
end case;
end process decode;
 
 
-- -- purpose: Load Memory from file
-- load_memory : process(A, D, G, W, RC, InitIsDoneFlag)
-- file init_mem_file : text open read_mode is "meminit.txt";
-- variable inline, outline : line;
-- variable add : natural;
-- variable c : character;
-- variable Mem_var : Flash_Type;
-- begin -- process load_memory
-- if InitIsDoneFlag = '0' then
-- -- Clear Memory
-- for i in 0 to Words-1 loop
-- Mem_var(i) := (others => '0');
-- end loop; -- i
-- -- Load
-- while not endfile(init_mem_file) loop
-- readline(init_mem_file, inline);
-- read(inline, add);
-- read(inline, c);
-- if c /= ':' then
-- write(outline, string'("Syntax Error"));
-- writeline(output, outline);
-- assert false report "Mem Loader Aborted" severity failure;
-- end if;
-- for i in (Data-1) downto 0 loop
-- read(inline, c);
-- if c = '1' then
-- Mem_var(add)(i) := '1';
-- elsif c = '0' then
-- Mem_var(add)(i) := '0';
-- else
-- write(outline, string'("Invalid Character-Set to '0'"));
-- writeline(output, outline);
-- Mem_var(add)(i) := '0';
-- end if;
-- end loop; -- i
-- end loop;
-- Mem <= Mem_var;
-- InitIsDoneFlag <= '1';
-- end if;
-- end process load_memory;
 
--synopsys synthesis_on
end Behavioural;
 
--synopsys synthesis_off
 
configuration CFG_Flash_MeM_RSV of Flash_MeM_RSV is
for Behavioural
end for;
end CFG_Flash_MeM_RSV;
 
--synopsys synthesis_on
/trunk/cmmdec.vhd
0,0 → 1,1787
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag - Command decoder
--
-- File name : commdec.vhd
--
-- Description : Tag Command decoder
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 26 June 06 - First Draft
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.all;
library work;
use work.epc_tag.all;
 
 
entity CommandDecoder is
 
generic (
LOG2_10_TARI_CK_CYC : integer := 9; -- Log2(clock cycles for 10 maximum TARI value) (def:Log2(490) = 9 @TCk=520ns)
DELIMITIER_TIME_CK_CYC_MIN : integer := 22; -- Min Clock cycles for 12,5 us delimitier
DELIMITIER_TIME_CK_CYC_MAX : integer := 24); -- Max Clock cycles for 12,5 us delimitier
port (
clk : in std_logic;
rst_n : in std_logic;
tdi : in std_logic;
en : in std_logic;
CommDone : out CommandInternalCode_t;
Data_r : out std_logic_vector(31 downto 0);
CRC_r : out std_logic_vector(15 downto 0);
Pointer_r : out std_logic_vector(15 downto 0);
RN16_r : out std_logic_vector(15 downto 0);
Length_r : out std_logic_vector(7 downto 0);
Mask_r : out std_logic_vector(MASKLENGTH-1 downto 0)
);
 
end CommandDecoder;
 
architecture CommandDec1 of CommandDecoder is
 
 
component SymbolDecoder
generic (
LOG2_10_TARI_CK_CYC : integer;
DELIMITIER_TIME_CK_CYC_MIN : integer;
DELIMITIER_TIME_CK_CYC_MAX : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
tdi : in std_logic;
en : in std_logic;
start : in std_logic;
sserror : out std_logic;
ssovalid : out std_logic;
sso : out std_logic);
end component;
 
 
component crc5encdec
generic (
PRESET_CRC5 : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
init : in std_logic;
ce : in std_logic;
sdi : in std_logic;
cout : out std_logic_vector(4 downto 0));
end component;
 
 
component crc16encdec
generic (
PRESET_CRC16 : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
init : in std_logic;
ce : in std_logic;
sdi : in std_logic;
cout : out std_logic_vector(15 downto 0));
end component;
 
 
component COUNTERCLR
generic (
width : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
en : in std_logic;
clear : in std_logic;
outcnt : out std_logic_vector(width-1 downto 0));
end component;
 
component shiftreg
generic (
REGWD : integer);
port (
clk : in std_logic;
rst_n : in std_logic;
ce : in std_logic;
sin : in std_logic;
pout : out std_logic_vector(REGWD - 1 downto 0));
end component;
 
 
type CmDecFSM_t is (st_Init, st_Start, st_Cm2_0, st_QueryRep, st_Ack,
st_Cm4or8_1, st_Cm4_10, st_Cm4_100,
st_Query, st_QueryAdjust, st_Cm4_101, st_Select,
st_Cm8_11, st_Cm8_110, st_Cm8_1100, st_Cm8_11000,
st_Cm8_110000, st_Cm8_1100000, st_Nak, st_ReqRN,
st_Cm8_1100001, st_Read, st_Write, st_Cm8_110001,
st_Cm8_1100010, st_Kill, st_Lock, st_Cm8_1100011,
st_Access, st_BlockWrite, st_Cm8_11001, st_Cm8_110010,
st_Cm8_1100100, st_BlockErase, st_ErrorDec, st_CommandReady,
st_QueryRep_w, st_Ack_w, st_Query_w, st_QueryAdjust_w, st_Select_w,
st_Nak_w, st_ReqRN_w, st_Read_w, st_Write_w, st_Kill_w, st_Lock_w,
st_Access_w, st_BlockWrite_w, st_BlockErase_w);
 
type CmDataRecFSM_t is (st_WaitCmd, st_QueryRep_GetData, st_QueryRep_Done,
st_Ack_GetRN, st_Ack_Done,
st_Nak_Done,
st_Query_GetData, st_Query_GetCRC5, st_Query_Done,
st_QueryAdjust_GetData, st_QueryAdjust_Done,
st_Select_GetData1, st_Select_GetPointer, st_Select_GetPointer_LastByte,
st_Select_GetPointer_NotLastByte, st_Select_GetLength,
st_Select_GetMask, st_Select_GetData2, st_Select_GetCRC16, st_Select_Done,
st_ReqRN_GetRN, st_ReqRN_GetCRC16, st_ReqRN_Done,
st_Read_GetData1, st_Read_GetWordPtr, st_Read_GetLength,
st_Read_GetRN, st_Read_GetCRC16, st_Read_Done,
st_Read_GetWordPtr_LastByte, st_Read_GetWordPtr_NotLastByte,
st_Write_GetData1, st_Write_GetWordPtr, st_Write_GetData2,
st_Write_GetRN, st_Write_GetCRC16, st_Write_Done,
st_Write_GetWordPtr_LastByte, st_Write_GetWordPtr_NotLastByte,
st_Kill_GetData, st_Kill_GetRN, st_Kill_GetCRC16, st_Kill_Done,
st_Lock_GetData, st_Lock_GetRN, st_Lock_GetCRC16, st_Lock_Done,
st_Access_GetData, st_Access_GetRN, st_Access_GetCRC16, st_Access_Done,
st_BlockWrite_GetData, st_BlockWrite_GetWordPtr,
st_BlockWrite_GetWordCnt, st_BlockWrite_GetWriteData,
st_BlockWrite_GetRN, st_BlockWrite_GetCRC16, st_BlockWrite_Done,
st_BlockErase_GetData1, st_BlockErase_GetWordPtr, st_BlockErase_GetData2,
st_BlockErase_GetRN, st_BlockErase_GetCRC16, st_BlockErase_Done);
 
 
-- Constants
constant PRESET_CRC5 : integer := 9;
constant PRESET_CRC16 : integer := 65535;
-- Decoder States Signals
signal StDec, NextStDec : CmDecFSM_t;
signal StartSDec_i, StartSDec : std_logic;
-- Data Receiver State Signals
signal StDat, NextStDat : CmDataRecFSM_t;
-- Command Start and Done
signal CommandDone, CommandDone_i : CommandInternalCode_t;
signal CommandStart, CommandStart_i : CommandInternalCode_t;
-- Counter signals
signal DataCnt, RNCnt, CRCCnt : std_logic_vector(7 downto 0);
signal PointerCnt : std_logic_vector(7 downto 0);
signal DataCnt_Inc, DataCnt_Inc_i, RNCnt_Inc : std_logic;
signal RNCnt_Inc_i, PointerCnt_Inc, PointerCnt_Inc_i : std_logic;
signal CRCCnt_Inc, CRCCnt_Inc_i, DataCnt_Clear : std_logic;
signal DataCnt_Clear_i, RNCnt_Clear, RNCnt_Clear_i : std_logic;
signal PointerCnt_Clear, PointerCnt_Clear_i : std_logic;
signal CRCCnt_Clear, CRCCnt_Clear_i : std_logic;
-- Flags
signal LastPntByteFlag, LastPntByteFlag_i : std_logic;
signal FirstPntBitTaken, FirstPntBitTaken_i : std_logic;
signal CommandDoneFlag, CommandDoneFlag_i : std_logic;
-- Register enables
signal DatRegEnable, RNRegEnable, CRCRegEnable : std_logic;
signal DatRegEnable_i, RNRegEnable_i, CRCRegEnable_i : std_logic;
signal PointerRegEnable, PointerRegEnable_i : std_logic;
signal LengthWCntRegEnable, LengthWCntRegEnable_i : std_logic;
signal MaskRegEnable_i, MaskRegEnable : std_logic;
-- Registers
signal RN16_o, CRC16_o : std_logic_vector(15 downto 0);
signal RN16_ce, CRC16_ce, GPReg_ce : std_logic;
signal GPReg_o : std_logic_vector(31 downto 0);
signal Pointer_o : std_logic_vector(15 downto 0);
signal Pointer_ce : std_logic;
signal Pointer_rst, Pointer_rst_i, Pointer_NOTrst : std_logic;
signal LengthWCnt_o : std_logic_vector(7 downto 0);
signal LengthWCnt_ce : std_logic;
signal MaskReg_o : std_logic_vector(MASKLENGTH-1 downto 0);
signal MaskReg_ce : std_logic;
-- CRC regs & control
signal CRC5Dec : std_logic_vector(4 downto 0);
signal CRC16Dec : std_logic_vector(15 downto 0);
signal CRC5Init, CRC16Init, CRC5Init_i, CRC16Init_i : std_logic;
signal CRC5ce, CRC16ce : std_logic;
-- Symbol Decoder signals
signal sso, ssovalid, sserror : std_logic;
begin -- CommandDec1
 
 
-------------------------------------------------------------------------------
-- COMMAND DECODER PROCESSES
-------------------------------------------------------------------------------
SYNCRO_DEC : process (clk, rst_n)
begin -- process SYNCRO
if rst_n = '0' then -- asynchronous reset (active low)
StartSDec <= '0';
-- Command start signal
CommandStart <= cmd_NULL;
-- CRC signals
CRC5Init <= '0';
CRC16Init <= '0';
-- State signal
StDec <= st_Init;
elsif clk'event and clk = '1' then -- rising clock edge
StartSDec <= StartSDec_i;
-- Command start signal
CommandStart <= CommandStart_i;
-- CRC signals
CRC5Init <= CRC5Init_i;
CRC16Init <= CRC16Init_i;
-- State signal
StDec <= NextStDec;
end if;
end process SYNCRO_DEC;
 
NEXT_ST_DEC : process (StDec, sso, ssovalid, CommandDoneFlag, sserror)
begin -- process NEXT_ST
NextStDec <= StDec;
 
case StDec is
when st_Init =>
NextStDec <= st_Start;
when st_Start =>
if ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Cm2_0;
else
NextStDec <= st_Cm4or8_1;
end if;
end if;
 
-- two-bit commands
when st_Cm2_0 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_QueryRep; -- 00
else
NextStDec <= st_Ack; -- 01
end if;
end if;
when st_Cm4or8_1 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Cm4_10;
else
NextStDec <= st_Cm8_11;
end if;
end if;
 
-- four-bit commands
when st_Cm4_10 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0'then
NextStDec <= st_Cm4_100;
else
NextStDec <= st_Cm4_101;
end if;
end if;
when st_Cm4_100 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Query; -- 1000
else
NextStDec <= st_QueryAdjust; -- 1001
end if;
end if;
when st_Cm4_101 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Select; -- 1010
else
NextStDec <= st_ErrorDec;
end if;
end if;
 
-- eight-bit commands
when st_Cm8_11 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Cm8_110;
else
NextStDec <= st_ErrorDec;
end if;
end if;
when st_Cm8_110 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Cm8_1100;
else
NextStDec <= st_ErrorDec;
end if;
end if;
when st_cm8_1100 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Cm8_11000;
else
NextStDec <= st_Cm8_11001;
end if;
end if;
when st_Cm8_11000 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Cm8_110000;
else
NextStDec <= st_Cm8_110001;
end if;
end if;
when st_Cm8_110000 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Cm8_1100000;
else
NextStDec <= st_Cm8_1100001;
end if;
end if;
when st_Cm8_1100000 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Nak; -- 11000000
else
NextStDec <= st_ReqRN; -- 11000001
end if;
end if;
when st_Cm8_1100001 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Read; -- 11000010
else
NextStDec <= st_Write; -- 11000011
end if;
end if;
when st_Cm8_110001 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Cm8_1100010;
else
NextStDec <= st_Cm8_1100011;
end if;
end if;
when st_Cm8_1100010 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Kill; -- 11000100
else
NextStDec <= st_Lock; -- 11000101
end if;
end if;
when st_Cm8_1100011 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Access; -- 11000110
else
NextStDec <= st_BlockWrite; -- 11000111
end if;
end if;
when st_Cm8_11001 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Cm8_110010;
else
NextStDec <= st_ErrorDec;
end if;
end if;
when st_Cm8_110010 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_Cm8_1100100;
else
NextStDec <= st_ErrorDec;
end if;
end if;
when st_Cm8_1100100 =>
if sserror = '1' then
NextStDec <= st_Init;
elsif ssovalid = '1' then
if sso = '0' then
NextStDec <= st_BlockErase; -- 11001000
else
NextStDec <= st_ErrorDec;
end if;
end if;
 
-- Command Start states
when st_QueryRep =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_QueryRep_w;
end if;
when st_Ack =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_Ack_w;
end if;
when st_Query =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_Query_w;
end if;
when st_QueryAdjust =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_QueryAdjust_w;
end if;
when st_Select =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_Select_w;
end if;
when st_Nak =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_Nak_w;
end if;
when st_ReqRN =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_ReqRN_w;
end if;
when st_Read =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_Read_w;
end if;
when st_Write =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_Write_w;
end if;
when st_Kill =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_Kill_w;
end if;
when st_Lock =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_Lock_w;
end if;
when st_Access =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_Access_w;
end if;
when st_BlockWrite =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_BlockWrite_w;
end if;
when st_BlockErase =>
if sserror = '1' then
NextStDec <= st_Init;
else
NextStDec <= st_BlockErase_w;
end if;
 
-- Command done-waiting states
when st_QueryRep_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_Ack_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_Query_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_QueryAdjust_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_Select_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_Nak_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_ReqRN_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_Read_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_Write_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_Kill_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_Lock_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_Access_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_BlockWrite_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when st_BlockErase_w =>
if sserror = '1' then
NextStDec <= st_Init;
elsif CommandDoneFlag = '1' then
NextStDec <= st_CommandReady;
end if;
when others =>
NextStDec <= st_Init;
end case;
end process NEXT_ST_DEC;
 
 
OUTPUTDEC_DEC : process (StDec)
begin -- process OUTPUT_DEC
StartSDec_i <= '0';
CommandStart_i <= cmd_NULL;
CRC5Init_i <= '0';
CRC16Init_i <= '0';
 
case StDec is
when st_Init =>
CRC5Init_i <= '1';
CRC16Init_i <= '1';
StartSDec_i <= '1';
when st_Start =>
StartSDec_i <= '1';
when st_QueryRep =>
CommandStart_i <= cmd_QueryRep;
when st_Ack =>
CommandStart_i <= cmd_Ack;
when st_Query =>
CommandStart_i <= cmd_Query;
when st_QueryAdjust =>
CommandStart_i <= cmd_QueryAdjust;
when st_Select =>
CommandStart_i <= cmd_Select;
when st_Nak =>
CommandStart_i <= cmd_Nak;
when st_ReqRN =>
CommandStart_i <= cmd_ReqRN;
when st_Read =>
CommandStart_i <= cmd_Read;
when st_Write =>
CommandStart_i <= cmd_Write;
when st_Kill =>
CommandStart_i <= cmd_Kill;
when st_Lock =>
CommandStart_i <= cmd_Lock;
when st_Access =>
CommandStart_i <= cmd_Access;
when st_BlockWrite =>
CommandStart_i <= cmd_BlockWrite;
when st_BlockErase =>
CommandStart_i <= cmd_BlockErase;
when others => null;
end case;
end process OUTPUTDEC_DEC;
 
 
-------------------------------------------------------------------------------
-- DATA RECEIVER PROCESSES
-------------------------------------------------------------------------------
 
SYNCRO_DAT : process (clk, rst_n)
begin -- process SYNCRO
if rst_n = '0' then -- asynchronous reset (active low)
-- Command Done signal
CommandDone <= cmd_NULL;
-- Counters
DataCnt_Inc <= '0';
DataCnt_Clear <= '0';
RNCnt_Inc <= '0';
RNCnt_Clear <= '0';
CRCCnt_Inc <= '0';
CRCCnt_Clear <= '0';
PointerCnt_Inc <= '0';
PointerCnt_Clear <= '0';
-- Reg CE
DatRegEnable <= '0';
RNRegEnable <= '0';
CRCRegEnable <= '0';
PointerRegEnable <= '0';
LengthWCntRegEnable <= '0';
MaskRegEnable <= '0';
Pointer_rst <= '0';
-- Flags
LastPntByteFlag <= '0';
FirstPntBitTaken <= '0';
CommandDoneFlag <= '0';
-- State signal
StDat <= st_WaitCmd;
elsif clk'event and clk = '1' then -- rising clock edge;
-- Command Done signal
CommandDone <= CommandDone_i;
-- Counters
DataCnt_Inc <= DataCnt_Inc_i;
DataCnt_Clear <= DataCnt_Clear_i;
RNCnt_Inc <= RNCnt_Inc_i;
RNCnt_Clear <= RNCnt_Clear_i;
CRCCnt_Inc <= CRCCnt_Inc_i;
CRCCnt_Clear <= CRCCnt_Clear_i;
PointerCnt_Inc <= PointerCnt_Inc_i;
PointerCnt_Clear <= PointerCnt_Clear_i;
-- Reg CE
DatRegEnable <= DatRegEnable_i;
RNRegEnable <= RNRegEnable_i;
CRCRegEnable <= CRCRegEnable_i;
PointerRegEnable <= PointerRegEnable_i;
LengthWCntRegEnable <= LengthWCntRegEnable_i;
MaskRegEnable <= MaskRegEnable_i;
Pointer_rst <= Pointer_rst_i;
-- Flags
LastPntByteFlag <= LastPntByteFlag_i;
FirstPntBitTaken <= FirstPntBitTaken_i;
CommandDoneFlag <= CommandDoneFlag_i;
-- State signal
StDat <= NextStDat;
end if;
end process SYNCRO_DAT;
 
 
NEXT_ST_DAT : process (StDat, CommandStart, sserror, DataCnt, RNCnt, CRCCnt, FirstPntBitTaken, LastPntByteFlag, PointerCnt, LengthWCnt_o)
begin -- process NEXT_ST_DAT
NextStDat <= StDat;
 
case StDat is
when st_WaitCmd =>
case CommandStart is
when cmd_Select =>
NextStDat <= st_Select_GetData1;
when cmd_Query =>
NextStDat <= st_Query_GetData;
when cmd_QueryAdjust =>
NextStDat <= st_QueryAdjust_GetData;
when cmd_QueryRep =>
NextStDat <= st_QueryRep_GetData;
when cmd_Ack =>
NextStDat <= st_Ack_GetRN;
when cmd_Nak =>
NextStDat <= st_Nak_Done;
when cmd_ReqRN =>
NextStDat <= st_ReqRN_GetRN;
when cmd_Read =>
NextStDat <= st_Read_GetData1;
when cmd_Write =>
NextStDat <= st_Write_GetData1;
when cmd_Kill =>
NextStDat <= st_Kill_GetData;
when cmd_Lock =>
NextStDat <= st_Lock_GetData;
when cmd_Access =>
NextStDat <= st_Access_GetData;
when cmd_BlockWrite =>
NextStDat <= st_BlockWrite_GetData;
when cmd_BlockErase =>
NextStDat <= st_BlockErase_GetData1;
when others => null;
end case;
 
-- Select
when st_Select_GetData1 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(8, 8) then -- Target(3)-Action(3)-Membank(2)
NextStDat <= st_Select_GetPointer;
end if;
when st_Select_GetPointer =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif FirstPntBitTaken = '1' then
if LastPntByteFlag = '1' then
NextStDat <= st_Select_GetPointer_LastByte;
else
NextStDat <= st_Select_GetPointer_NotLastByte;
end if;
end if;
when st_Select_GetPointer_NotLastByte =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif PointerCnt = conv_std_logic_vector(7, 8) then
NextStDat <= st_Select_GetPointer;
end if;
when st_Select_GetPointer_LastByte =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif PointerCnt = conv_std_logic_vector(7, 8) then
NextStDat <= st_Select_GetLength;
end if;
when st_Select_GetLength =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif RNCnt = conv_std_logic_vector(8, 8) then
NextStDat <= st_Select_GetMask;
end if;
when st_Select_GetMask =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif PointerCnt = LengthWCnt_o then
NextStDat <= st_Select_GetData2;
end if;
when st_Select_GetData2 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(1, 8) then -- Truncate(1)
NextStDat <= st_Select_GetCRC16;
end if;
when st_Select_GetCRC16 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif CRCCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Select_Done;
end if;
when st_Select_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- Query
when st_Query_GetData =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(13, 8) then -- DR(1)-M(2)-TRext(1)-Sel(2)-Session(2)-Target(1)-Q(4)
NextStDat <= st_Query_GetCRC5;
end if;
when st_Query_GetCRC5 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif CRCCnt = conv_std_logic_vector(5, 8) then
NextStDat <= st_Query_Done;
end if;
when st_Query_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- QueryAdjust
when st_QueryAdjust_GetData =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(5, 8) then -- Session(2)-UpDn(3)
NextStDat <= st_QueryAdjust_Done;
end if;
when st_QueryAdjust_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- QueryRep
when st_QueryRep_GetData =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(2, 8) then --Session(2)
NextStDat <= st_QueryRep_Done;
end if;
when st_QueryRep_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- Ack
when st_Ack_GetRN =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif RNCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Ack_Done;
end if;
when st_Ack_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- Nak
when st_Nak_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- ReqRN
when st_ReqRN_GetRN =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif RNCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_ReqRN_GetCRC16;
end if;
when st_ReqRN_GetCRC16 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif CRCCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_ReqRN_Done;
end if;
when st_ReqRN_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- Read
when st_Read_GetData1 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(2, 8) then -- Membank(2)
NextStDat <= st_Read_GetWordPtr;
end if;
when st_Read_GetWordPtr =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif FirstPntBitTaken = '1' then
if LastPntByteFlag = '1' then
NextStDat <= st_Read_GetWordPtr_LastByte;
else
NextStDat <= st_Read_GetWordPtr_NotLastByte;
end if;
end if;
when st_Read_GetWordPtr_LastByte =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif PointerCnt = conv_std_logic_vector(7, 8) then
NextStDat <= st_Read_GetLength;
end if;
when st_Read_GetWordPtr_NotLastByte =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif PointerCnt = conv_std_logic_vector(7, 8) then
NextStDat <= st_Read_GetWordPtr;
end if;
when st_Read_GetLength =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(8, 8) then -- WordCount(8)
NextStDat <= st_Read_GetRN;
end if;
when st_Read_GetRN =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif RNCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Read_GetCRC16;
end if;
when st_Read_GetCRC16 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif CRCCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Read_Done;
end if;
when st_Read_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- Write
when st_Write_GetData1 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(2, 8) then -- Membank(2)
NextStDat <= st_Write_GetWordPtr;
end if;
when st_Write_GetWordPtr =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif FirstPntBitTaken = '1' then
if LastPntByteFlag = '1' then
NextStDat <= st_Write_GetWordPtr_LastByte;
else
NextStDat <= st_Write_GetWordPtr_NotLastByte;
end if;
end if;
when st_Write_GetWordPtr_LastByte =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif PointerCnt = conv_std_logic_vector(7, 8) then
NextStDat <= st_Write_GetData2;
end if;
when st_Write_GetWordPtr_NotLastByte =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif PointerCnt = conv_std_logic_vector(7, 8) then
NextStDat <= st_Write_GetWordPtr;
end if;
when st_Write_GetData2 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(16, 8) then --Data(16)
NextStDat <= st_Write_GetRN;
end if;
when st_Write_GetRN =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif RNCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Write_GetCRC16;
end if;
when st_Write_GetCRC16 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif CRCCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Write_Done;
end if;
when st_Write_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- Kill
when st_Kill_GetData =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(19, 8) then -- Data(16)-RFU(3)
NextStDat <= st_Kill_GetRN;
end if;
when st_Kill_GetRN =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif RNCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Kill_GetCRC16;
end if;
when st_Kill_GetCRC16 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif CRCCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Kill_Done;
end if;
when st_Kill_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- Lock
when st_Lock_GetData =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(20, 8) then -- Payload(20)
NextStDat <= st_Lock_GetRN;
end if;
when st_Lock_GetRN =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif RNCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Lock_GetCRC16;
end if;
when st_Lock_GetCRC16 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif CRCCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Lock_Done;
end if;
when st_Lock_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- Access
when st_Access_GetData =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Access_GetRN;
end if;
when st_Access_GetRN =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif RNCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Access_GetCRC16;
end if;
when st_Access_GetCRC16 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif CRCCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_Access_Done;
end if;
when st_Access_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- BlockWrite
when st_BlockWrite_GetData =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(2, 8) then --Membank(2)
NextStDat <= st_BlockWrite_GetWordPtr;
end if;
when st_BlockWrite_GetWordPtr =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_BlockWrite_GetWordCnt;
end if;
when st_BlockWrite_GetWordCnt =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_BlockWrite_GetWriteData;
end if;
when st_BlockWrite_GetWriteData =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_BlockWrite_GetRN;
end if;
when st_BlockWrite_GetRN =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif RNCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_BlockWrite_GetCRC16;
end if;
when st_BlockWrite_GetCRC16 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif CRCCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_BlockWrite_Done;
end if;
when st_BlockWrite_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
-- BlockErase
when st_BlockErase_GetData1 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(2, 8) then --Membank(2)
NextStDat <= st_BlockErase_GetWordPtr;
end if;
when st_BlockErase_GetWordPtr =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_BlockErase_GetData2;
end if;
when st_BlockErase_GetData2 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif DataCnt = conv_std_logic_vector(8, 8) then
NextStDat <= st_BlockErase_GetRN;
end if;
when st_BlockErase_GetRN =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif RNCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_BlockErase_GetCRC16;
end if;
when st_BlockErase_GetCRC16 =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
elsif CRCCnt = conv_std_logic_vector(16, 8) then
NextStDat <= st_BlockErase_Done;
end if;
when st_BlockErase_Done =>
if sserror = '1' then
NextStDat <= st_WaitCmd;
else
NextStDat <= st_WaitCmd;
end if;
 
when others => null;
end case;
end process NEXT_ST_DAT;
 
OUPUTDEC_DAT : process (StDat, ssovalid, sso, CRC5Dec, CRC16Dec)
begin -- process OUPUTDEC_DAT
CommandDone_i <= cmd_NULL;
CommandDoneFlag_i <= '0';
-- Counters
DataCnt_Inc_i <= '0';
DataCnt_Clear_i <= '1';
RNCnt_Inc_i <= '0'; -- Used also as "Select.Length" counter
RNCnt_Clear_i <= '1';
CRCCnt_Inc_i <= '0';
CRCCnt_Clear_i <= '1';
PointerCnt_Inc_i <= '0'; -- Used also as "Select.Mask" counter
PointerCnt_Clear_i <= '1';
-- Reg CE
MaskRegEnable_i <= '0';
DatRegEnable_i <= '0';
PointerRegEnable_i <= '0';
LengthWCntRegEnable_i <= '0';
RNRegEnable_i <= '0';
CRCRegEnable_i <= '0';
-- Flags
LastPntByteFlag_i <= '0';
FirstPntBitTaken_i <= '0';
Pointer_rst_i <= '0';
 
case StDat is
 
-- Select
when st_Select_GetData1 =>
DatRegEnable_i <= '1';
Pointer_rst_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_Select_GetPointer =>
if ssovalid = '1' then
FirstPntbitTaken_i <= '1';
if sso = '0' then
LastPntByteFlag_i <= '1';
end if;
end if;
when st_Select_GetPointer_NotLastByte =>
PointerRegEnable_i <= '1';
PointerCnt_Clear_i <= '0';
if ssovalid = '1' then
PointerCnt_Inc_i <= '1';
end if;
when st_Select_GetPointer_LastByte =>
PointerRegEnable_i <= '1';
PointerCnt_Clear_i <= '0';
if ssovalid = '1' then
PointerCnt_Inc_i <= '1';
end if;
when st_Select_GetLength =>
LengthWCntRegEnable_i <= '1';
RNCnt_Clear_i <= '0';
if ssovalid = '1' then
RNCnt_Inc_i <= '1';
end if;
when st_Select_GetMask =>
MaskRegEnable_i <= '1';
PointerCnt_Clear_i <= '0';
if ssovalid = '1' then
PointerCnt_Inc_i <= '1';
end if;
when st_Select_GetData2 =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_Select_GetCRC16 =>
CRCRegEnable_i <= '1';
CRCCnt_Clear_i <= '0';
if ssovalid = '1' then
CRCCnt_Inc_i <= '1';
end if;
when st_Select_Done =>
CommandDoneFlag_i <= '1';
if CRC16Dec = X"0000" then
CommandDone_i <= cmd_Select;
end if;
 
-- Query
when st_Query_GetData =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_Query_GetCRC5 =>
CRCRegEnable_i <= '1';
CRCCnt_Clear_i <= '0';
if ssovalid = '1' then
CRCCnt_Inc_i <= '1';
end if;
when st_Query_Done =>
CommandDoneFlag_i <= '1';
if CRC5Dec = "00000" then
CommandDone_i <= cmd_Query;
end if;
 
-- QueryAdjust
when st_QueryAdjust_GetData =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_QueryAdjust_Done =>
CommandDoneFlag_i <= '1';
CommandDone_i <= cmd_QueryAdjust;
 
-- QueryRep
when st_QueryRep_GetData =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_QueryRep_Done =>
CommandDoneFlag_i <= '1';
CommandDone_i <= cmd_QueryRep;
 
-- Ack
when st_Ack_GetRN =>
RNRegEnable_i <= '1';
RNCnt_Clear_i <= '0';
if ssovalid = '1' then
RNCnt_Inc_i <= '1';
end if;
when st_Ack_Done =>
CommandDoneFlag_i <= '1';
CommandDone_i <= cmd_Ack;
 
-- Nak
when st_Nak_Done =>
CommandDoneFlag_i <= '1';
CommandDone_i <= cmd_Nak;
 
-- ReqRN
when st_ReqRN_GetRN =>
RNRegEnable_i <= '1';
RNCnt_Clear_i <= '0';
if ssovalid = '1' then
RNCnt_Inc_i <= '1';
end if;
when st_ReqRN_GetCRC16 =>
CRCRegEnable_i <= '1';
CRCCnt_Clear_i <= '0';
if ssovalid = '1' then
CRCCnt_Inc_i <= '1';
end if;
when st_ReqRN_Done =>
CommandDoneFlag_i <= '1';
if CRC16Dec = X"0000" then
CommandDone_i <= cmd_ReqRN;
end if;
 
-- Read
when st_Read_GetData1 =>
Pointer_rst_i <= '1';
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_Read_GetWordPtr =>
if ssovalid = '1' then
FirstPntbitTaken_i <= '1';
if sso = '0' then
LastPntByteFlag_i <= '1';
end if;
end if;
when st_Read_GetWordPtr_NotLastByte =>
PointerRegEnable_i <= '1';
PointerCnt_Clear_i <= '0';
if ssovalid = '1' then
PointerCnt_Inc_i <= '1';
end if;
when st_Read_GetWordPtr_LastByte =>
PointerRegEnable_i <= '1';
PointerCnt_Clear_i <= '0';
if ssovalid = '1' then
PointerCnt_Inc_i <= '1';
end if;
when st_Read_GetLength =>
--DatRegEnable_i <= '1';
LengthWCntRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_Read_GetRN =>
RNRegEnable_i <= '1';
RNCnt_Clear_i <= '0';
if ssovalid = '1' then
RNCnt_Inc_i <= '1';
end if;
when st_Read_GetCRC16 =>
CRCRegEnable_i <= '1';
CRCCnt_Clear_i <= '0';
if ssovalid = '1' then
CRCCnt_Inc_i <= '1';
end if;
when st_Read_Done =>
CommandDoneFlag_i <= '1';
if CRC16Dec = X"0000" then
CommandDone_i <= cmd_Read;
end if;
 
-- Write
when st_Write_GetData1 =>
DatRegEnable_i <= '1';
Pointer_rst_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_Write_GetWordPtr =>
if ssovalid = '1' then
FirstPntbitTaken_i <= '1';
if sso = '0' then
LastPntByteFlag_i <= '1';
end if;
end if;
when st_Write_GetWordPtr_NotLastByte =>
PointerRegEnable_i <= '1';
PointerCnt_Clear_i <= '0';
if ssovalid = '1' then
PointerCnt_Inc_i <= '1';
end if;
when st_Write_GetWordPtr_LastByte =>
PointerRegEnable_i <= '1';
PointerCnt_Clear_i <= '0';
if ssovalid = '1' then
PointerCnt_Inc_i <= '1';
end if;
when st_Write_GetData2 =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_Write_GetRN =>
RNRegEnable_i <= '1';
RNCnt_Clear_i <= '0';
if ssovalid = '1' then
RNCnt_Inc_i <= '1';
end if;
when st_Write_GetCRC16 =>
CRCRegEnable_i <= '1';
CRCCnt_Clear_i <= '0';
if ssovalid = '1' then
CRCCnt_Inc_i <= '1';
end if;
when st_Write_Done =>
CommandDoneFlag_i <= '1';
if CRC16Dec = X"0000" then
CommandDone_i <= cmd_Write;
end if;
 
-- Kill
when st_Kill_GetData =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_Kill_GetRN =>
RNRegEnable_i <= '1';
RNCnt_Clear_i <= '0';
if ssovalid = '1' then
RNCnt_Inc_i <= '1';
end if;
when st_Kill_GetCRC16 =>
CRCRegEnable_i <= '1';
CRCCnt_Clear_i <= '0';
if ssovalid = '1' then
CRCCnt_Inc_i <= '1';
end if;
when st_Kill_Done =>
CommandDoneFlag_i <= '1';
if CRC16Dec = X"0000" then
CommandDone_i <= cmd_Kill;
end if;
 
-- Lock
when st_Lock_GetData =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_Lock_GetRN =>
RNRegEnable_i <= '1';
RNCnt_Clear_i <= '0';
if ssovalid = '1' then
RNCnt_Inc_i <= '1';
end if;
when st_Lock_GetCRC16 =>
CRCRegEnable_i <= '1';
CRCCnt_Clear_i <= '0';
if ssovalid = '1' then
CRCCnt_Inc_i <= '1';
end if;
when st_Lock_Done =>
CommandDoneFlag_i <= '1';
if CRC16Dec = X"0000" then
CommandDone_i <= cmd_Lock;
end if;
 
-- Access (not fully implemented)
when st_Access_GetData =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_Access_GetRN =>
RNRegEnable_i <= '1';
RNCnt_Clear_i <= '0';
if ssovalid = '1' then
RNCnt_Inc_i <= '1';
end if;
when st_Access_GetCRC16 =>
CRCRegEnable_i <= '1';
CRCCnt_Clear_i <= '0';
if ssovalid = '1' then
CRCCnt_Inc_i <= '1';
end if;
when st_Access_Done =>
CommandDoneFlag_i <= '1';
CommandDone_i <= cmd_Access;
 
-- BlockWrite (not fully implemented)
when st_BlockWrite_GetData =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_BlockWrite_GetRN =>
RNRegEnable_i <= '1';
RNCnt_Clear_i <= '0';
if ssovalid = '1' then
RNCnt_Inc_i <= '1';
end if;
when st_BlockWrite_GetCRC16 =>
CRCRegEnable_i <= '1';
CRCCnt_Clear_i <= '0';
if ssovalid = '1' then
CRCCnt_Inc_i <= '1';
end if;
when st_BlockWrite_Done =>
CommandDoneFlag_i <= '1';
CommandDone_i <= cmd_BlockWrite;
 
-- BlockErase (not fully implemented)
when st_BlockErase_GetData1 =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_BlockErase_GetData2 =>
DatRegEnable_i <= '1';
DataCnt_Clear_i <= '0';
if ssovalid = '1' then
DataCnt_Inc_i <= '1';
end if;
when st_BlockErase_GetRN =>
RNRegEnable_i <= '1';
RNCnt_Clear_i <= '0';
if ssovalid = '1' then
RNCnt_Inc_i <= '1';
end if;
when st_BlockErase_GetCRC16 =>
CRCRegEnable_i <= '1';
CRCCnt_Clear_i <= '0';
if ssovalid = '1' then
CRCCnt_Inc_i <= '1';
end if;
when st_BlockErase_Done =>
CommandDoneFlag_i <= '1';
CommandDone_i <= cmd_BlockErase;
when others => null;
end case;
end process OUPUTDEC_DAT;
 
 
-------------------------------------------------------------------------------
-- Data Shift Registers
-------------------------------------------------------------------------------
 
-- 16 bit register:
-- RN 16
RN16_SHREG : shiftreg
generic map (
REGWD => 16)
port map (
clk => clk,
rst_n => rst_n,
ce => RN16_ce,
sin => sso,
pout => RN16_o);
 
RN16_ce <= ssovalid and RNRegEnable;
 
 
-- 16 bit register:
-- CRC 16
CRC16_SHREG : shiftreg
generic map (
REGWD => 16)
port map (
clk => clk,
rst_n => rst_n,
ce => CRC16_ce,
sin => sso,
pout => CRC16_o);
 
CRC16_ce <= ssovalid and CRCRegEnable;
 
 
-- 32 Register
-- General Purpose Register
GPREG_SHREG : shiftreg
generic map (
REGWD => 32)
port map (
clk => clk,
rst_n => rst_n,
ce => GPReg_ce,
sin => sso,
pout => GPReg_o);
 
GPReg_ce <= ssovalid and DatRegEnable;
 
 
-- 16 bit register:
-- Pointer register
POINTER_SHREG : shiftreg
generic map (
REGWD => 16)
port map (
clk => clk,
rst_n => Pointer_NOTrst,
ce => Pointer_ce,
sin => sso,
pout => Pointer_o);
 
Pointer_NOTrst <= not(Pointer_rst) and rst_n;
Pointer_ce <= ssovalid and PointerRegEnable;
 
 
-- 8 bit register
-- Length/WordCount Register
LNT_SHREG : shiftreg
generic map (
REGWD => 8)
port map (
clk => clk,
rst_n => rst_n,
ce => LengthWCnt_ce,
sin => sso,
pout => LengthWCnt_o);
 
LengthWCnt_ce <= ssovalid and LengthWCntRegEnable;
 
-- MASKLENGTH bit register (def: 256 bit)
-- MASK Register
MASK_SHREG : shiftreg
generic map (
REGWD => MASKLENGTH)
port map (
clk => clk,
rst_n => rst_n,
ce => MaskReg_ce,
sin => sso,
pout => MaskReg_o);
 
MaskReg_ce <= ssovalid and MaskRegEnable;
 
 
-------------------------------------------------------------------------------
-- Counters
-------------------------------------------------------------------------------
 
-- DataCnt
DataCnt_i : COUNTERCLR
generic map (
width => 8)
port map (
clk => clk,
rst_n => rst_n,
en => DataCnt_Inc,
clear => DataCnt_Clear,
outcnt => DataCnt);
 
-- PointerCnt
PointerCnt_i : COUNTERCLR
generic map (
width => 8)
port map (
clk => clk,
rst_n => rst_n,
en => PointerCnt_Inc,
clear => PointerCnt_Clear,
outcnt => PointerCnt);
 
-- RNCnt
RNCnt_i : COUNTERCLR
generic map (
width => 8)
port map (
clk => clk,
rst_n => rst_n,
en => RNCnt_Inc,
clear => RNCnt_Clear,
outcnt => RNCnt);
 
-- CRCCnt
CRCCnt_i : COUNTERCLR
generic map (
width => 8)
port map (
clk => clk,
rst_n => rst_n,
en => CRCCnt_Inc,
clear => CRCCnt_Clear,
outcnt => CRCCnt);
 
-------------------------------------------------------------------------------
-- CRC 5 & 16
-------------------------------------------------------------------------------
 
crc5encdec_i : crc5encdec
generic map (
PRESET_CRC5 => PRESET_CRC5)
port map (
clk => clk,
rst_n => rst_n,
init => CRC5Init,
ce => CRC5ce,
sdi => sso,
cout => CRC5Dec);
 
CRC5ce <= ssovalid;
 
 
crc16encdec_i : crc16encdec
generic map (
PRESET_CRC16 => PRESET_CRC16)
port map (
clk => clk,
rst_n => rst_n,
init => CRC16Init,
ce => CRC16ce,
sdi => sso,
cout => CRC16Dec);
 
CRC16ce <= ssovalid;
 
-------------------------------------------------------------------------------
-- Output Signals
-------------------------------------------------------------------------------
 
CommDone <= CommandDone;
Data_r <= GPReg_o;
CRC_r <= CRC16_o;
Pointer_r <= Pointer_o;
RN16_r <= RN16_o;
Mask_r <= MaskReg_o;
Length_r <= LengthWCnt_o;
 
 
-------------------------------------------------------------------------------
-- Symbol Decoder
-------------------------------------------------------------------------------
SymbolDecoder_i : SymbolDecoder
generic map (
LOG2_10_TARI_CK_CYC => LOG2_10_TARI_CK_CYC,
DELIMITIER_TIME_CK_CYC_MIN => DELIMITIER_TIME_CK_CYC_MIN,
DELIMITIER_TIME_CK_CYC_MAX => DELIMITIER_TIME_CK_CYC_MAX)
port map (
clk => clk,
rst_n => rst_n,
tdi => tdi,
en => en,
start => StartSDec,
sserror => sserror,
ssovalid => ssovalid,
sso => sso);
 
 
end CommandDec1;
/trunk/flashmemTID.vhd
0,0 → 1,220
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : Flash Memory TID
--
-- File name : flashmemTID.vhd
--
-- Description : Flash memory model.
--
-- Author : Paolo Bernardi <paolo.bernardi@polito.it>
--
-- Rev. History : Erwing Sanchez -- 17/07/06
-- - Ready/busy input removed because not used
-- - "Bits" generic removed
-- - RP input removed
-- - Command codes changed to work with Data = 16
-- E.R. Sanchez -- 13/10/06
-- - Include Parameters & Initialization
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.std_logic_textio.all;
use STD.TEXTIO.all;
 
 
entity Flash_MeM_TID is
generic (
Words : integer := 8; -- number of addresses
Addr : integer := 2; -- number of pins reserved for addresses
Data : integer := 16
);
port (
A : in std_logic_vector(Addr-1 downto 0); -- Address inputs
D : in std_logic_vector(Data-1 downto 0); -- Data input
Q : out std_logic_vector(Data-1 downto 0); -- Data output
G : in std_logic; -- Output enable
W : in std_logic; -- Write enable
RC : in std_logic; -- Row/Column address select
st : out std_logic -- Interface reset
);
 
end Flash_MeM_TID;
 
--synopsys synthesis_on
architecture Behavioural of Flash_MeM_TID is
--synopsys synthesis_off
 
type Flash_Type is array (0 to Words-1) of std_logic_vector(Data-1 downto 0);
signal Mem : Flash_Type := (others => (others => '1'));
 
 
signal Addr_int : std_logic_vector((2*Addr)-1 downto 0);
signal Data_int : std_logic_vector(Data-1 downto 0);
 
signal program : std_logic := '0';
signal erase : std_logic := '0';
signal i : natural range Words-1 downto 0;
signal status_register : std_logic_vector(Data-1 downto 0);
signal status : std_logic;
signal InitIsDoneFlag : std_logic := '0';
 
function resetVector (dim : natural) return std_logic_vector is
 
variable vectorOut : std_logic_vector(dim -1 downto 0);
variable i : natural range dim downto 0;
 
begin
for i in 0 to dim-1 loop
vectorOut(i) := '0';
end loop;
return vectorOut;
end resetVector;
 
function erase_mem (mem : Flash_Type) return Flash_Type is
 
variable mem_out : Flash_Type;
variable i : natural range Words-1 downto 0;
 
begin
for i in 0 to Words-1 loop
Mem_out(i) := (others => '1'); --"11111111";
end loop;
return mem_out;
 
end erase_mem;
--synopsys synthesis_on
begin --BEHAVIOURAL
--synopsys synthesis_off
 
write_first : process (RC)
begin
if RC'event and RC = '0' then
Addr_int(Addr-1 downto 0) <= A;
end if;
end process write_first;
 
write_second : process (RC)
begin
if RC'event and RC = '1' then
Addr_int((2*Addr)-1 downto Addr) <= A;
end if;
end process write_second;
 
w_data : process (W)
begin
if W'event and W = '1' then
if program = '1' then
Mem(conv_integer(unsigned(Addr_int))) <= D after 50 ns;
status_register <= conv_std_logic_vector(64, Data); --"01000000"
Data_int <= resetVector(Data_int'length);
st <= '0';
elsif erase = '1' then
Mem <= erase_mem(Mem) after 750000000 ns;
Data_int <= resetVector(Data_int'length);
st <= '1' after 750000000 ns;
else
Data_int <= D;
status_register <= (others => '0'); --"00000000";
st <= '0';
end if;
end if;
end process w_data;
 
read_data : process (G)
begin
if G'event and G = '0' then
if status = '0' then
Q <= Mem(conv_integer(unsigned(Addr_int))) after 50 ns;
else
Q <= status_register after 750000000 ns;
end if;
elsif G'event and G = '1' then
Q <= (others => 'U') after 50 ns; -- "UUUUUUUU"
end if;
end process read_data;
 
decode : process (Data_int)
begin
case conv_integer(Data_int) is
when 64 => -- "01000000" program
program <= '1';
erase <= '0';
status <= '0';
when 32 => -- "00100000" erase
program <= '0';
erase <= '1';
status <= '0';
when 112 => -- "01110000" read status reg
program <= '0';
erase <= '0';
status <= '1';
when others =>
program <= '0';
erase <= '0';
status <= '0';
end case;
end process decode;
 
 
-- -- purpose: Load Memory from file
-- load_memory : process(A, D, G, W, RC, InitIsDoneFlag)
-- file init_mem_file : text open read_mode is "meminit.txt";
-- variable inline, outline : line;
-- variable add : natural;
-- variable c : character;
-- variable Mem_var : Flash_Type;
-- begin -- process load_memory
-- if InitIsDoneFlag = '0' then
-- -- Clear Memory
-- for i in 0 to Words-1 loop
-- Mem_var(i) := (others => '0');
-- end loop; -- i
-- -- Load
-- while not endfile(init_mem_file) loop
-- readline(init_mem_file, inline);
-- read(inline, add);
-- read(inline, c);
-- if c /= ':' then
-- write(outline, string'("Syntax Error"));
-- writeline(output, outline);
-- assert false report "Mem Loader Aborted" severity failure;
-- end if;
-- for i in (Data-1) downto 0 loop
-- read(inline, c);
-- if c = '1' then
-- Mem_var(add)(i) := '1';
-- elsif c = '0' then
-- Mem_var(add)(i) := '0';
-- else
-- write(outline, string'("Invalid Character-Set to '0'"));
-- writeline(output, outline);
-- Mem_var(add)(i) := '0';
-- end if;
-- end loop; -- i
-- end loop;
-- Mem <= Mem_var;
-- InitIsDoneFlag <= '1';
-- end if;
-- end process load_memory;
 
--synopsys synthesis_on
end Behavioural;
--synopsys synthesis_off
 
 
 
configuration CFG_Flash_MeM_TID of Flash_MeM_TID is
for Behavioural
end for;
end CFG_Flash_MeM_TID;
 
--synopsys synthesis_on
/trunk/crc5encdec.vhd
0,0 → 1,65
-------------------------------------------------------------------------------
-- Politecnico di Torino
-- Dipartimento di Automatica e Informatica
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Title : EPC Class1 Gen2 RFID Tag - CRC5 encoder/decoder
--
-- File name : crc5encdec.vhd
--
-- Description : Tag CRC5 encoder/decoder
--
-- Authors : Erwing R. Sanchez <erwing.sanchezsanchez@polito.it>
--
-- Rev. History : 10 July 06
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.all;
 
 
entity crc5encdec is
 
generic(
PRESET_CRC5 : integer := 9); -- "01001"
port (
clk : in std_logic;
rst_n : in std_logic;
init : in std_logic;
ce : in std_logic;
sdi : in std_logic;
cout : out std_logic_vector(4 downto 0));
 
end crc5encdec;
 
architecture CRC5beh of crc5encdec is
 
 
signal crc5reg : std_logic_vector(4 downto 0);
begin -- CRC5beh
 
process (clk, rst_n)
begin -- process
if rst_n = '0' then -- asynchronous reset (active low)
crc5reg <= (others => '0');
elsif clk'event and clk = '1' then -- rising clock edge
if init = '1' then
crc5reg <= conv_std_logic_vector(PRESET_CRC5,5);
elsif ce = '1' then
crc5reg(0) <= crc5reg(4) xor sdi;
crc5reg(2 downto 1) <= crc5reg(1 downto 0);
crc5reg(3) <= crc5reg(4) xor sdi xor crc5reg(2);
crc5reg(4) <= crc5reg(3);
end if;
end if;
end process;
 
cout <= crc5reg;
end CRC5beh;

powered by: WebSVN 2.1.0

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