📄 nvsram.vhd
字号:
-- ------------------------------------------------
-- Model : SRAM loaded with Hex Format
--
-- Purpose : This SRAM model was adapted from Andre'
-- Klindworth's SRAM model. The load has
-- been replaced to use Intel hex format
-- files.
--
-- Author : Michael Mayer (mrmayer@computer.org),
-- Dr. Hardy J. Pottinger
-- Department of Electrical Engineering
-- University of Missouri - Rolla
--
-- Inspired By :
-- (C) Andre' Klindworth
-- Dept. of Computer Science
-- University of Hamburg
-- Vogt-Koelln-Str. 30
-- 22527 Hamburg
-- klindwor@informatik.uni-hamburg.de
--
-- This VHDL code may be freely copied as long as the copyright note isn't
-- removed from its header. Full affiliation of anybody modifying this file
-- shall be added to the header prior to further distribution.
-- The download procedure originates from DLX memory-behaviour.vhdl:
-- Copyright (C) 1993, Peter J. Ashenden
-- Mail: Dept. Computer Science
-- University of Adelaide, SA 5005, Australia
-- e-mail: petera@cs.adelaide.edu.au
--
--
-- Date : September 15, 1997
--
-- Limitations :
-- ------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_textio.ALL;
USE ieee.std_logic_unsigned.ALL;
USE work.pack8051.to_int;
USE std.textio.ALL;
ENTITY nvsram IS
GENERIC (
download_filename : STRING; -- filename for RAM initial contents
-- File must be Hex format
-- Configuring RAM size
size: INTEGER := 65536; -- number of memory words
addr_width: INTEGER := 16; -- number of address bits
width: INTEGER := 8; -- number of bits per memory word
t_rc : TIME := 70 ns; -- read cycle time
t_oe : TIME := 35 ns; -- oe to output valid
t_ce : TIME := 70 ns; -- ce to output valid
t_wc : TIME := 70 ns; -- write cycle time
t_ds : TIME := 30 ns; -- data setup time
t_dh1 : TIME := 7 ns -- data hold time
);
PORT (
addr : IN std_logic_vector(addr_width-1 DOWNTO 0); -- address
data : INOUT std_logic_vector(width-1 DOWNTO 0); -- data in/out
ce_N : IN std_logic; -- chip enable
we_N : IN std_logic; -- write enable
oe_N : IN std_logic -- output enable
);
END ENTITY nvsram;
ARCHITECTURE behav OF nvsram IS
SIGNAL do_write, do_read : std_logic; -- flags to command the memory process
-- to perform a given action (rising edge sensitive)
SIGNAL read_data : std_logic_vector(width-1 DOWNTO 0); -- the data read from memory process
BEGIN
do_write <= '1' WHEN (ce_N='0' AND we_N='0') ELSE '0';
do_read <= '1' WHEN (ce_N='0' AND oe_N='0') ELSE '0';
data <= read_data WHEN do_read='1' ELSE (OTHERS => 'Z');
memory: PROCESS (do_write, do_read) IS
CONSTANT low_address: natural := 0;
CONSTANT high_address: natural := size -1;
TYPE memory_array IS
ARRAY (natural RANGE low_address TO high_address) OF std_logic_vector(width-1 DOWNTO 0);
VARIABLE mem: memory_array;
VARIABLE address : natural;
VARIABLE write_data: std_logic_vector(width-1 DOWNTO 0);
VARIABLE initialized : BOOLEAN := FALSE;
PROCEDURE load_hex (mem: INOUT memory_array;
download_filename: IN string) IS
FILE progfile : TEXT OPEN read_mode IS download_filename;
VARIABLE L : LINE;
VARIABLE ch : CHARACTER;
VARIABLE rec_type : CHARACTER;
VARIABLE sum : INTEGER;
VARIABLE dig : INTEGER;
VARIABLE data : INTEGER;
VARIABLE numb_of_bytes : INTEGER;
VARIABLE address : INTEGER;
VARIABLE address_offset : INTEGER;
VARIABLE end_of_data : BOOLEAN;
VARIABLE checksum : INTEGER;
VARIABLE line_num : INTEGER;
BEGIN
line_num := 0;
address_offset := 0;
end_of_data := FALSE;
WHILE NOT (endfile(progfile) OR end_of_data) LOOP
-- Reset the variables for the line
sum := 0;
address := 0;
line_num := line_num + 1;
readline(progfile, L);
-- Read in the : character
read(L, ch);
IF ch /= ':' THEN
NEXT; -- go to next loop
END IF;
-- Read in the number of bytes
read(L, ch); -- msb
dig := to_int(ch);
sum := sum + dig;
read(L, ch); -- lsb
sum := sum + to_int(ch);
numb_of_bytes := dig*16 + to_int(ch);
-- Read in the address
FOR k IN 3 DOWNTO 0 LOOP
read(L, ch);
dig := to_int(ch);
sum := sum + dig;
address := address + dig * 16**k;
END LOOP;
-- Read in the record type
read(L,ch);
sum := sum + to_int(ch);
ASSERT ch = '0'
REPORT "Illegal Record Type - Bad Program File" &
" on line " & INTEGER'IMAGE(line_num);
read(L,rec_type);
sum := sum + to_int(rec_type);
-- If it is a line of all zeros, then it is the end of data.
IF (numb_of_bytes = 0) AND (address = 0)THEN
end_of_data := TRUE;
-- If it is normal data, then read in all of the bytes to program_mem
ELSIF rec_type = '0' THEN -- It has normal data
FOR byte_no IN 0 TO numb_of_bytes-1 LOOP
read(L,ch);
dig := to_int(ch);
sum := sum + dig;
read(L,ch);
sum := sum + to_int(ch);
data := dig*16 + to_int(ch);
mem(address_offset*16 + address + byte_no) :=
conv_std_logic_vector(data,width);
END LOOP;
-- If it is an end of file record, then set end_of_data true
ELSIF rec_type = '1' THEN -- it is an end of file record
end_of_data := TRUE;
ELSIF rec_type = '2' THEN
address_offset := 0;
FOR k IN 3 DOWNTO 0 LOOP
read(L, ch);
dig := to_int(ch);
sum := sum + dig;
address_offset := address_offset + dig*16**k;
END LOOP;
END IF;
-- get the checksum
read(L,ch);
dig := to_int(ch);
read(L,ch);
checksum := dig * 16 + to_int(ch);
--ASSERT (checksum + sum MOD 256) = 0;
-- REPORT "Checksum Error"& " on line " & INTEGER'IMAGE(line_num);
END LOOP;
END PROCEDURE load_hex;
BEGIN -- process memory
IF NOT initialized THEN
load_hex(mem,download_filename);
initialized := TRUE;
END IF;
IF rising_edge(do_write) THEN
mem(CONV_INTEGER(to_X01(addr))) := to_X01(data);
ELSIF rising_edge(do_read) THEN
read_data <= mem(CONV_INTEGER(to_X01(addr)));
END IF;
END PROCESS memory;
END ARCHITECTURE behav;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -