📄 chiprom.vhd
字号:
--*******************************************************************--
-- Copyright (c) 1999-2001 Evatronix SA --
--*******************************************************************--
-- Please review the terms of the license agreement before using --
-- this file. If you are not an authorized user, please destroy this --
-- source code file and notify Evatronix SA immediately that you --
-- inadvertently received an unauthorized copy. --
--*******************************************************************--
-----------------------------------------------------------------------
-- Project name : C8051
-- Project description : C8051 Microcontroller Unit
--
-- File name : CHIPROM.VHD
-- File contents : Entity INTERNAL_PROGRAM_MEMORY
-- Architecture SIM of INTERNAL_PROGRAM_MEMORY
-- Purpose : Asynchronous Program Memory
--
-- Destination library : C8051_LIB
-- Dependencies : STD.TEXTIO
-- IEEE.STD_LOGIC_1164
--
-- Design Engineer : M.B.
-- Quality Engineer : M.B.
-- Version : 3.01
-- Last modification : 2001-10-01
-----------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use STD.TEXTIO.ALL;
entity INTERNAL_PROGRAM_MEMORY is
generic (
DATAWIDTH : INTEGER := 8;
ADDRWIDTH : INTEGER := 12;
ROMFILE : STRING := "introm.hex"; -- Memory init file
FILEPATH : STRING := "tests/default/" -- Path to the init file
);
port (
addrbus : in STD_LOGIC_VECTOR (ADDRWIDTH-1 downto 0);
rd : in STD_LOGIC;
databus : out STD_LOGIC_VECTOR (DATAWIDTH-1 downto 0)
);
end INTERNAL_PROGRAM_MEMORY;
--*******************************************************************--
architecture SIM of INTERNAL_PROGRAM_MEMORY is
subtype MEMORY_ROW is STD_LOGIC_VECTOR (DATAWIDTH-1 downto 0);
subtype SIZE is NATURAL RANGE 0 TO 2**ADDRWIDTH-1;
type MEMORY_AREA is ARRAY (SIZE) of MEMORY_ROW;
signal initialized : BOOLEAN := false;
--------------------------------------------------------------------
-- Converts binary vector to INTEGER
--------------------------------------------------------------------
function TO_INTEGER (input : STD_LOGIC_VECTOR) return INTEGER is
variable result : INTEGER;
variable weight : INTEGER;
begin
result:=0;
weight:=1;
for i in input'LOW to input'HIGH loop
if (input(i)='1' or input(i)='H') then
result := result + weight;
end if;
weight := weight * 2;
end loop;
return result;
end TO_INTEGER;
--------------------------------------------------------------------
-- Converts hexadecimal string to integer
--------------------------------------------------------------------
function TO_INTEGER (input : string) return INTEGER is
variable result : INTEGER;
begin
result:=0;
for i in input'LEFT to input'RIGHT loop
result := result * 16;
case input(i) is
when '0' => result := result + 0;
when '1' => result := result + 1;
when '2' => result := result + 2;
when '3' => result := result + 3;
when '4' => result := result + 4;
when '5' => result := result + 5;
when '6' => result := result + 6;
when '7' => result := result + 7;
when '8' => result := result + 8;
when '9' => result := result + 9;
when 'A' => result := result + 10;
when 'B' => result := result + 11;
when 'C' => result := result + 12;
when 'D' => result := result + 13;
when 'E' => result := result + 14;
when 'F' => result := result + 15;
when others => null;
end case;
end loop;
return result;
end TO_INTEGER;
--------------------------------------------------------------------
-- Converts hexadecimal string to binary vector
--------------------------------------------------------------------
function TO_STD_LOGIC_VECTOR (input : STRING) return STD_LOGIC_VECTOR is
variable result : STD_LOGIC_VECTOR(0 to 4*input'LENGTH-1);
begin
result := (others => '0');
for i in input'LEFT to input'RIGHT loop
case input(i) is
when '0' => result((i-1)*4 to 3+(i-1)*4):="0000";
when '1' => result((i-1)*4 to 3+(i-1)*4):="0001";
when '2' => result((i-1)*4 to 3+(i-1)*4):="0010";
when '3' => result((i-1)*4 to 3+(i-1)*4):="0011";
when '4' => result((i-1)*4 to 3+(i-1)*4):="0100";
when '5' => result((i-1)*4 to 3+(i-1)*4):="0101";
when '6' => result((i-1)*4 to 3+(i-1)*4):="0110";
when '7' => result((i-1)*4 to 3+(i-1)*4):="0111";
when '8' => result((i-1)*4 to 3+(i-1)*4):="1000";
when '9' => result((i-1)*4 to 3+(i-1)*4):="1001";
when 'A' => result((i-1)*4 to 3+(i-1)*4):="1010";
when 'B' => result((i-1)*4 to 3+(i-1)*4):="1011";
when 'C' => result((i-1)*4 to 3+(i-1)*4):="1100";
when 'D' => result((i-1)*4 to 3+(i-1)*4):="1101";
when 'E' => result((i-1)*4 to 3+(i-1)*4):="1110";
when 'F' => result((i-1)*4 to 3+(i-1)*4):="1111";
when others => null;
end case;
end loop;
return result;
end TO_STD_LOGIC_VECTOR;
--------------------------------------------------------------------
-- Initializing memory contents :
--------------------------------------------------------------------
function INITIALIZATION return MEMORY_AREA is
file source : TEXT is in FILEPATH & ROMFILE;
variable row : LINE;
variable char : CHARACTER;
variable addr : STRING(1 to 4);
variable data : STRING(1 to 2);
variable data1 : STRING(1 to 2);
variable number : INTEGER;
variable address : INTEGER;
variable checksum : INTEGER;
variable sum : INTEGER;
variable vector : STD_LOGIC_VECTOR(7 downto 0);
variable memory : MEMORY_AREA;
begin
for i in memory'RANGE loop
memory(i) := (others => '0');
end loop;
while not ENDFILE(source) loop
READLINE(source, row);
if row'LENGTH>1 and row(1)=':' then
READ(row, char);
READ(row, data);
number:=TO_INTEGER(data);
sum :=number;
READ(row, data);
checksum :=TO_INTEGER(data);
sum :=(sum+checksum) mod 256;
READ(row, data1);
checksum :=TO_INTEGER(data1);
sum :=(sum+checksum) mod 256;
addr :=data & data1;
address :=TO_INTEGER(addr);
READ(row, data);
checksum :=TO_INTEGER(data);
sum :=(sum+checksum) mod 256;
while number>0 loop
READ(row, data);
vector :=TO_STD_LOGIC_VECTOR(data);
checksum :=TO_INTEGER(data);
sum :=(sum+checksum) mod 256;
memory(address) := vector;
address :=address+1;
number :=number-1;
end loop;
READ(row, data);
checksum :=TO_INTEGER(data);
sum :=(sum+checksum) mod 256;
assert (sum=0)
report "Invalid check sum in the program memory init file."
severity error;
end if;
end loop;
return memory;
end INITIALIZATION;
begin
--------------------------------------------------------------------
main :
--------------------------------------------------------------------
process (rd, addrbus)
variable memory : MEMORY_AREA;
begin
----------------------------------------
-- Memory initialization
----------------------------------------
if not initialized then
memory := INITIALIZATION;
initialized <= true;
end if;
----------------------------------------
-- Memory reading
----------------------------------------
if rd='1' then
databus <= memory(TO_INTEGER(addrbus));
else
databus <= (others => 'Z');
end if;
end process;
end SIM;
--*******************************************************************--
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -