测试平台Vivado 2017.2
本文设计了一个支持两个数的加法、减法、乘法、移位运算的IP,支持4个通道,并可通过IP的Re-customize界面配置每个通道的运算逻辑,4个通道可以选择使用数目,输入和运算符号可配置。
一、设计
第一步根据top.v文件建立一个基本工程;
然后点击Vivado菜单栏Tools->Create and Pacakge New IP;
点击Next,选择Pacakge your current project,点击Next;
暂时保持默认点击Next,之后点击Finished。
接下来Vivado会自动跳转到IP的编辑界面,首先点击Pacakge IP - top内的Customization GUI;
Vivado会自动导入我们verilog文件内的parameter,首先我们要对Channel Num这个参数做配置,希望的效果是它只能有1,2,3,4这几个参数值,默认值为1,默认它是可以输出所有整数,不符合我的预期,双击Channel Num,出现下图配置界面;
勾选Specify Range,这个Check Box功能是控制它可以显示哪些数,并选择,控制由Types和对应的框条件限制,Type选择Range of Integers,Type下面的框会消失,出现最小最大值选择:
Minimum写1,Maximum写4,并将最下面的Default Value修改为1。这样配置好第一个parameter,接下来配置的parameter需要依赖这个parameter,双击Channela Width;
将Editable设置为Dependent,右端会出现Expression,判断条件为CHANNEL_NUM值大于0,点击右端...,填入$CHANNEL_NUM>0,按照操作CHANNEL_NUM的参数一样设置Specify Range,范围0 - 31,点击OK。
同样操作对于CHANNELB_WIDTH、CHANNELC_WIDTH、CHANNELD_WIDTH;除了双击的方式,GUI手动填写,也可以通过tcl脚本实现配置(文件代码见附录SET_CHANNELWIDTH.tcl);
source SET_CHANNELWIDTH.tcl
接下来配置OP的参数,OP参数也有4个,以OPA为例简单演示。双击OPA;
根据CHANNELA_WIDTH配置Editable,勾选Specify,选择Pairs,填写如下图的参数;
点击OK(文件代码见附录SET_OP.tcl)。
source SET_OP.tcl
配置Parameter的最后几步,配置OCHA_WIDTH;如上述操作,条件为
expr $OPA==0?[expr $CHANNELA_WIDTH+1]:[expr $OPA==1?{$CHANNELA_WIDTH}:[expr $OPA==2?{$CHANNELA_WIDTH*2}:[expr $OPA==3?{$CHANNELA_WIDTH*16}:[expr $OPA==4?$CHANNELA_WIDTH:33]]]]
直接用tcl命令配置4个(文件代码见附录SET_OCH.tcl);
source SET_OCH.tcl
配置好parameter可以对paramter添加GROUP,GROUP可以选择水平或垂直排列;
接下来就是配置关键的地方,端口,上一篇IP如何控制端口的可见与不可见已经详细介绍了怎么设置,此处不再详细介绍。直接给出TCL代码(文件代码见附录SET_PORT.tcl);
source SET_PORT.tcl
之后点击Review and Package->Package IP。
二、验证
现在重新建一个工程,然后我们需要将之前建立的IP的路径包含进来,操作流程为:在Vivado左边的Flow Navigator内的PROJECT MANAGER上的Settings单击,会出现下面界面;
单击> IP项的>符号展开这个项,会出现Repository和Packager两个子项,单击Repository项,添加刚才设计IP的路径。点击OK,完成了我们设计的IP的添加;
现在,新建一个Block Design来验证效果,点击Flow Navigator内的IP INTEGRATOR内的Create Block Design,点击OK;
在Diagram内点击加号,弹出IP选择框;
输入我们之前做的IP的名字,我的是top开头,IP设计时如果没有什么修改,IP一般以模块名开头;
双击这个IP,完成IP添加。
双击这个IP进入Re-Customize IP界面;
可以尝试修改这些参数,验证验证效果;
可以发现D端口被隐藏了,通道D的parameter也是无法编辑的,OCH的值会更具CHANNEL WIDTH和OP值变化,点击OK。
top.v
module top #(
parameter CHANNEL_NUM = 4,
parameter CHANNELA_WIDTH = 32,
parameter CHANNELB_WIDTH = 32,
parameter CHANNELC_WIDTH = 32,
parameter CHANNELD_WIDTH = 32,
parameter OPA = 0,
parameter OPB = 0,
parameter OPC = 0,
parameter OPD = 0,
parameter OCHA_WIDTH = 32,
parameter OCHB_WIDTH = 32,
parameter OCHC_WIDTH = 32,
parameter OCHD_WIDTH = 32
)(
input [CHANNELA_WIDTH-1:0] CHANNELA1,
input [CHANNELA_WIDTH-1:0] CHANNELA2,
input [CHANNELB_WIDTH-1:0] CHANNELB1,
input [CHANNELB_WIDTH-1:0] CHANNELB2,
input [CHANNELC_WIDTH-1:0] CHANNELC1,
input [CHANNELC_WIDTH-1:0] CHANNELC2,
input [CHANNELD_WIDTH-1:0] CHANNELD1,
input [CHANNELD_WIDTH-1:0] CHANNELD2,
output [OCHA_WIDTH-1:0] OCHA,
output [OCHB_WIDTH-1:0] OCHB,
output [OCHC_WIDTH-1:0] OCHC,
output [OCHD_WIDTH-1:0] OCHD
);
localparam ADD = 0;
localparam SUB = 1;
localparam MULT = 2;
localparam LMOV = 3;
localparam RMOV = 4;
generate
case(OPA)
ADD: assign OCHA = CHANNELA1 + CHANNELA2;
SUB: assign OCHA = CHANNELA1 - CHANNELA2;
MULT: assign OCHA = CHANNELA1 * CHANNELA2;
LMOV: assign OCHA = CHANNELA1 << CHANNELA2;
RMOV: assign OCHA = CHANNELA1 >> CHANNELA2;
default: assign OCHA = CHANNELA1 + CHANNELA2;
endcase
endgenerate
generate
case(OPB)
ADD: assign OCHB = CHANNELB1 + CHANNELB2;
SUB: assign OCHB = CHANNELB1 - CHANNELB2;
MULT: assign OCHB = CHANNELB1 * CHANNELB2;
LMOV: assign OCHB = CHANNELB1 << CHANNELB2;
RMOV: assign OCHB = CHANNELB1 >> CHANNELB2;
default: assign OCHB = CHANNELB1 + CHANNELB2;
endcase
endgenerate
generate
case(OPC) &am
原创作品,未经权利人授权禁止转载。详情见转载须知。 举报文章
我要举报该内容理由
×