mspram.vhd
来自「一个航天航空用的Sparc处理器(配美国欧洲宇航局用的R_tems嵌入式操作系统」· VHDL 代码 · 共 325 行
VHD
325 行
-----------------------------------------------------------------------------
-- This file is a part of the LEON VHDL model
-- Copyright (C) 1999 European Space Agency (ESA)
--
-- 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 2 of the License, or
-- (at your option) any later version.
--
-- See the file COPYING for the full details of the license.
-------------------------------------------------------------------------------
-- File name : mspram.vhd
-- Title : mspram
-- Author(s) : Jiri Gaisler
-- Purpose : Ram model for microsparc test suite
--
-------------------------------------------------------------------------------
-- Modification history :
-------------------------------------------------------------------------------
-- Version No : | Author | Mod. Date : | Changes made :
-------------------------------------------------------------------------------
-- v 1.0 | JG | 99-08-17 | first version
--.............................................................................
-------------------------------------------------------------------------------
-- Copyright ESA/ESTEC
-------------------------------------------------------------------------------
---------|---------|---------|---------|---------|---------|---------|--------|
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.conv_integer;
library MMS;
use MMS.stdioimp.all;
use std.textio.all;
use work.macro.all;
entity mspram is
generic ( mspfile : string := "mspfile"; -- list of test files
romfile : string := "rom.dat"); -- rom boot file
port (
A : in std_logic_vector(15 downto 0);
D : inout std_logic_vector(38 downto 0);
romsel : in std_logic;
romoen : in std_logic;
ramsel : in std_logic;
ramoen : in std_logic;
write : in std_logic;
rst : out std_logic;
error : in std_logic
); end mspram;
architecture behav of mspram is
constant abits : integer := 16;
subtype word is std_logic_vector(38 downto 0);
type memarr is array(0 to ((2**Abits)-1)) of word;
signal rstl : std_logic := 'X';
constant ahigh : integer := abits - 1;
function Vpar(vec : std_logic_vector) return std_logic is
variable par : std_logic := '1';
begin
for i in vec'range loop
par := par xor vec(i);
end loop;
return par;
end;
procedure CHAR2QUADBITS(C: character; RESULT: out bit_vector(3 downto 0);
GOOD: out boolean; ISSUE_ERROR: in boolean) is
begin
case C is
when '0' => RESULT := x"0"; GOOD := true;
when '1' => RESULT := x"1"; GOOD := true;
when '2' => RESULT := X"2"; GOOD := true;
when '3' => RESULT := X"3"; GOOD := true;
when '4' => RESULT := X"4"; GOOD := true;
when '5' => RESULT := X"5"; GOOD := true;
when '6' => RESULT := X"6"; GOOD := true;
when '7' => RESULT := X"7"; GOOD := true;
when '8' => RESULT := X"8"; GOOD := true;
when '9' => RESULT := X"9"; GOOD := true;
when 'A' => RESULT := X"A"; GOOD := true;
when 'B' => RESULT := X"B"; GOOD := true;
when 'C' => RESULT := X"C"; GOOD := true;
when 'D' => RESULT := X"D"; GOOD := true;
when 'E' => RESULT := X"E"; GOOD := true;
when 'F' => RESULT := X"F"; GOOD := true;
when 'a' => RESULT := X"A"; GOOD := true;
when 'b' => RESULT := X"B"; GOOD := true;
when 'c' => RESULT := X"C"; GOOD := true;
when 'd' => RESULT := X"D"; GOOD := true;
when 'e' => RESULT := X"E"; GOOD := true;
when 'f' => RESULT := X"F"; GOOD := true;
when others =>
if ISSUE_ERROR then
assert false report
"HREAD Error: Read a '" & C & "', expected a Hex character (0-F).";
end if;
GOOD := false;
end case;
end;
procedure HREAD(L:inout line; VALUE:out bit_vector) is
variable OK: boolean;
variable C: character;
constant NE: integer := VALUE'length/4;
variable BV: bit_vector(0 to VALUE'length-1);
variable S: string(1 to NE-1);
begin
if VALUE'length mod 4 /= 0 then
assert false report
"HREAD Error: Trying to read vector " &
"with an odd (non multiple of 4) length";
return;
end if;
while L'length > 0 loop -- skip white space
read(L,C);
exit when ((C /= ' ') and (C /= CR) and (C /= HT));
end loop;
CHAR2QUADBITS(C, BV(0 to 3), OK, false);
if not OK then
return;
end if;
read(L, S, OK);
-- if not OK then
-- assert false report "HREAD Error: Failed to read the STRING";
-- return;
-- end if;
for I in 1 to NE-1 loop
CHAR2QUADBITS(S(I), BV(4*I to 4*I+3), OK, false);
if not OK then
return;
end if;
end loop;
VALUE := BV;
end HREAD;
procedure HREAD(L:inout line; VALUE:out std_ulogic_vector) is
variable TMP: bit_vector(VALUE'length-1 downto 0);
begin
HREAD(L, TMP);
VALUE := TO_X01(TMP);
end HREAD;
procedure HREAD(L:inout line; VALUE:out std_logic_vector) is
variable TMP: std_ulogic_vector(VALUE'length-1 downto 0);
begin
HREAD(L, TMP);
VALUE := std_logic_vector(TMP);
end HREAD;
function ishex(c:character) return boolean is
variable tmp : bit_vector(3 downto 0);
variable OK : boolean;
begin
CHAR2QUADBITS(C, tmp, OK, false);
return OK;
end ishex;
begin
RAM : process(ramsel,romsel,write,D,A,ramoen, romoen,rstl)
variable memram, memrom : memarr;
variable first : boolean := true;
variable romloaded : boolean := false;
variable ai : integer;
variable L : line;
variable S: string(1 to 64);
variable fail, ok : boolean;
variable log_area, stop : integer := 65535;
variable dint : word;
file testlist : text is in mspfile;
procedure loadmem(mem: inout memarr; fn : string) is
variable L1,L2 : line;
variable LEN : integer := 0;
variable ADR : std_logic_vector(15 downto 0);
variable BUF : std_logic_vector(31 downto 0);
variable CH : character;
file TCF : text is in fn;
begin
L1:= new string'("");
readline(TCF,L1);
while (L1'length /= 0) or not endfile(TCF) loop
if (L1'length /= 0) then
while (not (L1'length=0)) and (L1(L1'left) = ' ') loop
std.textio.read(L1,CH);
end loop;
if L1'length > 0 then
if not (L1'length=0)and ishex(L1(L1'left)) and ishex(L1(L1'left+1))
then
HREAD(L1,ADR); -- read address
len := conv_integer(adr(15 downto 2));
for i in 0 to 3 loop
HREAD(L1,BUF);
MEM(LEN+i) := std_logic_vector'(chkbitgen(BUF)) & BUF;
end loop;
end if;
end if;
end if;
if not endfile(TCF) then
readline(TCF,L1);
else
exit;
end if;
end loop;
end;
begin
-- load prom at power-up
if not romloaded then
loadmem(memrom, romfile);
print("*** Microsparc test suite ***");
print("");
rstl <= '0' after 500 ns; rst <= '0';
romloaded := true;
L:= new string'("");
end if;
-- check results and load next test
if rstl = '0' then
if not first then
fail := false;
if memram(log_area)(31 downto 0) /= "00000000000000000000000000000000" then
print(
tostring(conv_integer(memram(log_area)(31 downto 17)),"%d") & " errors detected ");
print( "error code(s): " &
tostring(conv_integer(memram(log_area)(15 downto 0)),"%04x") & " : " &
tostring(conv_integer(memram(log_area+1)(31 downto 16)),"%04x") & " : " &
tostring(conv_integer(memram(log_area+1)(15 downto 0)),"%04x"));
fail := true;
end if;
if fail then
assert not fail report
tostring(conv_integer(memram(log_area)(31 downto 17)),"%d") &
" errors in " & s severity failure ;
-- else
-- print("test passed, log_area: " &tostring(memram(log_area)(31 downto 0)));
end if;
end if;
first := false;
ok := false;
while (not ok) loop
if (not endfile(testlist)) then
readline(testlist,L); s := (others => nul);
std.textio.read(L, S(1 to L'length), ok);
if ok then
if s(1) /= '#' then
loadmem(memram, s); print(s);
else ok := false;
end if;
end if;
else
assert false
report "*** test completed, halting simulation with failure ***"
severity failure ;
end if;
end loop;
rstl <= '1';
rst <= '1' after 500 ns;
end if;
-- standard ram/rom memory
if TO_X01(ramsel) = '0' then
if not is_x(a) then ai := conv_integer(A(15 downto 2)); else ai := 0; end if;
if (to_x01(write) = '1') then dint := memram(ai); end if;
if ai = 65528/4 then
dint(31 downto 0) := std_logic_vector(conv_unsigned(log_area,32));
dint(38 downto 32) := std_logic_vector'(chkbitgen(dint(31 downto 0)));
elsif ai = 65532/4 then
dint(31 downto 0) := std_logic_vector(conv_unsigned(stop,32));
dint(38 downto 32) := std_logic_vector'(chkbitgen(dint(31 downto 0)));
end if;
if ai = stop then
rstl <= '0' after 200 ns;
rst <= '0' after 200 ns;
end if;
if write'event and (to_x01(write) = '1') then
memram(ai) := std_logic_vector(D);
if ai = 65528/4 then
log_area := conv_integer(D(15 downto 2));
elsif ai = 65532/4 then
stop := conv_integer(D(15 downto 2));
end if;
end if;
elsif TO_X01(romsel) = '0' then
if not is_x(a) then ai := conv_integer(A(15 downto 2));
else ai := 0; end if;
dint := memrom(ai);
end if;
if (romoen and ramoen) = '0' then
D <= Dint;
else
D <= (others => 'Z');
end if;
end process;
iuerr : process(error)
begin
assert error /= '0'
report "*** IU in error mode, test failed! ***"
severity failure ;
end process;
end behav;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?