作者: 时间:2007-09-21 来源: | ||||
1. 概述 传统的嵌入式系统设计的主要目标是找到一种优化的体系结构来完成单一的,特定的功能。对这样的系统来说,ASIC和核心处理器是作为特别的构件模块加以考虑的:设计者根据应用的要求选择适当的ASIC,根据给定的性能要求比如处理器主频,系统稳定性,以及对功耗的要求等选用适当的处理器内核。 然而,在当今移动通信已经进入每个人的生活的今天,现在的嵌入式系统比如PDA等已经不同于传统意义上的嵌入式系统了,它们有自己的独特特点。客观需要要求它们能够支持多种应用功能如网页浏览,播放音频/视频文件,以及进行无线网络通信等。 这样看来,传统的设计思路因为只面向单一的应用,无法满足多应用嵌入式系统的需求。而解决这一问题的良好途径便是向嵌入式系统引入可编程能力,以使得系统能够根据用户的不同要求实现对不同应用的支持。 为了向系统中引入可编程能力,我们考虑在系统中嵌入FPGA,因为FPGA具有下列特点,使得它成为我们的首选: 1.现在的FPGA的处理能力和逻辑容量已经接近于专用ASI 2.由于FPGA具有的可重编程能力,使用了FPGA的嵌入式系统能够满足各种不同的应用要求; 从嵌入式系统管理的角度来说,对网络通信的支持也是很有必要的,也是很有特色的一个应用,因为它使得从远端服务器下载新的应用程序并在本地运行成为可能。为实现对这个功能的支持,我们采用Java作为软件平台。因为Java运行在Java虚拟机之上,它能够下载并执行新的应用程序代码,并且无需在下载后重新启动系统。 综上所述,这个新的嵌入式系统是基于Java的,有一个FPGA和标准处理器相连。我们通过网络下载Java代码和可以对FPGA进行编程的比特流。该系统也支持对FPGA的动态重新配置。为了实现硬件(FPGA)和软件(Java应用程序代码)之间的通信,又定义了一组本地API,以使得从Java应用层能够访问到底层的硬件。为了调用这些本地API,采用了Java本地接口(JNI)。在本文中,将一些Java函数(Java method)用FPGA可编程硬件来实现,称之为硬件方法(HW method)。 2. 系统设计 实现一个Java函数功能的对应的硬件方法实现的逻辑结构图如图1所示。 输入缓存和输出缓存分别用来接收输入参数和存储输出结果。控制缓存用于对硬件方法的控制和检测,比如向硬件方法发出启动指令,检查其所处的状态并判断操作是否完成等。该模块中的所有缓存都映射到处理器物理地址空间中,处理器可以使用正常的读写指令完成对这些缓存的访问。 图2是该嵌入式系统的硬件平台,由一个标准处理器,一个FPGA和一个系统存储单元构成。它们之间通过共享的系统总线连接在一起。 当处理器向一个硬件方法发出读写操作指令时,该硬件方法在其自己的地址解码器的帮助下向数据总线上发送对应的响应信号。在这里,我们可以认为是处理器发起的硬件/软件通信指令,而FPGA则是作为一个从属单元做出回应。因为在处理器发起初始指令后,就由可配置管理器来负责管理FPGA编程。这样一来,就实现了处理器和FPGA的并行运行。 如图3所示,我们选择Java作为软件平台,并且装载了一个嵌入式操作系统为Java实时应用程序提供基本的服务,比如线程和其它硬件管理等。 通过系统管理器,可以从远程服务器下载Java应用程序。系统管理器主要实现了下面3种协议: 由于我们使用了Java软件平台,应用程序就无法直接访问底层的硬件。这就是说,运行在处理器Java虚拟机上的应用程序不能直接访问映射到FPGA中硬件方法的缓存区域。为解决这个问题,理论上可以采用下面两种方法: 本地通信库API形式如下: Java本地接口层接口的形式如下: class HWInterface{ static int ConfigStatus; public static native int setParam(CID hw_cid, object P) { if(type_of_P == XXX) err = hwWriteXXX(hw_cid.addr, (XXX)P); return err; } public static native int getResult(CID hw_cid, object R); public static native int setCMD(CID hw_cid, int cmd); public static native int getStatus(CID hw_cid); public synchronized static native int configHW( CID hw_cid); } 在上面代码中,XXX表示基本的Java数据类型如整型(integer)、浮点型(float)、双精度型(double)等。 使用上面给出的接口,则下面这段代码 methodA() { …; int a = objA.m1(2); //SW method int b = objB.m2(3); //HW method int c = a + b; …; } 就应该写成下面的形式: methodA() { …; 1 HWInterface.configHW(cid2); // cid2 is the ID of HW method m2 2 Object P = new Integer(3); 3 HWInterface.SetParam(cid2,P); 4 HWInterface.startHW(cid2); 5 int a = objA.m1(2); 6 Object R = new Integer(); 7 While(HWInterface.getResult(cid2, R) == 0) 8 HWInterface.getResult(cid2, R); 9 int b = ((Integer)R.getValue()); 10 int c = a + b; } 在上例中,为了执行FPGA中的函数objB.m2(),首先对FPGA进行编程(Line1)。然后,将参数拷贝到硬件方法的输 入缓存中(Line3),并对硬件方法进行初始化(Line4)。最后,采用了一个循环函数持续检查硬件方法缓存的状态(Line7,8),直至计算完成,然后拷贝得到结果(Line9)。 3. 系统实现
主机接口和一个串行口。并移植了一个嵌入式操作系统和一个小巧的Java实时运行环境。如图4: 4. 总结 1. T.Kuhn, W.Rosenstiel, Java Based Modeling and Simulation of Digital Systems on Register Transfer Level, Int. Workshop on System Design Automation, 1998 |
标签: Java 嵌入式 FPGA |
文章评论(0条评论)
登录后参与讨论