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; |