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

📄 sram.vhd

📁 vhdl code for GIF Image Viewer
💻 VHD
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use std.textio.all;

entity sram is
    Generic (
	 		mem_words : integer := 524288;
			word_size : integer := 16;

			tAA : time := 15 ns;
			tACE : time := 15 ns;
			tOE : time := 7 ns;
			tOH : time := 3 ns;
			tCLZ : time := 1 ns;
			tCHZ : time := 7 ns;
			tOLZ : time := 1 ns;
			tOHZ : time := 7 ns;

			tCW : time := 10 ns;
			tAW : time := 10 ns;
			tAS : time := 0 ns;
			tWP1 : time := 10 ns;
			tWP2 : time := 15 ns;
			tAH : time := 0 ns;		-- unimplemented
			tWR : time := 0 ns;		-- unimplemented
			tDW : time := 7 ns;
			tDH : time := 0 ns;		-- unimplemented
			tWZ : time := 7 ns;
			tOW : time := 3 ns
	 );
    Port ( addr : in std_logic_vector(18 downto 0);
           ceN : in std_logic;
           oeN : in std_logic;
           weN : in std_logic;
			  load : in std_logic;
			  filename : in string(1 to 12);
			  load_addr : in natural;
           data : inout std_logic_vector(15 downto 0);
			  violation : out std_logic
			  );
end sram;

architecture Behavioral of sram is
	type mem_array is array(0 to mem_words-1) of std_logic_vector(word_size-1 downto 0);

	signal baddr : std_logic_vector(18 downto 0);
	signal bceN, boeN, bweN : std_logic;
	signal latchdata, ce_latchdata, we_latchdata : std_logic_vector(word_size-1 downto 0);
	signal ce_cycle_start, we_cycle_start, ce_cycle_end, we_cycle_end : time;
	signal ce_error, we_error : std_logic;
begin

violation <= ce_error or we_error;

process (addr)
begin
	baddr <= (others => 'U') after tOH, addr after tAA;
end process;

process (ceN)
	variable cycle_start : time;
begin
	ce_error <= '0';
	if (ceN = '0') then 
		if (weN = '0') then 
			ce_cycle_start <= now;
		end if;
		bceN <= 'U' after tCLZ, '0' after tACE;
	elsif (ceN = '1') then
		if (weN = '0') then
			if (we_cycle_start > ce_cycle_start) then cycle_start := we_cycle_start;
			else													cycle_start := ce_cycle_start;
			end if;
			ce_cycle_end <= now;

			if (now - cycle_start < tCW) then
				ce_error <= 'U';
				assert (false)
				report "Chip enable to write end violation."
				severity error;
			end if;
			if (not addr'stable(tAW)) then
				ce_error <= 'U';
				assert (false)
				report "Address setup to write end violation."
				severity error;
			end if;
			if (not data'stable(tDW)) then
				ce_error <= 'U';
				assert (false)
				report "Data valid to write end violation."
				severity error;
			end if;

			if (oeN = '1') then 
				if (not weN'stable(tWP1)) then
					ce_error <= 'U';
					assert (false)
					report "Write pulse width violation."
					severity error;
				end if;
			else
				if (not weN'stable(tWP2)) then
					ce_error <= 'U';
					assert (false)
					report "Write pulse width violation."
					severity error;
				end if;
			end if;

			ce_latchdata <= data;
		end if;

		bceN <= '1' after tCHZ;
	end if;
end process;

process (oeN)
begin
	if (oeN = '0') then
		boeN <= 'U' after tOLZ, '0' after tOE;
	else
		boeN <= '1' after tOHZ;
	end if;
end process;

process (weN)
	variable cycle_start : time;
begin
	we_error <= '0';
	if (ceN = '1') then
		bweN <= weN;
	elsif (weN = '0' and ceN = '0') then
		we_cycle_start <= now;
		if (not addr'stable(tAS)) then
			we_error <= 'U';
			assert (false)
			report "Address setup time violation."
			severity error;
		end if;

		bweN <= '0' after tWZ;
	elsif (weN = '1' and ceN = '0') then
		if (we_cycle_start > ce_cycle_start) then cycle_start := we_cycle_start;
		else													cycle_start := ce_cycle_start;
		end if;
		we_cycle_end <= now;

		if (not ceN'stable(tCW)) then
			we_error <= 'U';
			assert (false)
			report "Chip enable to write end violation."
			severity error;
		end if;
		if (not addr'stable(tAW)) then
			we_error <= 'U';
			assert (false)
			report "Address setup to write end violation."
			severity error;
		end if;
		if (not data'stable(tDW)) then
			we_error <= 'U';
			assert (false)
			report "Data valid to write end violation."
			severity error;
		end if;

		if (oeN = '1') then 
			if (now - cycle_start < tWP1) then
				we_error <= 'U';
				assert (false)
				report "Write pulse width violation."
				severity error;
			end if;
		else
			if (now - cycle_start < tWP2) then
				we_error <= 'U';
				assert (false)	
				report "Write pulse width violation."
				severity error;
			end if;
		end if;

		if (data'event) then
			we_latchdata <= data'last_value;
		else
			we_latchdata <= data;
		end if;
		bweN <= '1';
	end if;
end process;
			

process (baddr, bceN, boeN, bweN, data, load)
	variable mem : mem_array;
	subtype nibble is std_logic_vector(3 downto 0);

	procedure hex_to_vector(variable c : in character; variable v : out nibble) is
		variable l : line;
	begin
		case c is 
			when '0' => v := x"0";
			when '1' => v := x"1";
			when '2' => v := x"2";
			when '3' => v := x"3";
			when '4' => v := x"4";
			when '5' => v := x"5";
			when '6' => v := x"6";
			when '7' => v := x"7";
			when '8' => v := x"8";
			when '9' => v := x"9";
			when 'A' => v := x"a";
			when 'B' => v := x"b";
			when 'C' => v := x"c";
			when 'D' => v := x"d";
			when 'E' => v := x"e";
			when 'F' => v := x"f";
			when others => 
				write(l, string'("unknown character"));
				writeline(output, l);
		end case;

	end procedure hex_to_vector;

	procedure load_file(filename : in string; addr : in natural; mem : inout mem_array) is
		file f : text is in filename;
		variable l : line;
		variable words : natural;
		variable c : character;
		variable b : nibble;
	begin
		readline(f, l);
		words := l'length / 4;
		for i in 0 to words-1 loop
			read(l, c);
			hex_to_vector(c, b);
			mem(addr + i)(3 downto 0) := b;
			read(l, c);
			hex_to_vector(c, b);
			mem(addr + i)(7 downto 4) := b;
			read(l, c);
			hex_to_vector(c, b);
			mem(addr + i)(11 downto 8) := b;
			read(l, c);
			hex_to_vector(c, b);
			mem(addr + i)(15 downto 12) := b;
		end loop;
	end procedure load_file;

begin

	if (load'event and load = '1') then
		load_file(filename, load_addr, mem);
	elsif ((bceN'event and bceN = '1' and bweN = '0') or
			 (bweN'event and bweN = '1' and bceN = '0')) then
		if (ce_cycle_end > we_cycle_end) then
			mem(conv_integer(baddr)) := ce_latchdata;
		else
	 		mem(conv_integer(baddr)) := we_latchdata;
		end if;
	end if;

	if (boeN /= '1' and (bceN = 'U' or boeN = 'U' or baddr = "UUUUUUUUUUUUUUUUUUU" or bweN = 'U')) then
		data <= (others => 'U');
	elsif (bceN = '0' and boeN = '0' and bweN = '1') then
		data <= mem(conv_integer(baddr));
	else
		data <= (others => 'Z');
	end if;

end process;


end Behavioral;

⌨️ 快捷键说明

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