OpenCores
URL https://opencores.org/ocsvn/the_wizardry_project/the_wizardry_project/trunk

Subversion Repositories the_wizardry_project

[/] [the_wizardry_project/] [trunk/] [Wizardry/] [VHDL/] [Wizardry Top Level/] [Address Generation/] [JOP/] [sc_sram32.vhd] - Rev 22

Compare with Previous | Blame | View Log

--
--
--  This file is a part of JOP, the Java Optimized Processor
--
--  Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com)
--
--  This program is free software: you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation, either version 3 of the License, or
--  (at your option) any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
 
 
--
--	sc_sram32.vhd
--
--	SimpCon compliant external memory interface
--	for 32-bit SRAM (e.g. Cyclone board, Spartan-3 Starter Kit)
--
--	Connection between mem_sc and the external memory bus
--
--	memory mapping
--	
--		000000-x7ffff	external SRAM (w mirror)	max. 512 kW (4*4 MBit)
--
--	RAM: 32 bit word
--
--
--	2005-11-22	first version
--	2007-03-17	changed SimpCon to records
--	2008-05-29	nwe on pos edge, additional wait state for write
--
 
Library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.jop_types.all;
use work.sc_pack.all;
 
entity sc_mem_if is
generic (ram_ws : integer; addr_bits : integer);
 
port (
 
	clk, reset	: in std_logic;
 
--
--	SimpCon memory interface
--
	sc_mem_out		: in sc_out_type;
	sc_mem_in		: out sc_in_type;
 
-- memory interface
 
	ram_addr	: out std_logic_vector(addr_bits-1 downto 0);
	ram_dout	: out std_logic_vector(31 downto 0);
	ram_din		: in std_logic_vector(31 downto 0);
	ram_dout_en	: out std_logic;
	ram_ncs		: out std_logic;
	ram_noe		: out std_logic;
	ram_nwe		: out std_logic
 
);
end sc_mem_if;
 
architecture rtl of sc_mem_if is
 
--
--	signals for mem interface
--
	type state_type		is (
							idl, rd1, rd2,
							wr1, wr2
						);
	signal state 		: state_type;
	signal next_state	: state_type;
 
	signal wait_state	: unsigned(3 downto 0);
	signal cnt			: unsigned(1 downto 0);
 
	signal dout_ena		: std_logic;
	signal rd_data_ena	: std_logic;
 
	signal ram_ws_wr	: integer;
 
begin
 
	ram_ws_wr <= ram_ws+1; -- additional wait state for SRAM
 
	assert SC_ADDR_SIZE>=addr_bits report "Too less address bits";
	ram_dout_en <= dout_ena;
 
	sc_mem_in.rdy_cnt <= cnt;
 
--
--	Register memory address, write data and read data
--
process(clk, reset)
begin
	if reset='1' then
 
		ram_addr <= (others => '0');
		ram_dout <= (others => '0');
		sc_mem_in.rd_data <= (others => '0');
 
	elsif rising_edge(clk) then
 
		if sc_mem_out.rd='1' or sc_mem_out.wr='1' then
			ram_addr <= sc_mem_out.address(addr_bits-1 downto 0);
		end if;
		if sc_mem_out.wr='1' then
			ram_dout <= sc_mem_out.wr_data;
		end if;
		if rd_data_ena='1' then
			sc_mem_in.rd_data <= ram_din;
		end if;
 
	end if;
end process;
 
--
--	next state logic
--
process(state, sc_mem_out.rd, sc_mem_out.wr, wait_state)
 
begin
 
	next_state <= state;
 
 
	case state is
 
		when idl =>
			if sc_mem_out.rd='1' then
				if ram_ws=0 then
					-- then we omit state rd1!
					next_state <= rd2;
				else
					next_state <= rd1;
				end if;
			elsif sc_mem_out.wr='1' then
				next_state <= wr1;
			end if;
 
		-- the WS state
		when rd1 =>
			if wait_state=2 then
				next_state <= rd2;
			end if;
 
		-- last read state
		when rd2 =>
			next_state <= idl;
			-- This should do to give us a pipeline
			-- level of 2 for read
			if sc_mem_out.rd='1' then
				if ram_ws=0 then
					-- then we omit state rd1!
					next_state <= rd2;
				else
					next_state <= rd1;
				end if;
			elsif sc_mem_out.wr='1' then
				next_state <= wr1;
			end if;
 
		-- the WS state
		when wr1 =>
			if wait_state=2 then
				next_state <= wr2;
			end if;
 
		-- last write state
		when wr2 =>
			next_state <= idl;
 
	end case;
 
end process;
 
--
--	state machine register
--	output register
--
process(clk, reset)
 
begin
	if (reset='1') then
		state <= idl;
		dout_ena <= '0';
		ram_ncs <= '1';
		ram_noe <= '1';
		rd_data_ena <= '0';
		ram_nwe <= '1';
 
	elsif rising_edge(clk) then
 
		state <= next_state;
		dout_ena <= '0';
		ram_ncs <= '1';
		ram_noe <= '1';
		rd_data_ena <= '0';
		ram_nwe <= '1';
 
		case next_state is
 
			when idl =>
 
			-- the wait state
			when rd1 =>
				ram_ncs <= '0';
				ram_noe <= '0';
 
			-- last read state
			when rd2 =>
				ram_ncs <= '0';
				ram_noe <= '0';
				rd_data_ena <= '1';
 
			-- the WS state
			when wr1 =>
				ram_nwe <= '0';
				dout_ena <= '1';
				ram_ncs <= '0';
 
			-- last write state	
			when wr2 =>
				dout_ena <= '1';
				ram_ncs <= '0';
 
		end case;
 
	end if;
end process;
 
--
-- wait_state processing
-- cs delay, dout enable
--
process(clk, reset)
begin
	if (reset='1') then
		wait_state <= (others => '1');
		cnt <= "00";
	elsif rising_edge(clk) then
 
		wait_state <= wait_state-1;
 
		cnt <= "11";
		if next_state=idl then
			cnt <= "00";
		-- if wait_state<4 then
		elsif wait_state(3 downto 2)="00" then
			cnt <= wait_state(1 downto 0)-1;
		end if;
 
		if sc_mem_out.rd='1' then
			wait_state <= to_unsigned(ram_ws+1, 4);
			if ram_ws<3 then
				cnt <= to_unsigned(ram_ws+1, 2);
			else
				cnt <= "11";
			end if;
		end if;
 
		if sc_mem_out.wr='1' then
			wait_state <= to_unsigned(ram_ws_wr+1, 4);
			if ram_ws_wr<3 then
				cnt <= to_unsigned(ram_ws_wr+1, 2);
			else
				cnt <= "11";
			end if;
		end if;
 
	end if;
end process;
 
end 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.