⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pctosraminterface-sv06.vhd

📁 vhdl code for GIF Image Viewer
💻 VHD
📖 第 1 页 / 共 2 页
字号:
					elsif syncWrite = '0' and syncRead = '0' then
						nextState <= stGetSettings1;
					end if;
				end if;
				
				stateOutput <= "0001";

			when stGetAddr1 =>
				nextState <= stGetAddr1;

				case inSliceNum is
					when "00" =>
					when "01" =>
						-- syncNextSlice should be high.
						-- We wait for syncNextSlice to go low:
						if syncNextSlice = '0' then
							-- Read the next address slice and
							-- increment the input slice number:
							regCurAddr <= '1';
							incInSliceNum <= '1';
						end if;
					when "10" =>
						-- syncNextSlice should be low.
						-- We wait for syncNextSlice to go high:
						if syncNextSlice = '1' then
							regCurAddr <= '1';
							incInSliceNum <= '1';
						end if;						
					when others =>
						-- inSliceNum should be "11" here.
						-- syncNextSlice should be high.
						-- We wait for syncNextSlice to go low:

						-- We are waiting for the final slice:
						if (syncNextSlice = '0' and syncWrite = '0' and
							syncRead = '0') then
							-- After this we are done setting
							-- the address.
							nextState <= stIdle;

							regCurAddr <= '1';
							clearInSliceNum <= '1';
						end if;						
				end case;
				
				-- The only exception to the above is that if
				-- syncWrite or syncRead have been prematurely changed
				-- then we abort the current operation.
				if inSliceNum /= "11" and
				   (syncWrite = '0'or syncRead = '0') then
				    nextState <= stIdle;
				    clearInSliceNum <= '1';
				end if;

			when stDoWrite1 =>
				nextState <= stDoWrite1;
				
				case inSliceNum is
					when "00" =>
					when "01" =>
						-- syncNextSlice should be high.
						-- We wait for syncNextSlice to go low:
						if syncNextSlice = '0' then
							-- Read the next write data slice and
							-- increment the input slice number:
							regWriteData <= '1';
							incInSliceNum <= '1';
						end if;
					when "10" =>
						-- syncNextSlice should be low.
						-- We wait for syncNextSlice to go high:
						if syncNextSlice = '1' then
							regWriteData <= '1';
							incInSliceNum <= '1';
						end if;						
					when others =>
						-- inSliceNum should be "11" here.
						-- syncNextSlice should be high.
						-- We wait for syncNextSlice to go low:

						-- We are waiting for the final slice:
						if (syncNextSlice = '0' and syncWrite = '0') then
							-- We are reading the final slice,
							-- so after this we actually perform
							-- the write to SRAM:
							nextState <= stDoWrite2;

							regWriteData <= '1';
							clearInSliceNum <= '1';
						end if;						
				end case;
				
				-- The only exception to the above is that if
				-- syncWrite has been prematurely changed
				-- then we abort the current operation.
				if (inSliceNum /= "11" and syncWrite = '0') then
				    nextState <= stIdle;
				    clearInSliceNum <= '1';
				end if;

			when stDoWrite2 =>
				nextState <= stDoWrite2;
				
				-- Wait to request the actual write to SRAM:
				if canWrite = '1' then
					-- The write will take place in subsequent
					-- clock cycle(s). We don't need to wait for
					-- the write to finish, since this FSM runs
					-- much faster than the rate at which the PC
					-- can control the parallel port.
					nextState <= stIdle;
					doSRAMWrite <= '1';					

					-- Auto-increment the current address:
					incCurAddr <= '1';
				end if;

			when stDoRead1 =>
				nextState <= stDoRead1;

				-- Wait to request the actual read from SRAM:
				if canRead = '1' then
					nextState <= stDoRead2;
					doSRAMRead <= '1';
				end if;

			when stDoRead2 =>
				nextState <= stDoRead2;
				
				-- Wait for the read to complete:
				if canRead = '1' then
					nextState <= stDoRead3;
					
					-- readData will be valid at the end of this
					-- clock cycle, so we register it at that point:	
					regReadData <= '1';
					
					-- Clear outSliceNum so that the first slice
					-- we output for the PC will be slice 0.
					clearOutSliceNum <= '1';
				end if;								
				
			when stDoRead3 =>
				nextState <= stDoRead3;

				case outSliceNum is
					when "00" =>
						-- syncNextSlice should be high.
						-- We wait for syncNextSlice to go low:
						if syncNextSlice = '0' then
							-- Increment the output slice number
							-- to output the next read data slice
							-- to the PC:
							incOutSliceNum <= '1';
						end if;
					when "01" =>
						-- syncNextSlice should be low.
						-- We wait for syncNextSlice to go high:
						if syncNextSlice = '1' then
							incOutSliceNum <= '1';
						end if;						
					when "10" =>
						-- syncNextSlice should be high.
						-- We wait for syncNextSlice to go low:

						-- We are waiting to output the final slice:
						if (syncNextSlice = '0' and syncRead = '0') then
							-- After this we have finished
							-- performing the read:
							nextState <= stIdle;

							-- Auto-increment the current address:
							incCurAddr <= '1';

							-- Increment the output slice number
							-- to output the final read data slice
							-- to the PC:
							incOutSliceNum <= '1';
						end if;
					when others =>				
				end case;
				
				-- The only exception to the above is that if
				-- syncRead has been prematurely changed
				-- then we abort the current operation.
				-- Note that for reads, outSliceNum is compared
				-- with the value "10" in the line below, rather
				-- than "11" that we compare inSliceNum with
				-- when doing address setting and writes.
				if (outSliceNum /= "10" and syncRead = '0') then
				    nextState <= stIdle;
				end if;
							
			when stGetSettings1 =>
				nextState <= stGetSettings1;
				
				if (syncNextSlice = '0' and syncWrite = '0'
					and syncRead = '0') then
					nextState <= stGetSettings2;
				elsif not (syncNextSlice = '1' and syncWrite = '0'
					   and syncRead = '0') then
					nextState <= stIdle;
				end if;

