diff --git a/src/completion/keyword.rs b/src/completion/keyword.rs index f9ff6f7..7a448cd 100644 --- a/src/completion/keyword.rs +++ b/src/completion/keyword.rs @@ -1,6 +1,6 @@ use tower_lsp::lsp_types::*; -// + pub fn keyword_completions(keywords: &[(&str, &str)]) -> Vec { let mut items: Vec = Vec::new(); for key in keywords { @@ -34,6 +34,7 @@ pub fn other_completions(tasks: &[&str]) -> Vec { .collect() } +/// (&str, &str, &str): (label, snippet, description) pub const VLOG_KEYWORDS: &[(&str, &str)] = &[ ("accept_on", ""), ("alias", ""), @@ -285,156 +286,6 @@ pub const VLOG_KEYWORDS: &[(&str, &str)] = &[ ("xor", ""), ]; -pub const SYS_TASKS: &[&str] = &[ - "finish", - "exit", - "fatal", - "warning", - "stop", - "error", - "info", - "realtime", - "time", - "asserton", - "assertkill", - "assertpasson", - "assertfailon", - "assertnonvacuouson", - "stime", - "printtimescale", - "timeformat", - "bitstoreal", - "bitstoshortreal", - "itor", - "signed", - "cast", - "realtobits", - "shortrealtobits", - "rtoi", - "unsigned", - "sampled", - "fell", - "changed", - "past_gclk", - "fell_gclk", - "changed_gclk", - "rising_gclk", - "steady_gclk", - "bits", - "typename", - "isunbounded", - "coverage_control", - "coverage_get", - "coverage_save", - "set_coverage_db_name", - "dimensions", - "right", - "high", - "size", - "random", - "dist_erlang", - "dist_normal", - "dist_t", - "asin", - "acos", - "atan", - "atan2", - "hypot", - "sinh", - "cosh", - "tanh", - "asinh", - "acosh", - "atanh", - "q_initialize", - "q_remove", - "q_exam", - "q_add", - "q_full", - "async$and$array", - "async$nand$array", - "async$or$array", - "async$nor$array", - "sync$and$array", - "sync$nand$array", - "sync$or$array", - "sync$nor$array", - "countones", - "onehot0", - "fatal", - "warning", - "dist_chi_square", - "dist_exponential", - "dist_poisson", - "dist_uniform", - "countbits", - "onehot", - "isunknown", - "coverage_get_max", - "coverage_merge", - "get_coverage", - "load_coverage_db", - "clog2", - "ln", - "log10", - "exp", - "sqrt", - "pow", - "floor", - "ceil", - "sin", - "cos", - "tan", - "rose", - "stable", - "past", - "rose_gclk", - "stable_gclk", - "future_gclk", - "falling_gclk", - "changing_gclk", - "unpacked_dimensions", - "left", - "low", - "increment", - "assertoff", - "assertcontrol", - "assertpassoff", - "assertfailoff", - "assertvacuousoff", - "error", - "info", - "async$and$plane", - "async$nand$plane", - "async$or$plane", - "async$nor$plane", - "sync$and$plane", - "sync$nand$plane", - "sync$or$plane", - "sync$nor$plane", - "system", - "countdrivers", - "getpattern", - "incsave", - "input", - "key", - "list", - "log", - "nokey", - "nolog", - "reset", - "reset_count", - "reset_value", - "restart", - "save", - "scale", - "scope", - "showscopes", - "showvars", - "sreadmemb", - "sreadmemh", -]; - pub const DIRECTIVES: &[&str] = &[ "__FILE__", "__LINE__", diff --git a/src/completion/mod.rs b/src/completion/mod.rs index ddaf741..7fc105d 100644 --- a/src/completion/mod.rs +++ b/src/completion/mod.rs @@ -3,9 +3,13 @@ use tower_lsp::lsp_types::*; pub mod keyword; pub mod feature; +pub mod sys_tasks; + +pub use sys_tasks::provide_vlog_sys_tasks_completions; mod vhdl; mod sv; + impl LSPServer { pub fn completion(&self, params: CompletionParams) -> Option { let language_id = get_language_id_by_uri(¶ms.text_document_position.text_document.uri); diff --git a/src/completion/sv.rs b/src/completion/sv.rs index 6b5e2a2..1fe5922 100644 --- a/src/completion/sv.rs +++ b/src/completion/sv.rs @@ -68,7 +68,8 @@ pub fn completion(server: &LSPServer, params: &CompletionParams) -> Option>( server.vlog_keyword_completion_items .iter() @@ -76,8 +77,12 @@ pub fn completion(server: &LSPServer, params: &CompletionParams) -> Option>( make_module_completions(server, &token, &language_id) ); diff --git a/src/completion/sys_tasks.rs b/src/completion/sys_tasks.rs new file mode 100644 index 0000000..f50df2f --- /dev/null +++ b/src/completion/sys_tasks.rs @@ -0,0 +1,382 @@ +use tower_lsp::lsp_types::*; + +/// 文档:ieee1364 page 308 +/// author: LSTM-Kirigaya +/// date: 2024.12.03 + +/// Display and write tasks ieee1364 17.1.1 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_DISPLAY_WRITE_TASKS: &[(&str, &str, &str)] = &[ + ("display", "$display($1);", "打印格式化字符串到标准输出。\n```verilog\n$display(\"Hello, World!\");\n```"), + ("displayb", "$displayb($1);", "以二进制格式打印表达式。\n```verilog\n$displayb(data);\n```"), + ("displayo", "$displayo($1);", "以八进制格式打印表达式。\n```verilog\n$displayo(data);\n```"), + ("displayh", "$displayh($1);", "以十六进制格式打印表达式。\n```verilog\n$displayh(data);\n```"), + + ("write", "$write($1);", "类似于 $display,但不自动添加换行符。\n```verilog\n$write(\"Hello, World!\");\n```"), + ("writeb", "$writeb($1);", "以二进制格式打印表达式,不自动添加换行符。\n```verilog\n$writeb(data);\n```"), + ("writeo", "$writeo($1);", "以八进制格式打印表达式,不自动添加换行符。\n```verilog\n$writeo(data);\n```"), + ("writeh", "$writeh($1);", "以十六进制格式打印表达式,不自动添加换行符。\n```verilog\n$writeh(data);\n```"), +]; + +/// Strobed monitoring ieee1364 17.1.2 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_STROBED_MONITOR_TASKS: &[(&str, &str, &str)] = &[ + ("strobe", "$strobe($1);", "在当前时间步结束时打印格式化字符串。\n```verilog\n$strobe(\"Data: %d\", data);\n```"), + ("strobeb", "$strobeb($1);", "在当前时间步结束时以二进制格式打印表达式。\n```verilog\n$strobeb(data);\n```"), + ("strobeo", "$strobeo($1);", "在当前时间步结束时以八进制格式打印表达式。\n```verilog\n$strobeo(data);\n```"), + ("strobeh", "$strobeh($1);", "在当前时间步结束时以十六进制格式打印表达式。\n```verilog\n$strobeh(data);\n```"), +]; + +/// Continuous monitoring tasks ieee1364 17.1.3 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_CONTINUOUS_MONITORING_TASKS: &[(&str, &str, &str)] = &[ + ("monitor", "$monitor($1);", "监控变量并在变量变化时打印。\n```verilog\n$monitor(\"Data: %d\", data);\n```"), + ("monitorb", "$monitorb($1);", "监控变量并在变量变化时以二进制格式打印。\n```verilog\n$monitorb(data);\n```"), + ("monitoro", "$monitoro($1);", "监控变量并在变量变化时以八进制格式打印。\n```verilog\n$monitoro(data);\n```"), + ("monitorh", "$monitorh($1);", "监控变量并在变量变化时以十六进制格式打印。\n```verilog\n$monitorh(data);\n```"), + ("monitoron", "$monitoron();", "启用监控任务。\n```verilog\n$monitoron();\n```"), + ("monitoroff", "$monitoroff();", "关闭监控任务。\n```verilog\n$monitoroff();\n```"), +]; + +/// File input-output system tasks and functions ieee1364 17.2.1 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_FILE_IO_TASKS: &[(&str, &str, &str)] = &[ + ("fopen", "$fopen($1);", "打开文件并返回文件句柄。\n```verilog\ninteger file_handle;\n// 默认以 \"w\" 作为 flag,如果 file_handle == 0,文件打开失败,file_handle == 1,文件打开成功\nfile_handle = $fopen(\"data.bin\", \"r\");\n```\n\n其余文件描述符\n| 参数 | 描述 |\n|------|-------|\n| `r` 或 `rb` | 以只读方式打开文件 |\n| `w` 或 `wb` | 截断文件长度为零或创建新文件以进行写入 |\n| `a` 或 `ab` | 追加;在文件末尾打开以进行写入,或创建新文件以进行写入 |\n| `r+`、`r+b` 或 `rb+` | 以读写方式打开文件 |\n| `w+`、`w+b` 或 `wb+` | 截断文件或创建新文件以进行读写 |\n| `a+`、`a+b` 或 `ab+` | 追加;在文件末尾打开或创建新文件以进行读写 |"), + ("fclose", "$fclose($1);", "关闭文件。\n```verilog\n$fclose(file_handle);\n```"), +]; + +/// File output system tasks ieee1364 17.2.2 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_FILE_OUTPUT_TASKS: &[(&str, &str, &str)] = &[ + ("fdisplay", "$fdisplay($1, $2);", "将格式化字符串写入文件。\n```verilog\n$fdisplay(file_handle, \"Data: %d\", data);\n```"), + ("fdisplayb", "$fdisplayb($1, $2);", "将二进制格式的表达式写入文件。\n```verilog\n$fdisplayb(file_handle, data);\n```"), + ("fdisplayo", "$fdisplayo($1, $2);", "将八进制格式的表达式写入文件。\n```verilog\n$fdisplayo(file_handle, data);\n```"), + ("fdisplayh", "$fdisplayh($1, $2);", "将十六进制格式的表达式写入文件。\n```verilog\n$fdisplayh(file_handle, data);\n```"), + + ("fwrite", "$fwrite($1, $2);", "将格式化字符串写入文件,不自动添加换行符。\n```verilog\n$fwrite(file_handle, \"Data: %d\", data);\n```"), + ("fwriteb", "$fwriteb($1, $2);", "将二进制格式的表达式写入文件,不自动添加换行符。\n```verilog\n$fwriteb(file_handle, data);\n```"), + ("fwriteo", "$fwriteo($1, $2);", "将八进制格式的表达式写入文件,不自动添加换行符。\n```verilog\n$fwriteo(file_handle, data);\n```"), + ("fwriteh", "$fwriteh($1, $2);", "将十六进制格式的表达式写入文件,不自动添加换行符。\n```verilog\n$fwriteh(file_handle, data);\n```"), + + ("fstrobe", "$fstrobe($1, $2);", "在当前时间步结束时将格式化字符串写入文件。\n```verilog\n$fstrobe(file_handle, \"Data: %d\", data);\n```"), + ("fstrobeb", "$fstrobeb($1, $2);", "在当前时间步结束时将二进制格式的表达式写入文件。\n```verilog\n$fstrobeb(file_handle, data);\n```"), + ("fstrobeo", "$fstrobeo($1, $2);", "在当前时间步结束时将八进制格式的表达式写入文件。\n```verilog\n$fstrobeo(file_handle, data);\n```"), + ("fstrobeh", "$fstrobeh($1, $2);", "在当前时间步结束时将十六进制格式的表达式写入文件。\n```verilog\n$fstrobeh(file_handle, data);\n```"), + + ("fmonitor", "$fmonitor($1, $2);", "监控变量并在变量变化时写入文件。\n```verilog\n$fmonitor(file_handle, \"Data: %d\", data);\n```"), + ("fmonitorb", "$fmonitorb($1, $2);", "监控变量并在变量变化时将二进制格式的表达式写入文件。\n```verilog\n$fmonitorb(file_handle, data);\n```"), + ("fmonitoro", "$fmonitoro($1, $2);", "监控变量并在变量变化时将八进制格式的表达式写入文件。\n```verilog\n$fmonitoro(file_handle, data);\n```"), + ("fmonitorh", "$fmonitorh($1, $2);", "监控变量并在变量变化时将十六进制格式的表达式写入文件。\n```verilog\n$fmonitorh(file_handle, data);\n```"), +]; + + +/// Formatting data to a string tasks ieee1364 17.2.3 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_FORMATTING_TASKS: &[(&str, &str, &str)] = &[ + ("sscanf", "$sscanf($1, $2, $3);", "从字符串中读取格式化数据。\n```verilog\ninteger value;\n$sscanf(\"123\", \"%d\", value);\n```"), + ("swrite", "$swrite($1, $2);", "将格式化字符串存储到字符串变量中,不自动添加换行符。\n```verilog\nstring formatted_string;\n$swrite(formatted_string, \"Data: %d\", data);\n```"), + ("swriteb", "$swriteb($1, $2);", "将二进制格式的表达式存储到字符串变量中,不自动添加换行符。\n```verilog\nstring formatted_string;\n$swriteb(formatted_string, data);\n```"), + ("swriteo", "$swriteo($1, $2);", "将八进制格式的表达式存储到字符串变量中,不自动添加换行符。\n```verilog\nstring formatted_string;\n$swriteo(formatted_string, data);\n```"), + ("swriteh", "$swriteh($1, $2);", "将十六进制格式的表达式存储到字符串变量中,不自动添加换行符。\n```verilog\nstring formatted_string;\n$swriteh(formatted_string, data);\n```"), + ("sformat", "$sformat($1, $2);", "将格式化字符串存储到字符串变量中。\n```verilog\nstring formatted_string;\n$sformat(formatted_string, \"Data: %d\", data);\n```"), +]; + +/// Reading data from a file tasks ieee1364 17.2.4 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_FILE_READING_TASKS: &[(&str, &str, &str)] = &[ + // 17.2.4.1 Reading a character at a time + ("fgetc", "$fgetc($1);", "从文件中读取一个字符。\n```verilog\ninteger char;\nchar = $fgetc(file_handle);\n```"), + ("ungetc", "$ungetc($1, $2);", "将字符推回到文件流中。\n```verilog\n$ungetc(char, file_handle);\n```"), + + // 17.2.4.2 Reading a line at a time + ("fgets", "$fgets($1, $2, $3);", "从文件中读取一行数据。\n```verilog\nstring line;\n$fgets(line, file_handle);\n```"), + + // 17.2.4.3 Reading formatted data + ("fscanf", "$fscanf($1, $2, $3);", "从文件中读取格式化数据。\n```verilog\ninteger value;\n$fscanf(file_handle, \"%d\", value);\n```"), + ("sscanf", "$sscanf($1, $2, $3);", "从字符串中读取格式化数据。\n```verilog\ninteger value;\n$sscanf(\"123\", \"%d\", value);\n```"), +]; + +/// File positioning tasks ieee1364 17.2.5 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_FILE_POSITIONING_TASKS: &[(&str, &str, &str)] = &[ + ("fseek", "$fseek($1, $2, $3);", "设置文件指针位置。\n```verilog\n$fseek(file_handle, 0, 0);\n```"), + ("ftell", "$ftell($1);", "返回文件指针的当前位置。\n```verilog\ninteger position;\nposition = $ftell(file_handle);\n```"), + ("rewind", "$rewind($1);", "将文件指针重置到文件开头。\n```verilog\n$rewind(file_handle);\n```"), +]; + +/// Flushing output tasks ieee1364 17.2.6 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_FLUSHING_OUTPUT_TASKS: &[(&str, &str, &str)] = &[ + ("fflush", "$fflush($1);", "刷新文件缓冲区。\n```verilog\n$fflush(file_handle);\n```"), +]; + +/// I/O error status tasks ieee1364 17.2.7 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_IO_ERROR_STATUS_TASKS: &[(&str, &str, &str)] = &[ + ("ferror", "$ferror($1);", "检查文件读写错误。\n```verilog\ninteger error;\nerror = $ferror(file_handle);\n```"), +]; + +/// Detecting EOF tasks ieee1364 17.2.8 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_DETECTING_EOF_TASKS: &[(&str, &str, &str)] = &[ + ("feof", "$feof($1);", "检查文件是否到达文件末尾。\n```verilog\ninteger eof;\neof = $feof(file_handle);\n```"), +]; + +/// Loading memory data from a file tasks ieee1364 17.2.9 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_LOADING_MEMORY_TASKS: &[(&str, &str, &str)] = &[ + ("readmemb", "$readmemb($1, $2);", "从文件中读取二进制数据到内存。\n```verilog\n$readmemb(\"data.bin\", memory);\n```"), + ("readmemh", "$readmemh($1, $2);", "从文件中读取十六进制数据到内存。\n```verilog\n$readmemh(\"data.hex\", memory);\n```"), +]; + +/// Loading timing data from an SDF file tasks ieee1364 17.2.10 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_LOADING_TIMING_TASKS: &[(&str, &str, &str)] = &[ + ("sdf_annotate", "$sdf_annotate($1, $2);", "从 SDF 文件加载时序数据并应用于模块实例。\n```verilog\n$sdf_annotate(\"timing.sdf\", top_module);\n```"), +]; + +/// $printtimescale tasks ieee1364 17.3.1 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_PRINTTIMESCALE_TASKS: &[(&str, &str, &str)] = &[ + ("printtimescale", "$printtimescale($1);", "打印指定模块的时间刻度信息。\n```verilog\n$printtimescale(module_instance);\n```"), +]; + +/// $timeformat tasks ieee1364 17.3.2 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_TIMEFORMAT_TASKS: &[(&str, &str, &str)] = &[ + ("timeformat", "$timeformat($1, $2, $3, $4);", "设置时间格式。\n```verilog\n$timeformat(-9, 3, \" ns\", 8);\n```"), +]; + +/// $finish tasks ieee1364 17.4.1 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_FINISH_TASKS: &[(&str, &str, &str)] = &[ + ("finish", "$finish($1);", "终止仿真。\n```verilog\n$finish(0);\n```"), +]; + +/// $stop tasks ieee1364 17.4.2 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_STOP_TASKS: &[(&str, &str, &str)] = &[ + ("stop", "$stop($1);", "暂停仿真。\n```verilog\n$stop(0);\n```"), +]; + +/// Array types tasks ieee1364 17.5.1 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_ARRAY_TYPES_TASKS: &[(&str, &str, &str)] = &[ + ("async$and$array", "$async$and$array($1, $2);", "对数组进行异步与操作。\n```verilog\n$async$and$array(array1, array2);\n```"), + ("async$nand$array", "$async$nand$array($1, $2);", "对数组进行异步与非操作。\n```verilog\n$async$nand$array(array1, array2);\n```"), + ("async$or$array", "$async$or$array($1, $2);", "对数组进行异步或操作。\n```verilog\n$async$or$array(array1, array2);\n```"), + ("async$nor$array", "$async$nor$array($1, $2);", "对数组进行异步或非操作。\n```verilog\n$async$nor$array(array1, array2);\n```"), + ("sync$and$array", "$sync$and$array($1, $2);", "对数组进行同步与操作。\n```verilog\n$sync$and$array(array1, array2);\n```"), + ("sync$nand$array", "$sync$nand$array($1, $2);", "对数组进行同步与非操作。\n```verilog\n$sync$nand$array(array1, array2);\n```"), + ("sync$or$array", "$sync$or$array($1, $2);", "对数组进行同步或操作。\n```verilog\n$sync$or$array(array1, array2);\n```"), + ("sync$nor$array", "$sync$nor$array($1, $2);", "对数组进行同步或非操作。\n```verilog\n$sync$nor$array(array1, array2);\n```"), +]; + +/// Array logic types tasks ieee1364 17.5.2 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_ARRAY_LOGIC_TYPES_TASKS: &[(&str, &str, &str)] = &[ + ("async$and$plane", "$async$and$plane($1, $2);", "对数组平面进行异步与操作。\n```verilog\n$async$and$plane(plane1, plane2);\n```"), + ("async$nand$plane", "$async$nand$plane($1, $2);", "对数组平面进行异步与非操作。\n```verilog\n$async$nand$plane(plane1, plane2);\n```"), + ("async$or$plane", "$async$or$plane($1, $2);", "对数组平面进行异步或操作。\n```verilog\n$async$or$plane(plane1, plane2);\n```"), + ("async$nor$plane", "$async$nor$plane($1, $2);", "对数组平面进行异步或非操作。\n```verilog\n$async$nor$plane(plane1, plane2);\n```"), + ("sync$and$plane", "$sync$and$plane($1, $2);", "对数组平面进行同步与操作。\n```verilog\n$sync$and$plane(plane1, plane2);\n```"), + ("sync$nand$plane", "$sync$nand$plane($1, $2);", "对数组平面进行同步与非操作。\n```verilog\n$sync$nand$plane(plane1, plane2);\n```"), + ("sync$or$plane", "$sync$or$plane($1, $2);", "对数组平面进行同步或操作。\n```verilog\n$sync$or$plane(plane1, plane2);\n```"), + ("sync$nor$plane", "$sync$nor$plane($1, $2);", "对数组平面进行同步或非操作。\n```verilog\n$sync$nor$plane(plane1, plane2);\n```"), +]; + +/// $q_initialize tasks ieee1364 17.6.1 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_Q_INITIALIZE_TASKS: &[(&str, &str, &str)] = &[ + ("q_initialize", "$q_initialize($1, $2, $3, $4);", "创建新的队列。\n```verilog\n$q_initialize(q_id, q_type, max_length, status);\n```\n\nTable 17-14—队列类型表:\n\n| q_type 值 | 队列类型 |\n|-----------|----------|\n| 1 | 先进先出 |\n| 2 | 后进先出 |\n\nTable 17-16—状态代码表:\n\n| 状态代码 | 含义 |\n|----------|------|\n| 0 | 成功 |\n| 1 | 队列已满,无法添加 |\n| 2 | 未定义的 q_id |\n| 3 | 队列已空,无法移除 |\n| 4 | 不支持的队列类型,无法创建队列 |\n| 5 | 指定的长度 <= 0,无法创建队列 |\n| 6 | 重复的 q_id,无法创建队列 |\n| 7 | 内存不足,无法创建队列 |"), +]; + +/// $q_add tasks ieee1364 17.6.2 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_Q_ADD_TASKS: &[(&str, &str, &str)] = &[ + ("q_add", "$q_add($1, $2, $3, $4);", "向队列中添加一个条目。\n```verilog\n$q_add(q_id, job_id, inform_id, status);\n```\n\nTable 17-16—状态代码表:\n\n| 状态代码 | 含义 |\n|----------|------|\n| 0 | 成功 |\n| 1 | 队列已满,无法添加 |\n| 2 | 未定义的 q_id |\n| 3 | 队列已空,无法移除 |\n| 4 | 不支持的队列类型,无法创建队列 |\n| 5 | 指定的长度 <= 0,无法创建队列 |\n| 6 | 重复的 q_id,无法创建队列 |\n| 7 | 内存不足,无法创建队列 |"), +]; + +/// $q_remove tasks ieee1364 17.6.3 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_Q_REMOVE_TASKS: &[(&str, &str, &str)] = &[ + ("q_remove", "$q_remove($1, $2, $3, $4);", "从队列中移除一个条目。\n```verilog\n$q_remove(q_id, job_id, inform_id, status);\n```\n\nTable 17-16—状态代码表:\n\n| 状态代码 | 含义 |\n|----------|------|\n| 0 | 成功 |\n| 1 | 队列已满,无法添加 |\n| 2 | 未定义的 q_id |\n| 3 | 队列已空,无法移除 |\n| 4 | 不支持的队列类型,无法创建队列 |\n| 5 | 指定的长度 <= 0,无法创建队列 |\n| 6 | 重复的 q_id,无法创建队列 |\n| 7 | 内存不足,无法创建队列 |"), +]; + +/// $q_full tasks ieee1364 17.6.4 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_Q_FULL_TASKS: &[(&str, &str, &str)] = &[ + ("q_full", "$q_full($1, $2);", "检查队列是否有空间再添加一个条目。\n```verilog\ninteger is_full;\nis_full = $q_full(q_id, status);\n```\n\nTable 17-16—状态代码表:\n\n| 状态代码 | 含义 |\n|----------|------|\n| 0 | 成功 |\n| 1 | 队列已满,无法添加 |\n| 2 | 未定义的 q_id |\n| 3 | 队列已空,无法移除 |\n| 4 | 不支持的队列类型,无法创建队列 |\n| 5 | 指定的长度 <= 0,无法创建队列 |\n| 6 | 重复的 q_id,无法创建队列 |\n| 7 | 内存不足,无法创建队列 |"), +]; + +/// $q_exam tasks ieee1364 17.6.5 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_Q_EXAM_TASKS: &[(&str, &str, &str)] = &[ + ("q_exam", "$q_exam($1, $2, $3, $4);", "提供关于队列 q_id 活动的统计信息。\n```verilog\n$q_exam(q_id, q_stat_code, q_stat_value, status);\n```\n\nTable 17-15—$q_exam 系统任务的参数值:\n\n| 请求的 q_stat_code 值 | 从 q_stat_value 接收到的信息 |\n|-----------------------|------------------------------|\n| 1 | 当前队列长度 |\n| 2 | 平均到达间隔时间 |\n| 3 | 最大队列长度 |\n| 4 | 最短等待时间 |\n| 5 | 队列中作业的最长等待时间 |\n| 6 | 队列中的平均等待时间 |\n\nTable 17-16—状态代码表:\n\n| 状态代码 | 含义 |\n|----------|------|\n| 0 | 成功 |\n| 1 | 队列已满,无法添加 |\n| 2 | 未定义的 q_id |\n| 3 | 队列已空,无法移除 |\n| 4 | 不支持的队列类型,无法创建队列 |\n| 5 | 指定的长度 <= 0,无法创建队列 |\n| 6 | 重复的 q_id,无法创建队列 |\n| 7 | 内存不足,无法创建队列 |"), +]; + +/// $time tasks ieee1364 17.7.1 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_TIME_TASKS: &[(&str, &str, &str)] = &[ + ("time", "$time;", "返回当前仿真时间。\n```verilog\ninteger current_time;\ncurrent_time = $time;\n```"), +]; + +/// $stime tasks ieee1364 17.7.2 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_STIME_TASKS: &[(&str, &str, &str)] = &[ + ("stime", "$stime;", "返回当前仿真时间(以整数形式)。\n```verilog\ninteger current_time;\ncurrent_time = $stime;\n```"), +]; + +/// $realtime tasks ieee1364 17.7.3 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_REALTIME_TASKS: &[(&str, &str, &str)] = &[ + ("realtime", "$realtime;", "返回当前仿真时间(以实数形式)。\n```verilog\nreal current_time;\ncurrent_time = $realtime;\n```"), +]; + +/// Conversion functions tasks ieee1364 17.8 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_CONVERSION_FUNCTIONS_TASKS: &[(&str, &str, &str)] = &[ + ("itor", "$itor($1);", "将整数转换为实数。\n```verilog\nreal real_value;\nreal_value = $itor(integer_value);\n```"), + ("rtoi", "$rtoi($1);", "将实数转换为整数。\n```verilog\ninteger integer_value;\ninteger_value = $rtoi(real_value);\n```"), + ("bitstoreal", "$bitstoreal($1);", "将 64 位位向量转换为实数。\n```verilog\nreal real_value;\nreal_value = $bitstoreal(bit_vector);\n```"), + ("realtobits", "$realtobits($1);", "将实数转换为 64 位位向量。\n```verilog\nreg [63:0] bit_vector;\nbit_vector = $realtobits(real_value);\n```"), + ("bitstoshortreal", "$bitstoshortreal($1);", "将 32 位位向量转换为短实数。\n```verilog\nshortreal shortreal_value;\nshortreal_value = $bitstoshortreal(bit_vector);\n```"), + ("shortrealtobits", "$shortrealtobits($1);", "将短实数转换为 32 位位向量。\n```verilog\nreg [31:0] bit_vector;\nbit_vector = $shortrealtobits(shortreal_value);\n```"), +]; + +/// $random function tasks ieee1364 17.9.1 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_RANDOM_FUNCTION_TASKS: &[(&str, &str, &str)] = &[ + ("random", "$random($1);", "生成一个随机数。\n```verilog\ninteger rand_num;\nrand_num = $random(seed);\n```"), +]; + +/// $dist_functions tasks ieee1364 17.9.2 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_DIST_FUNCTIONS_TASKS: &[(&str, &str, &str)] = &[ + ("dist_chi_square", "$dist_chi_square($1, $2);", "生成一个卡方分布的随机数。\n```verilog\nreal rand_num;\nrand_num = $dist_chi_square(seed, k);\n```"), + ("dist_erlang", "$dist_erlang($1, $2, $3);", "生成一个埃尔朗分布的随机数。\n```verilog\nreal rand_num;\nrand_num = $dist_erlang(seed, k, lambda);\n```"), + ("dist_exponential", "$dist_exponential($1, $2);", "生成一个指数分布的随机数。\n```verilog\nreal rand_num;\nrand_num = $dist_exponential(seed, lambda);\n```"), + ("dist_normal", "$dist_normal($1, $2, $3);", "生成一个正态分布的随机数。\n```verilog\nreal rand_num;\nrand_num = $dist_normal(seed, mean, stddev);\n```"), + ("dist_poisson", "$dist_poisson($1, $2);", "生成一个泊松分布的随机数。\n```verilog\nreal rand_num;\nrand_num = $dist_poisson(seed, lambda);\n```"), + ("dist_t", "$dist_t($1, $2);", "生成一个 t 分布的随机数。\n```verilog\nreal rand_num;\nrand_num = $dist_t(seed, v);\n```"), + ("dist_uniform", "$dist_uniform($1, $2, $3);", "生成一个均匀分布的随机数。\n```verilog\nreal rand_num;\nrand_num = $dist_uniform(seed, low, high);\n```"), +]; + +/// $test$plusargs (string) tasks ieee1364 17.10.1 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_TEST_PLUSARGS_TASKS: &[(&str, &str, &str)] = &[ + ("test$plusargs", "$test$plusargs($1);", "检查仿真命令行参数中是否包含指定的字符串。\n```verilog\ninteger result;\nresult = $test$plusargs(\"test_string\");\n```\n\n示例代码:\n```verilog\ninitial begin\n\tif ($test$plusargs(\"HELLO\")) $display(\"Hello argument found.\");\n\tif ($test$plusargs(\"HE\")) $display(\"The HE subset string is detected.\");\n\tif ($test$plusargs(\"H\")) $display(\"Argument starting with H found.\");\n\tif ($test$plusargs(\"HELLO_HERE\")) $display(\"Long argument.\");\n\tif ($test$plusargs(\"HI\")) $display(\"Simple greeting.\");\n\tif ($test$plusargs(\"LO\")) $display(\"Does not match.\");\nend\n```"), +]; + +/// $value$plusargs (user_string, variable) tasks ieee1364 17.10.2 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_VALUE_PLUSARGS_TASKS: &[(&str, &str, &str)] = &[ + ("value$plusargs", "$value$plusargs($1, $2);", "从仿真命令行参数中提取值并赋给变量。\n```verilog\ninteger result;\nresult = $value$plusargs(\"test_string=\", value);\n```\n\n示例代码:\n```verilog\n`define STRING reg [1024 * 8:1]\nmodule goodtasks;\n\t`STRING str;\n\tinteger int;\n\treg [31:0] vect;\n\treal realvar;\n\tinitial\n\tbegin\n\t\tif ($value$plusargs(\"TEST=%d\", int))\n\t\t\t$display(\"value was %d\", int);\n\t\telse\n\t\t\t$display(\"+TEST= not found\");\n\t\t#100 $finish;\n\tend\nendmodule\n```"), +]; + +/// Integer math functions tasks ieee1364 17.11.1 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_INTEGER_MATH_FUNCTIONS_TASKS: &[(&str, &str, &str)] = &[ + ("clog2", "$clog2($1);", "返回大于或等于给定整数的最小 2 的幂次。\n```verilog\ninteger result;\nresult = $clog2(value);\n```"), + ("countones", "$countones($1);", "返回位向量中 1 的个数。\n```verilog\ninteger count;\ncount = $countones(bit_vector);\n```"), + ("isunknown", "$isunknown($1);", "检查位向量中是否有未知值(x 或 z)。\n```verilog\ninteger result;\nresult = $isunknown(bit_vector);\n```"), + ("onehot", "$onehot($1);", "检查位向量中是否只有一个位为 1。\n```verilog\ninteger result;\nresult = $onehot(bit_vector);\n```"), + ("onehot0", "$onehot0($1);", "检查位向量中是否只有一个位为 1 或没有位为 1。\n```verilog\ninteger result;\nresult = $onehot0(bit_vector);\n```"), +]; + +/// Real math functions tasks ieee1364 17.11.2 +/// (&str, &str, &str): (label, snippet, description) +pub const VLOG_REAL_MATH_FUNCTIONS_TASKS: &[(&str, &str, &str)] = &[ + ("ln", "$ln($1);", "计算自然对数。\n```verilog\nreal result;\nresult = $ln(value);\n```"), + ("log10", "$log10($1);", "计算以 10 为底的对数。\n```verilog\nreal result;\nresult = $log10(value);\n```"), + ("exp", "$exp($1);", "计算指数函数。\n```verilog\nreal result;\nresult = $exp(value);\n```"), + ("sqrt", "$sqrt($1);", "计算平方根。\n```verilog\nreal result;\nresult = $sqrt(value);\n```"), + ("pow", "$pow($1, $2);", "计算幂函数。\n```verilog\nreal result;\nresult = $pow(base, exponent);\n```"), + ("floor", "$floor($1);", "返回不大于给定实数的最大整数。\n```verilog\nreal result;\nresult = $floor(value);\n```"), + ("ceil", "$ceil($1);", "返回不小于给定实数的最小整数。\n```verilog\nreal result;\nresult = $ceil(value);\n```"), + ("sin", "$sin($1);", "计算正弦函数。\n```verilog\nreal result;\nresult = $sin(value);\n```"), + ("cos", "$cos($1);", "计算余弦函数。\n```verilog\nreal result;\nresult = $cos(value);\n```"), + ("tan", "$tan($1);", "计算正切函数。\n```verilog\nreal result;\nresult = $tan(value);\n```"), + ("asin", "$asin($1);", "计算反正弦函数。\n```verilog\nreal result;\nresult = $asin(value);\n```"), + ("acos", "$acos($1);", "计算反余弦函数。\n```verilog\nreal result;\nresult = $acos(value);\n```"), + ("atan", "$atan($1);", "计算反正切函数。\n```verilog\nreal result;\nresult = $atan(value);\n```"), + ("atan2", "$atan2($1, $2);", "计算反正切函数(带两个参数)。\n```verilog\nreal result;\nresult = $atan2(y, x);\n```"), + ("hypot", "$hypot($1, $2);", "计算直角三角形的斜边长度。\n```verilog\nreal result;\nresult = $hypot(x, y);\n```"), + ("sinh", "$sinh($1);", "计算双曲正弦函数。\n```verilog\nreal result;\nresult = $sinh(value);\n```"), + ("cosh", "$cosh($1);", "计算双曲余弦函数。\n```verilog\nreal result;\nresult = $cosh(value);\n```"), + ("tanh", "$tanh($1);", "计算双曲正切函数。\n```verilog\nreal result;\nresult = $tanh(value);\n```"), + ("asinh", "$asinh($1);", "计算反双曲正弦函数。\n```verilog\nreal result;\nresult = $asinh(value);\n```"), + ("acosh", "$acosh($1);", "计算反双曲余弦函数。\n```verilog\nreal result;\nresult = $acosh(value);\n```"), + ("atanh", "$atanh($1);", "计算反双曲正切函数。\n```verilog\nreal result;\nresult = $atanh(value);\n```"), +]; + +fn make_function_profile(section: &str, description: &str) -> MarkupContent { + MarkupContent { + kind: MarkupKind::Markdown, + value: format!("{}\n---\n{}", section, description) + } +} + +fn update_task_completions( + items: &mut Vec, + tasks: &[(&str, &str, &str)], + section: &str +) { + for (label, snippet_code, description) in tasks { + let function_profile = make_function_profile(section, description); + items.push(CompletionItem { + label: label.to_string(), + detail: Some(section.to_string()), + documentation: Some(Documentation::MarkupContent(function_profile)), + kind: Some(CompletionItemKind::FUNCTION), + insert_text: Some(snippet_code.to_string()), + insert_text_format: Some(InsertTextFormat::SNIPPET), + insert_text_mode: Some(InsertTextMode::ADJUST_INDENTATION), + ..CompletionItem::default() + }); + } +} + +/// 提供 verilog sys task 相关的函数补全 +/// 遵循 IEEE 1364 标准 +pub fn provide_vlog_sys_tasks_completions() -> Vec { + let mut items: Vec = Vec::new(); + + update_task_completions(&mut items, VLOG_DISPLAY_WRITE_TASKS, "Display and write tasks ieee1364 17.1.1"); + update_task_completions(&mut items, VLOG_STROBED_MONITOR_TASKS, "Strobed monitoring ieee1364 17.1.2"); + update_task_completions(&mut items, VLOG_CONTINUOUS_MONITORING_TASKS, "Continuous monitoring tasks ieee1364 17.1.3"); + update_task_completions(&mut items, VLOG_FILE_IO_TASKS, "File input-output system tasks and functions ieee1364 17.2.1"); + update_task_completions(&mut items, VLOG_FILE_OUTPUT_TASKS, "File output system tasks ieee1364 17.2.2"); + update_task_completions(&mut items, VLOG_FORMATTING_TASKS, "Formatting data to a string tasks ieee1364 17.2.3"); + update_task_completions(&mut items, VLOG_FILE_READING_TASKS, "Reading data from a file tasks ieee1364 17.2.4"); + update_task_completions(&mut items, VLOG_FILE_POSITIONING_TASKS, "File positioning tasks ieee1364 17.2.5"); + update_task_completions(&mut items, VLOG_FLUSHING_OUTPUT_TASKS, "Flushing output tasks ieee1364 17.2.6"); + update_task_completions(&mut items, VLOG_IO_ERROR_STATUS_TASKS, "I/O error status tasks ieee1364 17.2.7"); + update_task_completions(&mut items, VLOG_DETECTING_EOF_TASKS, "Detecting EOF tasks ieee1364 17.2.8"); + update_task_completions(&mut items, VLOG_LOADING_MEMORY_TASKS, "Loading memory data from a file tasks ieee1364 17.2.9"); + update_task_completions(&mut items, VLOG_LOADING_TIMING_TASKS, "Loading timing data from an SDF file tasks ieee1364 17.2.10"); + update_task_completions(&mut items, VLOG_PRINTTIMESCALE_TASKS, "$printtimescale tasks ieee1364 17.3.1"); + update_task_completions(&mut items, VLOG_TIMEFORMAT_TASKS, "$timeformat tasks ieee1364 17.3.2"); + update_task_completions(&mut items, VLOG_FINISH_TASKS, "$finish tasks ieee1364 17.4.1"); + update_task_completions(&mut items, VLOG_STOP_TASKS, "$stop tasks ieee1364 17.4.2"); + update_task_completions(&mut items, VLOG_ARRAY_TYPES_TASKS, "Array types tasks ieee1364 17.5.1"); + update_task_completions(&mut items, VLOG_ARRAY_LOGIC_TYPES_TASKS, "Array logic types tasks ieee1364 17.5.2"); + update_task_completions(&mut items, VLOG_Q_INITIALIZE_TASKS, "$q_initialize tasks ieee1364 17.6.1"); + update_task_completions(&mut items, VLOG_Q_ADD_TASKS, "$q_add tasks ieee1364 17.6.2"); + update_task_completions(&mut items, VLOG_Q_REMOVE_TASKS, "$q_remove tasks ieee1364 17.6.3"); + update_task_completions(&mut items, VLOG_Q_FULL_TASKS, "$q_full tasks ieee1364 17.6.4"); + update_task_completions(&mut items, VLOG_Q_EXAM_TASKS, "$q_exam tasks ieee1364 17.6.5"); + update_task_completions(&mut items, VLOG_TIME_TASKS, "$time tasks ieee1364 17.7.1"); + update_task_completions(&mut items, VLOG_STIME_TASKS, "$stime tasks ieee1364 17.7.2"); + update_task_completions(&mut items, VLOG_REALTIME_TASKS, "$realtime tasks ieee1364 17.7.3"); + update_task_completions(&mut items, VLOG_CONVERSION_FUNCTIONS_TASKS, "Conversion functions tasks ieee1364 17.8"); + update_task_completions(&mut items, VLOG_RANDOM_FUNCTION_TASKS, "$random function tasks ieee1364 17.9.1"); + update_task_completions(&mut items, VLOG_DIST_FUNCTIONS_TASKS, "$dist_functions tasks ieee1364 17.9.2"); + update_task_completions(&mut items, VLOG_TEST_PLUSARGS_TASKS, "$test$plusargs (string) tasks ieee1364 17.10.1"); + update_task_completions(&mut items, VLOG_VALUE_PLUSARGS_TASKS, "$value$plusargs (user_string, variable) tasks ieee1364 17.10.2"); + update_task_completions(&mut items, VLOG_INTEGER_MATH_FUNCTIONS_TASKS, "Integer math functions tasks ieee1364 17.11.1"); + update_task_completions(&mut items, VLOG_REAL_MATH_FUNCTIONS_TASKS, "Real math functions tasks ieee1364 17.11.2"); + + + items +} \ No newline at end of file diff --git a/src/server.rs b/src/server.rs index 6e67f94..ea686a3 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,6 +1,6 @@ use crate::core::cache_storage::CacheManager; use crate::sources::*; -use crate::completion::keyword::*; +use crate::completion::{keyword::*, provide_vlog_sys_tasks_completions}; use flexi_logger::LoggerHandle; #[allow(unused)] use log::{debug, info, warn}; @@ -31,7 +31,7 @@ impl LSPServer { cache: CacheManager::new(dide_home), vlog_keyword_completion_items: keyword_completions(VLOG_KEYWORDS), vhdl_keyword_completiom_items: keyword_completions(VHDL_KEYWORDS), - sys_tasks: other_completions(SYS_TASKS), + sys_tasks: provide_vlog_sys_tasks_completions(), directives: other_completions(DIRECTIVES), conf: Arc::new(RwLock::new(ProjectConfig::default())), log_handle: Mutex::new(log_handle),