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

Subversion Repositories sdhc-sc-core

[/] [sdhc-sc-core/] [trunk/] [grpSd/] [unitSdWbSlave/] [src/] [SdWbSlave-Rtl-a.vhdl] - Rev 185

Compare with Previous | Blame | View Log

-- SDHC-SC-Core
-- Secure Digital High Capacity Self Configuring Core
-- 
-- (C) Copyright 2010, Rainer Kastl
-- All rights reserved.
-- 
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
--     * Redistributions of source code must retain the above copyright
--       notice, this list of conditions and the following disclaimer.
--     * Redistributions in binary form must reproduce the above copyright
--       notice, this list of conditions and the following disclaimer in the
--       documentation and/or other materials provided with the distribution.
--     * Neither the name of the <organization> nor the
--       names of its contributors may be used to endorse or promote products
--       derived from this software without specific prior written permission.
-- 
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  "AS IS" AND
-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- 
-- File        : SdWbSlave-Rtl-a.vhdl
-- Owner       : Rainer Kastl
-- Description : Wishbone interface of SDHC-SC-Core
-- Links       : 
-- 
 
architecture Rtl of SdWbSlave is
 
	type aWbState is (idle, ClassicWrite, ClassicRead);
	type aSdIntState is (idle, newOperation);
	type aReadBufferState is (invalid, readreq, latchdata, valid);
 
	type aRegs is record
 
		WbState             : aWbState; -- state of the wb interface
		SdIntState          : aSdIntState; -- state of the sd controller interface
		OperationBlock      : aOperationBlock; -- Operation for the SdController
		ReqOperation        : std_ulogic; -- Register for catching edges on the SdController ReqOperationEdge line
		ReadBuffer          : aData;
		ReadBufferState     : aReadBufferState;
		-- Register outputs
		oWbDat              : aSdWbSlaveDataOutput;
		oWbCtrl             : aWbSlaveCtrlOutput;
		oController         : aSdWbSlaveToSdController;
		oWriteFifo          : aoWriteFifo;
		oReadFifo 			: aoReadFifo;
 
	end record aRegs;
 
	constant cDefaultRegs : aRegs := (
	WbState                            => idle,
	SdIntState                         => idle,
	OperationBlock                     => cDefaultOperationBlock,
	ReqOperation                       => cInactivated,
	oWbDat                             => (Dat                             => (others => 'X')),
	oWbCtrl                            => cDefaultWbSlaveCtrlOutput,
	oController                        => cDefaultSdWbSlaveToSdController,
	oWriteFifo                         => cDefaultoWriteFifo,
	oReadFifo  					       => cDefaultoReadFifo,
	ReadBuffer                         => (others                          => '0'),
	ReadBufferState                    => invalid);
 
	signal R, NxR : aRegs;
 
