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 56 to Rev 57
- ↔ Reverse comparison
Rev 56 → Rev 57
/sdhc-sc-core/trunk/src/grpSd/unitSdCardModel/src/SdCardModel.sv
22,13 → 22,54
cSdCmdSendCSD = 9, // [31:16] RCA |
cSdCmdSendCID = 10, // [31:16] RCA |
cSdCmdStopTrans = 12, |
cSdCmdSendStatus = 13 // [31:16] RCA |
cSdCmdSendStatus = 13, // [31:16] RCA |
cSdCmdNextIsACMD = 55 // [31:16] RCA |
} SDCommandId; |
|
typedef enum { |
idle |
} SDCardState; |
cSdCmdACMD41 = 41 |
} SDAppCommandId; |
|
const SDCommandArg cSdArgACMD41HCS = 'b01000000111111111000000000000000; |
|
typedef enum { |
idle = 0, ready = 1, ident = 2, stby = 3, trans = 4, |
data = 5, rcv = 6, prg = 7, dis = 8 |
} SDCardStates; |
|
class SDCardState; |
local logic OutOfRange; |
local logic AddressError; |
local logic BlockLenError; |
|
local logic[3:0] state; |
|
local logic AppCmd; |
|
function new(); |
OutOfRange = 0; |
AddressError = 0; |
BlockLenError = 0; |
state = idle; |
AppCmd = 0; |
endfunction |
|
function void recvCMD55(); |
AppCmd = 1; |
endfunction |
|
function automatic SDCommandArg get(); |
SDCommandArg temp = 0; |
temp[31] = OutOfRange; |
temp[30] = AddressError; |
temp[29] = BlockLenError; |
temp[12:9] = state; |
temp[5] = AppCmd; |
return temp; |
endfunction |
|
endclass |
|
class SDCommandToken; |
logic startbit; |
logic transbit; |
158,6 → 199,18
|
endclass |
|
class SDCommandR1 extends SDCommandResponse; |
|
function new(SDCommandId id, SDCardState state); |
startbit = 0; |
transbit = 0; |
this.id = id; |
this.arg = state.get(); |
endbit = 1; |
endfunction |
|
endclass |
|
class SDCard; |
local virtual ISdCmd.Card ICmd; |
|
168,13 → 221,12
|
function new(virtual ISdCmd CmdInterface, event CmdReceived, event InitDone); |
ICmd = CmdInterface; |
state = idle; |
state = new(); |
this.CmdReceived = CmdReceived; |
this.InitDone = InitDone; |
endfunction |
|
task reset(); |
state = idle; |
endtask |
|
// Receive a command token and handle it |
218,7 → 270,7
|
task automatic init(); |
SDCommandR7 voltageresponse; |
SDCommandResponse response; |
SDCommandR1 response; |
|
// expect CMD0 so that state is clear |
recv(); |
232,9 → 284,23
// respond with R7: we are SD 2.00 compatible and compatible to the |
// voltage |
voltageresponse = new(recvcmd.arg); |
response = voltageresponse; |
response.send(ICmd); |
voltageresponse.send(ICmd); |
|
// expect CMD55 with default RCA |
recv(); |
assert(recvcmd.id == cSdCmdNextIsACMD); |
assert(recvcmd.arg == 0); |
state.recvCMD55(); |
|
// respond with R1 |
response = new(cSdCmdNextIsACMD, state); |
response.send(ICmd); |
|
// expect ACMD41 with HCS = 1 |
recv(); |
assert(recvcmd.id == cSdCmdACMD41); |
assert(recvcmd.arg == cSdArgACMD41HCS); |
|
-> InitDone; |
|
endtask |
/sdhc-sc-core/trunk/src/grpSd/pkgSd/src/Sd-p.vhdl
46,11 → 46,17
Ack : std_ulogic; -- Gets asserted when crc was sent, but endbit was |
-- not. This way we can minimize the wait time between sending 2 cmds. |
Receiving : std_ulogic; |
CmdContent : aSdCmdContent; |
Content : aSdCmdContent; |
Valid : std_ulogic; -- gets asserted when CmdContent is valid (therefore |
-- a cmd was received) |
Err : std_ulogic; -- gets asserted when an error occurred during |
-- receiving a cmd |
end record aSdCmdToController; |
|
-- constants for Controller |
subtype aRCA is std_ulogic_vector(15 downto 0); |
constant cSdDefaultRCA : aRCA := (others => '0'); |
|
-- command ids |
-- abbreviations: |
-- RCA: relative card address |
97,5 → 103,14
constant cSdCmdSendStatus : aSdCmdId := std_ulogic_vector(to_unsigned(13, |
cSdCmdIdHigh)); -- [31:16] RCA |
|
constant cSdNextIsACMD : aSdCmdId := std_ulogic_vector(to_unsigned(55, |
cSdCmdIdHigh)); |
constant cSdACMDArg : aSdCmdArg := cSdDefaultRCA & X"0000"; -- [31:16] RCA |
constant cSdArgAppCmdPos : natural := 5; |
|
constant cSdCmdACMD41 : aSdCmdId := std_ulogic_vector(to_unsigned(41, cSdCmdIdHigh)); |
constant cVoltageWindow : std_ulogic_vector(23 downto 0) := |
"111111111000000000000000"; |
|
end package Sd; |
|
/sdhc-sc-core/trunk/src/grpSd/unitSdCmd/src/SdCmd-Rtl-ea.vhdl
51,7 → 51,8
|
constant cDefaultOut : aSdCmdOut := ((cInactivated, cInactivated,cInactivated), |
(Ack => cInactivated, Receiving => cInactivated, Valid => cInactivated, |
CmdContent => (id => (others => '0'), arg => (others => '0'))), 'Z'); |
Content => (id => (others => '0'), arg => (others => '0')), Err => |
cInactivated), 'Z'); |
|
signal ReceivedToken, NextReceivedToken : aSdCmdToken; |
|
115,7 → 116,7
NextCounter <= Counter; |
NextReceivedToken <= ReceivedToken; |
Output <= cDefaultOut; |
Output.Controller.CmdContent <= ReceivedToken.content; |
Output.Controller.Content <= ReceivedToken.content; |
|
case State is |
when idle => |
192,8 → 193,10
NextReceivedToken.endbit <= ioCmd; |
|
-- check |
if (CrcCorrect = cActivated) then |
if (CrcCorrect = cActivated and ReceivedToken.transbit = cSdTransBitSlave) then |
Output.Controller.Valid <= cActivated; |
else |
Output.Controller.Err <= cActivated; |
end if; |
NextState <= idle; |
|
/sdhc-sc-core/trunk/src/grpSd/unitSdController/src/SdController-Rtl-ea.vhdl
25,11 → 25,22
|
architecture Rtl of SdController is |
|
type aSdControllerState is (CMD0, CMD8Ws, CMD8, CMD8Response, idle); |
type aSdControllerState is (CMD0, CMD8Ws, CMD8, CMD8Response, CMD55, |
CMD55Response, ACMD41, ACMD41Response, idle, |
invalidCard); |
constant cDefaultControllerState : aSdControllerState := CMD0; |
constant cDefaultoSdCmd : aSdCmdFromController := ((id => (others => '0'), |
arg => (others => '0')), Valid => cInactivated); |
|
type aSdControllerReg is record |
HCS : std_ulogic; |
CCS : std_ulogic; |
end record aSdControllerReg; |
constant cDefaultSdControllerReg : aSdControllerReg := (cActivated, |
cInactivated); |
|
signal Reg, NextReg : aSdControllerReg; |
|
signal State, NextState : aSdControllerState; |
|
begin |
38,15 → 49,18
begin |
if (inResetAsync = cnActivated) then |
State <= cDefaultControllerState; |
Reg <= cDefaultSdControllerReg; |
elsif (iClk'event and iClk = cActivated) then |
Reg <= NextReg; |
State <= NextState; |
end if; |
end process Regs; |
|
Comb : process (iSdCmd, State) |
Comb : process (iSdCmd, State, Reg) |
begin |
-- default assignments |
oSdCmd <= cDefaultoSdCmd; |
NextReg <= Reg; |
|
case State is |
when idle => null; |
70,10 → 84,56
if (iSdCmd.Ack = cActivated) then |
NextState <= CMD8Response; |
end if; |
|
|
when CMD8Response => |
if (iSdCmd.Valid = cActivated) then |
if (iSdCmd.Content.id = cSdCmdSendIfCond and |
iSdCmd.Content.arg = cSdArgVoltage) then |
NextReg.HCS <= cActivated; |
NextState <= CMD55; |
else |
NextState <= invalidCard; |
end if; |
-- elsif timeout |
end if; |
|
when invalidCard => |
null; |
|
when CMD55 => |
oSdCmd.Content.id <= cSdNextIsACMD; |
oSdCmd.Content.arg <= cSdACMDArg; |
oSdCmd.Valid <= cActivated; |
if (iSdCmd.Ack = cActivated) then |
NextState <= CMD55Response; |
end if; |
|
when CMD55Response => |
if (iSdCmd.Valid = cActivated) then |
NextState <= invalidCard; |
if (iSdCmd.Content.id = cSdNextIsACMD) then |
if (iSdCmd.Content.arg(cSdArgAppCmdPos) = cActivated) |
then |
NextState <= ACMD41; |
end if; |
end if; |
-- elsif timeout |
end if; |
|
when ACMD41 => |
oSdCmd.Content.id <= cSdCmdACMD41; |
oSdCmd.Content.arg(31) <= '0'; |
oSdCmd.Content.arg(30) <= Reg.HCS; |
oSdCmd.Content.arg(29 downto 24) <= (others => '0'); |
oSdCmd.Content.arg(23 downto 0) <= cVoltageWindow; |
oSdCmd.Valid <= cActivated; |
if (iSdCmd.Ack = cActivated) then |
NextState <= ACMD41Response; |
end if; |
|
when ACMD41Response => |
null; -- TODO |
|
when others => |
report "SdController: State not handled" severity error; |
end case; |