📄 smartcard.vhd
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
entity smartcard is
Port ( reset_button : in std_logic;
card_enable : in std_logic;
clk : in std_logic;
card_vpp : out std_logic;
card_vcc : out std_logic;
card_clk : out std_logic;
card_rst : out std_logic;
card_io : inout std_logic;
data_ready : out std_logic;
done : out std_logic;
data_out : out std_logic_vector(7 downto 0));
attribute DONT_OPTIMIZE : string;
attribute KEEP : string;
end smartcard;
architecture Behavioral of smartcard is
--**************************************************************************
-- STATE MACHINE SIGNAL DECLARATION:
type StateType is (IDLE, Init, ClkEnable, WaitForData, ReadData, ProcessData, WriteCommand);
signal CurrentState, NextState : StateType;
--**************************************************************************
signal io_rw : std_logic;
signal clk_en : std_logic;
signal counter_enable : std_logic;
signal counter : std_logic_vector(8 downto 0);
signal Bitcounter : std_logic_vector(3 downto 0);
signal Bitcounter_clk : std_logic;
signal Bytecounter : std_logic_vector(7 downto 0);
signal Bytecounter_clk : std_logic;
signal data : std_logic_vector(9 downto 0);
signal data_mux : std_logic_vector(9 downto 0);
signal Enable_signal : std_logic;
signal Wait_a_Byte : std_logic;
signal Command_ready : std_logic;
signal Command_end : std_logic;
signal data_valid : std_logic;
signal reset : std_logic;
attribute DONT_OPTIMIZE of card_io : signal is "TRUE";
--attribute KEEP of data_valid : signal is "TRUE";
begin
--**************************************************************************
COMB: process(CurrentState, Enable_signal, Card_io, Bitcounter, Wait_a_byte, Command_ready, Command_end)
begin
case CurrentState is
when IDLE =>
if(Enable_signal = '1') then
NextState <= Init;
else
NextState <= IDLE;
end if;
when Init =>
NextState <= ClkEnable;
when ClkEnable =>
NextState <= WaitForData;
when WaitForData =>
if(Card_io = '0') then
NextState <= ReadData;
else
Nextstate <= WaitForData;
end if;
when ReadData =>
if (Bitcounter = 11)then
NextState <= ProcessData;
else
NextState <= ReadData;
end if;
when Processdata =>
if (Wait_a_byte = '1') then
NextState <= ReadData;
elsif (Command_ready = '1') then
NextState <= WriteCommand;
else
NextState <= WaitForData;
end if;
when WriteCommand =>
if (Command_end = '1') then
Nextstate <= WaitForData;
else
NextState <= WriteCommand;
end if;
end case;
end process COMB;
--**************************************************************************
SEQ: process(Clk,Reset)
begin
if(Reset = '1') then
CurrentState <= Idle;
elsif (clk'event and clk = '1') then
CurrentState <= NextState;
end if;
end process SEQ;
--**************************************************************************
with CurrentState select
Card_rst <= '0' when IDLE,
'0' when Init,
'0' when ClkEnable,
'1' when others;
with CurrentState select
clk_en <= '0' when IDLE,
'0' when Init,
'1' when others;
with CurrentState select
Card_vcc <= '0' when IDLE,
'Z' when others;
with CurrentState select
Card_vpp <= '0' when IDLE,
'Z' when others;
with CurrentState select
io_rw <= '0' when WriteCommand,
'1' when others;
with CurrentState select
counter_enable <= '1' when ReadData,
'1' when WriteCommand,
'0' when others;
--**************************************************************************
-- 9-bit counter, elementary time unit etu = 372 / f
--**************************************************************************
process(counter_enable, clk)
begin
if(counter_enable = '0') then
counter <= (others=>'0');
elsif (clk'event and clk = '1') then
if (counter = 371) then
counter <= (others=>'0');
else
counter <= counter + 1;
end if;
end if;
end process;
--**************************************************************************
-- 4-bit Bitcounter, counting bits in a character frame
--**************************************************************************
Bitcounter_clk <= '1' when (counter = 371) else '0';
process(counter_enable, clk)
begin
if(counter_enable = '0') then
Bitcounter <= (others=>'0');
elsif (Bitcounter_clk'event and Bitcounter_clk = '1') then
if (Bitcounter = 11) then
Bitcounter <= (others=>'0');
else
Bitcounter <= Bitcounter + 1;
end if;
end if;
end process;
--**************************************************************************
-- 8-bit Bytecounter, counting bytes in a command/response
--**************************************************************************
Bytecounter_clk <= '1' when (Bitcounter = 11) else '0';
process(Enable_signal, Bytecounter_clk)
begin
if(Enable_signal = '0') then
Bytecounter <= (others=>'0');
elsif (Bytecounter_clk'event and Bytecounter_clk = '1') then
Bytecounter <= Bytecounter + 1;
end if;
end process;
--**************************************************************************
-- 9 bit shifter
--**************************************************************************
process(counter_enable, clk)
begin
if(counter_enable = '0') then
data <= (others=>'0');
elsif (clk'event and clk = '1') then
if ((counter = 186) and (io_rw = '1')) then --read
data <= data(8 downto 0) & Card_io;
elsif ((bitcounter = 0) and (counter = 0) and (io_rw = '0')) then --write
data <= data_mux;
elsif ((counter = 371) and (io_rw = '0')) then
data(9 downto 0) <= '1' & data(9 downto 1);
else
data <= data;
end if;
end if;
end process;
--**************************************************************************
-- debounce ff
--**************************************************************************
process(Reset, clk)
begin
if(reset = '1') then
Enable_signal <= '0';
elsif (clk'event and clk = '1') then
Enable_signal <= Card_enable or Enable_signal;
end if;
end process;
--**************************************************************************
-- COMBINATORIAL SIGNALS
--**************************************************************************
--shift_end <= '0' when ((Bitcounter = 10) and (counter < 160)) else '1';
Card_clk <= clk and clk_en;
Card_io <= data(0) when (io_rw = '0') else 'Z';
--data_out <= data(8 downto 1) when (data_valid = '1') else (others => '0');
reset <= reset_button or (not card_enable);
data_out(7) <= data(1) when (data_valid = '1') else '0';
data_out(6) <= data(2) when (data_valid = '1') else '0';
data_out(5) <= data(3) when (data_valid = '1') else '0';
data_out(4) <= data(4) when (data_valid = '1') else '0';
data_out(3) <= data(5) when (data_valid = '1') else '0';
data_out(2) <= data(6) when (data_valid = '1') else '0';
data_out(1) <= data(7) when (data_valid = '1') else '0';
data_out(0) <= data(8) when (data_valid = '1') else '0';
--data_out <= Bytecounter;
data_ready <= '1' when ((data_valid = '1') and (Bitcounter = 10)) else '0';
data_mux <= "1100000000" when (Bytecounter = 20) --80
else "1101001000" when (Bytecounter = 21) --A4
else "0000000000" when (Bytecounter = 22) --00
else "0000000000" when (Bytecounter = 23) --00
else "1000000100" when (Bytecounter = 24) --02
-- A4
else "0111100000" when (Bytecounter = 27) --F0
else "0000000000" when (Bytecounter = 28) --00
-- 91
-- 00
else "1100000000" when (Bytecounter = 32) --80
else "0101100100" when (Bytecounter = 33) --B2
else "0000000000" when (Bytecounter = 34) --00
else "0000000000" when (Bytecounter = 35) --00
else "1001000000" when (Bytecounter = 36) --20
-- B2
-- 32 bytes data
--
else "1100000000" when (Bytecounter = 73) --80
else "1101001000" when (Bytecounter = 74) --A4
else "0000000000" when (Bytecounter = 75) --00
else "0000000000" when (Bytecounter = 76) --00
else "1000000100" when (Bytecounter = 77) --02
-- A4
else "0111100000" when (Bytecounter = 80) --F0
else "1000000010" when (Bytecounter = 81) --01
-- 91
-- 00
else "1100000000" when (Bytecounter = 86) --80
else "0101100100" when (Bytecounter = 87) --B2
else "0000000000" when (Bytecounter = 88) --00
else "0000000000" when (Bytecounter = 89) --00
else "0000000110" when (Bytecounter = 90) --03
-- B2 01 01 12 90 00
else "1100000000" when (Bytecounter = 99) --80
else "0111000010" when (Bytecounter = 100) --E1
else "0000000000" when (Bytecounter = 101) --00
else "0000000000" when (Bytecounter = 102) --00
else "1000001000" when (Bytecounter = 103) --04
-- E1
else "0000000000" when (Bytecounter = 106) --00
else "0000000000" when (Bytecounter = 107) --00
else "0000000000" when (Bytecounter = 108) --00
else "0000000000" when (Bytecounter = 109) --00
-- 61 19
else "1100000000" when (Bytecounter = 113) --80
else "0110000000" when (Bytecounter = 114) --C0
else "0000000000" when (Bytecounter = 115) --00
else "0000000000" when (Bytecounter = 116) --00
else "1000110010" when (Bytecounter = 117) --19
-- 25 byte data
else "1111111111";
Wait_a_byte <= '1' when ((Bytecounter = 19)
or (Bytecounter = 26)
or (Bytecounter = 31)
or (Bytecounter = 72)
or (Bytecounter = 79)
or (Bytecounter = 84)
or (Bytecounter = 85)
or (Bytecounter = 97)
or (Bytecounter = 98)
or (Bytecounter = 105)
or (Bytecounter = 112)) else '0';
Command_ready <= '1' when ((Bytecounter = 20)
or (Bytecounter = 27)
or (Bytecounter = 32)
or (Bytecounter = 73)
or (Bytecounter = 80)
or (Bytecounter = 86)
or (Bytecounter = 99)
or (Bytecounter = 106)
or (Bytecounter = 113)) else '0';
Command_end <= '1' when ((Bytecounter = 25)
or (Bytecounter = 29)
or (Bytecounter = 37)
or (Bytecounter = 78)
or (Bytecounter = 82)
or (Bytecounter = 91)
or (Bytecounter = 104)
or (Bytecounter = 110)
or (Bytecounter = 118)) else '0';
data_valid <= '1' when (((Bytecounter > 37) and (Bytecounter < 53))
or ((Bytecounter > 91) and (Bytecounter < 95))
--or ((Bytecounter > 124) and (Bytecounter < 127))
) else '0';
done <= '1' when (Bytecounter >= 95) else '0';
end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -