mms.vhd

来自「一个航天航空用的Sparc处理器(配美国欧洲宇航局用的R_tems嵌入式操作系统」· VHDL 代码 · 共 1,831 行 · 第 1/5 页

VHD
1,831
字号

	type to_integer_table is array (character'low to character'high) of integer;
	-- TO_INTEGER gives digit_value without control; 1000 for non-digit
	constant TO_INTEGER : to_integer_table := (
		'0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6,
		'7' => 7, '8' => 8, '9' => 9, 
		'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 
		'a' => 10, 'b' => 11, 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15, 
		others => 1000);

	function DigitValue (VALUE : digit; BASE : base_type := 10) return integer is
		constant RES : integer := TO_INTEGER(VALUE);
	begin
		assert RES < BASE report "Incorrect digit in that base !" severity error;
		return RES;
	end DigitValue;

	----------------------------

	function IsDigit (VALUE : character; BASE : base_type := 10) return boolean is
	begin
		return TO_INTEGER(VALUE) < BASE;
	end IsDigit;	-- function

	----------------------------

	function IsBlank (S : string) return boolean is
	begin
		return LeadBlank(S) = StrLen(S);
	end IsBlank;	-- function

	----------------------------

	function LeadBlank (S : string) return integer is
		constant L : integer := S'length;
		alias Si : string (1 to L) is S;
	begin
		for i in 0 to L - 1 loop
			if not (Si(i + 1) = ' ' or Si(i + 1) = HT) then return i; end if;
		end loop;
		return L;
	end LeadBlank;	-- function

	----------------------------
	constant a_A : integer := character'pos('a') - character'pos('A');

	function ToUpper (VALUE : character) return character is
	begin
		if 'a' <= VALUE and VALUE <= 'z' then
			return character'val(character'pos(VALUE) - a_A);
		else return VALUE;
		end if;
	end ToUpper;	-- function

	----------------------------

	function ToUpper (S : string) return string is
		variable Res : string (S'range);
	begin
		for i in S'range loop
			Res(i) := ToUpper(S(i));
		end loop;
		return Res;
	end ToUpper;	-- function

	----------------------------

	function ToLower (VALUE : character) return character is
	begin
		if 'A' <= VALUE and VALUE <= 'Z' then
			return character'val(character'pos(VALUE) + a_A);
		else return VALUE;
		end if;
	end ToLower;	-- function

	----------------------------

	function ToLower (S : string) return string is
		variable Res : string (S'range);
	begin
		for i in S'range loop
			Res(i) := ToLower(S(i));
		end loop;
		return Res;
	end ToLower;	-- function

	----------------------------

	function ToDigit (VALUE : natural) return character is
		constant TO_DIGIT_TABLE : string (1 to 16) := "0123456789ABCDEF"; 
	begin   
		if VALUE >= 16 then
			assert FALSE report "Not a digit !" severity error;
			return ' ';
		else return TO_DIGIT_TABLE(VALUE + 1);
		end if;
	end ToDigit;    -- function

	----------------------------

	function Mirror (S : string) return string is
		alias Si : string (1 to S'length) is S;
		constant L : integer := StrLen(S);
		variable Res : string (1 to S'length) := (others => NUL);
	begin
		for i in 1 to L loop
			Res(i) := Si(L - i + 1);
		end loop;
		return Res;
	end Mirror;	-- function

	----------------------------

	-- local procedure definition for extracting a natural from a string
	procedure GetNatural (variable S : inout string;
									variable N : out natural;
									BASE : base_type := 10) is
		constant L : integer := S'length;
		alias Si : string (1 to L) is S;
		variable Index : integer := 0;
		variable Ni : natural := 0;
	begin
		for i in 1 to L loop
			exit when not IsDigit(Si(i), BASE);
			Ni := Ni * BASE + DigitValue(Si(i), BASE);
			Index := Index + 1;
		end loop;
		N := Ni;
		Shift(Si, Index);
	end GetNatural;	-- procedure

	----------------------------

	function ToString (VALUE : integer; FORMAT : string := "%d") return string is
		variable Si : string (1 to FORMAT'length) := FORMAT;
		variable FieldWidth : natural := 0;
		type case_type is (UPPER, LOWER);
		variable MyCase : case_type;
		variable BaseValue : base_type := 10;
		variable Res : string(BUF_SIZE downto 1)  := (others => ' ');
		variable Index : integer := 1;
		variable VAbs : integer := abs(VALUE);
		variable FillZero : boolean := FALSE;
	begin
		assert StrLen(Si) > 1 and Si(1) = '%' 
			report "Wrong format in string conversion !" severity error;
		Shift(Si);
		if Si(1) = '0' then
			FillZero := TRUE;
			Res := ZERO_BUFFER;
		end if;
		if IsDigit(Si(1)) then GetNatural(Si, FieldWidth); end if;
		assert FieldWidth < Res'length 
				report "Wrong format in string conversion !" severity error;
		case Si(1) is
			when 'b' => MyCase := UPPER; BaseValue := 2;
			when 'd' => MyCase := UPPER; BaseValue := 10;
			when 'x' => MyCase := LOWER; BaseValue := 16;
			when 'X' => MyCase := UPPER; BaseValue := 16;
			when others => assert FALSE
				report "Wrong format in string conversion !" severity error;
		end case;
		assert StrLen(Si) = 1
			report "Wrong format in string conversion !" severity error;
		
		loop
			Res(Index) := ToDigit(VAbs mod BaseValue);
			VAbs := VAbs / BaseValue;
			Index := Index + 1;
			exit when VAbs = 0;
		end loop;
		
		if VALUE < 0 then
			if FillZero and Index <= FieldWidth then
				Index := FieldWidth + 1;
				Res(Index - 1) := '-';
			else
				Res(Index) := '-';
				Index := Index + 1;
			end if;
		end if;
		if Index <= FieldWidth then Index := FieldWidth + 1; end if;
		if MyCase = LOWER then return ToLower(Res(Index - 1 downto 1));
		else return Res(Index - 1 downto 1);
		end if;
	end ToString;	-- function

	----------------------------

	function ToString (VALUE : real; FORMAT : string := "%") return string is
		variable Si : string (1 to FORMAT'length) := FORMAT;
		variable FieldWidth : natural := 0;
		variable Precision : natural := 0;
		variable Index : integer := 1;
		variable FillZero : boolean := FALSE;
		variable L : line;
	begin
		assert StrLen(Si) > 0 and Si(1) = '%' 
			report "Wrong format in string conversion !" severity error;
		Shift(Si);
		FillZero := Si(1) = '0';
		if IsDigit(Si(1)) then GetNatural(Si, FieldWidth); end if;
		if Si(1) = '.' then
			Shift(Si);
			if IsDigit(Si(1)) then GetNatural(Si, Precision); end if;
		end if;
		assert StrLen(Si) = 0
			report "Wrong format in string conversion !" severity error;
		write(L => L, VALUE => VALUE, FIELD => FieldWidth, DIGITS => Precision);
		if FillZero and L(1) = ' ' then
			for i in 1 to L'length loop
				case L(i) is
					when '-' => L(i) := '0'; exit;
					when ' ' => L(i) := '0';
					when others => exit;
				end case;
			end loop;
			if VALUE < 0.0 then L(1) := '-'; end if;
		end if;
		return L.all;
	end ToString;	-- function

	----------------------------

	function ToString (VALUE : time; FORMAT : string := "% ns") return string is
		variable Si : string (1 to FORMAT'length) := FORMAT;
		variable FieldWidth : natural := 0;
		variable Unit : time := ns;
		variable L : line;
	begin
		assert StrLen(Si) > 0 and Si(1) = '%' 
			report "Wrong format in string conversion !" severity error;
		Shift(Si);
		if IsDigit(Si(1)) then GetNatural(Si, FieldWidth); end if;
		assert Si(1) = ' ' or Si(1) = HT
			report "No blank between time value and unit !"
			severity error;
		Shift(Si, LeadBlank(Si));
		if StrEqu(Si, "fs") then Unit := 1.0E-6 ns;	-- avoid warning
		elsif StrNcEqu(Si, "ps") then Unit := 1.0E-3 ns;	-- avoid warning
		elsif StrNcEqu(Si, "ns") then Unit := ns;	-- conform to textio
		elsif StrNcEqu(Si, "us") then Unit := us;
		elsif StrNcEqu(Si, "ms") then Unit := ms;
		elsif StrNcEqu(Si, "sec") then Unit := sec;
--		elsif StrNcEqu(Si, "min") then Unit := min;
--		elsif StrNcEqu(Si, "hr") then Unit := hr;
		else 
			assert FALSE report "Wrong format in string conversion !" severity error;
		end if;
		write(L => L, VALUE => VALUE, FIELD => FieldWidth, UNIT => Unit);
		return L.all;
	end ToString;	-- function

	----------------------------

	function ToString (VALUE : boolean) return string is
	begin	
		if VALUE then return "TRUE";
		else return "FALSE";
		end if;
	end ToString;	-- function

	----------------------------

	type bit_to_char_table is 
			array(bit'low to bit'high) of character;
	constant BIT_TO_CHAR : bit_to_char_table := ('0', '1');
	type std_ulogic_to_char_table is 
			array(std_ulogic'low to std_ulogic'high) of character;
	constant STD_ULOGIC_TO_CHAR : std_ulogic_to_char_table :=
			('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');

	function ToString (VALUE : std_ulogic) return string	is
	begin	
		return STD_ULOGIC_TO_CHAR(VALUE) & "";
	end ToString;	-- function

	----------------------------

	function ToString (VALUE : bit) return string is
	begin
		return BIT_TO_CHAR(VALUE) & "";
	end ToString;	-- function

	----------------------------

	function ToString (VALUE : bit_vector) return string is
    constant L : integer := VALUE'length;
	  alias Vec : bit_vector(1 to L) is VALUE;
		variable Res : string (1 to L);
	begin
		for i in Res'range loop
			Res(i) := BIT_TO_CHAR(Vec(i));
		end loop;
		return Res;
	end ToString;	-- function

	----------------------------

	function ToString (VALUE : std_ulogic_vector) return string is
    constant L : integer := VALUE'length;
	  alias Vec : std_ulogic_vector(1 to L) is VALUE;
		variable Res : string (1 to L);
	begin
		for i in Res'range loop
			Res(i) := STD_ULOGIC_TO_CHAR(Vec(i));
		end loop;
		return Res;
	end ToString;	-- function

	----------------------------

	function ToString (VALUE : std_logic_vector) return string is
    constant L : integer := VALUE'length;
	  alias Vec : std_logic_vector(1 to L) is VALUE;
		variable Res : string (1 to L);
	begin
		for i in Res'range loop
			Res(i) := STD_ULOGIC_TO_CHAR(Vec(i));
		end loop;
		return Res;
	end ToString;	-- function

	----------------------------

	function FromString (S : string; BASE : base_type := 10) return integer is
		variable L : natural := S'length;
		variable Si : string (1 to L) := S;
		variable Res : integer := 0;
		variable Invert : boolean := FALSE;
		variable Index : natural := LeadBlank(Si) + 1;
	begin
		if Index <= L and Si(Index) = '-' then
			Invert := TRUE;
			Index := Index + 1;
		end if;
		if Index > L or not IsDigit(Si(Index), BASE) then 
			assert FALSE report "Not an integer string !" severity error;
			return Res;
		end if;
		while Index <= L and IsDigit(Si(Index), BASE) loop
			Res := Res * BASE + DigitValue(Si(Index), BASE);
			Index := Index + 1;
		end loop;
		assert Index > L or Si(Index) = NUL or Si(Index) = ' ' or Si(Index) = HT
				report "Not an integer string !" severity error;
		if Invert then return -Res;
		else return Res;
		end if;
	end FromString;	-- function

	----------------------------

	function FromString (S : string) return real is
		variable L : line;
		variable Success : boolean;
		variable Res : real := 0.0;
	begin
		Write(L, S);
		Read(L, Res, Success);
		assert Success report "Not a real string !" severity error;
		return Res;
	end FromString;	-- function

	----------------------------

	function FromString (S : string) return time is

⌨️ 快捷键说明

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