[{"content":"很多测试数据存储在大型文本文件（如 CSV）中。考虑采样率为 1kHz 的情况，持续采集几分钟就能产生百万行数据文件。\n本文考虑 csv 文件，其特征在于：\n具有标题行，有的场景下标题行数目不固定 每行数据列数固定，分隔符固定（比如逗号或分号） 本文介绍提升 MATLAB 读取大型文本数据文件性能的方法。\n读取大文件：使用 textscan 替代 readtable 考虑如下 csv 文件：\n1 2 3 4 5 6 7 # Data acquisition time, Epoch time (ms), Distance1 (μm), Distance2 (μm), Distance3 (μm), Distance4 (μm) 2025-12-02 15:02:50.881160, 1764658970881.160, 143.571, 126.013, 153.311, 139.996 2025-12-02 15:02:50.881416, 1764658970881.416, 143.569, 126.012, 153.311, 139.998 2025-12-02 15:02:50.881672, 1764658970881.672, 143.569, 126.015, 153.307, 139.998 2025-12-02 15:02:50.881928, 1764658970881.928, 143.567, 126.015, 153.312, 139.995 2025-12-02 15:02:50.882184, 1764658970882.184, 143.570, 126.013, 153.308, 139.998 ... 初始代码使用 readtable 读取数据：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 %% 设置导入选项并导入数据 opts = delimitedTextImportOptions(\u0026#34;NumVariables\u0026#34;, 6); % 指定范围和分隔符 opts.DataLines = [2, Inf]; opts.Delimiter = \u0026#34;,\u0026#34;; % 指定列名称和类型 opts.VariableNames = [\u0026#34;acq_time\u0026#34;, \u0026#34;epoch_time_ms\u0026#34;, \u0026#34;dist1_um\u0026#34;, \u0026#34;dist2_um\u0026#34;, \u0026#34;dist3_um\u0026#34;, \u0026#34;dist4_um\u0026#34;]; opts.VariableTypes = [\u0026#34;datetime\u0026#34;, \u0026#34;double\u0026#34;, \u0026#34;double\u0026#34;, \u0026#34;double\u0026#34;, \u0026#34;double\u0026#34;, \u0026#34;double\u0026#34;]; % 指定文件级属性 opts.ExtraColumnsRule = \u0026#34;ignore\u0026#34;; opts.EmptyLineRule = \u0026#34;read\u0026#34;; opts.ConsecutiveDelimitersRule = \u0026#34;join\u0026#34;; % 指定变量属性 opts = setvaropts(opts, \u0026#34;acq_time\u0026#34;, \u0026#34;InputFormat\u0026#34;, \u0026#34;yyyy-MM-dd HH:mm:ss.SSSSSS\u0026#34;, \u0026#34;DatetimeFormat\u0026#34;, \u0026#34;preserveinput\u0026#34;); opts = setvaropts(opts, [\u0026#34;epoch_time_ms\u0026#34;, \u0026#34;dist1_um\u0026#34;, \u0026#34;dist2_um\u0026#34;, \u0026#34;dist3_um\u0026#34;, \u0026#34;dist4_um\u0026#34;], \u0026#34;ThousandsSeparator\u0026#34;, \u0026#34;,\u0026#34;); % 导入数据 tic; T = readtable(filePath, opts); toc; 历时 1.919952 秒。\ntextscan 是底层 C 实现，比 readtable 快 2-3倍。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 % 打开文件 fid = fopen(filePath, \u0026#39;r\u0026#39;, \u0026#39;n\u0026#39;, \u0026#39;US-ASCII\u0026#39;); % 跳过标题行 header = fgetl(fid); % 定义格式字符串 formatSpec = \u0026#39;%s%f%f%f%f%f\u0026#39;; % 使用 textscan 读取数据 tic; data = textscan(fid, formatSpec, \u0026#39;Delimiter\u0026#39;, \u0026#39;,\u0026#39;, \u0026#39;CollectOutput\u0026#39;, true); toc; fclose(fid); % 解析数据 tic; acq_time = datetime(data{1}, \u0026#39;InputFormat\u0026#39;, \u0026#39;yyyy-MM-dd HH:mm:ss.SSSSSS\u0026#39;); numeric_data = data{2}; epoch_time_ms = numeric_data(:, 1); dist1_um = numeric_data(:, 2); dist2_um = numeric_data(:, 3); dist3_um = numeric_data(:, 4); dist4_um = numeric_data(:, 5); % 构建表格 T = table(acq_time, epoch_time_ms, dist1_um, dist2_um, dist3_um, dist4_um); toc; 历时 0.650829 秒。（用时减少 66%） 历时 0.168380 秒。（考虑数据解析的总用时减少 57%）\n优化文件打开参数 数据基本上只由 ASCII 字符组成（数字、逗号、换行等），我们可以优化 fopen 的参数，这里显式指定机器格式为 'native'，避免做不必要的字节序转换；同时将字符编码固定为 US-ASCII，跳过自动编码检测，从而进一步提升性能：\n1 2 3 4 fid = fopen(filePath, \u0026#39;r\u0026#39;, \u0026#39;n\u0026#39;, \u0026#39;US-ASCII\u0026#39;); % ↑ ↑ % | └─ US-ASCII 字符集最简单，解析开销最小 % └────── 按本机字节序读写二进制数据 编码方案 耗时 相对性能 不指定（自动检测） ~1.0s 基准 GB18030 0.75s +25% UTF-8 0.70s +30% US-ASCII 0.65s +35% ⭐ 处理变长标题行 有时标题行位置不固定，比如随测量通道数变化：\n1 2 3 4 5 6 7 8 9 10 11 # softwareVersion: 1.2.3.4 # SensorTypeName: veryGoodSensor XXXX, ... # SignalName, SensorName, SerialNumber, ArticleNumber, RangeMin, RangeMax # Distance1, DL1234, 0002, 1234567, 0 μm, 200 μm # Distance2, DL1234, 0003, 1234567, 0 μm, 200 μm # Distance3, DL1234, 0004, 1234567, 0 μm, 200 μm # Distance4, DL1234, 0005, 1234567, 0 μm, 200 μm # 1_Averaging:Disabled, 2_Triggering:Disabled, 3_Subsampling:Disabled, 4_Mastering:Disabled # Data acquisition time, Epoch time (ms), Distance1 (μm), Distance2 (μm), Distance3 (μm), Distance4 (μm) 2025-12-02 15:02:50.881160, 1764658970881.160, 143.571, 126.013, 153.311, 139.996 ... 这时我们当然希望能动态定位标题行，而不是手动数行。注意到“真正的”标题行是：\n1 # Data acquisition time, Epoch time (ms), Distance1 (μm), Distance2 (μm), Distance3 (μm), Distance4 (μm) 容易想到的做法是逐行读取，直到找到该行：\n1 2 3 4 5 6 7 8 9 10 11 fid = fopen(filePath, \u0026#39;r\u0026#39;, \u0026#39;n\u0026#39;, \u0026#39;US-ASCII\u0026#39;); tic; while ~feof(fid) line = fgetl(fid); if startsWith(line, \u0026#39;# Data acquisition time\u0026#39;) fprintf(\u0026#39;Found header line.\\n\u0026#39;); break; end end toc; % 读取数据部分 Found header line. 历时 0.786832 秒。\n更快的方法是使用 fread 一次性读取整个文件内容，然后使用 strfind 在内存中搜索标题行：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 fid = fopen(filePath, \u0026#39;r\u0026#39;, \u0026#39;n\u0026#39;, \u0026#39;US-ASCII\u0026#39;); file_content = fread(fid, \u0026#39;*char\u0026#39;)\u0026#39;; fclose(fid); % 查找并提取标题行 tic; [header_line, data_start_pos] = find_data_header(file_content); toc; % 解析变量名（从第3列开始） header_cells = strsplit(header_line, \u0026#39;,\u0026#39;); vars = cellfun(@(x) [\u0026#39;d\u0026#39; regexp(x, \u0026#39;\\d+\u0026#39;, \u0026#39;match\u0026#39;, \u0026#39;once\u0026#39;)], ... header_cells(3:end), \u0026#39;UniformOutput\u0026#39;, false); % 读取数据（跳过前两列） data_content = file_content(data_start_pos:end); format_str = [\u0026#39;%*s%*f\u0026#39;, repmat(\u0026#39;%f\u0026#39;, 1, numel(vars))]; % 动态生成格式字符串 data_cells = textscan(data_content, format_str, \u0026#39;Delimiter\u0026#39;, \u0026#39;,\u0026#39;); % 合并为二维数组 D = [data_cells{:}]; function [header_line, data_start_pos] = find_data_header(file_content) % 定位标题行 marker = \u0026#39;# Data acquisition time\u0026#39;; pos = strfind(file_content, marker); if isempty(pos) error(\u0026#39;未找到以 \u0026#34;%s\u0026#34; 开头的标题行\u0026#39;, marker); end % 回溯到行首（上一行换行符之后） line_start = pos(1); if line_start \u0026gt; 1 prev_nl = regexp(file_content(1:line_start-1), \u0026#39;\\r?\\n\u0026#39;, \u0026#39;once\u0026#39;, \u0026#39;end\u0026#39;); if ~isempty(prev_nl) line_start = prev_nl + 1; end end % 到行尾（下一个换行符之前） rel_end = regexp(file_content(line_start:end), \u0026#39;\\r?\\n\u0026#39;, \u0026#39;once\u0026#39;); if isempty(rel_end) header_line = file_content(line_start:end); data_start_pos = length(file_content) + 1; else line_end = line_start + rel_end - 2; % 去掉换行本身 header_line = file_content(line_start:line_end); data_start_pos = line_end + 2; % 跳到下一行开头（兼容 \\r?\\n） end end 历时 0.052721 秒。\n其他 如果数据中包含空数据（即连续分隔符），需要在 textscan 中指定 'EmptyValue', NaN 以正确处理。\n如果可能重复读取同一文件，考虑将数据缓存到 MAT 文件中以加快后续读取速度。\n1 2 3 4 5 6 7 8 9 10 [fileDir, fileBase] = fileparts(filePath); matPath = fullfile(fileDir, [fileBase \u0026#39;.mat\u0026#39;]); if exist(matPath, \u0026#39;file\u0026#39;) cache = load(matPath, \u0026#39;data\u0026#39;, \u0026#39;vars\u0026#39;); data = cache.data; vars = cache.vars; else [data, vars] = loaderFunc(filePath); save(matPath, \u0026#39;data\u0026#39;, \u0026#39;vars\u0026#39;); end ","permalink":"https://guguming.github.io/matlab-load-large-file/","summary":"\u003cp\u003e很多测试数据存储在大型文本文件（如 CSV）中。考虑采样率为 1kHz 的情况，持续采集几分钟就能产生百万行数据文件。\u003c/p\u003e\n\u003cp\u003e本文考虑 csv 文件，其特征在于：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e具有标题行，有的场景下标题行数目不固定\u003c/li\u003e\n\u003cli\u003e每行数据列数固定，分隔符固定（比如逗号或分号）\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e本文介绍提升 MATLAB 读取大型文本数据文件性能的方法。\u003c/p\u003e","title":"🛠️ MATLAB 读取大型文本数据文件的方法"},{"content":"本文介绍基于 Hexo 和 GitHub 搭建个人博客网站的简要步骤。\n环境搭建 Node.js 首先安装 fnm，这是一个 Node.js 版本管理工具。Node.js 是一个 JavaScript 运行环境，Hexo 静态博客生成器基于它运行。\nWindows 使用 winget 安装 fnm：\n1 winget install Schniz.fnm Linux 确保已经安装了 curl 和 unzip，然后运行：\n1 curl -fsSL https://fnm.vercel.app/install | bash 然后使用 fnm 安装 Node.js 最新 LTS 版本（当前是 22）：\n1 fnm install 22 安装成功的标志是运行 node -v 和 npm -v 会产生软件的版本号。\nGit \u0026amp; GitHub Git是一款版本控制工具，Linux 系统一般已经默认安装，Windows 系统可运行以下命令安装：\n1 2 winget install Git.Git git -v # 检查是否安装成功 安装完成后，Windows 终端将可以使用 Git Bash，后续所有操作都将在此进行。 然后，注册一个 GitHub 账号，并创建一个名为 \u0026lt;username\u0026gt;.github.io 的仓库，其中 \u0026lt;username\u0026gt; 为你的 GitHub 用户名，下同。 执行以下命令来连接到 GitHub：\n1 2 git config --global user.name \u0026#34;username\u0026#34; git config --global user.email \u0026#34;your@mail.com\u0026#34; 为了能将本地仓库推送到 GitHub，需要配置 SSH key：\n1 2 ssh-keygen -t rsa -C \u0026#34;your@mail.com\u0026#34; cat ~/.ssh/id_rsa.pub 生成过程中会提示输入文件保存位置和密码，直接回车使用默认设置即可。\n将输出的内容复制（如果是在 Git Bash，不要使用 Ctrl+C，选中内容后右键点击 Copy 进行复制）。 在 GitHub 账户设置页面点击 SSH and GPG keys 和 New SSH key，Title 可任取，在 Key 中粘贴前一步复制的内容，点击 Add SSH key 完成操作。 执行ssh -T git@github.com，出现下面的结果说明操作成功：\n1 2 $ ssh -T git@github.com Hi \u0026lt;username\u0026gt;! You\u0026#39;ve successfully authenticated, but GitHub does not provide shell access. 如果出现以下提示，输入yes然后回车：\n1 Are you sure you want to continue connecting (yes/no)? Hexo 新建一个文件夹，用于存放博客网站相关文件，比如 D:\\blog（Windows）或 ~/blog（Linux）。在此目录下，执行以下命令：\n1 2 3 npm install hexo-cli -g # 安装 hexo hexo init # 初始化博客网站 npm install # 安装依赖 这时，文件夹中将生成 _config.yml 文件，这是网站的配置文件。还有一个 _config.landscape.yml 文件，这是主题的配置文件，我们稍后会用到。\n然后，安装几个有用的插件：\n1 2 3 4 npm install hexo-deployer-git --save # 用于部署到 GitHub npm uninstall hexo-renderer-marked --save # 卸载默认的渲染器，不支持图片 npm install hexo-renderer-markdown-it --save # 安装支持图片的渲染器 npm install hexo-image-link --save # 用于在文章中插入图片 打开网站配置文件 _config.yml，修改文件末尾处的 Deployment 配置：\n1 2 3 4 5 6 # Deployment ## Docs: https://hexo.io/docs/one-command-deployment deploy: type: \u0026#39;git\u0026#39; repository: git@github.com:\u0026lt;username\u0026gt;/\u0026lt;username\u0026gt;.github.io.git branch: deploy 至此，环境就搭建好了。你可以执行 hexo g 生成静态网页，然后执行 hexo s 启动本地服务器预览。这时，使用浏览器进入http://localhost:4000/就可以预览 Hexo 生成的网页了。按下 Ctrl+C 可以关闭本地服务器。执行 hexo d 将网页部署到 GitHub 上，稍等一分钟后，就可以在浏览器中访问你的博客网站了。\n个性化配置 修改网站基本信息 在网站配置文件中，有几个个性化信息需要修改：\ntitle：网站标题，就是浏览器标签页上显示的标题 subtitle：网站副标题，在有的主题中显示为标题下面的一行小字 author：作者姓名，通常显示在页面底部 language：中文为zh-CN 写下第一篇文章 首先，为了便于在文章中插入图片，请在网站配置文件中将 post_asset_folder 的值设置为 true。\n要新建文章，执行以下命令：\n1 hexo new post \u0026#34;postname\u0026#34; 命令执行后，打开 \\source\\_posts 目录，会发现多了一个 .md 文件和同名的文件夹。你也可以手动新建这个文件和同名文件夹，和前面的命令效果相同。接下来，你就可以在 .md 文件中写作，而同名的文件夹将用来存放文章中的图片等数据。\n执行 hexo clean 清除缓存（也可不执行），重新执行 hexo g \u0026amp;\u0026amp; hexo s 生成并预览，可以看到新文章已经出现在页面上。\n更换主题 可访问主题页面找到自己喜欢的主题进行下载。这里以笔者使用的 NexT 主题为例，执行以下命令来安装：\n1 npm install hexo-theme-next --save 打开网站配置文件，在文件的末尾处修改主题：\n1 2 ## Themes: https://hexo.io/themes/ theme: next 重新生成看看效果吧！\nNexT 主题配置 在主题文件夹可以找到另一个配置文件 ./node_modules/hexo-theme-next/_config.yml，将其复制一份到根目录，并重命名为 _config.next.yml，这么做的原因详见此处。你也可以用一行代码完成这个步骤：\n1 cp ./node_modules/hexo-theme-next/_config.yml _config.next.yml 修改其中的内容就可对主题进行配置，详见主题文档。\n基于 GitHub Actions 自动部署 上述操作，只将构建好的网页部署到了 GitHub 上，而没有对 .md 源文件进行备份。基于 GitHub Actions，我们可以实现自动部署，省去本地构建的步骤，从而更专注于写作。下面进行简要介绍。\n卸载不再需要的 hexo-deployer-git 插件：\n1 npm uninstall hexo-deployer-git --save 同时，在 _config.yml 文件中，注释掉 Deployment 部分的配置，因为已经不需要了。\n在仓库根目录下新建 .github/workflows/deploy.yml 文件，内容如下：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 name: Deploy Hexo to GitHub Pages on: push: branches: [ main ] jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout main uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: \u0026#39;22\u0026#39; cache: \u0026#39;npm\u0026#39; - name: Cache Hexo files uses: actions/cache@v4 with: path: | db.json .deploy_git public key: hexo-${{ runner.os }}-${{ hashFiles(\u0026#39;_config.yml\u0026#39;, \u0026#39;_config.next.yml\u0026#39;, \u0026#39;package-lock.json\u0026#39;) }} restore-keys: | hexo-${{ runner.os }}- - name: Install dependencies run: npm ci - name: Clean and generate run: | npm run clean npm run build - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v4 if: github.ref == \u0026#39;refs/heads/main\u0026#39; with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./public publish_branch: deploy force_orphan: true enable_jekyll: false keep_files: false 前往 GitHub 仓库 Settings → Actions → General，在 \u0026ldquo;Workflow permissions\u0026rdquo; 部分，选择 \u0026ldquo;Read and write permissions\u0026rdquo; 并保存更改。\n在根目录初始化 Git 仓库，并且将本地源码推送到新分支，比如 main：\n1 2 3 4 5 6 git init # 在根目录初始化 git add . # 添加所有文件 git commit -m \u0026#34;Initial commit\u0026#34; # 提交 git branch -M main # 重命名本地主分支为 main git remote add origin git@github.com:\u0026lt;username\u0026gt;/\u0026lt;username\u0026gt;.github.io.git # 连接远程仓库 git push -u origin main # 推送到远程仓库 或许你已经注意到，根目录已经存在了 .gitignore 文件，这是刚刚初始化 Hexo 时就已经创建的，其内容为：\n1 2 3 4 5 6 7 8 .DS_Store Thumbs.db db.json *.log node_modules/ public/ .deploy*/ _multiconfig.yml 这为我们提供了一些方便。\n每次写作完成后，执行以下命令即可将文章推送到 GitHub：\n1 2 3 git add . git commit -m \u0026#34;Update\u0026#34; git push 或者在 Visual Studio Code 中使用源代码管理功能进行提交和推送。\n实用功能：文章时效性提示 一些文章很容易随时间过时，如何添加提醒呢？以下是简单的示范。\n在仓库根目录下新建 scripts 文件夹，并在其中新建 injector.js 文件，内容如下：\n1 2 //注入文章过期提示 hexo.extend.injector.register(\u0026#39;body_end\u0026#39;, `\u0026lt;script src=\u0026#34;/js/outdate.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt;`,\u0026#39;post\u0026#39;) 在仓库根目录下新建 source/js 文件夹，并在其中新建 outdate.js 文件，内容如下（部分代码由人工智能生成）：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 // 文章时效性提示 - 简化版本，充分信任 Hexo/NexT 的结构化 HTML (function() { \u0026#39;use strict\u0026#39;; // 配置参数 const CONFIG = { warningDays: 200, errorDays: 400, warningClass: \u0026#39;note warning\u0026#39;, errorClass: \u0026#39;note danger\u0026#39;, title: \u0026#39;文章时效性提示\u0026#39;, template: \u0026#39;这是一篇{type}于 {time} 前的文章，部分信息可能已发生改变，请注意甄别。\u0026#39; }; // 仅在文章页面执行（信任 NexT 主题的 DOM 结构） const postBody = document.querySelector(\u0026#39;.post-body\u0026#39;); if (!postBody) return; // 信任 Hexo 的结构化时间元素（使用标准 Schema.org microdata） const updateTimeEl = document.querySelector(\u0026#39;time[itemprop*=\u0026#34;dateModified\u0026#34;]\u0026#39;); const publishTimeEl = document.querySelector(\u0026#39;time[itemprop*=\u0026#34;dateCreated\u0026#34;], time[itemprop*=\u0026#34;datePublished\u0026#34;]\u0026#39;); if (!publishTimeEl) return; // 静默失败，避免控制台噪音 // 信任 Hexo 生成的 datetime 属性格式 const referenceTime = updateTimeEl?.dateTime || publishTimeEl.dateTime; const diffDays = Math.floor((Date.now() - new Date(referenceTime)) / 86400000); // 简化的时间格式化 const formatTimeAgo = days =\u0026gt; { const years = Math.floor(days / 365); const months = Math.floor((days % 365) / 30); return years ? `${years} 年${months ? ` ${months} 个月` : \u0026#39;\u0026#39;}` : months ? `${months} 个月` : `${days} 天`; }; // 添加时效性提示 if (diffDays \u0026gt; CONFIG.warningDays) { const notice = Object.assign(document.createElement(\u0026#39;div\u0026#39;), { className: diffDays \u0026gt;= CONFIG.errorDays ? CONFIG.errorClass : CONFIG.warningClass, innerHTML: `\u0026lt;h5\u0026gt;${CONFIG.title}\u0026lt;/h5\u0026gt;\u0026lt;p\u0026gt;${CONFIG.template .replace(\u0026#39;{time}\u0026#39;, formatTimeAgo(diffDays)) .replace(\u0026#39;{type}\u0026#39;, updateTimeEl ? \u0026#39;更新\u0026#39; : \u0026#39;发布\u0026#39;)}\u0026lt;/p\u0026gt;` }); postBody.insertAdjacentElement(\u0026#39;afterbegin\u0026#39;, notice); } })(); 参考文献 [1] 超详细Hexo+Github博客搭建小白教程 | 韦阳的博客 [2] Hexo 插入图片_疾风jf的博客-CSDN博客 [3] Hexo博客进阶：为 Next 主题的 Hexo 博客内容添加文章过期/时效提示_hexo配置过期时间-CSDN博客\n","permalink":"https://guguming.github.io/hexo-github-intro/","summary":"\u003cp\u003e本文介绍基于 Hexo 和 GitHub 搭建个人博客网站的简要步骤。\u003c/p\u003e","title":"🛠️ 基于 Hexo 和 GitHub 搭建个人博客网站"},{"content":"","permalink":"https://guguming.github.io/about/","summary":"","title":"关于"},{"content":"进入大二下学期，电脑软件喜加一。无论是四节连上、教室未知的课程安排，还是微信群里一遍又一遍的@所有人，都暗示着我们将要和某款软件度过新学期的美好时光……\n它就是：Xilinx Vivado，简称 “喂娃兜”，主要用于HDL（Hardware Description Language，硬件描述语言）的设计、综合与分析。此软件以其安装复杂、启动缓慢、不支持中文以及玄学报错等特性广受学生好评，自带编辑器更是以朴实、简约著称，几乎没有任何辅助功能，时刻让人体会着最原始的编程意境。\n懒是人类进步的动力。我们总希望敲代码的过程能更简单些，好让我们专注于知识的学习——我们开始吧。\n一点点快乐 安装Visual Studio Code Visual Studio Code（下面简称VS Code）是一个由微软开发的开源代码编辑器，支持多个平台。它支持测试，并内置了Git版本控制功能，同时也具有开发环境功能，例如代码补全、代码片段和代码重构等。安装过程十分简单，官网下载并按照提示安装即可。\n安装完成后，软件界面默认为英文，可以选择安装并使用中文插件。\n搜索下载简体中文插件 切换语言 按照操作重新启动程序，即可设置为中文界面。 此外，还可以通过设置改变编辑器字体大小（设置 - 文本编辑器 - 字体）以及软件窗口主题色（设置 - 工作台 - 外观）。\n下载插件获得快乐 和安装简体中文插件的步骤差不多，找一个最热门的下载安装。\n至此，在使用VS Code编辑.v文件时就可以体会自动补全语句的快乐了！只要选择语言模式为Verilog即可。\n放个动图大家感受一下：\n如果只是想敲代码自动补全的话，看到这里其实就可以了。如果各科作业都写完了，可以再往下看看。\n更多快乐 更改Vivado默认编辑器 打开设置（Tools - Settings\u0026hellip;），将Text Editor中的Current Editor改为Custom Editor\u0026hellip;，在弹出的窗口中输入：\n1 C:/Program Files/Microsoft VS Code/Code.exe -g [file name]:[line number] 其中，前面的那一串字符表示你电脑上VS Code的安装位置，请根据个人实际情况自行修改。\n这样一波操作之后，在Vivado中打开.v文件将自动跳转至VS Code中进行操作。\n安装Ctags实现高级功能 本文1.2中提到的插件，除自动补全一些代码外，还具有Document Symbols Outline、Go to Definition等一些看不懂的便捷功能，而这些功能需要Ctags支持。笔者虽然不知道Ctags是啥、有什么用，但经过摸索，已经熟练掌握了其安装与卸载。\n点击此处挑一个看得顺眼的版本下载：\n将压缩包解压至电脑的某个角落：\n编辑系统变量：\n这一步操作在安装各种软件、环境时十分常见。在Windows搜索框中输入Path，找到并打开“编辑系统环境变量”，在弹出的窗口中点击“环境变量(N)\u0026hellip;”，在系统变量中找到“Path”，将上一步解压的文件夹路径添加到Path中。\n检验安装结果：Win+R调出运行窗口，输入cmd打开命令提示符，输入：\n1 ctags --version 如果没有报错，那就大功告成了。不出意外的话，VS Code的界面会变成这样：\n左下角的大纲虽然似乎没太大用处，不过看起来很高级。转到定义似乎也很方便。\nPS：完成以上操作后建议重启一下系统。\n使用Icarus Verilog检查语法错误 本文1.2中提到的插件还支持检查语法错误（linting），此功能可以基于xvlog、iverilog、verilator或者modelsim。其中，xvlog是Vivado自带的，不过在笔者的电脑上似乎并不好用。因此，这里简要介绍一下Icarus Verilog（iVerilog）。\n戳此链接下载安装包，按照提示安装。安装过程中有一个复选框“Add executable folder(s) to the user PATH”，要勾选上（如果不勾选就需要手动修改PATH，这样比较麻烦）。\n安装后，在命令提示符中输入iverilog，出现以下结果说明安装成功：\n最后，在VS Code设置中将“Verilog \u0026gt; Linting: Linter”设置为“iverilog”。\n这样，在写代码时，每次Ctrl+S保存之后都会自动检查语法错误。\n以上就是本文的全部内容了。如果VS Code出现了什么问题，百度或Google可能会有你想要的答案，或者直接去GitHub上反馈Issue。如果实在解决不了，那就换回朴实的Vivado吧。在VS Code里敲完代码再复制粘贴回Vivado也挺好的。\n参考文献 [1] 南工小王子. Vivado加上VsCode让你的生活更美好.\n[2] Michael ee. Visual Stduio Code for Verilog Coding.\n[3] Visual Studio Code Docs. The Visual Studio Code command-line options.\n[4] Xilinx Vivado - Wikipedia.\n[5] mshr-h. Verilog HDL/SystemVerilog support for VS Code.\n[6] TERRA. VSCode加iverilog环境.\n","permalink":"https://guguming.github.io/vscode-verilog/","summary":"\u003cp\u003e进入大二下学期，电脑软件喜加一。无论是四节连上、教室未知的课程安排，还是微信群里一遍又一遍的@所有人，都暗示着我们将要和某款软件度过新学期的美好时光……\u003c/p\u003e\n\u003cp\u003e它就是：\u003cstrong\u003eXilinx Vivado\u003c/strong\u003e，简称 \u003cstrong\u003e“喂娃兜”\u003c/strong\u003e，主要用于HDL（Hardware Description Language，硬件描述语言）的设计、综合与分析。此软件以其\u003cstrong\u003e安装复杂\u003c/strong\u003e、\u003cstrong\u003e启动缓慢\u003c/strong\u003e、\u003cstrong\u003e不支持中文\u003c/strong\u003e以及\u003cstrong\u003e玄学报错\u003c/strong\u003e等特性广受学生好评，自带编辑器更是以朴实、简约著称，几乎没有任何辅助功能，时刻让人体会着最原始的编程意境。\u003c/p\u003e\n\u003cp\u003e懒是人类进步的动力。我们总希望敲代码的过程能更简单些，好让我们专注于知识的学习——我们开始吧。\u003c/p\u003e","title":"🛠️ VS Code + Verilog 实现快乐编程"}]