用户指令就是我们让NIOS II软核完成的一个功能,这个功能由电路模块来实现,这个电路模块是用HDL语言描述的。它被连接到NIOS II软核的算术逻辑部件上,下面就是示意图:
用户指令分多种,有组合逻辑指令、多周期指令、扩展指令等等,学明白一个,也就举一反三了, Altera提供了用户模块HDL的模板,通过裁减就可以适应多种指令类型了。下面就是这个模版的Verilog形式,很简单吧,我想看到这里很多人会说:oh,that's 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
下面两张图和表可以帮助我们更深入的理解和总结:
万事开头难,那我们就挑个软的捏,来做一条组合逻辑指令吧,下面就是模块示意图:
这个模块只有两个输入,A,B,都是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_inii是Altera 移植GCC后的built_in 。
最后,我们创建一个Hello World工程,稍微改动一下:
#include <system.h>
#include <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头文件包含进来。
好了,马上可以进行调试了。
发表评论 评论 (0 个评论)