?? sd_rd.vhd
字號:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use WORK.sd_rd_state.all;
entity sd_rd is
generic
(
BLOCK_LEN_LOG2: integer := 9;
FIFO_DEPTH_LOG2:integer := 11
);
port
(
clk: in std_logic; -- from bus
reset: in std_logic; -- from bus
chipselect: in std_logic; -- from bus
address: in std_logic_vector( 1 downto 0 ); -- from bus
write: in std_logic; -- from bus
read: in std_logic; -- from bus
writedata: in std_logic_vector( 15 downto 0 ); -- from bus
wr_buzy: in std_logic; -- from sd_wr (async)
cardready: in std_logic; -- from sd_wr (async)
crcerr: in std_logic; -- from recvdata (async)
rdempty: in std_logic; -- from dcfifo
rdusedw: in std_logic_vector( 10 downto 0 ); -- from dcfifo
data: in std_logic_vector( 15 downto 0 ); -- from dcfifo
waitrequest: out std_logic; -- to bus
readdata: out std_logic_vector( 15 downto 0 ); -- to bus
wr_init: out std_logic; -- to sd_wr (async)
wr_read: out std_logic; -- to sd_wr (async)
wr_readm: out std_logic; -- to sd_wr (async)
dataaddr: out std_logic_vector( 31 downto 0 ); -- to sd_wr (async)
autoreread: out std_logic; -- to sd_wr (async)
rdreq: out std_logic; -- to dcfifo
------------- for debug ---------------
-- ostat: out SD_RD_STAT;
-- owr_buzy_r: out std_logic;
-- owr_buzy_dl: out std_logic;
---------------------------------------
areset: out std_logic -- to dcfifo, sd_wr, sendcmd, recvresp, recvdata
);
end sd_rd;
architecture RTL of sd_rd is
constant CARDREADY_BIT: integer := 0; -- I
constant DATAREADY_BIT: integer := 1; -- I
constant CRCERR_BIT: integer := 2; -- I
constant AUTOREREAD_BIT: integer := 3; -- I/O
constant STREAMREAD_BIT: integer := 4; -- I/O
constant READCARD_BIT: integer := 5; -- O
constant INITCARD_BIT: integer := 6; -- O
constant RESET_BIT: integer := 7; -- O
constant READ_TH_BIT: integer := BLOCK_LEN_LOG2 - 1;
-- reg async input
signal wr_buzy_r: std_logic;
signal cardready_r: std_logic;
signal crcerr_r: std_logic;
signal wr_buzy_dl: std_logic;
signal data_addr: std_logic; -- data addr
signal state_addr: std_logic; -- state addr
signal rdaddrlo_addr: std_logic; -- read address low 16
signal rdaddrhi_addr: std_logic; -- read address high 16
signal stat: SD_RD_STAT;
signal stat_next: SD_RD_STAT;
signal dataready: std_logic;
-- reg async output
signal wr_init_r: std_logic;
signal wr_read_r: std_logic;
signal wr_readm_r: std_logic; -- latch
signal dataaddr_r: std_logic_vector( 31 downto 0 ); -- latch
signal autoreread_r: std_logic; -- latch
begin
Reg_async: process( clk, wr_buzy, cardready, crcerr, wr_buzy_r )
begin
if( rising_edge( clk ) ) then
wr_buzy_dl <= wr_buzy_r;
wr_buzy_r <= wr_buzy;
cardready_r <= cardready;
crcerr_r <= crcerr;
end if;
end process Reg_async;
data_addr <= '1' when( address = "00" ) else '0';
state_addr <= '1' when( address = "01" ) else '0';
rdaddrlo_addr <= '1' when( address = "10" ) else '0';
rdaddrhi_addr <= '1' when( address = "11" ) else '0';
dataready <= '1' when( rdusedw( FIFO_DEPTH_LOG2-1 downto READ_TH_BIT ) /= conv_std_logic_vector( 0, FIFO_DEPTH_LOG2 - BLOCK_LEN_LOG2 + 1 ) )
else '0';
Stat_P: process( clk, reset, stat_next )
begin
if( rising_edge( clk ) ) then
if( reset = '1' ) then
stat <= SD_RD_INIT;
else
stat <= stat_next;
end if;
end if;
end process Stat_P;
Stat_next_P: process( stat, chipselect, read, write, data_addr, rdaddrlo_addr, rdaddrhi_addr, writedata, wr_buzy_dl, wr_buzy_r, dataready )
begin
case stat is
when SD_RD_INIT =>
stat_next <= SD_RD_IDLE;
when SD_RD_IDLE =>
stat_next <= SD_RD_IDLE;
if( chipselect = '1' ) then
if( read = '1' ) then
if( data_addr = '1' ) then
stat_next <= SD_RD_WAITDATA;
else
stat_next <= SD_RD_RDSTATE;
end if;
end if;
if( write = '1' ) then
stat_next <= SD_RD_WRSTATE;
if( rdaddrlo_addr = '1' ) then
stat_next <= SD_RD_WR_RDADDR_LO;
end if;
if( rdaddrhi_addr = '1' ) then
stat_next <= SD_RD_WR_RDADDR_HI;
end if;
end if;
end if;
when SD_RD_WRSTATE =>
stat_next <= SD_RD_IDLE;
if( writedata(RESET_BIT) = '1' ) then
stat_next <= SD_RD_INIT;
elsif( writedata(INITCARD_BIT) = '1' or writedata(READCARD_BIT) = '1'
or writedata(STREAMREAD_BIT) = '1' ) then
if( wr_buzy_dl = '0' and wr_buzy_r = '1' ) then
stat_next <= SD_RD_IDLE;
else
stat_next <= SD_RD_WRSTATE;
end if;
end if;
when SD_RD_WR_RDADDR_LO =>
stat_next <= SD_RD_IDLE;
when SD_RD_WR_RDADDR_HI =>
stat_next <= SD_RD_IDLE;
when SD_RD_RDSTATE =>
stat_next <= SD_RD_IDLE;
when SD_RD_WAITDATA =>
if( dataready = '1' ) then
stat_next <= SD_RD_FIFO;
else
stat_next <= SD_RD_WAITDATA;
end if;
when SD_RD_FIFO =>
if( chipselect = '1' ) then
stat_next <= SD_RD_FIFO;
else
stat_next <= SD_RD_IDLE;
end if;
when others =>
stat_next <= SD_RD_INIT;
end case;
end process Stat_next_P;
Output: process( stat, writedata, wr_buzy_dl, wr_buzy_r, read, cardready_r, dataready, crcerr_r, autoreread_r, data, wr_readm_r, rdusedw, rdempty )
begin
waitrequest <= '1';
readdata <= ( others => '0' );
rdreq <= '0';
case stat is
when SD_RD_INIT =>
when SD_RD_IDLE =>
when SD_RD_WRSTATE =>
waitrequest <= '0';
if( writedata(INITCARD_BIT) = '1' or writedata(READCARD_BIT) = '1'
or writedata(STREAMREAD_BIT) = '1' ) then
if( wr_buzy_dl = '0' and wr_buzy_r = '1' ) then
waitrequest <= '0';
else
waitrequest <= '1';
end if;
end if;
when SD_RD_WR_RDADDR_LO =>
waitrequest <= '0';
when SD_RD_WR_RDADDR_HI =>
waitrequest <= '0';
when SD_RD_RDSTATE =>
waitrequest <= '0';
readdata(CARDREADY_BIT) <= cardready_r;
readdata(DATAREADY_BIT) <= dataready;
readdata(CRCERR_BIT) <= crcerr_r;
readdata(AUTOREREAD_BIT) <= autoreread_r;
readdata(STREAMREAD_BIT) <= wr_readm_r;
when SD_RD_FIFO =>
waitrequest <= rdempty;
rdreq <= read;
readdata <= data;
when others =>
end case;
end process Output;
Async_output: process( clk, stat, wr_readm_r, dataaddr_r, autoreread_r, writedata )
begin
if( rising_edge( clk ) ) then
wr_init_r <= '0';
wr_read_r <= '0';
wr_readm_r <= wr_readm_r;
dataaddr_r <= dataaddr_r;
autoreread_r <= autoreread_r;
areset <= '0';
case stat is
when SD_RD_INIT =>
wr_readm_r <= '0';
autoreread_r <= '1';
areset <= '1';
when SD_RD_WRSTATE =>
areset <= writedata(RESET_BIT);
autoreread_r <= writedata(AUTOREREAD_BIT);
if( writedata(READCARD_BIT) = '1' ) then
wr_read_r <= '1';
wr_readm_r <= '0';
end if;
wr_readm_r <= writedata(STREAMREAD_BIT);
if( writedata(INITCARD_BIT) = '1' ) then
wr_init_r <= '1';
wr_readm_r <= '0';
end if;
when SD_RD_WR_RDADDR_LO =>
dataaddr_r( 15 downto 0 ) <= writedata;
when SD_RD_WR_RDADDR_HI =>
dataaddr_r( 31 downto 16 ) <= writedata;
when others =>
end case;
end if;
end process Async_output;
wr_init <= wr_init_r;
wr_read <= wr_read_r;
wr_readm <= wr_readm_r;
dataaddr <= dataaddr_r;
autoreread <= autoreread_r;
------------- for debug ---------------
-- ostat <= stat;
-- owr_buzy_r <= wr_buzy_r;
-- owr_buzy_dl <= wr_buzy_dl;
---------------------------------------
end RTL;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -