旋转式栅门是一个由三个齐腰高旋转柄组成的门,其中一个旋转柄在进道
口。旋转式栅门一般安装在地铁站出入口等公共场所人行道,控制行人的进出。
初始时这旋转柄是锁住的,挡住进口,阻止行人通过。当交通卡(或投币)
在旋转式栅门上的刷卡机扫描(或投币)成功时,这旋转柄就解锁了,允许一个
行人通过。在行人通过后,旋转柄又锁住了。
以两种形式来对栅门进行IP建模,分别是图形化建模IP和Verilog建模IP。
首先是Turnstile.h
#include
uint8 turnstile(uint8 C, uint8 P, uint8 reset);
函数声明完成后,需要具体实现该函数,Turnstile.cpp内容如下所示:
#include "turnstile.h"
uint8 S = 0;
uint8 reset = 0;
uint8 S0 = 0;
uint8 S1 = 1;
uint8 C_last = 0;
uint8 turnstile(uint8 C, uint8 P, uint8 reset)
{
if(reset)
{
S = S0;
}
else
{
switch (S)
{
case 0:
if(C)
{
S = S1;
}
else
{
S = S0;
}
break;
case 1:
if(P)
{
S = S0;
}
else
{
S = S1;
}
break;
default:
break;
}
}
return S;
}
最后还需要一个test bench文件,Turnstile_tb.cpp内容如下所示:
#include
#include
#include "turnstile.h"
using namespace std;
int main()
{
uint8 reset = 0;
uint8 C = 0;
uint8 P = 0;
const uint8 time = 8;
for(uint8 i = 0; i < time; i++)
{
if(i<=2)
{
reset = 1;
}
else if(i<=4)
{
reset = 0;
C = 1;
}
else if(i <= 6)
{
C = 0;
P = 1;
}
else{
P = 0;
}
uint8 result = turnstile(C, P, reset);
// cout<
printf("%d\n",reset);
}
return 0;
}
添加设计文件
C Synthesis
左侧的C,P,reset 分别代表输入, return 代表状态:0表示闸门关,1表示闸门开,从波形图可以看出当C=1时 闸门开。
打开Vivado,创建新项目,在Settings里的Ip下的Repository加载之前导出的verilog核。
双击Turnstile得到图形化核
相同性:两者都有相同的输入和输出端口C、P、 reset、clk。
差异性:使用HLS生成的verilog代码更加复杂,端口种类也更多,多了一些控制端口,C/C++ 的参数输入作为输入端口,参数返回作为输出端口。而在自己写的verilog中是自己设定的。
一款餐巾纸售货机,只接受 5 角和 1 元硬币,1 包餐巾纸价格为 1.5 元,没有找零功能。其中, Mealy型自动机如图2.1所示。
使用两种形式来对售货机进行IP建模,分别是图形化建模IP和Verilog建模IP。
首先是Vender.h
typedef unsigned char uint8;
uint8 vender(uint8 J, uint8 Y, uint8 reset);
函数声明完成后,需要具体实现该函数,vender.cpp的内容如下所示:
#include "vender.h"
uint8 S = 0;
uint8 reset = 0;
uint8 S0 = 0, S5 = 1, S10 = 2;
uint8 state = 0;
uint8 open = 1;
uint8 close = 0;
uint8 vender(uint8 J, uint8 Y, uint8 reset)
{
state = 0;
if(reset)
{
S = S0;
state = 0;
}
else
{
switch (S)
{
case 0:
if(J)
{
S = S5;
state = 0;
}
else if(Y)
{
S = S10;
state = 0;
}
else{
S = S;
}
break;
case 1:
if(J)
{
S = S10;
state = 0;
}
else if(Y)
{
S = S0;
state = 1;
}
else{
S = S;
}
break;
case 2:
if(J)
{
S = S0;
state = 1;
}
else if(Y)
{
S = S0;
state = 1;
}
else{
S = S;
}
break;
default:
break;
}
}
if(state == 1)
return open;
else
return close;
}
最后还需要一个test bench文件,vender_tb.cpp内容如下所示:
#include
#include
#include "vender.h"
using namespace std;
int main()
{
uint8 reset = 0;
uint8 J = 0;
uint8 Y = 0;
uint8 result = 0;
const uint8 time = 4;
for(uint8 i = 0; i <= time; i++)
{
if(i<=1)
{
reset = 1;
}
else if(i<=2)
{
reset = 0;
J = 1;
Y = 0;
}
else if(i <= 3)
{
J = 0;
Y = 1;
}
else
{
Y = 0;
J = 1;
}
result = vender(J, Y, reset);
// cout<
printf("%d\n",result);
}
return 0;
}
源代码添加到vitis HLS的源文件中,需要添加Top Function。
测试文件vender_tb.cpp添加到TestBench中。
运行C Synthesis,Part选择xc7z20clg484-1;
综合结果如下图所示,可以得到运行时间和LUT、FF等一系列资源的使用情况。
当收到J和Y = 1 的时候,售货机打开。
打开Vivado,创建新项目,在Settings里的Ip下的Repository加载之前导出的verilog核。
相同性:两者都有相同的输入和输出端口J、Y、 reset、clk,都能实现相同的功能。
差异性:使用HLS生成的verilog代码更加复杂,没有自己编写的verilog代码简洁,端口种类也更多,多了一些控制端口,C/C++ 的参数输入作为输入端口,参数返回作为输出端口。HLS使得设计师不掌握硬件描述语言就可以使用一些硬件IP核。