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