【驯服野生verilog-mode全记录】day4 —— 对循环展开语法的python脚本外挂支持

news2024/12/25 23:54:53

 我们的目标是┏ (゜ω゜)=☞芯片前端全栈工程师~喵!

系列文章目录

【驯服野生verilog-mode全记录】day3 —— 基于vim自动生成verilog-mode格式初始文件模板_尼德兰的喵的博客-CSDN博客

【驯服野生verilog-mode全记录】day2 —— 模块的例化_尼德兰的喵的博客-CSDN博客_verilog模块例化格式

【驯服野生verilog-mode全记录】day1 —— 常用链接与基本命令模板_尼德兰的喵的博客-CSDN博客

【驯服野生verilog-mode全记录】day0 —— verilog-mode的安装_尼德兰的喵的博客-CSDN博客

前言

时间2022年12月19日02点28分,恭喜煤老板终于圆梦!

回归主题,其实我最初想在本地尝试安装verilog-mode,除了想使用自动连线功能外,就是想使用这个循环展开的功能。装完之后一打听,原来这并不是verilog-mode的原生功能。这就非常尴尬了,而我又没有去改原生工具的能力,万般无奈只能通过外挂python脚本的手段来补充这个功能点了。

循环展开功能其实主要是避免手写复制类似如下代码时出现错误笔误:

assign start_addr         =  (conv_bitmap[0] ? cfg_param0_start_addr : 8'b0) | //{{{
                             (conv_bitmap[1] ? cfg_param1_start_addr : 8'b0) |
                             (conv_bitmap[2] ? cfg_param2_start_addr : 8'b0) |
                             (conv_bitmap[3] ? cfg_param3_start_addr : 8'b0) |
                             (conv_bitmap[4] ? cfg_param4_start_addr : 8'b0) |
                             (conv_bitmap[5] ? cfg_param5_start_addr : 8'b0) |
                             (conv_bitmap[6] ? cfg_param6_start_addr : 8'b0) |
                             (conv_bitmap[7] ? cfg_param7_start_addr : 8'b0) |
                             (conv_bitmap[8] ? cfg_param8_start_addr : 8'b0) |
                             (conv_bitmap[9] ? cfg_param9_start_addr : 8'b0) |
                             (conv_bitmap[10] ? cfg_param10_start_addr : 8'b0) |
                             (conv_bitmap[11] ? cfg_param11_start_addr : 8'b0) |
                             (conv_bitmap[12] ? cfg_param12_start_addr : 8'b0) |
                             (conv_bitmap[13] ? cfg_param13_start_addr : 8'b0) |
                             (conv_bitmap[14] ? cfg_param14_start_addr : 8'b0) |
                             (conv_bitmap[15] ? cfg_param15_start_addr : 8'b0) |
                             (conv_bitmap[16] ? cfg_param16_start_addr : 8'b0) |
                             (conv_bitmap[17] ? cfg_param17_start_addr : 8'b0) |
                             (conv_bitmap[18] ? cfg_param18_start_addr : 8'b0) |
                             (conv_bitmap[19] ? cfg_param19_start_addr : 8'b0) |
                             (conv_bitmap[20] ? cfg_param20_start_addr : 8'b0) |
                             (conv_bitmap[21] ? cfg_param21_start_addr : 8'b0) |
                             (conv_bitmap[22] ? cfg_param22_start_addr : 8'b0) |
                             (conv_bitmap[23] ? cfg_param23_start_addr : 8'b0) |
                             (conv_bitmap[24] ? cfg_param24_start_addr : 8'b0) |
                             (conv_bitmap[25] ? cfg_param25_start_addr : 8'b0) |
                             (conv_bitmap[26] ? cfg_param26_start_addr : 8'b0) |
                             (conv_bitmap[27] ? cfg_param27_start_addr : 8'b0) |
                             (conv_bitmap[28] ? cfg_param28_start_addr : 8'b0) |
                             (conv_bitmap[29] ? cfg_param29_start_addr : 8'b0) |
                             (conv_bitmap[30] ? cfg_param30_start_addr : 8'b0) |
                             (conv_bitmap[31] ? cfg_param31_start_addr : 8'b0) ; //}}}

以及替代generate的一些功能,因为generate有时会导致代码结构层次的不易识别以及对后端eco的一些困扰(这个是我听说的),所以在循环数为定值时直接展开写也是一种不错的选择。

效果演示

假设我的.v文件中有这样一段代码:

/* AUTO_UNFOLD
#for i 0..4
dffre u_dff#i#(
    .clk(clk),
    .rst_n(rst_n),
    .d(in_d[#i#]),
    .q(in_q[#i#]),
    .en(in_en[#i#])
);
END */

在vim中键入:U回车,得到如下代码:

/* AUTO_UNFOLD
#for i 0..4
dffre u_dff#i#(
    .clk(clk),
    .rst_n(rst_n),
    .d(in_d[#i#]),
    .q(in_q[#i#]),
    .en(in_en[#i#])
);
END */
//AUTO_UNFOLD_START
dffre u_dff0(
    .clk(clk),
    .rst_n(rst_n),
    .d(in_d[0]),
    .q(in_q[0]),
    .en(in_en[0])
);
dffre u_dff1(
    .clk(clk),
    .rst_n(rst_n),
    .d(in_d[1]),
    .q(in_q[1]),
    .en(in_en[1])
);
dffre u_dff2(
    .clk(clk),
    .rst_n(rst_n),
    .d(in_d[2]),
    .q(in_q[2]),
    .en(in_en[2])
);
dffre u_dff3(
    .clk(clk),
    .rst_n(rst_n),
    .d(in_d[3]),
    .q(in_q[3]),
    .en(in_en[3])
);
//AUTO_UNFOLD_END

展开循环的规则遵循python中的规则,i 0..4的话会将i依次赋值为0 1 2 3。再次键入:UD后,生成的代码被删除;

再如有下面一段代码:

/* AUTO_UNFOLD
#for i 2..4
#for j 1..3
#for k 1..4
assign undg_vipi#i#_j#j#_k#k#_#i*j+k# = 0;
END */

键入:U回车后,得到最后的代码为:

/* AUTO_UNFOLD
#for i 2..4
#for j 1..3
#for k 1..4
assign undg_vipi#i#_j#j#_k#k#_#i*j+k# = 0;
END */
//AUTO_UNFOLD_START
assign undg_vipi2_j1_k1_3 = 0;
assign undg_vipi3_j1_k1_4 = 0;
assign undg_vipi2_j2_k1_5 = 0;
assign undg_vipi3_j2_k1_7 = 0;
assign undg_vipi2_j1_k2_4 = 0;
assign undg_vipi3_j1_k2_5 = 0;
assign undg_vipi2_j2_k2_6 = 0;
assign undg_vipi3_j2_k2_8 = 0;
assign undg_vipi2_j1_k3_5 = 0;
assign undg_vipi3_j1_k3_6 = 0;
assign undg_vipi2_j2_k3_7 = 0;
assign undg_vipi3_j2_k3_9 = 0;
//AUTO_UNFOLD_END

还能支持数学运算哈哈哈哈!当有多层for循环体的时候,上面为最内层循环下面为外层循环依次展开(这块代码可难写了,我带着刚羊完的脑子一边看决赛一边想到了半夜1点)。

最后再比如上文提到的怕错的代码,可以先写成这个形式:

assign start_addr         =   (conv_bitmap[0] ? cfg_param0_start_addr : 8'b0)
/* AUTO_UNFOLD
#for i 1..32
                            | (conv_bitmap[#i#] ? cfg_param#i#_start_addr : 8'b0)
END */
                            ;

然后直接一手展开:

assign start_addr         =   (conv_bitmap[0] ? cfg_param0_start_addr : 8'b0)
/* AUTO_UNFOLD
#for i 1..32
                            | (conv_bitmap[#i#] ? cfg_param#i#_start_addr : 8'b0)
END */
//AUTO_UNFOLD_START
                            | (conv_bitmap[1] ? cfg_param1_start_addr : 8'b0)
                            | (conv_bitmap[2] ? cfg_param2_start_addr : 8'b0)
                            | (conv_bitmap[3] ? cfg_param3_start_addr : 8'b0)
                            | (conv_bitmap[4] ? cfg_param4_start_addr : 8'b0)
                            | (conv_bitmap[5] ? cfg_param5_start_addr : 8'b0)
                            | (conv_bitmap[6] ? cfg_param6_start_addr : 8'b0)
                            | (conv_bitmap[7] ? cfg_param7_start_addr : 8'b0)
                            | (conv_bitmap[8] ? cfg_param8_start_addr : 8'b0)
                            | (conv_bitmap[9] ? cfg_param9_start_addr : 8'b0)
                            | (conv_bitmap[10] ? cfg_param10_start_addr : 8'b0)
                            | (conv_bitmap[11] ? cfg_param11_start_addr : 8'b0)
                            | (conv_bitmap[12] ? cfg_param12_start_addr : 8'b0)
                            | (conv_bitmap[13] ? cfg_param13_start_addr : 8'b0)
                            | (conv_bitmap[14] ? cfg_param14_start_addr : 8'b0)
                            | (conv_bitmap[15] ? cfg_param15_start_addr : 8'b0)
                            | (conv_bitmap[16] ? cfg_param16_start_addr : 8'b0)
                            | (conv_bitmap[17] ? cfg_param17_start_addr : 8'b0)
                            | (conv_bitmap[18] ? cfg_param18_start_addr : 8'b0)
                            | (conv_bitmap[19] ? cfg_param19_start_addr : 8'b0)
                            | (conv_bitmap[20] ? cfg_param20_start_addr : 8'b0)
                            | (conv_bitmap[21] ? cfg_param21_start_addr : 8'b0)
                            | (conv_bitmap[22] ? cfg_param22_start_addr : 8'b0)
                            | (conv_bitmap[23] ? cfg_param23_start_addr : 8'b0)
                            | (conv_bitmap[24] ? cfg_param24_start_addr : 8'b0)
                            | (conv_bitmap[25] ? cfg_param25_start_addr : 8'b0)
                            | (conv_bitmap[26] ? cfg_param26_start_addr : 8'b0)
                            | (conv_bitmap[27] ? cfg_param27_start_addr : 8'b0)
                            | (conv_bitmap[28] ? cfg_param28_start_addr : 8'b0)
                            | (conv_bitmap[29] ? cfg_param29_start_addr : 8'b0)
                            | (conv_bitmap[30] ? cfg_param30_start_addr : 8'b0)
                            | (conv_bitmap[31] ? cfg_param31_start_addr : 8'b0)
//AUTO_UNFOLD_END
                            ;

这效果不是完美吗!

使用说明

auto_unfold.py · 尼德兰的喵/myscript_python - Gitee.com

把脚本搞到本地,然后根据脚本路径在.vimrc中加入两句话:

command! U  :execute '%! /home/ICer/auto_unfold.py -f %'
command! UD :execute '%! /home/ICer/auto_unfold.py -d -f %'

之后重新打开.v文件就可以使用这个功能了。

关键实现

python中可以通过eval("2*4+5*4")来计算一个字符串输入的运算式~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/100418.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微服务框架 SpringCloud微服务架构 服务异步通讯 53 MQ 集群 53.4 仲裁队列【RabbitMQ控制台搭建】

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 服务异步通讯 文章目录微服务框架服务异步通讯53 MQ 集群53.4 仲裁队列【RabbitMQ控制台搭建】53.4.1 仲裁队列53.4.2 搭建仲裁队列53 MQ 集…

10. 注解开发Bean作用范围和生命周期管理

1. bean作用范围注解配置 使用Scope注解定义bean作用范围 1.1. singleton为单例 1.1.1 在bean头上使用Scope注解,singleton package com.lin.dao.impl;import com.lin.dao.BookDao; import org.springframework.context.annotation.Scope; import org.springfra…

企业档案管理实务:档案的检索方法知多少

在鸿翼档案的企业档案系统设计中,企业档案常用的检索实际上包括两个行为:企业档案信息的贮存和企业档案信息的查找。档案检索工具一方面是整个企业档案检索体系中贮存结果的最终体现,直接反映贮存的质量和水平;另一方面又是各项业…

Redis 哈希(Hash)方法使用详解

目录一、简介二、常用方法2.1、HSET2.2、HSETNX2.3、HGET2.4、HINCRBY、HINCRBYFLOAT2.5、HSTRLEN2.6、HEXISTS2.7、HDEL2.8、HLEN2.9、HMSET、HMGET2.10、HKEYS、HVALS、HGETALL2.11、HSCAN一、简介 本文今天主要是讲哈希(Hash)的方法的使用&#xff0c…

毕业设计 单片机手势检测识别系统 - arduino 物联网 嵌入式

文章目录0 前言1 简介2 主要器件3 实现效果4 设计原理5 部分核心代码6 最后0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长…

uniapp中video层级太高(或者在页面中不跟随页面滚动)解决方案

我觉得这个问题有必要记录一下。最近项目中遇到的问题:项目是uniapp开发,有一个商品详情的页面和一个视频竖向轮播的页面。 问题描述 1、商品详情页上面是图片轮播(包含视频),下面是商品详情,当页面上下滑动时,如果当…

微服务框架 SpringCloud微服务架构 服务异步通讯 52 惰性队列 52.2 惰性队列

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 服务异步通讯 文章目录微服务框架服务异步通讯52 惰性队列52.2 惰性队列52.2.1 惰性队列52.2.2 总结52 惰性队列 52.2 惰性队列 52.2.1 惰…

【BTC】Fork

区块链中fork的分类: state fork: 两个节点差不多同一个时候挖到了矿,就会出现一个临时性的分叉。 forking attack(deliberate fork):也是属于对比特币这个区块链当前的状态产生的意见分歧,只不…

汇编语言笔记——汇编程序开发、汇编大作业

文章目录传送门汇编程序开发汇编代码初步实践dos虚拟机与挂载实模式Hello World代码解析汇编链接重新汇编与批处理反汇编与debug保护模式Hello WorldVS2017masm32环境配置汇编基础语言概述汇编环境汇编语言语句格式常用伪指令数据定义符号定义操作符\$OFFSET算术操作符逻辑操作…

【基础】RabbitMQ 基础

RabbitMQ 基础RabbitMQ 基本介绍RabbitMQ 基本概念ConnectionChannelVirtual HostQueueExchangedirectfanouttopicheadersRabbitMQ 基本介绍 RabbitMQ 是使用 Erlang 语言开发的基于 AMQP 协议来实现的开源消息队列系统。 RabbitMQ 的特点: 灵活路由:E…

社招前端二面react面试题整理

解释 React 中 render() 的目的。 每个React组件强制要求必须有一个 render()。它返回一个 React 元素&#xff0c;是原生 DOM 组件的表示。如果需要渲染多个 HTML 元素&#xff0c;则必须将它们组合在一个封闭标记内&#xff0c;例如 <form>、<group>、<div&g…

什么是数据标注,它的用途是什么?

什么是数据标注&#xff1f; 从本质上讲&#xff0c;数据标注是对计算机视觉或自然语言处理 (NLP)可识别的材料内容进行标记的过程。当我们标记或标注这些类型的数据时&#xff0c;它们变得更容易输入算法或编程以通过 NLP 进行解释。 得益于数据标注&#xff0c;人工智能 (…

【Vue】Vue项目打包上线流程--20221219

Vue项目打包上线流程 我的链接https://blog.csdn.net/m0_46629123/article/details/128371149 1.打包 npm run build 2.准备服务器 1.准备demo文件夹&#xff0c;并CMD输入npm init 2.CMD输入npm i express 3.新建并编辑server.js server.js const express require(…

电动汽车对系统运行的影响(Matlab实现)

目录 0 写在前面 1 插式电动车介绍 2 全系统 PEV 充电需求估算 2.1 旅行模式模型 2.2 能源消耗模型 2.3 电力消耗模型 3 单个 PEV 充电设施需求估算 4 PEV充电站需求估算网络 5 电动汽车对电力系统影响的评估 6 系统模型 6.1 结果 6.2 Matlab代码 0 写在前面 在不久…

论文笔记High-Resolution Image Synthesis with Latent Diffusion Models

普通的扩散模型在像素空间操作&#xff0c;运算复杂度较高。为了保证在低资源下训练扩散模型&#xff0c;并保留扩散模型的质量和灵活性&#xff0c;该论文使用预训练的自编码器得到隐含空间&#xff0c;并在隐含空间中训练扩散模型。另一方面&#xff0c;该论文使用cross-atte…

设计模式原则 - 里氏替换原则

一 背景&#xff1a; 里氏替换原则是针对继承的。介绍前先聊聊继承性的特点 继承优势 提高代码的复用性&#xff08;每个子类有拥有父类的属性和方法&#xff09;提高代码的可扩展性 继承劣势 继承是侵入性的&#xff08;只要继承&#xff0c;就必须拥有父类的属性和方法&…

齐鲁转债上市价格预测

齐鲁转债基本信息转债名称&#xff1a;齐鲁转债&#xff0c;评级&#xff1a;AAA&#xff0c;发行规模&#xff1a;80.0亿元。正股名称&#xff1a;齐鲁银行&#xff0c;今日收盘价&#xff1a;4.28&#xff0c;转股价格&#xff1a;5.87。当前转股价值 转债面值 / 转股价格 *…

endo BCN-PEG4-COOH,endo BCN-四聚乙二醇-羧酸

中文名&#xff1a;endo BCN-四聚乙二醇-羧酸 英文名&#xff1a;endo BCN-PEG4-acid CAS号&#xff1a;1881221-47-1 分子式/分子量&#xff1a;C22H35NO8/441.5 结构式 溶解性&#xff1a;溶于大部分有机溶剂&#xff0c;如&#xff1a;DCM、DMF、DMSO、THF等等&#…

公务员备考(四十) 图推提升

第一章 平面专题总结 一、线总结 1、曲线直线 曲直图形判断原则:有曲则为曲,无曲才为直。阴影图形不讨论曲直性。 曲直规律图形特点:a.纯直线曲线图形;b.简笔画实物图形;c.单区域简单图形;d.内外结构图形 2、平行线(含回旋折线) a.轮廓自带平行线条;b.N字型、Z字…