OpenCores
URL https://opencores.org/ocsvn/sdhc-sc-core/sdhc-sc-core/trunk

Subversion Repositories sdhc-sc-core

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 133 to Rev 134
    Reverse comparison

Rev 133 → Rev 134

/sdhc-sc-core/trunk/src/grpSd/unitSdData/src/SdData-Rtl-a.vhdl
11,30 → 11,15
 
type aState is (idle, send, receive); -- overall states
type aRegion is (startbit, data, crc, endbit); -- regions in send and receive state
subtype aCounter is unsigned(LogDualis(512*8)-1 downto 0); -- bit counter
 
-- types for used counters
subtype aWordCounter is unsigned(LogDualis(128)-1 downto 0);
subtype aByteCounter is unsigned(LogDualis(4)-1 downto 0);
subtype aBitCCounter is unsigned(LogDualis(8)-1 downto 0);
 
type aCounters is record
Word : aWordCounter;
Byte : aByteCounter;
BitC : aBitCCounter;
end record aCounters;
 
constant cDefaultCounters : aCounters := (
Word => (others => '0'),
Byte => (others => '0'),
BitC => (others => '0'));
 
-- all registers
type aReg is record
-- state, region and counters
 
State : aState;
Region : aRegion;
Counter : aCounters;
Counter : aCounter;
 
Mode : aSdDataBusMode; -- standard or wide SD mode
 
