基于Verilog HDL的电子电路设计图的一种可视化编程方法

2014-11-19 16:25邓凯升赵宇晴
卷宗 2014年10期
关键词:端口变量电路

邓凯升 赵宇晴

随着计算机软件工程技术的迅速发展,可视化编程技术已经成为当今软件开发最重要的工具和手段。尤其是Power Builder、Visual C++等开发工具的出现,大大推动了可视化编程技术的发展。本文旨在探索可视化编程技术在基于硬件描述语言的电子电路设计领域的实现,介绍一种将电路设计图自动转换成硬件描述语言(Verilog HDL)的方法。

1.设计思想及实现方法

1.1.电路图的处理思想

电路图的处理是指将电路设计图的信息转换成可处理的数据存储到数据结构中的过程。在电子电路图设计者完成画图后,将电路图的图形信息转化成数据结构信息进行存储,方便进行接下来硬件描述语言的自动生成。我们选择在电路图完成后统一进行信息转换,这样不容易出错,而且实时转换可能会造成转换信息的反复更新重写,增加了转换过程的设计负担、降低了效率。具体的数据结构描述见1.2。

1.2 主要数据结构

每个电路图都由一个类对象存储,类对象的定义如下:

struct mycircuit

{

gate[];//gate类数组,记录门信息

ngate; //整型变量,记录电路中门的个数

pin[]; //pin类数组,记录端口详细信息

npin; //整型变量,记录电路中端口的个数

wire[]; //wire类数组,记录线路信息

nwire; //整型变量,记录电路中连线的条数

}此处引入一个新的概念——电路信息表,是在逻辑上存储电路连接关系的数据结构。和路由器维护的路由表原理相似,电路图中的每个元件都会维护一张电路信息表,这张表记录了该元件的位置,该元件的种类,以及该元件的连线情况。

下面以组合逻辑电路为例建立示范电路信息表:

struct position /* Position类,记录元器件所在位置的坐标*/ {x;y;};

struct gate/* gate类,记录门信息*/ {

inwrie[];//整型数组,输入线路编号

nwin;//整型变量,输入线路数量

outwrie[];//整型数组,输出线路编号

nwrout;//整型变量,输出线路数量

psi;//position類对象,门的位置信息

type;//整型标志位,区分电路中门类型

};

struct pin/* pin类,记录输出输出端口信息*/ {

psi;//position类对象,记录端口位置

type;//整型变量,标志位,0为输入端口,1为输出端口

iowire;//整型变量,记录与该端口连接的线路编号

};

struct wire/*wire类,存储连线相关的信息*/ {

start;//position类对象,线头位置

end;//position类对象,线尾位置

endgate;//整型变量,起点连接的门编号

startgate;//整型变量,终点连接的门编号

endpin;//整型变量,起点连接的端口编号

startpin;/整型变量,终点连接的端口编号

status;//整形变量,生成硬件描述语言过程中的状态位,当前算法生成过程只需一次扫描

};

为了提高效率,电路信息表中对其他类的保存均由整型数组记录其编号,编号是自动分配的,具体分配方法见1.3。

电路信息表亦可设置为在每个gate类对象与pin类对象中记录其上游器件和下游器件,这样则不用设置wire类,但生成硬件描述语言时需要对电路进行深度优先遍历,增加了时间复杂度,本文采用的记录方法,只需对每个门生成对应赋值语句,不用考虑遍历顺序,详细算法见1.4.2。

1.3.生成电路信息表

生成电路信息表的过程主要包括对预处理得到的关键字段的处理和电路连接关系的判断。其中关键字段的处理主要包括:连线信息处理、输入输出端口以及门信息处理。

其中连线信息处理包括线路信息提取、拐线合并和线路排序。为了方便存储,我们并不存储完整的拐线,而是将其分割为相连接的直线,故一条完整的拐线由若干条直线连接而成,记录每条wire的坐标时按照从上到下,从左到右的顺序区分起点和终点。

考虑到硬件描述语言的连续赋值语句中会出现线路编号,为了增加交互性和可读性,我们这里按照线路起点的横坐标由小到大、纵坐标从小到大进行排序,自动匹配编号,方便用户对应位置来理解、检查电路。

输入输出端口编号也会出现在最终生成的Verilog 硬件描述语言中,因此需要也根据端口位置信息进行一次排序处理。

通过以上操作,我们已经将电路设计图的元件位置信息以及元件编号都存到了相应的数据结构中,接下来的电路的逻辑连接关系判断正是基于坐标信息实现的。判断一条连线是否连接到端口或门,是通过连线的起点、终点坐标和端口或门的尺寸大小及坐标等信息来判定的。在这一结论的基础上,我们可以对电路信息表中的各字段进行赋值从而完成电路信息表的构建。

1.4.生成数据流描述的Verilog HDL硬件描述语言

1.4.1模块及声明

Verilog HDL中,需要在模块开始就声明所有端口和模块名,算法如下:先输出固定字符“module test(”,然后在括号内执行:

for(1;i<=pin的个数;i++){

输出“pin_i”;

if(i不等于pin的个数){

输出“,”;

}

else 输出“);”

}

然后进行端口指定,即声明端口的输入输出属性,算法如下:

for(i=1;i<=pin的个数;i++){

if(pin[i].type = 0)

输出“input pin_i”;

else if(pin[i].type = 1)

输出“output pin_i”;

}

接下来声明wire型变量,需要注意的是,如果连线的一端有输入输出端口,则在连续赋值语句中不会出现该线路而是由相应的输入输出端口替代,相应实现过程算法为:

for(i=1;i<=wire的个数;i++)

if(wire[i]的首尾均是gate)

输出“wire W_i;”

1.4.2连续赋值语句

由于数据流描述的模块是连线与端口的逻辑运算的描述,即有多少个门就有多少连续赋值语句,所以只需要对门进行一次遍历。

生成算法为:

for (gate[i]){

输出“gate[i]的输出线路 or该线路终点连接的端口”;//赋值表达式左端

输出 “=”; //赋值运算符

for(gate[i]的每个输入线路j) //赋值表达式右端{

输出“j or j起点连接的端口”;

if(j不是最后一条线路)

输出“gate[i].type对应的逻辑运算符”;

}

}

上述算法中,若連线的一端连接端口,则在生成过程中用端口名替换线路名。

以这种方法对每个门进行扫描,最后加上“endmodule”即完成了数据流的模块硬件语言描述转换。

1.5.结构化模块调用

结构化模块调用是Verilog HDL普遍使用的一种描述方法:对于用户已经连接好的模块,进行封装保存,记录该模块的名称、输入输出接口和对应的Verilog HDL代码。当用户在图形化界面中调用自定义模块时,先是生成自定义模块的实例化代码,保存为单独的用户自定义Verilog文件,然后将该模块视作一个封装起来的元件,用基于位置的连接判断方法确定每个接口与当前电路中wire的连接关系。然后在顶层模块生成过程中,根据用户指定的函数名称和判断得到的端口信息来调用该模块。

本文以组合逻辑电路为例,介绍了一种将电子电路设计图自动转化为Verilog HDL硬件描述语言的方法,若再进行引脚分配,将生成的硬件描述语言下载到现场可编程逻辑阵列中,就可以完成整个EDA的设计。该方法可以作为可视化编程工具的原型进行学习、使用和进一步开发。

猜你喜欢
端口变量电路
电路的保护
抓住不变量解题
也谈分离变量
巧用立创EDA软件和Altium Designer软件设计电路
基于MATLAB模拟混沌电路
端口阻塞与优先级
SL(3,3n)和SU(3,3n)的第一Cartan不变量
初识电脑端口
8端口IO-Link参考设计套件加快开发速度
分离变量法:常见的通性通法