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