基于FPGA:运动目标检测(包围盒仿真工程,及一些调试问题)

news/2024/11/28 19:45:16/

目录

  • 前言
  • 一、安装器件库
  • 二、仿真工程操作
    • 1、进入文件列表
    • 2、找到bounding_box_locate.vt,双击打开文件
    • 3、修改路径
    • 4、路径设置
    • 5、切换回“Hierarchy”,即工程界面
    • 6、运行仿真
    • 7、查看波形
  • 重点:调试问题
  • 三、仿真代码
    • 1、仿真顶层文件
    • 2、绘制包围盒模块
  • 四、工程获取

前言

      前面写了几篇关于运动目标检测的文章了:
1、基于FPGA:运动目标检测(VGA显示,原理图+源码+硬件选择)
2、基于FPGA:运动目标检测(LCD显示+串口输出,纯Verilog工程)
3、基于FPGA:运动目标检测(补充仿真结果,可用毕设)

      LCD显示、VGA显示都做完了,这篇文章补充一下包围盒的仿真代码,下载工程可以直接运行仿真。

一、安装器件库

      因为仿真占用逻辑资源比较多,这里需要用的cyclone V的器件库,如果没有的,自己安装(最好是Quartus II 18.0以上)
       18.0器件库链接:https://www.intel.com/content/www/us/en/software-kit/667160/intel-quartus-prime-standard-edition-design-software-version-18-0-for-windows.html
      在这里面就能找到了。其他版本可以自己选。(下载的时候,最好自己用邮箱注册一个英特尔账号)
在这里插入图片描述
在这里插入图片描述

      下载完器件库,把器件库放在quartus的安装目录的bin目录下,然后在win开始页,选择Device Installer,进行安装。
在这里插入图片描述
      选择Bin路径
在这里插入图片描述

      一路nex。
在这里插入图片描述

二、仿真工程操作

1、进入文件列表

在这里插入图片描述

2、找到bounding_box_locate.vt,双击打开文件

在这里插入图片描述

3、修改路径

      在右侧窗口中找到45~47行,修改里面的文件路径,如果不知道怎么修改请看第4条
在这里插入图片描述

4、路径设置

      路径修改主要是确保doc文件夹路径要正确,因为在你的电脑上解压存放的路径和我的路径不一定一样,比如在我电脑上doc路径是:F:\FPGA\FPGA\bounding_box_locate\doc,注意在修改3中的路径时单斜杠要换成双斜杠;
在这里插入图片描述

5、切换回“Hierarchy”,即工程界面

在这里插入图片描述

6、运行仿真

      点击“Tools”–“Run Simulation Tool”–“RTL Simulation”

在这里插入图片描述

7、查看波形

      仿真开始后可以在“Wave”窗口看到波形,仿真完成会自动停止
在这里插入图片描述

重点:调试问题

问题1:
      如果第6步点了之后,出现这个界面,证明你的quartus没有安装modelsim,或者指定modelsim路径。

在这里插入图片描述

      这个时候,需要点击Tools-Options…

在这里插入图片描述

      添加正确真实的ModelSim-Altera安装路径。

在这里插入图片描述
问题2:

Error: (vish-42) Unsupported ModelSim library format for "F:/FPGA/FPGA/bounding_box_locate/par/simulation/modelsim/rtl_work". (Format: 4)

在这里插入图片描述

      这种问题多出现在拷贝别人的工程然后直接打开进行仿真,或者电脑软件重装且Modelsim软件降版之后。
      实际原因为工程中已经有的编译生成的仿真库文件版本比正在使用的仿真软件版本高,导致现在版本的Modelsim无权限去删除旧的库文件以重新生成新的库文件。所以报这个错误。

解决办法:
      手动将当前工程目录(注意,是当前工程目录,不是你的Quartus或者Modelsim软件安装目录,这种低级理解性错误很多人都犯),你当前仿真的是哪个工程,就把这个工程目录下的simulation文件夹删除了,然后重新运行仿真就可以了。

问题3:

#** Error: (vlog-7) Failed to open design unit file "F:/FPGA/FPGA/bounding_box_locate/par/simulation/modelsim/bounding_box_locate.vt" in read mode.