53,10 → 38,10
constant cDefaultReg : aReg := (
State => idle,
Region => startbit,
Counter => cDefaultCounters,
Counter => (others => '0'),
Mode => standard,
WordInvalid => cInactivated,
Word => (others => '0'),
Word => (others => '0'),
Data => cDefaultSdData,
Controller => cDefaultSdDataToController,
ReadWriteFifo => cDefaultoReadFifo,
84,6 → 69,11
signal CrcDataIn : std_ulogic_vector(3 downto 0);
signal R, NextR : aReg;
 
-- aliases for bits, bytes and words from the bit counter
alias RBitC is R.Counter(LogDualis(8)-1 downto 0);
alias RByteC is R.Counter(LogDualis(4)+LogDualis(8)-1 downto LogDualis(8));
alias RWordC is R.Counter(R.Counter'high downto LogDualis(4)+LogDualis(8));
 
begin
 
-- registered outputs
121,13 → 111,23
Comb : process (iData.Data, iSdDataFromController, CrcIn, iReadWriteFifo, iWriteReadFifo, R)
 
--------------------------------------------------------------------------------
-- Calculate the bit addr from the byte and bit counters
-- Handle accessing the fifo
--------------------------------------------------------------------------------
function CalcBitAddrInWord (constant bytes : aByteCounter; constant bits : aBitCCounter) return integer is
procedure HandleFifoAccess (signal status : in std_ulogic; signal req : out std_ulogic) is
begin
return (to_integer(bytes) * 8) + to_integer(bits);
end function CalcBitAddrInWord;
if (status = cActivated) then
-- stop data transfer to card and wait for a change of the fifo status
report "Fifo not ready, waiting" severity note;
 
NextR.DisableSdClk <= cActivated;
NextR.Counter <= R.Counter;
req <= cInactivated;
else
NextR.DisableSdClk <= cInactivated;
req <= cActivated;
end if;
end procedure HandleFifoAccess;
 
--------------------------------------------------------------------------------
-- Set crc outputs so data is shifted in
--------------------------------------------------------------------------------
161,58 → 161,42
BitEnd := 3;
BitDec := 4;
end if;
if (R.Counter.BitC = BitEnd) then
 
if (RBitC = BitEnd) then
-- Byte finished
NextR.Counter.BitC <= to_unsigned(7, aBitCCounter'length);
NextR.Counter <= R.Counter + (16 - BitDec);
 
if (R.Counter.Byte = 3) then
if (RByteC = 3) then
-- Word finished
NextR.Counter.Byte <= to_unsigned(0, aByteCounter'length);
NextR.WordInvalid <= cInactivated;
 
if (R.Counter.Word = 127) then
if (RWordC = 127) then
-- whole block finished, send crc next
NextR.Region <= crc;
NextR.Counter.Word <= to_unsigned(0, aWordCounter'length);
NextR.Region <= crc;
NextR.Counter <= to_unsigned(0, aCounter'length);
 
else
NextR.Counter.Word <= R.Counter.Word + 1;
 
if (send = true) then
-- save next word from fifo
NextR.Word <= iReadWriteFifo.q;
end if;
end if;
else
NextR.Counter.Byte <= R.Counter.Byte + 1;
end if;
else
NextR.Counter.BitC <= R.Counter.BitC - BitDec;
NextR.Counter <= R.Counter - BitDec;
end if;
 
if (send = true) then
if ((R.Counter.BitC = BitEnd + BitDec and R.Counter.Byte = 3 and R.Counter.Word < 127)) then
if ((RBitC = BitEnd + BitDec and RByteC = 3 and RWordC < 127)) then
-- request next word from fifo
if (iReadWriteFifo.rdempty = cActivated) then
-- handle rdempty: Disable SdClk until data is available
report "No data available, fifo empty, waiting for new data" severity note;
HandleFifoAccess(iReadWriteFifo.rdempty, NextR.ReadWriteFifo.rdreq);
 
NextR.DisableSdClk <= cActivated;
NextR.Counter.BitC <= R.Counter.BitC;
 
else
-- request new data from fifo
NextR.DisableSdClk <= cInactivated;
NextR.ReadWriteFifo.rdreq <= cActivated;
end if;
end if;
else
if (R.Counter.Byte = 0 and R.Counter.BitC = 7 and R.WordInvalid = cInactivated) then
if (RByteC = 0 and RBitC = 7 and R.WordInvalid = cInactivated) then
-- save word to ram
-- TODO: handle write full
NextR.WriteReadFifo.wrreq <= cActivated;
NextR.WriteReadFifo.data <= R.Word;
NextR.WriteReadFifo.data <= R.Word;
HandleFifoAccess(iWriteReadFifo.wrfull, NextR.WriteReadFifo.wrreq);
end if;
end if;
end procedure CalcNextAndHandleData;
220,13 → 204,14
--------------------------------------------------------------------------------
-- Calculate the bit address in widewidth mode
--------------------------------------------------------------------------------
function IsBitAddrInRangeWideWidth (constant addr : in natural; constant C : in aCounters; constant mode : aSdDataBusMode) return boolean is
impure
function IsBitAddrInRangeWideWidth (constant addr : in natural) return boolean is
variable curHighAddr : integer;
begin
-- calculate current address (of the high bit in case of wide mode)
curHighAddr := (127 - to_integer(C.Word)) * 32 + (3 - to_integer(C.Byte)) * 8 + to_integer(C.BitC);
curHighAddr := (127 - to_integer(RWordC)) * 32 + (3 - to_integer(RByteC)) * 8 + to_integer(RBitC);
 
if (mode = standard) then
if (R.Mode = standard) then
return curHighAddr = addr;
else
return curHighAddr >= addr and curHighAddr - 3 <= addr;
272,219 → 257,198
 
-- start receiving
 
NextR.Region <= data;
NextR.State <= receive;
NextR.Counter.BitC <= to_unsigned(7,aBitCCounter'length);
NextR.Counter.Byte <= to_unsigned(0, aByteCounter'length);
NextR.WordInvalid <= cActivated;
NextR.Region <= data;
NextR.State <= receive;
NextR.Counter <= to_unsigned(7,aCounter'length);
NextR.WordInvalid <= cActivated;
 
-- which response is expected?
if (iSdDataFromController.DataMode = widewidth) then
if (iSdDataFromController.ExpectBits = ScrBits) then
NextR.Counter.Word <= to_unsigned(cScrBitsCount, aWordCounter'length);
NextR.Counter <= to_unsigned(cScrBitsCount, aCounter'length);
elsif (iSdDataFromController.ExpectBits = SwitchFunctionBits) then
NextR.Counter.Word <= to_unsigned(cSwitchFunctionBitsCount, aWordCounter'length);
NextR.Counter <= to_unsigned(cSwitchFunctionBitsCount, aCounter'length);
end if;
else
NextR.Counter.Word <= to_unsigned(0, aWordCounter'length);
end if;
 
elsif (iSdDataFromController.Valid = cActivated) then
elsif (iSdDataFromController.Valid = cActivated) then
 
case iReadWriteFifo.rdempty is
when cActivated =>
report "Fifo empty, waiting for data" severity note;
NextR.DisableSdClk <= cActivated;
case iReadWriteFifo.rdempty is
when cActivated =>
report "Fifo empty, waiting for data" severity note;
NextR.DisableSdClk <= cActivated;
 
when cInactivated =>
when cInactivated =>
-- start sending
NextR.State <= send;
NextR.Region <= startbit;
NextR.ReadWriteFifo.rdreq <= cActivated;
NextR.DisableSdClk <= cInactivated;
NextR.Counter.BitC <= to_unsigned(7, aBitCCounter'length);
NextR.Counter.Byte <= to_unsigned(0, aByteCounter'length);
NextR.Counter.Word <= to_unsigned(0, aWordCounter'length);
 
when others =>
report "rdempty invalid" severity error;
end case;
else
NextR.State <= send;
NextR.Region <= startbit;
NextR.ReadWriteFifo.rdreq <= cActivated;
NextR.DisableSdClk <= cInactivated;
NextR.Counter <= to_unsigned(7, aCounter'length);
 
when others =>
report "rdempty invalid" severity error;
end case;
else
-- switch between standard and wide mode
NextR.Mode <= iSdDataFromController.Mode;
end if;
NextR.Mode <= iSdDataFromController.Mode;
end if;
 
when send =>
when send =>
 
-- Handle the data enable signal
case R.Mode is
when wide =>
NextR.Data.En <= (others => cActivated);
-- Handle the data enable signal
case R.Mode is
when wide =>
NextR.Data.En <= (others => cActivated);
 
when standard =>
NextR.Data.En <= "0001";
when standard =>
NextR.Data.En <= "0001";
 
when others =>
report "Invalid mode" severity error;
NextR.Data.En <= (others => 'X');
end case;
when others =>
report "Invalid SDData mode" severity error;
NextR.Data.En <= (others => 'X');
end case;
 
case R.Region is
when startbit =>
SendBitsAndShiftIntoCrc(cSdStartBits);
NextR.Region <= data;
case R.Region is
when startbit =>
SendBitsAndShiftIntoCrc(cSdStartBits);
NextR.Region <= data;
 
-- save data from fifo
NextR.Word <= iReadWriteFifo.q;
-- save data from fifo
NextR.Word <= iReadWriteFifo.q;
 
when data =>
case R.Mode is
when wide =>
for i in 0 to 3 loop
temp(i) := R.Word(CalcBitAddrInWord(R.Counter.Byte, R.Counter.BitC - i));
end loop;
when standard =>
temp := "111" & R.Word(CalcBitAddrInWord(R.Counter.Byte, R.Counter.BitC));
when data =>
case R.Mode is
when wide =>
for i in 0 to 3 loop
temp(i) := R.Word(to_integer(R.Counter(4 downto 0)) - i);
end loop;
 
when others =>
temp := "XXXX";
report "Invalid SdData mode!" severity error;
end case;
SendBitsAndShiftIntoCrc(temp);
CalcNextAndHandleData(true);
when standard =>
temp := "---" & R.Word(to_integer(R.Counter(4 downto 0)));
 
when crc =>
NextR.Data.Data <= CrcIn.Serial;
when others =>
temp := "XXXX";
end case;
 
if (R.Counter.Word = 15) then
SendBitsAndShiftIntoCrc(temp);
CalcNextAndHandleData(true);
 
when crc =>
NextR.Data.Data <= CrcIn.Serial;
 
if (R.Counter = 15) then
-- all crc bits sent
NextR.Counter.Word <= to_unsigned(0, aWordCounter'length);
NextR.Region <= endbit;
NextR.Controller.Ack <= cActivated;
NextR.Counter <= to_unsigned(0, aCounter'length);
NextR.Region <= endbit;
NextR.Controller.Ack <= cActivated;
 
else
NextR.Counter.Word <= R.Counter.Word + 1;
end if;
else
NextR.Counter <= R.Counter + 1;
end if;
 
when endbit =>
NextR.Data.Data <= cSdEndBits;
NextR.State <= idle;
when endbit =>
NextR.Data.Data <= cSdEndBits;
NextR.State <= idle;
 
when others =>
report "Region not handled" severity error;
end case;
when others =>
report "Region not handled" severity error;
end case;
 
when receive =>
case R.Region is
when data =>
-- save received data to temporary word register
case R.Mode is
when standard =>
NextR.Word(CalcBitAddrInWord(R.Counter.Byte, R.Counter.BitC)) <= iData.Data(0);
when receive =>
case R.Region is
when data =>
-- save received data to temporary word register
case R.Mode is
when standard =>
NextR.Word(to_integer(R.Counter(4 downto 0))) <= iData.Data(0);
 
when wide =>
for idx in 0 to 3 loop
NextR.Word(CalcBitAddrInWord(R.Counter.Byte, R.Counter.BitC - idx)) <= iData.Data(3 - idx);
end loop;
when wide =>
for i in 0 to 3 loop
NextR.Word(to_integer(R.Counter(4 downto 0)) - i) <= iData.Data(3 - i);
end loop;
 
when others =>
report "Unhandled mode" severity error;
end case;
when others =>
report "Unhandled mode" severity error;
end case;
 
ShiftIntoCrc(std_ulogic_vector(iData.Data));
CalcNextAndHandleData(false);
ShiftIntoCrc(std_ulogic_vector(iData.Data));
CalcNextAndHandleData(false);
 
-- check responses
if (iSdDataFromController.DataMode = widewidth) then
if (iSdDataFromController.ExpectBits = ScrBits) then
if (IsBitAddrInRangeWideWidth(cWideModeBitAddr, R.Counter, R.Mode)) then
NextR.Controller.WideMode <= GetBitFromData(cWideModeBitAddr);
if (iSdDataFromController.DataMode = widewidth) then
if (iSdDataFromController.ExpectBits = ScrBits) then
if (IsBitAddrInRangeWideWidth(cWideModeBitAddr)) then
NextR.Controller.WideMode <= GetBitFromData(cWideModeBitAddr);
end if;
end if;
end if;
 
if (iSdDataFromController.ExpectBits = SwitchFunctionBits) then
if (IsBitAddrInRangeWideWidth(cHighSpeedBitAddr, R.Counter, R.Mode)) then
NextR.Controller.SpeedBits.HighSpeedSupported <= GetBitFromData(cHighSpeedBitAddr);
elsif (IsBitAddrInRangeWideWidth(cSwitchFunctionBitLowAddr, R.Counter, R.Mode)) then
NextR.Controller.SpeedBits.SwitchFunctionOK <= iData.Data;
if (iSdDataFromController.ExpectBits = SwitchFunctionBits) then
if (IsBitAddrInRangeWideWidth(cHighSpeedBitAddr)) then
NextR.Controller.SpeedBits.HighSpeedSupported <= GetBitFromData(cHighSpeedBitAddr);
elsif (IsBitAddrInRangeWideWidth(cSwitchFunctionBitLowAddr)) then
NextR.Controller.SpeedBits.SwitchFunctionOK <= iData.Data;
end if;
end if;
end if;
end if;
 
when crc =>
if iSdDataFromController.DataMode = usual then
-- save last word to ram
-- TODO: handle full fifo
NextR.WriteReadFifo.wrreq <= cActivated;
NextR.WriteReadFifo.data <= R.Word;
end if;
when crc =>
-- save last word to ram
HandleFifoAccess(iWriteReadFifo.wrfull, NextR.WriteReadFifo.wrreq);
NextR.WriteReadFifo.data <= R.Word;
 
-- shift received crc into crc
case R.Mode is
when standard =>
ShiftIntoCrc("000" & iData.Data(0));
ShiftIntoCrc(std_ulogic_vector(iData.Data));
 
when wide =>
ShiftIntoCrc(std_ulogic_vector(iData.Data));
 
when others =>
report "Unhandled mode" severity error;
end case;
 
if (R.Counter.Word = 15) then
if (R.Counter = 15) then
-- all 16 crc bits received
NextR.Region <= endbit;
else
NextR.Counter.Word <= R.Counter.Word + 1;
end if;
NextR.Region <= endbit;
else
NextR.Counter <= R.Counter + 1;
end if;
 
when endbit =>
if (CrcIn.Correct = "1111" and R.Mode = wide) or
(CrcIn.Correct(0) = cActivated and R.Mode = standard) then
NextR.Controller.Valid <= cActivated;
when endbit =>
-- in standard mode all unused crcs have to be correct, because no data was shifted in
if (CrcIn.Correct = "1111") then
NextR.Controller.Valid <= cActivated;
else
NextR.Controller.Err <= cActivated;
end if;
 
else
-- CRC error
report "CRC error occurred" severity note;
NextR.Controller.Err <= cActivated;
end if;
NextR.Region <= startbit;
NextR.State <= idle;
 
NextR.Region <= startbit;
NextR.State <= idle;
when others =>
report "Region not handled" severity error;
end case;
 
when others =>
report "Region not handled" severity error;
end case;
when others =>
report "State not handled" severity error;
end case;
 
when others =>
report "State not handled" severity error;
end case;
end process Comb;
 
end process Comb;
CrcDataIn <= (others => CrcOut.DataIn) when R.Mode = wide else
"000" & CrcOut.DataIn;
 
CrcDataIn <= (others => CrcOut.DataIn) when R.Mode = wide else
"000" & CrcOut.DataIn;
crcs: for idx in 3 downto 0 generate
 
crcs: for idx in 3 downto 0 generate
CRC_inst : entity work.Crc
generic map (
gPolynom => crc16
)
port map (
iClk => iClk,
inResetAsync => inResetAsync,
iStrobe => iStrobe,
iClear => CrcOut.Clear,
iDataIn => CrcDataIn(idx),
iData => CrcOut.Data(idx),
oIsCorrect => CrcIn.Correct(idx),
oSerial => CrcIn.Serial(idx)
);
 
CRC_inst : entity work.Crc
generic map (
gPolynom => crc16
)
port map (
iClk => iClk,
inResetAsync => inResetAsync,
iStrobe => iStrobe,
iClear => CrcOut.Clear,
iDataIn => CrcDataIn(idx),
iData => CrcOut.Data(idx),
oIsCorrect => CrcIn.Correct(idx),
oSerial => CrcIn.Serial(idx)
);
end generate crcs;
 
end generate crcs;
 
end architecture Rtl;
 
/sdhc-sc-core/trunk/src/grpSd/pkgSd/src/Sd-p.vhdl
118,8 → 118,8
type aSdDataMode is (usual, widewidth);
type aSdDataBits is (ScrBits, SwitchFunctionBits);
constant cScrBitsCount : natural := 127 - (64/32 - 1); -- expressed in words
constant cSwitchFunctionBitsCount : natural := 127 - (512/32 - 1); -- expressed in words
constant cScrBitsCount : natural := 4096 - 64 + 7; -- expressed in bits
constant cSwitchFunctionBitsCount : natural := 4096 - 512 + 7; -- expressed in bits
constant cWideModeBitAddr : natural := 50;
constant cHighSpeedBitAddr : natural := 401;
constant cSwitchFunctionBitLowAddr : natural := 376;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.