CY7C68013A是Cypress公司FX2LP系列的一款USB2.0控制器,该款芯片以8051内核(是不是想到了STC 51单片机了)为核心,配合USB硬件实现,再加上高速的对外并行接口GPIF(SlaveFIFO),简直是FPGA与PC之间的高速公路,这也正是我选择这款芯片的原因。
具体原理图就不贴了,FPGA+CY7C68013A
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
ENTITY USB_FPGA IS
GENERIC (
FIFOLENTH : integer := 1024;
FIFOWITH : integer := 16;
PACKAGENUM : integer := 256;
FRM_HEAD : integer := 83;
FRM_LEN : integer := 8;
CMD_RESET : integer := 53;
CMD_SETUP : integer := 160;
CMD_SLEEP : integer := 161;
CMD_COMPENT : integer := 170;
CMD_ECT : integer := 162
);
PORT
(
IFCLK : IN STD_LOGIC ;
rst : IN STD_LOGIC ;
mRdRequest : OUT STD_LOGIC;
mRdData : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
mRdEmpty : IN STD_LOGIC;
FX2FD : INOUT STD_LOGIC_VECTOR (15 DOWNTO 0);
CTL0_FLAGA : IN STD_LOGIC ;
CTL2_FLAGC : IN STD_LOGIC ;
PA7_FLAGD : OUT STD_LOGIC ;
PA2_SLOE : OUT STD_LOGIC ;
RDY0_SLRD : OUT STD_LOGIC ;
RDY1_SLWR : OUT STD_LOGIC ;
PA6_PKTEND : OUT STD_LOGIC ;
FIFOADR : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) ;
mDemodMode : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
mDemodChn : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
mGain1 : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
mGain2 : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
mReset : OUT STD_LOGIC;
--mSleep : OUT STD_LOGIC;
Test : OUT STD_LOGIC
);
END USB_FPGA;
ARCHITECTURE ARC_USB_FPGA OF USB_FPGA IS
TYPE Bit16_arry IS ARRAY(0 TO FRM_LEN) OF STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL RxBuf:Bit16_arry;
TYPE fifo_arry IS ARRAY(0 to (FIFOLENTH-1)) OF bit_vector((FIFOWITH-1) DOWNTO 0);
SIGNAL fifomemory:fifo_arry;
SIGNAL fifowraddr,fifordaddr : NATURAL RANGE 0 TO (FIFOLENTH-1) ;
--
SIGNAL data2usb,data2fpga : STD_LOGIC_VECTOR((FIFOWITH-1) DOWNTO 0) ;
SIGNAL slrdbuf,slwrbuf,sloebuf : STD_LOGIC ;
SIGNAL state:INTEGER;
BEGIN
PA2_SLOE <= sloebuf;
RDY0_SLRD <= slrdbuf ;
RDY1_SLWR <= slwrbuf ;
PA6_PKTEND <= '1';
PROCESS(state,rst)
BEGIN
IF(rst = '0') THEN
data2fpga <= FX2FD;
FX2FD <="ZZZZZZZZZZZZZZZZ" ;
ELSIF(state=1) THEN
data2fpga <= FX2FD;
FX2FD <="ZZZZZZZZZZZZZZZZ" ;
ELSE
data2fpga <= "ZZZZZZZZZZZZZZZZ" ;
FX2FD <=data2usb ;
END IF;
END PROCESS;
PROCESS(rst,IFCLK)
VARIABLE cnt:NATURAL RANGE 0 TO FRM_LEN ;
VARIABLE rx:INTEGER;
VARIABLE cmd:INTEGER;
VARIABLE CRC:INTEGER;
VARIABLE wrstate:INTEGER;
VARIABLE flag : INTEGER;
BEGIN
IF(rst = '0') THEN
sloebuf <= '1';
slrdbuf <= '1';
slwrbuf <= '1';
cnt:=0;
flag:=0;
state<=0;
mRdRequest<='0';
Test<='0';
wrstate:=0;
mDemodMode<="100";
mDemodChn<="00000000";
mGain1<="000";
mGain2<="000";
mReset<='1';
ELSIF(IFCLK'event AND IFCLK='1') THEN
CASE state IS
WHEN 0 =>
IF(CTL0_FLAGA = '1') THEN --wr to fpga
FIFOADR <= "00";
state<=state+1;
sloebuf <= '0';
slwrbuf <= '1';
ELSE
FIFOADR <= "10";
state<=state+2;
sloebuf <= '1';
slrdbuf <= '1';
END IF;
WHEN 1 =>
IF(CTL0_FLAGA = '1') THEN --wr to fpga
CASE wrstate IS
WHEN 0 =>
wrstate := wrstate + 1;
slrdbuf <= '0';
cnt:=0;
WHEN 1 =>
slrdbuf <= '0';
rx:=conv_integer(data2fpga(7 DOWNTO 0));
cmd:=conv_integer(data2fpga(15 DOWNTO 8));
IF((cnt=0)AND(rx=FRM_HEAD)) THEN
RxBuf(cnt)<=data2fpga;
cnt:=cnt+1;
wrstate := wrstate + 1;
ELSE
state<=0;
END IF;
WHEN 2 =>
slrdbuf <= '0';
RxBuf(cnt)<=data2fpga;
cnt:=cnt+1;
IF(cnt=FRM_LEN) THEN
CRC:=0;
FOR cnt IN 1 TO 6 LOOP
CRC:= CRC+conv_integer(RxBuf(cnt)(7 DOWNTO 0)) + conv_integer(RxBuf(cnt)(15 DOWNTO 8));
END LOOP;
CRC:=CRC+conv_integer(RxBuf(0)(15 DOWNTO 8))+conv_integer(data2fpga(7 DOWNTO 0));
CRC:=CRC rem 256;
rx:=conv_integer(data2fpga(15 DOWNTO 8));
IF(CRC=rx) THEN
CASE cmd IS
WHEN CMD_SETUP =>
mDemodMode<=RxBuf(1)(2 DOWNTO 0);
mDemodChn<=RxBuf(1)(15 DOWNTO 8);
mGain1<=RxBuf(2)(2 DOWNTO 0);
mGain2<=RxBuf(2)(6 DOWNTO 4);
mReset<='1';
WHEN CMD_RESET => --复位
mReset<='0';
WHEN CMD_SLEEP => --睡眠
--mSleep<='1';
WHEN OTHERS=>
END CASE;
--指示灯提示
IF(flag=0) THEN
Test<='1';
flag:=1;
ELSE
Test<='0';
flag:=0;
END IF;
END IF;
wrstate := 0;
END IF;
WHEN OTHERS =>
END CASE;
ELSE
slrdbuf <= '1';
wrstate:=0;
state<=0;
END IF;
WHEN 2 =>
slwrbuf <= '1';
IF((CTL2_FLAGC = '1') AND (mRdEmpty='0'))THEN
mRdRequest<='1';
state<=state+1;
ELSE
state<=0;
data2usb <= "ZZZZZZZZZZZZZZZZ";
END IF;
WHEN 3=>
mRdRequest<='0';
IF(CTL2_FLAGC = '1') THEN
slwrbuf <= '0';
data2usb <= mRdData;
state<=state-1;
END IF;
WHEN OTHERS =>
END CASE;
END IF;
END PROCESS;
END ARC_USB_FPGA;