?? recvresp.vhd
字號:
library IEEE;
use IEEE.std_logic_1164.all;
use WORK.pck_CRC7.all;
entity recvresp is
port
(
clk: in std_logic; -- sd clk
areset: in std_logic; -- async reset
recv: in std_logic; -- recv response
longresp: in std_logic; -- long response(136) /short(48)
cmd: in std_logic; -- cmd port
buzy: out std_logic; -- buzy receiving
cmdno: out std_logic_vector( 5 downto 0 ); -- response cmd number
content: out std_logic_vector( 126 downto 0 ); -- response content
---------- for debug ----------------
-- ocnt: out integer range 0 to 126;
-- ocrc: out std_logic_vector( 6 downto 0 );
-------------------------------------
crcerr: out std_logic -- response crc error
);
end recvresp;
architecture RTL of recvresp is
type RR_STAT is
(
RR_IDLE, -- idle, wait for recv signal
RR_PRERECV, -- wait for card responsing
RR_PRERECVCMDNO, -- pre-recv cmd number, only load counter
RR_RECVCMDNO, -- recv cmd number
RR_PRERECVCONTENT, -- pre-recv content(load counter and recv first bit)
RR_RECVCONTENT, -- recv content
RR_PRECHECKCRC, -- pre-check crc7(load counter and check first bit)
RR_CHECKCRC, -- check crc7
RR_WAITFINISH, -- wait for receiving response finished
RR_SUCCESS, -- received a correct response
RR_WAITRECVEND -- wait for "recv" become low
);
signal stat: RR_STAT;
signal stat_next: RR_STAT;
signal cnt_q: integer range 0 to 126;
signal cnt_d: integer range 0 to 126;
signal contlen: integer range 0 to 126; -- latch
signal longresp_r: std_logic; -- latch
signal cmdno_r: std_logic_vector( 5 downto 0 ); -- latch
signal content_r: std_logic_vector( 126 downto 0 ); -- latch
signal crcerr_r: std_logic; -- latch
signal crc: std_logic_vector( 6 downto 0 );
signal crc_next: std_logic_vector( 6 downto 0 );
begin
Reg: process( clk, longresp )
begin
if( rising_edge( clk ) ) then
longresp_r <= longresp;
end if;
end process Reg;
Stat_P: process( clk, areset, stat_next )
begin
if( areset = '1' ) then
stat <= RR_IDLE;
elsif( rising_edge( clk ) ) then
stat <= stat_next;
end if;
end process Stat_P;
Stat_next_P: process( stat, recv, cmd, crc, cnt_q, longresp_r )
begin
case stat is
when RR_IDLE =>
if( recv = '1' ) then
stat_next <= RR_PRERECV;
else
stat_next <= RR_IDLE;
end if;
when RR_PRERECV =>
if( cmd = '0' ) then
stat_next <= RR_PRERECVCMDNO;
else
stat_next <= RR_PRERECV;
end if;
when RR_PRERECVCMDNO =>
stat_next <= RR_RECVCMDNO;
when RR_RECVCMDNO =>
if( cnt_q = 0 ) then
stat_next <= RR_PRERECVCONTENT;
else
stat_next <= RR_RECVCMDNO;
end if;
when RR_PRERECVCONTENT =>
stat_next <= RR_RECVCONTENT;
when RR_RECVCONTENT =>
if( cnt_q = 0 ) then
if( longresp_r = '1' ) then
stat_next <= RR_SUCCESS;
else
stat_next <= RR_PRECHECKCRC;
end if;
else
stat_next <= RR_RECVCONTENT;
end if;
when RR_PRECHECKCRC =>
if( crc(6) = cmd ) then
stat_next <= RR_CHECKCRC;
else
stat_next <= RR_WAITFINISH;
end if;
when RR_CHECKCRC =>
if( crc(cnt_q) = cmd ) then
if( cnt_q = 0 ) then
stat_next <= RR_SUCCESS;
else
stat_next <= RR_CHECKCRC;
end if;
else
stat_next <= RR_WAITFINISH;
end if;
when RR_SUCCESS =>
if( recv = '1' ) then
stat_next <= RR_WAITRECVEND;
else
stat_next <= RR_IDLE;
end if;
when RR_WAITFINISH =>
if( cnt_q = 0 ) then
if( recv = '1' ) then
stat_next <= RR_WAITRECVEND;
else
stat_next <= RR_IDLE;
end if;
else
stat_next <= RR_WAITFINISH;
end if;
when RR_WAITRECVEND =>
if( recv = '1' ) then
stat_next <= RR_WAITRECVEND;
else
stat_next <= RR_IDLE;
end if;
when others =>
stat_next <= RR_IDLE;
end case;
end process Stat_next_P;
Contlen_P: process( clk, recv )
begin
if( rising_edge( clk ) ) then
if( recv = '1' ) then
if( longresp = '1' ) then
contlen <= 127 - 1;
else
contlen <= 32 - 1;
end if;
else
contlen <= contlen;
end if;
end if;
end process Contlen_P;
Cnt_q_P: process( clk, stat, contlen, cnt_d )
begin
if( rising_edge( clk ) ) then
case stat is
when RR_PRERECVCMDNO =>
cnt_q <= 5;
when RR_PRERECVCONTENT =>
cnt_q <= contlen - 1;
when RR_PRECHECKCRC =>
cnt_q <= 6 - 1;
when others =>
cnt_q <= cnt_d;
end case;
end if;
end process Cnt_q_P;
Cnt_d_P: process( cnt_q )
begin
if( cnt_q > 0 ) then
cnt_d <= cnt_q - 1;
else
cnt_d <= 0;
end if;
end process Cnt_d_P;
Crc_P: process( clk, crc, crc_next )
begin
if( rising_edge( clk ) ) then
case stat is
when RR_PRERECV =>
crc <= ( others => '0' );
when RR_PRERECVCMDNO =>
crc <= crc_next;
when RR_RECVCMDNO =>
crc <= crc_next;
when RR_PRERECVCONTENT =>
crc <= crc_next;
when RR_RECVCONTENT =>
crc <= crc_next;
when others =>
crc <= crc;
end case;
end if;
end process Crc_P;
Crc_next_P: process( crc, cmd )
begin
crc_next <= nextCRC7( cmd, crc );
end process Crc_next_P;
Buzy_P: process( stat )
begin
case stat is
when RR_IDLE =>
buzy <= '0';
when RR_WAITRECVEND =>
buzy <= '0';
when others =>
buzy <= '1';
end case;
end process Buzy_P;
Output: process( clk, stat, cmdno_r, content_r, crcerr_r, cnt_q, cmd, contlen )
begin
if( rising_edge( clk ) ) then
cmdno_r <= cmdno_r;
content_r <= content_r;
crcerr_r <= crcerr_r;
case stat is
when RR_PRERECV =>
crcerr_r <= '1';
when RR_RECVCMDNO =>
cmdno_r( cnt_q ) <= cmd;
when RR_PRERECVCONTENT =>
content_r( contlen ) <= cmd;
when RR_RECVCONTENT =>
content_r( cnt_q ) <= cmd;
when RR_SUCCESS =>
crcerr_r <= '0';
when others =>
end case;
end if;
end process Output;
cmdno <= cmdno_r;
content <= content_r;
crcerr <= crcerr_r;
---------- for debug ----------------
-- ocnt <= cnt_q;
-- ocrc <= crc;
-------------------------------------
end RTL;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -