第一个excel VBA demo —— 添加信号并生成一段Verilog代码

简介: 第一个excel VBA demo —— 添加信号并生成一段Verilog代码

前言

小时候记得excel里有一个神秘的赛车游戏,发现excel原来并不简单啊;

之前我哥跟我讲excel可能是最牛逼的编程软件,但是当时我没信,现在我有点信了;

工作后发现很多代码原来并不需要写,通过excel、xml直接生成还是爽爽的;

最好的是,自带的编译器自动补全自动大小写转换自动联想比平时用的IDE舒服多了;

所以说啊,学一学VBA还是挺有意思的,你也不知道啥时候就用得上;

作为我写的第一个excel vba demo,必须好好记录下。

目标

通过excel添加信号,并生成Verilog module代码,每个sheet作为一个模块,最终的实现的效果如下:

1.点击添加信号;

2.输入信号名称;

3.输入信号位宽,默认为1;

4.输入信号类型,默认wires;

5.输入是否接口,默认no;

6.完成一个信号输入后,可以继续添加;单一信号输入途中选择取消,则推出输入;

7.点击“生成代码”,直接生成module rtl,除了对齐失败以外,可以说非常完美;

实现

列举一下用到的sub/function;

信号输入

1. Option Explicit
2. 
3. Dim sigName As String
4. Dim sigWidh As String
5. Dim sigType As String
6. Dim sigPort As String
7. 
8. Public Type sigInfo
9.     name As String
10.     widh As Integer
11.     type As String
12.     port As String
13. End Type

全局定义,由于开始没考虑清楚,有重复定义之嫌;全局变量用来输入和获取信号信息;

 

1. Private Function gainLastRow() As Integer
2. 
3.     Dim lastRow As Integer
4.     
5.     lastRow = ActiveSheet.UsedRange.Rows.Count
6.     gainLastRow = ActiveSheet.UsedRange.Rows(lastRow).Row + 1
7.     'Debug.Print gainLastRow
8.     
9. End Function

获取当前sheet最后一行位置,之后添加信号时默认向最后添加;

 

1. Private Function gainSigIn() As Boolean
2. 
3.     sigName = InputBox(prompt:="信号名称")
4.     If sigName = "" Then
5.         gainSigIn = False
6.         Exit Function
7.     End If
8.       
9.     
10.     sigWidh = InputBox(prompt:="信号位宽", Default:="1")
11.     If sigWidh = "" Then
12.         gainSigIn = False
13.         Exit Function
14.     End If
15.     
16.     sigType = InputBox(prompt:="信号类型reg/wire??", Default:="wire")
17.     If sigType = "" Then
18.         gainSigIn = False
19.         Exit Function
20.     End If
21.     
22.     sigPort = InputBox(prompt:="接口属性no/input/output/inout??", Default:="no")
23.     If sigPort = "" Then
24.         gainSigIn = False
25.         Exit Function
26.     End If
27.     
28.     gainSigIn = True
29.     
30. End Function

通过inputbox函数获取键入的信号信息;

 

1. Public Sub mainAddSig()
2. 
3. Dim addRow As Integer
4. 
5. Do
6. If gainSigIn() = True Then
7. 'Debug.Print "@@@@@@@"
8.             addRow = gainLastRow()
9. With ActiveSheet
10.                 .Cells(addRow, 1).Value = sigName
11.                 .Cells(addRow, 2).Value = sigWidh
12.                 .Cells(addRow, 3).Value = sigType
13.                 .Cells(addRow, 4).Value = sigPort
14. End With
15. Else
16. Exit Sub
17. End If
18. Loop Until MsgBox("是否继续输入", vbOKCancel) <> vbOK
19. 
20. End Sub

“添加信号”按钮绑定sub,将获取到的信号信息写入单元格最后一行后面,写入完成后询问是否继续输入;

生成代码

1. Private Function gainOrgLoc() As Integer
2. 
3. Dim keyCell As Range
4. 
5.     Cells(1, 1).Select
6. 
7. 'Set keyCell = ActiveSheet.UsedRange.Find(What:="???????", After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True, SearchFormat:=False)
8. Set keyCell = Cells.Find(What:="???????", After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True, SearchFormat:=False)
9. 
10. If keyCell Is Nothing Then
11.         gainOrgLoc = -1
12. Else
13.         gainOrgLoc = keyCell.Row
14. 'Debug.Print gainOrgLoc
15. End If
16. 
17. End Function

以左上角(1,1)坐标为起始,寻找标志“信号名称”,其下一行到最后一行为信号定义区间;

 

1. Private Function gainSigInfo(setRow As Integer) As sigInfo
2.     
3.     With ActiveSheet
4.         gainSigInfo.name = .Cells(setRow, 1)
5.         gainSigInfo.widh = .Cells(setRow, 2)
6.         gainSigInfo.type = .Cells(setRow, 3)
7.         gainSigInfo.port = .Cells(setRow, 4)
8.     End With
9.     
10. End Function

获取某一行信号信息;

 

1. Public Sub genRtlCode()
2. 
3.     Dim inputArray As New Collection
4.     Dim outputArray As New Collection
5.     Dim inoutArray As New Collection
6.     Dim wireArray As New Collection
7.     Dim regArray As New Collection
8. 
9.     Dim startRow As Integer
10.     Dim sig  As sigInfo
11.     Dim ss As New Collection
12.     
13.     Dim i As Integer
14.     Dim s As String
15.       
16.     startRow = gainOrgLoc() + 1
17.     
18.     For i = startRow To gainLastRow
19.         sig = gainSigInfo(i)
20.         If sig.name <> "" Then
21.             If sig.port = "input" Then
22.                 inputArray.Add ("    input  " & sig.type & " [" & sig.widh & " -1:0] " & sig.name & ";")
23.                 'Debug.Print "    input " & sig.type & " [" & sig.widh & " -1:0] " & sig.name & ";"
24.             ElseIf sig.port = "output" Then
25.                 outputArray.Add ("    output " & sig.type & " [" & sig.widh & " -1:0] " & sig.name & ";")
26.                 'Debug.Print "    output " & sig.type & " [" & sig.widh & " -1:0] " & sig.name & ";"
27.             ElseIf sig.port = "inout" Then
28.                 inoutArray.Add ("    inout  " & sig.type & " [" & sig.widh & " -1:0] " & sig.name & ";")
29.             ElseIf sig.port = "no" And sig.type = "wire" Then
30.                 wireArray.Add ("    wire " & " [" & sig.widh & " -1:0] " & sig.name & ";")
31.                 'Debug.Print "    wire " & " [" & sig.widh & " -1:0] " & sig.name & ";"
32.             ElseIf sig.port = "no" And sig.type = "reg" Then
33.                 regArray.Add ("    reg  " & " [" & sig.widh & " -1:0] " & sig.name & ";")
34.                 'Debug.Print "    reg " & " [" & sig.widh & " -1:0] " & sig.name & ";"
35.             End If
36.         End If
37.     Next
38.     
39.     Open "C:\Users\gaoji\Desktop\RISC_SPM\gen.sv" For Output As #1
40.     Print #1, "module " & ActiveSheet.name & "("
41.     
42.     For i = 1 To inputArray.Count
43.         s = inputArray.Item(i)
44.         Print #1, s
45.     Next
46.     For i = 1 To outputArray.Count
47.         s = outputArray.Item(i)
48.         Print #1, s
49.     Next
50.     For i = 1 To inoutArray.Count
51.         s = inoutArray.Item(i)
52.         Print #1, s
53.     Next
54.     
55.     Print #1, ");"
56.     
57.     For i = 1 To regArray.Count
58.         s = regArray.Item(i)
59.         Print #1, s
60.     Next
61.     For i = 1 To wireArray.Count
62.         s = wireArray.Item(i)
63.         Print #1, s
64.     Next
65.     
66.     Print #1, "endmodule"
67.     
68.     Close #1
69.     
70.     
71. End Sub

从起始行到最终行,获取每一行的信号信息并根据属性组织代码放入不同的collection中;

之后将组织好的代码写入文件中。


相关文章
|
5天前
|
数据处理
Excel VBA 自动填充空白并合并相同值的解决方案
在Excel中,常需将一列数据中的空白单元格用上方最近的非空值填充,并合并连续相同值。本VBA宏方案自动完成此操作,包含代码实现、使用方法及注意事项。通过简单步骤添加宏,一键处理数据,提升效率,确保准确性。适用于频繁处理类似数据的用户。
18 7
|
7月前
|
数据安全/隐私保护
杨老师课堂之Excel VBA 程序开发第六讲根据部门列创建工作表
杨老师课堂之Excel VBA 程序开发第六讲根据部门列创建工作表
47 0
Excel中用宏VBA实现GBT 4761-2008 家庭关系代码转换
Excel中用宏VBA实现GBT 4761-2008 家庭关系代码转换
|
3月前
|
Java Apache
Apache POI java对excel表格进行操作(读、写) 有代码!!!
文章提供了使用Apache POI库在Java中创建和读取Excel文件的详细代码示例,包括写入数据到Excel和从Excel读取数据的方法。
85 0
|
4月前
|
数据采集 数据库
在EXCEL中VBA编程检验身份证号码有效性
在EXCEL中VBA编程检验身份证号码有效性
|
5月前
|
开发工具 开发者
Excel 2016 VBA 提取单元格的中文字符
Excel 2016 VBA 提取单元格的中文字符
47 1
|
5月前
|
C# 开发者 Windows
WPF遇上Office:一场关于Word与Excel自动化操作的技术盛宴,从环境搭建到代码实战,看WPF如何玩转文档处理的那些事儿
【8月更文挑战第31天】Windows Presentation Foundation (WPF) 是 .NET Framework 的重要组件,以其强大的图形界面和灵活的数据绑定功能著称。本文通过具体示例代码,介绍如何在 WPF 应用中实现 Word 和 Excel 文档的自动化操作,包括文档的读取、编辑和保存等。首先创建 WPF 项目并设计用户界面,然后在 `MainWindow.xaml.cs` 中编写逻辑代码,利用 `Microsoft.Office.Interop` 命名空间实现 Office 文档的自动化处理。文章还提供了注意事项,帮助开发者避免常见问题。
337 0
|
5月前
|
算法 数据挖掘 Java
日常工作中,Python+Pandas是否能代替Excel+VBA?
日常工作中,Python+Pandas是否能代替Excel+VBA?
53 0
|
5月前
|
SQL
SQL SERVER 查询表结构,导出到Excel 生成代码用
SQL SERVER 查询表结构,导出到Excel 生成代码用
51 0
|
6月前
|
数据格式 Python
Python代码示例,读取excel表格,将行数据转为列数据。(10)
【7月更文挑战第10天】Python代码示例,读取excel表格,将行数据转为列数据。
225 2