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; |