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

📄 sdramcntl.vhd

📁 用FPGA来实现摄像头的捕捉和采集
💻 VHD
📖 第 1 页 / 共 2 页
字号:
		
		if refTimer_r /= TO_UNSIGNED(0,refTimer_r'length) then
			refTimer_next <= refTimer_r - 1;
		else
			-- on timeout, reload the timer with the interval between row refreshes
			-- and set the flag that indicates a refresh operation is needed.
			refTimer_next <= TO_UNSIGNED(REF_CYCLES,refTimer_next'length);
			doRfshFlag_next <= YES;
		end if;

		-- determine if another row or bank in the SDRAM is being addressed
		if row /= activeRow_r or bank /= activeBank_r or inactiveFlag_r = YES then
			changeRow <= YES;
		else
			changeRow <= NO;
		end if;
		
		-- ***** compute next state and outputs *****
		
		-- SDRAM initialization			
		if state_r = INITWAIT then
			-- initiate wait for SDRAM power-on initialization
--			timer_next <= TO_UNSIGNED(INIT_CYCLES,timer_next'length);	-- set timer for init interval
			cs_n <= HI;
			dqml <= HI;
			dqmh <= HI;
			initFlag_next <= YES;			-- indicate initialization is in progress
			if timer_r = TO_UNSIGNED(0,timer_r'length) then
				state_next <= INITPCHG;	-- precharge SDRAM after power-on initialization
			end if;
			sdramCntl_state <= "0001";

		-- don't do anything if the previous operation has not completed yet.
		-- Place this before anything else so operations in the previous state
		-- complete before any operations in the new state are executed.
		elsif timer_r /= TO_UNSIGNED(0,timer_r'length) then
			sdramCntl_state <= "0000";

		elsif state_r = INITPCHG then
			cmd <= PCHG_CMD;	-- initiate precharge of the SDRAM
			sAddr(ColCmdPos) <= ALL_BANKS;	-- precharge all banks
			timer_next <= TO_UNSIGNED(RP_CYCLES,timer_next'length);	-- set timer for this operation
			-- now setup the counter for the number of refresh ops needed during initialization
			rfshCntr_next <= TO_UNSIGNED(RfshCycles,rfshCntr_next'length);
			state_next <= INITRFSH;	-- perform refresh ops after setting the mode
			sdramCntl_state <= "0010";
		elsif state_r = INITRFSH then
			-- refresh the SDRAM a number of times during initialization
			if rfshCntr_r /= TO_UNSIGNED(0,rfshCntr_r'length) then
				-- do a refresh operation if the counter is not zero yet
				cmd <= RFSH_CMD;	-- refresh command goes to SDRAM
				timer_next <= TO_UNSIGNED(RFC_CYCLES,timer_next'length);	-- refresh operation interval
				rfshCntr_next <= rfshCntr_r - 1;	-- decrement refresh operation counter
				state_next <= INITRFSH;	-- return to this state while counter is non-zero
			else
				-- refresh op counter reaches zero, so set the operating mode of the SDRAM
				state_next <= INITSETMODE;
			end if;
			sdramCntl_state <= "0100";
		elsif state_r = INITSETMODE then
			-- set the mode register in the SDRAM
			cmd <= MODE_CMD;	-- initiate loading of mode register in the SDRAM
			sAddr <= MODE;		-- output mode register bits onto the SDRAM address bits
			timer_next <= TO_UNSIGNED(Cmrd,timer_next'length);	-- set timer for this operation
			state_next <= RW;	-- process read/write operations after initialization is done
			initFlag_next <= NO;	-- reset flag since initialization is done
			sdramCntl_state <= "0011";
			
		-- refresh a row of the SDRAM when the refresh timer hits zero and sets the flag
		-- and the SDRAM is no longer being initialized or read/written.
		-- Place this before the RW state so the host can't block refreshes by doing
		-- continuous read/write operations.
		elsif doRfshFlag_r = YES and initFlag_r = NO and wrFlag_r = NO and rdFlag_r = NO then
			if rasTimer_r = TO_UNSIGNED(0,rasTimer_r'length) and wrTimer_r = TO_UNSIGNED(0,wrTimer_r'length) then
				doRfshFlag_next <= NO;		-- reset the flag that initiates a refresh operation
				cmd <= PCHG_CMD;	-- initiate precharge of the SDRAM
				sAddr(ColCmdPos) <= ALL_BANKS;	-- precharge all banks
				timer_next <= TO_UNSIGNED(RP_CYCLES,timer_next'length);	-- set timer for this operation
				inactiveFlag_next <= YES;	-- all rows are inactive after a precharge operation
				state_next <= REFRESH;	-- refresh the SDRAM after the precharge
			end if;
			sdramCntl_state <= "0101";
		elsif state_r = REFRESH then
			cmd <= RFSH_CMD;			-- refresh command goes to SDRAM
			timer_next <= TO_UNSIGNED(RFC_CYCLES,timer_next'length);	-- refresh operation interval
			-- after refresh is done, resume writing or reading the SDRAM if in progress
			state_next <= RW;
			sdramCntl_state <= "0110";

		-- do nothing but wait for read or write operations
		elsif state_r = RW then
			if rd = YES then
				-- the host has initiated a read operation
				rdFlag_next <= YES;		-- set flag to indicate a read operation is in progress
				-- if a different row or bank is being read, then precharge the SDRAM and activate the new row
				if changeRow = YES then
					-- wait for any row activations or writes to finish before doing a precharge
					if rasTimer_r = TO_UNSIGNED(0,rasTimer_r'length) and wrTimer_r = TO_UNSIGNED(0,wrTimer_r'length) then
						cmd <= PCHG_CMD;	-- initiate precharge of the SDRAM
						sAddr(ColCmdPos) <= ALL_BANKS;	-- precharge all banks
						timer_next <= TO_UNSIGNED(RP_CYCLES,timer_next'length);	-- set timer for this operation
						inactiveFlag_next <= YES;	-- all rows are inactive after a precharge operation
						state_next <= ACTIVATE;	-- activate the new row after the precharge is done
					end if;
				-- read from the currently active row
				else
					cmd <= READ_CMD;	-- initiate a read of the SDRAM
					timer_next <= TO_UNSIGNED(Ccas,timer_next'length);	-- setup timer for read access
					state_next <= RDDONE;	-- read the data from SDRAM after the access time
				end if;
				sdramCntl_state <= "0111";
			elsif wr = YES then
				-- the host has initiated a write operation
				-- if a different row or bank is being written, then precharge the SDRAM and activate the new row
				if changeRow = YES then
					wrFlag_next <= YES;		-- set flag to indicate a write operation is in progress
					-- wait for any row activations or writes to finish before doing a precharge
					if rasTimer_r = TO_UNSIGNED(0,rasTimer_r'length) and wrTimer_r = TO_UNSIGNED(0,wrTimer_r'length) then
						cmd <= PCHG_CMD;	-- initiate precharge of the SDRAM
						sAddr(ColCmdPos) <= ALL_BANKS;	-- precharge all banks
						timer_next <= TO_UNSIGNED(RP_CYCLES,timer_next'length);	-- set timer for this operation
						inactiveFlag_next <= YES;	-- all rows are inactive after a precharge operation
						state_next <= ACTIVATE;	-- activate the new row after the precharge is done
					end if;
				-- write to the currently active row
				else
					cmd <= WRITE_CMD;	-- initiate the write operation
					dirOut <= YES;
					-- set timer so precharge doesn't occur too soon after write operation
					wrTimer_next <= TO_UNSIGNED(WR_CYCLES,wrTimer_next'length);
					state_next <= WRDONE;	-- go back and wait for another read/write operation
				end if;
				sdramCntl_state <= "1000";
			else
				null;	-- no read or write operation, so do nothing
				sdramCntl_state <= "1001";
			end if;

		-- enter this state when the data read from the SDRAM is available
		elsif state_r = RDDONE then
			rdFlag_next <= NO;	-- set flag to indicate the read operation is over
			done <= YES;				-- tell the host that the data is ready
			state_next <= RW;		-- go back and do another read/write operation
			sdramCntl_state <= "1010";

		-- enter this state when the data is written to the SDRAM
		elsif state_r = WRDONE then
			dirOut <= YES;
			wrFlag_next <= NO;		-- set flag to indicate the write operation is over
			done <= YES;			-- tell the host that the data is ready
			state_next <= RW;		-- go back and do another read/write operation
			sdramCntl_state <= "1011";

		-- activate a row of the SDRAM
		elsif state_r = ACTIVATE then
			cmd <= ACTIVE_CMD;	-- initiate the SDRAM activation operation
			sAddr <= (others=>'0');		-- output the address for the row that will be activated
			sAddr(row'range) <= row;
			activeBank_next <= bank;	-- remember the active SDRAM row
			activeRow_next <= row;		-- remember the active SDRAM bank
			inactiveFlag_next <= NO;	-- the SDRAM is no longer inactive
			rasTimer_next <= TO_UNSIGNED(RCD_CYCLES,rasTimer_next'length);
			timer_next <= TO_UNSIGNED(RCD_CYCLES,timer_next'length);
			state_next <= RW;	-- go back and do the read/write operation that caused this activation
			sdramCntl_state <= "1100";

		-- no operation
		else
			null;
			sdramCntl_state <= "1101";
		
		end if;
						
	end process combinatorial;


	-- update registers on the rising clock edge	
	update: process(clk)
	begin
		if clk'event and clk='1' then
			if rst = NO then
				state_r				<= INITWAIT;
				activeBank_r		<= (others=>'0');
				activeRow_r			<= (others=>'0');
				inactiveFlag_r		<= YES;
				initFlag_r			<= YES;
				doRfshFlag_r		<= NO;
				rdFlag_r			<= NO;
				wrFlag_r			<= NO;
				rfshCntr_r			<= TO_UNSIGNED(0,rfshCntr_r'length);
				timer_r				<= TO_UNSIGNED(INIT_CYCLES,timer_r'length);
				refTimer_r			<= TO_UNSIGNED(REF_CYCLES,refTimer_r'length);
				rasTimer_r			<= TO_UNSIGNED(0,rasTimer_r'length);
				wrTimer_r			<= TO_UNSIGNED(0,wrTimer_r'length);
			else
				state_r				<= state_next;
				activeBank_r		<= activeBank_next;
				activeRow_r			<= activeRow_next;
				inactiveFlag_r		<= inactiveFlag_next;
				initFlag_r			<= initFlag_next;
				doRfshFlag_r		<= doRfshFlag_next;
				rdFlag_r			<= rdFlag_next;
				wrFlag_r			<= wrFlag_next;
				rfshCntr_r			<= rfshCntr_next;
				timer_r				<= timer_next;
				refTimer_r			<= refTimer_next;
				rasTimer_r			<= rasTimer_next;
				wrTimer_r			<= wrTimer_next;
			end if;
		end if;
	end process update;

end arch;

⌨️ 快捷键说明

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