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 + -
显示快捷键?