Merge branch 'main' into vhdl_project

This commit is contained in:
light-ly 2024-12-04 01:24:41 +08:00
commit 3774068671
16 changed files with 520 additions and 171 deletions

1
Cargo.lock generated
View File

@ -1416,6 +1416,7 @@ dependencies = [
name = "sv-parser"
version = "0.13.3"
dependencies = [
"log",
"nom",
"nom-greedyerror",
"sv-parser-error",

View File

@ -3,5 +3,5 @@
cargo test --release --package digital-lsp --lib -- core::primitive_parser::tests::gen_primitive_bin --exact --show-output --nocapture
mkdir -p /home/dide/project/Digital-IDE/resources/dide-lsp/static/xilinx
cp target/primitive.bin /home/dide/project/Digital-IDE/resources/dide-lsp/static/xilinx
cargo build --release
cp target/release/digital-lsp /home/dide/project/Digital-IDE/resources/dide-lsp/server/0.4.0/
#cargo build --release
#cp target/release/digital-lsp /home/dide/project/Digital-IDE/resources/dide-lsp/server/0.4.0/

View File

@ -1,6 +1,6 @@
use tower_lsp::lsp_types::*;
//
pub fn keyword_completions(keywords: &[(&str, &str)]) -> Vec<CompletionItem> {
let mut items: Vec<CompletionItem> = Vec::new();
for key in keywords {
@ -34,6 +34,7 @@ pub fn other_completions(tasks: &[&str]) -> Vec<CompletionItem> {
.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__",

View File

@ -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<CompletionResponse> {
let language_id = get_language_id_by_uri(&params.text_document_position.text_document.uri);

View File

@ -39,11 +39,11 @@ pub fn completion(server: &LSPServer, params: &CompletionParams) -> Option<Compl
},
"$" => Some(CompletionList {
is_incomplete: false,
items: server.sys_tasks.clone(),
items: server.vlog_sys_tasks_completion_items.clone(),
}),
"`" => Some(CompletionList {
is_incomplete: false,
items: server.directives.clone(),
items: server.vlog_directives.clone(),
}),
"/" => {
info!("trigger include");
@ -68,7 +68,8 @@ pub fn completion(server: &LSPServer, params: &CompletionParams) -> Option<Compl
info!("current completion token: {}", token);
// 2. 根据 token 再加入关键词
// 2. 根据 token 加入关键词
// TODO: 考虑使用前缀树进行优化
completion_items.items.extend::<Vec<CompletionItem>>(
server.vlog_keyword_completion_items
.iter()
@ -77,7 +78,17 @@ pub fn completion(server: &LSPServer, params: &CompletionParams) -> Option<Compl
.collect(),
);
// 3. 加入例化自动补全的
// 3. 根据 token 加入系统函数
// TODO: 考虑使用前缀树进行优化
completion_items.items.extend::<Vec<CompletionItem>>(
server.vlog_sys_tasks_completion_items
.iter()
.filter(|x| x.label.starts_with(&token))
.cloned()
.collect(),
);
// 4. 加入例化自动补全的
completion_items.items.extend::<Vec<CompletionItem>>(
make_module_completions(server, &token, &language_id)
);
@ -100,11 +111,11 @@ pub fn completion(server: &LSPServer, params: &CompletionParams) -> Option<Compl
)?),
'$' => Some(CompletionList {
is_incomplete: false,
items: server.sys_tasks.clone(),
items: server.vlog_sys_tasks_completion_items.clone(),
}),
'`' => Some(CompletionList {
is_incomplete: false,
items: server.directives.clone(),
items: server.vlog_directives.clone(),
}),
_ => {
let mut completion_items = server.srcs.get_completions(

441
src/completion/sys_tasks.rs Normal file
View File

@ -0,0 +1,441 @@
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```"),
];
/// Specifying name of dump file ($dumpfile) tasks ieee1364 18.1.1
/// (&str, &str, &str): (label, snippet, description)
pub const VLOG_DUMPFILE_TASKS: &[(&str, &str, &str)] = &[
("dumpfile", "$dumpfile($1);", "指定波形转储文件的名称。\n```verilog\n$dumpfile(\"waveform.vcd\");\n```"),
];
/// Specifying variables to be dumped ($dumpvars) tasks ieee1364 18.1.2
/// (&str, &str, &str): (label, snippet, description)
pub const VLOG_DUMPVARS_TASKS: &[(&str, &str, &str)] = &[
("dumpvars", "$dumpvars($1, $2);", "指定要转储的变量。\n```verilog\n$dumpvars(1, module_instance);\n```"),
];
/// Stopping and resuming the dump ($dumpoff/$dumpon) tasks ieee1364 18.1.3
/// (&str, &str, &str): (label, snippet, description)
pub const VLOG_DUMPOFF_DUMPON_TASKS: &[(&str, &str, &str)] = &[
("dumpoff", "$dumpoff;", "暂停波形转储。\n```verilog\n$dumpoff;\n```"),
("dumpon", "$dumpon;", "恢复波形转储。\n```verilog\n$dumpon;\n```"),
];
/// Generating a checkpoint ($dumpall) tasks ieee1364 18.1.4
/// (&str, &str, &str): (label, snippet, description)
pub const VLOG_DUMPALL_TASKS: &[(&str, &str, &str)] = &[
("dumpall", "$dumpall;", "生成一个检查点,转储所有变量的当前状态。\n```verilog\n$dumpall;\n```"),
];
/// Limiting size of dump file ($dumplimit) tasks ieee1364 18.1.5
/// (&str, &str, &str): (label, snippet, description)
pub const VLOG_DUMPLIMIT_TASKS: &[(&str, &str, &str)] = &[
("dumplimit", "$dumplimit($1);", "限制波形转储文件的大小。\n```verilog\n$dumplimit(1000000);\n```"),
];
/// Reading dump file during simulation ($dumpflush) tasks ieee1364 18.1.6
/// (&str, &str, &str): (label, snippet, description)
pub const VLOG_DUMPFLUSH_TASKS: &[(&str, &str, &str)] = &[
("dumpflush", "$dumpflush;", "刷新波形转储文件,确保所有数据都写入文件。\n```verilog\n$dumpflush;\n```"),
];
/// FSDB related tasks
/// (&str, &str, &str): (label, snippet, description)
pub const VLOG_FSDB_TASKS: &[(&str, &str, &str)] = &[
("fsdbDumpfile", "$fsdbDumpfile($1);", "指定 FSDB 文件的名称。\n```verilog\n$fsdbDumpfile(\"waveform.fsdb\");\n```"),
("fsdbDumpvars", "$fsdbDumpvars($1, $2);", "指定要转储到 FSDB 文件的变量。\n```verilog\n$fsdbDumpvars(1, module_instance);\n```"),
("fsdbDumpoff", "$fsdbDumpoff;", "暂停 FSDB 文件的转储。\n```verilog\n$fsdbDumpoff;\n```"),
("fsdbDumpon", "$fsdbDumpon;", "恢复 FSDB 文件的转储。\n```verilog\n$fsdbDumpon;\n```"),
("fsdbDumpflush", "$fsdbDumpflush;", "刷新 FSDB 文件,确保所有数据都写入文件。\n```verilog\n$fsdbDumpflush;\n```"),
];
fn make_function_profile(
#[allow(unused)]
section: &str,
description: &str
) -> MarkupContent {
MarkupContent {
kind: MarkupKind::Markdown,
value: format!("{}", description)
}
}
fn update_task_completions(
items: &mut Vec<CompletionItem>,
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<CompletionItem> {
let mut items: Vec<CompletionItem> = 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");
update_task_completions(&mut items, VLOG_DUMPFILE_TASKS, "Specifying name of dump file ($dumpfile) tasks ieee1364 18.1.1");
update_task_completions(&mut items, VLOG_DUMPVARS_TASKS, "Specifying variables to be dumped ($dumpvars) tasks ieee1364 18.1.2");
update_task_completions(&mut items, VLOG_DUMPOFF_DUMPON_TASKS, "Stopping and resuming the dump ($dumpoff/$dumpon) tasks ieee1364 18.1.3");
update_task_completions(&mut items, VLOG_DUMPALL_TASKS, "Generating a checkpoint ($dumpall) tasks ieee1364 18.1.4");
update_task_completions(&mut items, VLOG_DUMPLIMIT_TASKS, "Limiting size of dump file ($dumplimit) tasks ieee1364 18.1.5");
update_task_completions(&mut items, VLOG_DUMPFLUSH_TASKS, "Reading dump file during simulation ($dumpflush) tasks ieee1364 18.1.6");
update_task_completions(&mut items, VLOG_FSDB_TASKS, "FSDB related tasks");
items
}

View File

@ -295,6 +295,7 @@ impl Instance {
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Module {
pub name: String,
#[serde(rename = "archName")]
pub arch_name: String,
pub params: Vec<Parameter>,
pub ports: Vec<Port>,

View File

@ -271,6 +271,7 @@ mod tests {
const TESTDIR: &str = "primitive_files";
#[test]
fn gen_primitive_bin() {
if let Ok(primitive_info) = init_parse_primitive_files("primitive_files") {
let serialized_data = bincode::serialize(&primitive_info).unwrap();
@ -282,6 +283,13 @@ mod tests {
}
}
#[test]
fn read_primitive_bin() {
let target_path = "target/primitive.bin";
let load = crate::core::primitive_parser::load_primitive_bin(&target_path);
assert!(load.is_some());
}
#[test]
fn test_xml() {
let res = xml_parser(TESTFILE);

View File

@ -6,6 +6,10 @@ use std::process::{Command, Stdio};
use tower_lsp::lsp_types::*;
use walkdir::DirEntry;
mod modelsim;
mod verible;
mod verilator;
mod vivado;
pub fn get_diagnostics(
uri: Url,

View File

View File

View File

View File

@ -0,0 +1,5 @@
pub fn provide_diagnostics() {
}

View File

@ -10,6 +10,9 @@ use crate::{core::{self, hdlparam::{Define, FastHdlparam}, primitive_parser::Pri
use super::{get_language_id_by_path_str, get_word_range_at_position, resolve_path, to_escape_path};
/// 将 4'b0011 分解为 ("b", "0011")
/// 需要支持的格式:
/// - `4'b0011`
/// - `8'b0000_1111`
fn parse_digit_string(digit_string: &str) -> Option<(&str, &str)> {
if digit_string.len() == 0 {
return None;
@ -29,7 +32,14 @@ fn parse_digit_string(digit_string: &str) -> Option<(&str, &str)> {
return None;
}
return Some((tag.unwrap(), digit.unwrap()));
// 此时4'b0011 被自动分割成了
// tag: b
// digit: 0011
// 前面的 4 被丢弃了,因为 4 可以通过 0011 的长度判断出来
let tag = tag.unwrap();
let digit = digit.unwrap();
return Some((tag, digit));
},
None => return None
};
@ -46,13 +56,20 @@ fn convert_tag_to_radix(tag: &str) -> Option<u32> {
}
/// 计算出有符号和无符号下的表示
/// - `tag`: b, o, h 这些代表进制的字符,
/// - `digit_string`: 进制数
///
/// 需要支持的格式:
/// - `4'b0011`
/// - `8'b0000_1111`
fn convert_to_sign_unsign<'a>(tag: &'a str, digit_string: &str) -> Option<(String, String)> {
let radix = convert_tag_to_radix(tag);
if radix.is_none() {
return None;
}
let radix = radix.unwrap();
let unsigned_decimal = u128::from_str_radix(digit_string, radix);
let raw_digit_string = digit_string.replace("_", "");
let unsigned_decimal = u128::from_str_radix(&raw_digit_string, radix);
if unsigned_decimal.is_err() {
return None;
@ -87,7 +104,7 @@ pub fn hover_format_digit(line: &RopeSlice, pos: Position, language_id: &str) ->
if let Some((signed_string, unsigned_string)) = convert_to_sign_unsign(tag, digit) {
let digit_title = LanguageString {
language: language_id.to_string(),
value: format!("{}'{}{}", digit.len(), tag, digit)
value: format!("{}'{}{}", digit.replace("_", "").len(), tag, digit)
};
let markdown = HoverContents::Array(vec![
MarkedString::LanguageString(digit_title),

View File

@ -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};
@ -15,8 +15,8 @@ pub struct LSPServer {
pub cache: CacheManager,
pub vlog_keyword_completion_items: Vec<CompletionItem>,
pub vhdl_keyword_completiom_items: Vec<CompletionItem>,
pub sys_tasks: Vec<CompletionItem>,
pub directives: Vec<CompletionItem>,
pub vlog_sys_tasks_completion_items: Vec<CompletionItem>,
pub vlog_directives: Vec<CompletionItem>,
pub conf: Arc<RwLock<ProjectConfig>>,
#[allow(unused)]
pub log_handle: Mutex<Option<LoggerHandle>>,
@ -31,8 +31,8 @@ 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),
directives: other_completions(DIRECTIVES),
vlog_sys_tasks_completion_items: provide_vlog_sys_tasks_completions(),
vlog_directives: other_completions(DIRECTIVES),
conf: Arc::new(RwLock::new(ProjectConfig::default())),
log_handle: Mutex::new(log_handle),
}
@ -284,8 +284,7 @@ impl LanguageServer for Backend {
// .await;
// } else {
let diagnostics = self.server.did_open(params);
self.client
.publish_diagnostics(
self.client.publish_diagnostics(
diagnostics.uri,
diagnostics.diagnostics,
diagnostics.version,

View File

@ -52,12 +52,19 @@ impl LSPServer {
} else {
self.srcs.add(self, document);
}
// diagnostics
// 生成诊断信息
let urls = self.srcs.names.read().unwrap().keys().cloned().collect();
let file_id = self.srcs.get_id(&uri);
if let Some(file) = self.srcs.get_file(file_id) {
let file = file.read().unwrap();
get_diagnostics(uri, &file.text, urls, &self.conf.read().unwrap())
let diagnostics = get_diagnostics(
uri,
&file.text,
urls,
&self.conf.read().unwrap()
);
diagnostics
} else {
PublishDiagnosticsParams {
uri,