在这里插入图片描述
      因为很乖巧,按问题2我说的方法解决了问题2,所以就出现了问题3🐸
      这个问题,很明显,就是在simulation文件夹下,有bounding_box_locate.vt,然后被你删除了🐸

      到这里应该就没有其他问题了,一些路径过长,路径有空格,中文的,记得不要有。

三、仿真代码

1、仿真顶层文件

//功能:绘制包围盒模块
module bounding_box_top#(parameter MAX_NUM    = 8  ,parameter GAP_THR    = 60 ,//离散阈值,即任意白点到某个已存在的包围盒距离小于等于GAP_THR则归属于此包围盒parameter CW         = 10 , //cordinate widthparameter BOX_COLOR  = 24'hff_00_00//包围盒默认红色)
(input         clk    ,input         rst_n  ,//原始图像input         i_vsync,input         i_hsync,input         i_clken,input [23:0]  i_data ,////目标检测并二值化后图像input         i_vsync_bin,input         i_hsync_bin,input         i_clken_bin,input [0:0]   i_data_bin ,////目标数量output [$clog2(MAX_NUM)-1:0] obj_num,//原始图像添加包围盒后的图像output        o_vsync,output        o_hsync,output        o_clken,output [23:0] o_data  //
);
wire       post1_frame_vsync;
wire       post1_frame_href ;
wire       post1_frame_clken;
wire [7:0] post1_frame_data ;wire [CW*MAX_NUM-1:0] x_min;
wire [CW*MAX_NUM-1:0] x_max;
wire [CW*MAX_NUM-1:0] y_min;
wire [CW*MAX_NUM-1:0] y_max;
multy_locate#(.MAX_NUM(MAX_NUM),//支持的最大目标数量.GAP_THR(GAP_THR),//离散阈值,即任意白点到某个已存在的包围盒距离小于等于GAP_THR则归属于此包围盒.CW     (CW     )//cordinate width)u_multy_locate_0
(.clk    (clk        ) ,.rst_n  (rst_n      ) ,.i_vsync(i_vsync_bin) ,.i_hsync(i_hsync_bin) ,.i_clken(i_clken_bin) ,.i_data (i_data_bin ) ,//binary data.obj_num(obj_num    ) ,//检测到的目标个数.x_min  (x_min      ) ,//目标的包围盒坐标.x_max  (x_max      ) ,//目标的包围盒坐标.y_min  (y_min      ) ,//目标的包围盒坐标.y_max  (y_max      ) //目标的包围盒坐标
);
// bounding_box_locate #(
//     .MAX_NUM    (MAX_NUM )  ,
//     .GAP_THR    (GAP_THR)  ,//离散阈值,即任意白点到某个已存在的包围盒距离小于等于GAP_THR则归属于此包围盒
//     .CW         (CW)   //cordinate width
// )u_bounding_box_locate_0
// (
//     .clk  (clk),
//     .rst_n(rst_n),
//     .i_vsync(i_vsync_bin),
//     .i_hsync(i_hsync_bin),
//     .i_clken(i_clken_bin),
//     .i_data (i_data_bin ),//binary data
//     .o_valid(),
//     .x_min(x_min),
//     .x_max(x_max),
//     .y_min(y_min),
//     .y_max(y_max)
// );
wire [MAX_NUM-1:0] i_vsync_w;
wire [MAX_NUM-1:0] i_hsync_w;
wire [MAX_NUM-1:0] i_clken_w;
wire [23:0]        i_data_w[MAX_NUM-1:0];
wire [MAX_NUM-1:0] o_vsync_w;
wire [MAX_NUM-1:0] o_hsync_w;
wire [MAX_NUM-1:0] o_clken_w;
wire [23:0]        o_data_w[MAX_NUM-1:0];
//使用generate语句循环例化多个bounding_box_draw模块,每个bounding_box_draw模块画一个包围盒,同时产生一个时钟的数据延迟
generate
genvar m;
for(m=0;m<MAX_NUM;m=m+1)begin:u_drwif(m==0)begin:u_drw_0bounding_box_draw#(.BOX_COLOR  ( BOX_COLOR ),//包围盒默认红色.CW         ( CW           ) //cordinate width) u_bounding_box_draw_0(.clk    (clk  ),.rst_n  (rst_n),.i_vsync(i_vsync) ,.i_hsync(i_hsync) ,.i_clken(i_clken) ,.i_data (i_data ) ,.x_min  (x_min[(m+1)*CW-1-:CW]),.x_max  (x_max[(m+1)*CW-1-:CW]),.y_min  (y_min[(m+1)*CW-1-:CW]),.y_max  (y_max[(m+1)*CW-1-:CW]),.o_vsync(o_vsync_w[m]),.o_hsync(o_hsync_w[m]),.o_clken(o_clken_w[m]),.o_data (o_data_w[m]) //binary data);endelse begin:u_drw_mbounding_box_draw#(.BOX_COLOR  ( BOX_COLOR ),//包围盒默认红色.CW         ( CW           ) //cordinate width) u_bounding_box_draw_0(.clk    (clk  ),.rst_n  (rst_n),.i_vsync(o_vsync_w[m-1]),.i_hsync(o_hsync_w[m-1]),.i_clken(o_clken_w[m-1]),.i_data (o_data_w[m-1] ),.x_min  (x_min[(m+1)*CW-1-:CW]),.x_max  (x_max[(m+1)*CW-1-:CW]),.y_min  (y_min[(m+1)*CW-1-:CW]),.y_max  (y_max[(m+1)*CW-1-:CW]),.o_vsync(o_vsync_w[m]),.o_hsync(o_hsync_w[m]),.o_clken(o_clken_w[m]),.o_data (o_data_w[m] ) //binary data);end
end
endgenerate
assign o_vsync = o_vsync_w[MAX_NUM-1];
assign o_hsync = o_hsync_w[MAX_NUM-1];
assign o_clken = o_clken_w[MAX_NUM-1];
assign o_data  = o_data_w[MAX_NUM-1] ;
endmodule 