-- Debug:
				stateOutput <= "1000";	
						
			when stGetSettings2 =>
				nextState <= stGetSettings2;
				
				if (syncNextSlice = '0' and syncWrite = '1'
					and syncRead = '0') then
					nextState <= stGetSettings3;
				elsif not (syncNextSlice = '0' and syncWrite = '0'
						and syncRead = '0') then
					nextState <= stIdle;
				end if;

				stateOutput <= "1001";	

			when stGetSettings3 =>
				nextState <= stGetSettings3;
				
				if (syncNextSlice = '0' and syncWrite = '0'
					and syncRead = '0') then
					nextState <= stIdle;
					
					getSettings <= '1';
				Elsif not (syncNextSlice = '0' and syncWrite = '1'
						and syncRead = '0') then
					nextState <= stIdle;
				End if;

				stateOutput <= "1010";	

				
			when others =>
				nextState <= stIdle;
				clearInSliceNum <= '1';
		end case;		
	end process;

end pctosraminterface_arch;



-------------------------------------------------------------------------------
-- History of major changes
-------------------------------------------------------------------------------
-- (15/02/2001) The VHDL for buffering the control signals has been
-- simplified. Additionally, we also buffer the value of DataIn. We only
-- change the value we are using for DataIn or the control signals when
-- EVERY level of flip-flops is holding the same set of values. This is just
-- a minor change to help ensure that any skew that the incoming signals
-- have relative to other incoming signals is removed. This change does
-- NOT affect the protocol between the PC and the board.
-- There are now only 4 levels of flip-flops instead of 5, to reduce the
-- amount of comparison logic needed.
-- (15/02/2001) pctosraminterface-sv06.vhd created from sv05.
-- (14/02/2001) The protocol for setting the address, writing a data value and
-- updating settings has now been changed. Instead of sending slice 0 of the
-- address or write data *before* we assert the control signals for the first
-- time, slice 0 of the address or write data must now be sent at the 
-- *same time* as the control signals are first asserted. Overall this means
-- that we have shifted the timing of when each slice is sent to later in
-- time. Similarly, the protocol for updating settings has changed. You must
-- now do the following: set NextSlice to 1, set NextSlice to 0, set Write
-- to 1, set Write to 0 *and at the same time* place the new settings on
-- DataIn.
-- All this has been done so that we no longer have to remember the "old"
-- value of DataIn like we used to previously. The fact that we now buffer the
-- control signals through several levels of flip-flops meant that it was
-- becoming more awkward to remember the "old" value of DataIn. We now have no
-- need to remember the "old" value of DataIn.
-- (14/02/2001) pctosraminterface-sv05.vhd created from sv04.
-- (13/02/2001) We now buffer the control signals through 5 levels of
-- flip-flops.
-- (06/02/2001) The bug that caused the interface to incorrectly update its
-- settings has now been fixed. The protocol to update settings was made
-- to be more different from the protocols for reading and writing. This fixed
-- the problem.
-- (03/02/2001) pctosraminterface-sv04.vhd created from sv03.
-- (03/02/2001) Known bug: Occasionally the interface will incorrectly try
-- to update its settings. This probably means that the interface is not
-- robust enough when it comes to handling unexpected glitches in the
-- incoming control signals.
-- (29/01/2001) The sraminterface version
-- sram512kleft16bit50mhzreadreq-sv02.vhd has reverted to NOT registering
-- the read data internally. Therefore we must once again register the read
-- data ourselves. We know that when canRead goes high at the end of a read
-- then the read data will be valid at the end of the same clock cycle. It is
-- at that point (at the end of the cycle in which canRead returns to high)
-- that we register the read data.
-- (24/01/2001) Updated to use the sraminterfaces that need read requests.
-- Previously the sraminterface was always reading when it wasn't writing.
-- But versions of the file including the letters "readreq", such as
-- "sram512kleft16bit50mhzreadreq-sv01b.vhd" require a read request to
-- be made for a read to occur. The request is made by setting doRead high.
-- We also now use the canRead and canWrite signals to determine when a read
-- or write has completed. canRead and canWrite go high when new read and write
-- requests respectively can be made (and thus indicating that the current
-- read or write will be finished by the end of the clock cycle in which
-- canRead or canWrite goes high).
-- Also, although we no longer need to register readData (as the new
-- sraminterface registers it itself internally), we register it ourselves
-- anyway. See the comments in code.
-- (24/01/2001) pctosraminterface-sv03.vhd created from sv02.
-- The concept of "settings" has been introduced. See the comments in the
-- code.
-- (22/01/2001) DataIn now passes through 5 registers before its value is
-- used, rather than 6 as before. This is just to try and save a couple
-- of flip flops. It's probably an unnecessary  and insignificant change.
-- (22/01/2001) Current address now increments by one after a write or a read.
-- This is designed to make bulk writes or reads to SRAM faster, since when
-- consecutive memory locations need to be accessed, the current address only
-- has to set once, at the start. It will then automatically increment after a
-- read or a write. If the PC programme does not want to access the next
-- consecutive location, it has to specifically set the current address.
-- (19/01/2001) Asynchronous control signals (Write, Read, NextSlice) are
-- now synchronised (i.e. put through flip-flops) before being read or used
-- in any way. Before this, the state-machine would often enter an unknown
-- state.
-- (18/01/2001) pctosraminterface-sv02.vhd created from
-- pctosraminterface-sv01.vhd. We stop looking for transitions of NextSlice 
-- and look for the specific correct value. This is being done because in
-- testing it seemed that we sometimes missed transitions in NextSlice, which
-- really messes up the protocol. Now, if we don't see a change in NextSlice
-- during one clock cycle, we will see it in the next, or maybe even the one
-- after that. As long as we see it before the PC changes NextSlice again we
-- will be fine.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -