• 使用Vitis HLS生成 IP核 (verilog版和图形化版)


    实验一、 自动旋转式栅门

    1.1 实验题目

    旋转式栅门是一个由三个齐腰高旋转柄组成的门,其中一个旋转柄在进道
    口。旋转式栅门一般安装在地铁站出入口等公共场所人行道,控制行人的进出。
    初始时这旋转柄是锁住的,挡住进口,阻止行人通过。当交通卡(或投币)
    在旋转式栅门上的刷卡机扫描(或投币)成功时,这旋转柄就解锁了,允许一个
    行人通过。在行人通过后,旋转柄又锁住了。

    1.2 实验建模

    以两种形式来对栅门进行IP建模,分别是图形化建模IP和Verilog建模IP。

    1.2.1 Verilog建模IP

    首先是Turnstile.h

    #include
    uint8 turnstile(uint8 C, uint8 P, uint8 reset);
    
    • 1
    • 2

    函数声明完成后,需要具体实现该函数,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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    最后还需要一个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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    添加设计文件

    在这里插入图片描述

    添加测试文件
    在这里插入图片描述

    C Simulation
    在这里插入图片描述
    在这里插入图片描述

    C Synthesis

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    C/RTL Cosimulation

    左侧的C,P,reset 分别代表输入, return 代表状态:0表示闸门关,1表示闸门开,从波形图可以看出当C=1时 闸门开。
    在这里插入图片描述

    导出生成verilog 版IP。
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    1.2.2 图形化建模IP

    打开Vivado,创建新项目,在Settings里的Ip下的Repository加载之前导出的verilog核。
    在这里插入图片描述

    打开IP Catalog,找到Turnstile。
    在这里插入图片描述

    双击Turnstile得到图形化核

    在这里插入图片描述

    1.3 实验总结

    相同性:两者都有相同的输入和输出端口C、P、 reset、clk。
    差异性:使用HLS生成的verilog代码更加复杂,端口种类也更多,多了一些控制端口,C/C++ 的参数输入作为输入端口,参数返回作为输出端口。而在自己写的verilog中是自己设定的。

    实验二、 餐巾纸售货机

    2.1 实验题目

    一款餐巾纸售货机,只接受 5 角和 1 元硬币,1 包餐巾纸价格为 1.5 元,没有找零功能。其中, Mealy型自动机如图2.1所示。
    在这里插入图片描述

    2.2 实验建模

    使用两种形式来对售货机进行IP建模,分别是图形化建模IP和Verilog建模IP。

    2.2.1 Verilog建模IP

    首先是Vender.h

    typedef unsigned char uint8;
    uint8 vender(uint8 J, uint8 Y, uint8 reset);
    
    • 1
    • 2

    函数声明完成后,需要具体实现该函数,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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    最后还需要一个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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    源代码添加到vitis HLS的源文件中,需要添加Top Function。

    在这里插入图片描述

    测试文件vender_tb.cpp添加到TestBench中。
    在这里插入图片描述

    运行C simulation,结果如下图所示。
    在这里插入图片描述

    运行C Synthesis,Part选择xc7z20clg484-1;
    在这里插入图片描述

    综合结果如下图所示,可以得到运行时间和LUT、FF等一系列资源的使用情况。
    在这里插入图片描述

    执行CoSimulation,结果如下。
    在这里插入图片描述

    当收到J和Y = 1 的时候,售货机打开。

    在这里插入图片描述

    导出Verilog 版IP
    在这里插入图片描述

    导出成功。
    在这里插入图片描述
    在这里插入图片描述

    2.2.2 图形化建模IP

    打开Vivado,创建新项目,在Settings里的Ip下的Repository加载之前导出的verilog核。
    在这里插入图片描述

    打开IP Catalog,找到Vender。
    在这里插入图片描述

    双击Turnstile得到图形化核
    在这里插入图片描述

    2.3 实验总结

    相同性:两者都有相同的输入和输出端口J、Y、 reset、clk,都能实现相同的功能。
    差异性:使用HLS生成的verilog代码更加复杂,没有自己编写的verilog代码简洁,端口种类也更多,多了一些控制端口,C/C++ 的参数输入作为输入端口,参数返回作为输出端口。HLS使得设计师不掌握硬件描述语言就可以使用一些硬件IP核。

  • 相关阅读:
    面对陕西省2022年职称评审政策调整有没有好的对策
    kafka消费/发送消息,消息过大报错解决whose size is larger than the fetch size 1048576
    记录不存在如何加锁MySQL_innodb select for update 没有满足条件的记录的情况下 是怎么加锁的呢
    SpringCloud_第3章_微服务保护_Sentinel
    小学生python游戏编程arcade----精灵调用图片的两种类
    web前端期末大作业:JavaScript大作业——福五鼠动漫网页制作(6页)带轮播图效果 学生个人单页面网页作业 学生网页设计成品 静态HTML网页单页制作
    关于git 解决分支冲突问题(具体操作,包含截图,教你一步一步解决冲突问题)
    python算法例14 整数加法
    经典伴读_GOF设计模式_结构型模式
    【工作中问题解决实践 一】最小单元染色法的应用
  • 原文地址:https://blog.csdn.net/qq_43570528/article/details/127936949