Calendar
载入中。。。
Placard
载入中。。。
Category
载入中。。。
Latest Entries
载入中。。。
Latest Comments
载入中。。。
Last Messages
载入中。。。
User Login
载入中。。。
Links
Information
载入中。。。
Search
Other


Welcome to my blog!
  NIOS II Step By Step(1)---NIOS II自定义指令
 

 可编程软核处理器最大的特点是灵活,灵活到我们可以方便的增加指令,这在其他SOC系统中做不到的,增加用户指令可以把我们系统中用软件处理时耗费时间多的关键算法用硬逻辑电路来实现,大大提高系统的效率,更突出的一点是:我们通过下面的逐步操作会认识到,这是一个听起来高深,其实比较容易实现的功能(我们站在EDA工具这个巨人肩上,风光无限啊:),通过这一文档的介绍可以增强我们掌握NIOS II所有的技术手段的信心,这也是我把NIOS II 用户指令放在最前面的用意。

    用户指令就是我们让NIOS II软核完成的一个功能,这个功能由电路模块来实现,这个电路模块是用HDL语言描述的。它被连接到NIOS II软核的算术逻辑部件上,下面就是示意图: 
    

    用户指令分多种,有组合逻辑指令、多周期指令、扩展指令等等,学明白一个,也就举一反三了, Altera提供了用户模块HDL的模板,通过裁减就可以适应多种指令类型了。下面就是这个模版的Verilog形式,很简单吧,我想看到这里很多人会说:oh,thats easy。模块里面的内容不要我说了,也说不尽,是你智慧表演的舞台了,八仙过海,各显神通的机会来了:)
//Verilog Custom Instruction Template
module __module_name(
clk,         // CPU
s master-input clk <required for multi-cycle>
reset,         // CPU
s master asynchronous reset <required for multi-cycle>
clk_en, // Clock-qualifier <required for multi-cycle>
start,         // True when this instr. issues <required for multi-cycle>
done,         // True when instr. completes <required for variable muli-cycle>
dataa,         // operand A <always required>
datab,         // operand B <optional>
n,                 // N-field selector <required for extended>
a,                 // operand A selector <used for Internal register file access>
b,                 // operand b selector <used for Internal register file access>
c,                 // result destination selector <used for Internal register file access>
readra, // register file index <used for Internal register file access>
readrb, // register file index <used for Internal register file access>
writerc,// register file index <used for Internal register file access>
result         // result <always required>
);
input clk;
input reset;
input clk_en;
input start;
input readra;
input readrb;
input writerc;
input [7:0] n;
input [4:0] a;
input [4:0] b;
input [4:0] c;
input [31:0]dataa;
input [31:0]datab;
output[31:0]result;
output done;

// Port Declaration
// Wire Declaration
// Integer Declaration
// Concurrent Assignment
// Always Construct
endmodule

下面两张图和表可以帮助我们更深入的理解和总结:


万事开头难,那我们就挑个软的捏,来做一条组合逻辑指令吧,下面就是模块示意图:


这个模块只有两个输入,AB,都是32BIT的,输出也是32BIT的。你可以让他们是C=A+B,也可以C=A+1。我们给出一个HDL范例:
//Verilog Custom Instruction Template
module test_custom_instruction(
dataa,         // operand A <always required>
datab,         // operand B <optional>
result         // result <always required>
);
input [31:0]dataa;
input [31:0]datab;
output[31:0]result;

assign result=dataa+1;

endmodule
上面的模块实现A+1,很简单。

其他指令类型也就是增加了PORT口,里面处理更复杂一点。下面是多周期指令的块图:

 

    
有了以上概念,和HDL模块的准备,我们可以进入实际操作了,打开QUARTUS II,建一个工程,再进入SOPC BUILDER,建好相关的SOPC 环境,下图是FreeDev2.1 EP1C12+100M开发板的一个配置

 
双击CPU项就进入CPU配置,设置用户指令我们要选最后一个表单(Custom Instructions TAB)。见下图

 

在该表单中我们点击IMPORT,来加入我们的HDL模块,见下图:


 
IMPORT操作窗口上,点击ADD增加用户指令模块,点击read port list from files显示模块PORT
最后点击Add to System完成用户指令的添加。

SOPC BUILDER 中生成系统,并在QUARTUS II中重新编译整个工程,并program编程开发板器件,这样硬件部分就完成了。下面我们就可以在NIOS II IDE中来编程使用我们的指令了。

    由于我们在SOPC BUILDER 中增加了用户指令,SOPC BUILDER 生成的PTF文件中包含了相关信息,我们在NIOS II IDE 中增加新软件工程项目编译时,系统根据SOPC BUILDER生成的PTF文件生成了硬件系统描述的system.h。在该头文件中系统已经为用户指令生成了相关的宏,我们以上定制的用户指令在system.h中相关部分如下:
/*
* custom instruction macros
*
*/

#define ALT_CI_TEST_CUSTOM_INSTRUCTION_N 0x00000000
#define ALT_CI_TEST_CUSTOM_INSTRUCTION(A,B) __builtin_custom_inii(ALT_CI_TEST_CUSTOM_INSTRUCTION_N,(A),(B))

注意__builtin_custom_iniiAltera 移植GCC后的built_in Function

最后,我们创建一个Hello World工程,稍微改动一下:
#i nclude <system.h>
#i nclude <stdio.h>

int main()
{
  int a,b,c;
  
  a=1;
  
  c=ALT_CI_TEST_CUSTOM_INSTRUCTION(a,b);
  printf("c=%d\n",c);
  
  return 0;
}

主要把system.h头文件包含进来。

好了,马上可以进行调试了。

[ 阅读全文 | 回复(1) | 引用通告 | 编辑

  Post  by  jearome 发表于 2006-9-6 11:42:00
  Re:NIOS II Step By Step(1)---NIOS II自定义指令
  houdangui顶啊!我是在校学生,我想学习nios ii啊!

我看不到上面的截图啊,郁闷!
[ 个人主页 | 引用 | 返回 | 删除 | 回复

  Post  by  houdangui发表评论于2007-4-28 10:43:00
发表评论:
载入中。。。
载入中。。。