begin
	oWbDat      <= R.oWbDat;
	oWbCtrl     <= R.oWbCtrl;
	oController <= R.oController;
	oWriteFifo  <= R.oWriteFifo;
	oReadFifo   <= R.oReadFifo;
 
	WbStateReg  : process (iClk, iRstSync)
	begin
		if (iClk'event and iClk = cActivated) then
			if (iRstSync = cActivated) then -- sync. reset
				R <= cDefaultRegs;
			else
				R <= NxR;
			end if;
		end if;
	end process WbStateReg ;
 
	WbStateAndOutputs : process (iWbCtrl, iWbDat, iController, iWriteFifo, iReadFifo, R)
	begin
		-- Default Assignments
 
		NxR             <= R;
		NxR.oWbDat.Dat  <= (others => 'X');
		NxR.oWbCtrl     <= cDefaultWbSlaveCtrlOutput;
		NxR.oWriteFifo  <= cDefaultoWriteFifo;
 
		case R.ReadBufferState is
			when invalid => 
				-- is new data available?
				if (iReadFifo.rdempty = cInactivated) then
					NxR.oReadFifo.rdreq <= cActivated;
					NxR.ReadBufferState <= readreq;
				end if;
 
			when readreq => 
			-- readreq was sent, data is available next cycle
				NxR.oReadFifo.rdreq <= cInactivated;
				NxR.ReadBufferState <= latchdata;
 
			when latchdata => 
				NxR.ReadBuffer <= iReadFifo.q;
				NxR.ReadBufferState <= valid;
 
			when valid => 
			-- do nothing, wishbone statemachine sets the state to invalid when it used it
				null;
 
			when others => 
				report "Error: Invalid ReadBufferState" severity error;
		end case;
 
 
		-- Determine next state
		case R.WbState is
			when idle =>
				if iWbCtrl.Cyc = cActivated and iWbCtrl.Stb = cActivated then
 
					case iWbCtrl.Cti is
						when cCtiClassicCycle => 
							case iWbCtrl.We is
								when cInactivated => 
 
									-- perform a ClassicRead
									NxR.oWbCtrl.Ack <= cActivated;
									NxR.WbState     <= ClassicRead;
 
									if (iWbDat.Sel = "1") then
										case iWbDat.Adr is
											when cOperationAddr => 
												NxR.oWbDat.Dat <= R.OperationBlock.Operation;
 
											when cStartAddrAddr => 
												NxR.oWbDat.Dat <= R.OperationBlock.StartAddr;
 
											when cEndAddrAddr => 
												NxR.oWbDat.Dat <= R.OperationBlock.EndAddr;
 
											when cReadDataAddr => 
												-- check if data is available
												case R.ReadBufferState is
													when valid =>
														-- use buffered data
														NxR.oWbDat.Dat <= R.ReadBuffer;
														NxR.ReadBufferState <= invalid;
 
													when latchdata => 
														-- use input directly
														NxR.oWbDat.Dat <= iReadFifo.q;
														NxR.ReadBufferState <= invalid;
 
													when readreq => 
													-- no data available, insert a waitstate
														NxR.oWbCtrl.Ack <= cInactivated;
														NxR.WbState     <= idle;
 
													when invalid => 
													-- no data available, insert a waitstate
														NxR.oWbCtrl.Ack <= cInactivated;
														NxR.WbState     <= idle;
 
													when others => 
														report "Invalid ReadBufferState" severity error;
												end case;
 
											when others => 
												report "Read to an invalid address" severity warning;
												NxR.oWbCtrl.Err <= cActivated;
												NxR.oWbCtrl.Ack <= cInactivated;
										end case;
									end if;
 
								when cActivated => 
 
									--perform a ClassicWrite
									NxR.oWbCtrl.Ack <= cActivated;
									NxR.WbState     <= ClassicWrite;
 
									if (iWbDat.Sel = "1") then
										if (iWbDat.Adr = cOperationAddr or iWbDat.Adr = cStartAddrAddr or iWbDat.Adr = cEndAddrAddr) and 
										R.SdIntState = newOperation then
										-- insert waitstates until we can notify the SdController again
 
											NxR.oWbCtrl.Ack <= cInactivated;
											NxR.WbState     <= idle;
										end if;
 
										if (iWbDat.Adr = cWriteDataAddr and iWriteFifo.wrfull = cActivated) then
											NxR.oWbCtrl.Ack <= cInactivated;
											NxR.oWbCtrl.Err <= cActivated;
											NxR.WbState     <= idle;
										end if;
 
									end if;
 
								when others => 
									report "iWbCtrl.We is invalid" severity warning;
							end case;		
 
						when others => null;
					end case;
 
				end if;
 
			when ClassicRead => 
				NxR.WbState <= idle;
 
			when ClassicWrite => 
				NxR.WbState <= idle;
 
				if (iWbDat.Sel = "1") then
					case iWbDat.Adr is
						when cOperationAddr => 
 
							NxR.OperationBlock.Operation <= iWbDat.Dat;
							NxR.SdIntState               <= newOperation;
 
						when cStartAddrAddr => 
 
							NxR.OperationBlock.StartAddr <= iWbDat.Dat;
 
						when cEndAddrAddr => 
 
							NxR.OperationBlock.EndAddr <= iWbDat.Dat;
 
						when cWriteDataAddr => 
 
							NxR.oWriteFifo.data  <= iWbDat.Dat;
							NxR.oWriteFifo.wrreq <= cActivated;
 
						when others => 
							report "Write to an invalid address" severity warning;
							NxR.oWbCtrl.Err <= cActivated;
							NxR.oWbCtrl.Ack <= cInactivated;
					end case;
				end if;
 
 
			when others => 
				report "Invalid state" severity error;
		end case;
 
		-- send operations to SdController
		case R.SdIntState is
			when idle => 
				-- save edges on the ReqOperationEdge line which would be missed otherwise
 
				if (iController.ReqOperation = cActivated) then
 
					NxR.ReqOperation <= cActivated;
 
				end if;
 
			when newOperation => 
				-- send a new operation, when the controller requested it
				if (R.ReqOperation = cActivated or iController.ReqOperation = cActivated) then
 
					NxR.oController.OperationBlock <= R.OperationBlock;
					NxR.oController.AckOperation   <= not R.oController.AckOperation;
 
					-- go to idle state, the next request will come only after the SdController received this block
 
					NxR.ReqOperation <= cInactivated;
					NxR.SdIntState   <= idle;
 
				end if;
 
			when others => 
				report "Invalid state" severity error;
		end case;
 
	end process WbStateAndOutputs;
end architecture Rtl;
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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