2、绘制包围盒模块

//功能:绘制包围盒模块
module bounding_box_draw#(parameter BOX_COLOR  = 24'hff_00_00,//包围盒默认红色parameter CW         = 12  //cordinate width)
(input       clk    ,input       rst_n  ,input       i_vsync,input       i_hsync,input       i_clken,input [23:0]i_data ,//binary datainput [CW-1:0] x_min,x_max,y_min,y_max,output reg       o_vsync,output reg       o_hsync,output reg       o_clken,output reg [23:0]o_data  //binary data
);
reg [CW-1:0] x_cnt,y_cnt;//当前输入的像素坐标
reg i_vsync_r,i_hsync_r,i_vsync_neg_r;
wire i_vsync_neg,i_hsync_neg;
assign i_vsync_neg = ~i_vsync && i_vsync_r;//vsyn下降沿检测
assign i_hsync_neg = ~i_hsync && i_hsync_r;//hsyn下降沿检测
//产生i_vsync_r、i_hsync_r逻辑
always@(posedge clk or negedge rst_n)
if(~rst_n)begini_vsync_r <= 1'b0;i_hsync_r <= 1'b0;end
elsebegini_vsync_r <= i_vsync;i_hsync_r <= i_hsync;end
//产生x_cnt,y_cnt逻辑
always @(posedge clk or negedge rst_n) 
if(~rst_n) //复位,包围盒坐标全部清零,坐标全零的包围盒视为不存在beginx_cnt   <= 'd0;y_cnt   <= 'd0;end 
else if(i_vsync_neg)beginx_cnt   <= 'd0;//每帧结束清空坐标计数器y_cnt   <= 'd0;//每帧结束清空坐标计数器 end
elsebegin	 //坐标计数器计数x_cnt <= i_hsync_neg?'d0:(i_clken?x_cnt+1'b1:x_cnt);//hsyn下降沿清零,i_clken高电平时自增1y_cnt <= i_hsync_neg?y_cnt+1'b1:y_cnt;//hsyn下降沿自增1		end
//包围盒着色 
always@(posedge clk or negedge rst_n)
begin
if(~rst_n) //复位begino_vsync <= 1'b0;o_hsync <= 1'b0;o_clken <= 1'b0;o_data  <= 'd0;		end	
else begino_vsync <= i_vsync; o_hsync <= i_hsync; o_clken <= i_clken; if( (( (x_cnt+2'd3 >= x_min && x_cnt <= x_min) || (x_cnt <= x_max+2'd3 && x_cnt >= x_max)) && y_cnt+2'd3 >= y_min && y_cnt <= y_max+2'd3) || (( (y_cnt+2'd3 >= y_min && y_cnt <= y_min) || (y_cnt <= y_max+2'd3 && y_cnt >= y_max)) && x_cnt+2'd3 >= x_min && x_cnt <= x_max+2'd3) )    o_data <= BOX_COLOR;else   o_data <= i_data;end
end
endmodule 

