grt-sdf.adb

来自「vhdl集成电路设计软件.需要用gcc-4.0.2版本编译.」· ADB 代码 · 共 1,333 行 · 第 1/3 页

ADB
1,333
字号
               Add ("10");            when Edge_0z =>               Add ("0z");            when Edge_Z1 =>               Add ("Z1");            when Edge_1z =>               Add ("1z");            when Edge_Z0 =>               Add ("ZO");            when Edge_None =>               if Force then                  Add ("noedge");               end if;            when Edge_Error =>               Add ("?");         end case;      end Add_Edge;      Ok : Boolean;   begin      case Sdf_Context.Kind is         when Delay_Iopath =>            Start ("tpd");         when Delay_Port =>            Start ("tipd");         when Timingcheck_Setup =>            Start ("tsetup");         when Timingcheck_Hold =>            Start ("thold");         when Timingcheck_Setuphold =>            Start ("tsetup");         when Timingcheck_Recovery =>            Start ("trecovery");         when Timingcheck_Skew =>            Start ("tskew");         when Timingcheck_Width =>            Start ("tpw");         when Timingcheck_Period =>            Start ("tperiod");         when Timingcheck_Nochange =>            Start ("tncsetup");      end case;      for I in 1 .. Sdf_Context.Port_Num loop         Add (Sdf_Context.Ports (I).Name              (1 .. Sdf_Context.Ports (I).Name_Len));      end loop;      if Sdf_Context.Kind in Timing_Generic_Full_Condition then         Add_Edge (Sdf_Context.Ports (1).Edge, True);         Add_Edge (Sdf_Context.Ports (2).Edge, False);      elsif Sdf_Context.Kind in Timing_Generic_Simple_Condition then         Add_Edge (Sdf_Context.Ports (1).Edge, False);      end if;      Vital_Annotate.Sdf_Generic (Sdf_Context.all, Name (1 .. Len), Ok);      if not Ok then         Error_Sdf ("could not annotate generic");         return False;      end if;      return True;   end Handle_Generic;   function Parse_Sdf return Boolean   is      Tok : Sdf_Token_Type;      Ok : Boolean;   begin      if Get_Token /= Tok_Oparen        or else Get_Token /= Tok_Identifier        or else not Is_Ident ("DELAYFILE")        or else Get_Token /= Tok_Oparen        or else Get_Token /= Tok_Identifier      then         Error_Sdf ("not an SDF file");         return False;      end if;      if Is_Ident ("SDFVERSION") then         Tok := Get_Token;         if Tok = Tok_Qstring then            Sdf_Context.Version := Sdf_Version_Bad;            if Ident_Length = 3 and then Buf (Ident_Start + 1) = '.' then               --  Version has the format '"X.Y"' (without simple quote).               if Buf (Ident_Start) = '2'                 and then Buf (Ident_Start + 2) = '1'               then                  Sdf_Context.Version := Sdf_2_1;               end if;            end if;            Tok := Get_Token;         end if;         if not Expect_Cp_Op_Ident (Tok) then            return False;         end if;      end if;      if not Expect_Qstr_Cp_Op_Ident ("DESIGN") then         return False;      end if;      if not Expect_Qstr_Cp_Op_Ident ("DATE") then         return False;      end if;      if not Expect_Qstr_Cp_Op_Ident ("VENDOR") then         return False;      end if;      if not Expect_Qstr_Cp_Op_Ident ("PROGRAM") then         return False;      end if;      if not Expect_Qstr_Cp_Op_Ident ("VERSION") then         return False;      end if;      if Is_Ident ("DIVIDER") then         Tok := Get_Token;         if Tok = Tok_Div or Tok = Tok_Dot then            Tok := Get_Token;         end if;         if not Expect_Cp_Op_Ident (Tok) then            return False;         end if;      end if;      if Is_Ident ("VOLTAGE") then         if not Expect_Rexpr_Cp_Op_Ident then            return False;         end if;      end if;      if not Expect_Qstr_Cp_Op_Ident ("PROCESS") then         return False;      end if;      if Is_Ident ("TEMPERATURE") then         if not Expect_Rexpr_Cp_Op_Ident then            return False;         end if;      end if;      if Is_Ident ("TIMESCALE") then         Tok := Get_Token;         if Tok = Tok_Rnumber or Tok = Tok_Dnumber then            if Scan_Exp = 0 and (Scan_Int = 1                                 or Scan_Int = 10                                 or Scan_Int = 100)            then               Sdf_Context.Timescale := Scan_Int;            else               Error_Sdf ("bad timescale value");               return False;            end if;            Tok := Get_Token;            if Tok /= Tok_Identifier then               Error_Sdf (Tok_Identifier);            end if;            if Is_Ident ("ps") then               null;            elsif Is_Ident ("ns") then               Sdf_Context.Timescale := Sdf_Context.Timescale * 1000;            elsif Is_Ident ("us") then               Sdf_Context.Timescale := Sdf_Context.Timescale * 1000_000;            else               Error_Sdf ("bad timescale unit");               return False;            end if;            Tok := Get_Token;         end if;         if not Expect_Cp_Op_Ident (Tok) then            return False;         end if;      end if;      Vital_Annotate.Sdf_Header (Sdf_Context.all);      --  Parse cell+      loop         if not Is_Ident ("CELL") then            Error_Sdf ("CELL expected");            return False;         end if;         --  Parse celltype         if Get_Token /= Tok_Oparen           or else Get_Token /= Tok_Identifier           or else not Is_Ident ("CELLTYPE")           or else Get_Token /= Tok_Qstring         then            Error_Sdf ("CELLTYPE expected");            return False;         end if;         Sdf_Context.Celltype_Len := Ident_Length;         if Sdf_Context.Celltype_Len > Sdf_Context.Celltype'Length then            Error_Sdf ("CELLTYPE qstring is too long");            return False;         end if;         for I in Ident_Start .. Ident_End loop            Sdf_Context.Celltype (I - Ident_Start + 1) := To_Lower (Buf (I));         end loop;         Vital_Annotate.Sdf_Celltype (Sdf_Context.all);         if Get_Token /= Tok_Cparen           or else Get_Token /= Tok_Oparen           or else Get_Token /= Tok_Identifier           or else not Is_Ident ("INSTANCE")         then            Error_Sdf ("INSTANCE expected");            return False;         end if;         --  Parse instance+         loop            exit when not Is_Ident ("INSTANCE");            Tok := Get_Token;            if Tok /= Tok_Cparen then               if Tok /= Tok_Identifier then                  Error_Sdf ("instance identifier expected");                  return False;               end if;               for I in Ident_Start .. Ident_End loop                  Buf (I) := To_Lower (Buf (I));               end loop;               Vital_Annotate.Sdf_Instance                 (Sdf_Context.all, Buf (Ident_Start .. Ident_End), Ok);               if not Ok then                  Error_Sdf ("cannot find instance");                  return False;               end if;               Tok := Get_Token;            end if;            if Tok /= Tok_Cparen              or else Get_Token /= Tok_Oparen              or else Get_Token /= Tok_Identifier            then               Error_Sdf ("instance or timing_spec expected");               return False;            end if;         end loop;         Vital_Annotate.Sdf_Instance_End (Sdf_Context.all, Ok);         if not Ok then            Error_Sdf ("bad instance or celltype mistmatch");            return False;         end if;         --  Parse timing_spec+         loop            if Is_Ident ("DELAY") then               --  Parse deltype+               Tok := Get_Token;               loop                  if Tok /= Tok_Oparen                    or else Get_Token /= Tok_Identifier                  then                     Error_Sdf ("deltype expected");                     return False;                  end if;                  if Is_Ident ("PATHPULSE")                    or else Is_Ident ("GLOBALPATHPULSE")                  then                     Error_Sdf ("PATHPULSE and GLOBALPATHPULSE not allowed");                     return False;                  end if;                  if Is_Ident ("ABSOLUTE") then                     null;                  elsif Is_Ident ("INCREMENT") then                     null;                  else                     Error_Sdf ("ABSOLUTE or INCREMENT expected");                     return False;                  end if;                  --  Parse absvals+ or incvals+                  Tok := Get_Token;                  loop                     if Tok /= Tok_Oparen                       or else Get_Token /= Tok_Identifier                     then                        Error_Sdf ("absvals or incvals expected");                        return False;                     end if;                     if Is_Ident ("IOPATH") then                        Start_Generic_Name (Delay_Iopath);                        if not Parse_Port_Spec                          or else not Parse_Port_Path                          or else not Parse_Rvalue                        then                           return False;                        end if;                     elsif Is_Ident ("PORT") then                        Start_Generic_Name (Delay_Port);                        if not Parse_Port_Path                          or else not Parse_Rvalue                        then                           return False;                        end if;                     elsif Is_Ident ("COND")                       or else Is_Ident ("INTERCONNECT")                       or else Is_Ident ("DEVICE")                     then                        Error_Sdf                          ("COND, INTERCONNECT, or DEVICE not handled");                        return False;                     elsif Is_Ident ("NETDELAY") then                        Error_Sdf ("NETDELAY not allowed in VITAL SDF");                        return False;                     else                        Error_Sdf ("absvals or incvals expected");                        return False;                     end if;                     if not Handle_Generic then                        return False;                     end if;                     Tok := Get_Token;                     exit when Tok = Tok_Cparen;                  end loop;                  Tok := Get_Token;                  exit when Tok = Tok_Cparen;               end loop;            elsif Is_Ident ("TIMINGCHECK") then               --  parse tc_def+               Tok := Get_Token;               loop                  if Tok /= Tok_Oparen                    or else Get_Token /= Tok_Identifier                  then                     Error_Sdf ("tc_def expected");                     return False;                  end if;                  if Is_Ident ("SETUP") then                     Start_Generic_Name (Timingcheck_Setup);                  elsif Is_Ident ("HOLD") then                     Start_Generic_Name (Timingcheck_Hold);                  elsif Is_Ident ("SETUPHOLD") then                     Start_Generic_Name (Timingcheck_Setuphold);                  elsif Is_Ident ("RECOVERY") then                     Start_Generic_Name (Timingcheck_Recovery);                  elsif Is_Ident ("SKEW") then                     Start_Generic_Name (Timingcheck_Skew);                  elsif Is_Ident ("WIDTH") then                     Start_Generic_Name (Timingcheck_Width);                  elsif Is_Ident ("PERIOD") then                     Start_Generic_Name (Timingcheck_Period);                  elsif Is_Ident ("NOCHANGE") then                     Start_Generic_Name (Timingcheck_Nochange);                  elsif Is_Ident ("PATHCONSTRAINT")                    or else Is_Ident ("SUM")                    or else Is_Ident ("DIFF")                    or else Is_Ident ("SKEWCONSTRAINT")                  then                     Error_Sdf ("non-VITAL tc_def");                     return False;                  else                     Error_Sdf ("bad tc_def");                     return False;                  end if;                  case Sdf_Context.Kind is                     when Timingcheck_Setup                       | Timingcheck_Hold                       | Timingcheck_Recovery                       | Timingcheck_Skew                       | Timingcheck_Setuphold                       | Timingcheck_Nochange =>                        if not Parse_Port_Tchk                          or else not Parse_Port_Tchk                          or else not Parse_Simple_Tc_Rvalue                        then                           return False;                        end if;                     when Timingcheck_Width                       | Timingcheck_Period =>                        if not Parse_Port_Tchk                          or else not Parse_Simple_Tc_Rvalue                        then                           return False;                        end if;                     when others =>                        Internal_Error ("sdf_parse");                  end case;                  if not Handle_Generic then                     return False;                  end if;                  case Sdf_Context.Kind is                     when Timingcheck_Setuphold                       | Timingcheck_Nochange =>                        if not Parse_Simple_Tc_Rvalue then                           return False;                        end if;                        Error_Sdf ("setuphold and nochange not yet handled");                        return False;                     when others =>                        null;                  end case;                  if Get_Token /= Tok_Cparen then                     Error_Sdf (Tok_Cparen);                     return False;                  end if;                  Tok := Get_Token;                  exit when Tok = Tok_Cparen;               end loop;            end if;            Tok := Get_Token;            exit when Tok = Tok_Cparen;            if Tok /= Tok_Oparen then               Error_Sdf (Tok_Oparen);               return False;            end if;            if Get_Token /= Tok_Identifier then               Error_Sdf (Tok_Identifier);               return False;            end if;         end loop;         Tok := Get_Token;         exit when Tok = Tok_Cparen;         if Tok /= Tok_Oparen           or else Get_Token /= Tok_Identifier         then            Error_Sdf (Tok_Identifier);         end if;      end loop;      if Get_Token /= Tok_Eof then         Error_Sdf ("EOF expected");         return False;      end if;      return True;   end Parse_Sdf;   function Parse_Sdf_File (Filename : String) return Boolean   is      Res : Boolean;   begin      if not Open_Sdf (Filename) then         return False;      end if;      Res := Parse_Sdf;      Close_Sdf;      return Res;   end Parse_Sdf_File;end Grt.Sdf;

⌨️ 快捷键说明

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