四、工程获取

1、直接点击下载:
基于FPGA:运动目标包围盒仿真(Quartus+modelsim)
注:如果点击无效,证明资源还在审核。

2、私信我或添加邮箱获取


http://www.ppmy.cn/news/105066.html

相关文章

什么是Redis

概述 什么是Redis Redis(Remote Dictionary Server) 是一个使用 C 语言编写的&#xff0c;开源的&#xff08;BSD许可&#xff09;高性能非关系型&#xff08;NoSQL&#xff09;的键值对数据库。 Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串&#xff…

Linux输入输出重定向

目录 Linux输入输出重定向 Linux中的默认设备 输入输出重定向定义 输入输出重定向操作符 实用形式 标准输入、标准输出、标准错误 输出重定向案例 案例1 --- 输出重定向&#xff08;覆盖&#xff09; 案例2 --- 输出重定向&#xff08;追加&#xff09; 案例3 --- 错误…

ifconfig工具与驱动交互解析(ioctl)

Linux ifconfig&#xff08;network interfaces configuring&#xff09; Linux ifconfig命令用于显示或设置网络设备。ifconfig可设置网络设备的状态&#xff0c;或是显示目前的设置。同netstat一样&#xff0c;ifconfig源码也位于net-tools中。源码位于net-tools工具包中&am…

《消息队列高手课》课程笔记(七)

如何使用异步设计提升系统性能&#xff1f; 异步设计如何提升系统性能&#xff1f; 假设我们要实现一个转账的微服务 Transfer(accountFrom, accountTo, amount)&#xff0c;这个服务有三个参数&#xff1a;分别是转出账户、转入账户和转账金额。 这个例子的实现过程中&…

Vue登录界面精美模板分享

文章目录 &#x1f412;个人主页&#x1f3c5;Vue项目常用组件模板仓库&#x1f4d6;前言&#xff1a;&#x1f380;源码如下&#xff1a; &#x1f412;个人主页 &#x1f3c5;Vue项目常用组件模板仓库 &#x1f4d6;前言&#xff1a; 本篇博客主要提供vue组件之登陆组件源码…

S7-1200 和 CP342-5 PROFIBUS DP主从通信例程

S7-1200 与 CP342-5 之间 PROFIBUS DP主从通信的几种可能情况分别提供了例程&#xff1a; 1. 同一项目中S7-1200 与 S7-300 CP342-5 之间 DP 主从通信&#xff0c;S7-1200 通过CM1243-5作为 DP 主站&#xff0c;CP342-5作为 DP 从站&#xff1b; 2. 不同项目中S7-1200 与 S7-3…

2022年软件测试人员调查统计

1、软件测试从业人员的年龄分布 测试行业的主力军年龄分布主要是集中在 26-30 岁这个区间&#xff0c;这部分的群体承担着行 业发展的主导力量&#xff0c;占 43.2%。根据数据显示&#xff0c;被调查者中占比最多的是 26-30 岁区间的软件测试从业人员&#xff0c;26-30 岁的测试…

spring入门-bean

Spring 是一个开源的、轻量级的企业级 Java 应用程序框架&#xff0c;它提供了一种全新的、基于 IoC &#xff08;控制反转&#xff09;和 AOP&#xff08;面向切面编程&#xff09;的软件开发方式&#xff0c;以及众多的企业级应用程序开发组件和 API。使用 Spring 框架可以大…