FPGA系统开发 综合实验记录

实验时间节点与想法记录

  • 2023.4.24 新建本文档。目前决定有以下两个方案,要根据学校发的器件和自己的水平和后面时间决定。

    课设想法 具体情况
    基于FPGA的高速运动体速度测量系统设计 难,可以当小型的毕业设计
    基于FPGA的智能交通装置 做的人比较多,要有创新点
  • 2023.4.27 决定使用超声波雷达作为项目。目前想法是使用舵机+雷达实现360度探测障碍物,如果在某一方向有距离接近,则在某一方向锁定探测范围,并报告距离。如果距离达到设定值则蜂鸣器报警。

  • 2023.5.12 购买以下器件用于实验

    器件 具体情况 备注
    杜邦线 公对母/母对母若干条
    HC-SR04超声波模块 宽电压3-5.5V
    SG90舵机 9克经典舵机180度
    无源蜂鸣器 2-4V无源9042电磁式16欧2731HZ 2只
  • 2023.5.13 完成比较清晰的实现思路 厂家把GPIO对应图放在User Manner里很难吗?

  • 2023.5.15 完成实体连接 每周一晚固定在Uboot上浪费2小时

  • 2023.5.21 要做了才发现舵机买错了,360°舵机没法控制特定角度,只能控制转速。下单180°

  • 2023.5.22 完成状态转移图 超声波测距模块 舵机模块和数码管模块的编写

  • 2023.5.25 Good News:谢天谢地,全编译能过了! Bad News: IO口只有16mA的电流,蜂鸣器要50mA的电流,估计响不起来,硬件真难!

  • 2023.5.26 Good News:舵机能转! Bad News:数码管显示全部无效,按钮无效。蜂鸣器响不起来。

  • 2023.5.27 写二进制转BCD的最好方法——写一个Python代码直生成对应CASE直接查,要多快有多快。

  • 2023.5.29 Good News:超声波模块能用了! Bad News:效果太差,器件原因很不稳定,没法做到检测物体位置变化。

  • 2023.6.1 位宽又错了! 如何在浩如烟海的Warning中找到错误?

  • 2023.6.2 Good News:基本实现功能,等待进一步测试。 Bad News:舵机驱动不到0°,范围只能在30°到180°。

  • 2023.6.4 完成全部内容。

器件功能与使用

HC-SR04超声波模块

1 基本工作原理

(1)采用 IO 口 TRIG 触发测距,需要给最少 10us 的高电平信号。

(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;

(3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。

测试距离=(高电平时间*声速(340M/S))/2

2 实物图

3 电气参数

4 超声波时序图

5 使用建议

建议测量周期为 60ms 以上,以防止发射信号对回响信号的影响。

模块不宜带电连接,若要带电连接,则先让模块的 GND 端先连接,否则会影响模块的正常工作。

测距时,被测物体的面积不少于 0.5 平方米且平面尽量要求平整,否则影响测量的结果。

SG90舵机

1 基本工作原理

控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。

2 实物连接

黄线接信号线,红线接VCC 5V,褐色线接GND。

3 FPGA与舵机

FPGA可以很方便地将脉宽的精度精确地控制在2微秒甚至2微秒以下。主要还是Delay Memory这样的具有创造性的指令发挥了功效。该指令的延时时间为数据单元中的立即数的值加1个指令周期(数据0除外,详情请参见Delay指令使用注意事项)因为是8位的数据存储单元,所以Memory中的数据为(0~255),记得前面有提过,舵机的角度级数一般为1024级,所以只用一个存储空间来存储延时参数好像还不够用的,所以可以采用2个内存单元来存放舵机的角度伺服参数了。所以这样一来,我们可以采用这样的软件结构了。

SG90(360°)需要什么信号? 首先必须明确,SG90不论是90°、180°还是360°,它需要的控制信号都是周期为20ms的脉宽调制(PWM)信号,只是脉冲宽度从0.5ms-2.5ms在三种舵机上的作用不同。对于360°舵机来说,0.5-1.5ms的脉冲宽度实现顺时针转动,只是速度不同;1.5-2.5ms的脉冲宽度实现逆时针转动,也只是速度不同;1.5ms的脉冲宽度实现暂停。 这里还需要明确一点(举例来说),脉冲宽度为1ms、周期为20ms的脉宽调制信号需要不断传输给舵机才能保证舵机不停地顺时针转动,并不是给了一个周期信号就完事了!https://blog.csdn.net/SHRtuji/article/details/113354315

无源蜂鸣器

基本工作原理

何为有源,何为无源?有源指的是蜂鸣器内部包含振荡电路。无源指的是蜂鸣器内部不包含振荡电路。有源蜂鸣器接入电源即可发声,但发声频率是固定的。无源蜂鸣器因为它本身没有内部振荡电路,所以需要一个外部的时钟信号才能将其驱动起来,令其发声。

PWM方波

通过输入不同频率和占空比的PWM方波实现驱动蜂鸣器。频率影响音调,占空比影响大小。

https://blog.csdn.net/cabinGGG/article/details/124745482

开发板与外设连接

GPIO

The board has two 40-pin expansion headers. Each header has 36 user pins connected directly to the Cyclone V SoC FPGA. It also comes with DC +5V (VCC5), DC +3.3V (VCC3P3), and two GND pins. The maximum power consumption allowed for a daughter card connected to one or two GPIO ports is shown in Table 3-10.





7段数码管

LED、按键、开关



管脚分配

实体连接

A端 B端 线类型
JP1 11 HC-SR04 VCC 母对母
JP1 12 HC-SR04 GND 母对母
JP1 13 HC-SR04 TRIG 母对母
JP1 14 HC-SR04 ECHO 母对母
JP1 29 9042 + 母对母
JP1 30 9042 - 母对母
JP2 11 SG90 VCC 红线 公对母
JP2 12 SG90 GND 褐线 公对母
JP2 13 SG90 信号线 黄线 公对母
JP2 29 9042 + 母对母
JP2 30 9042 - 母对母

实现思路

  1. 7段数码管总计使用6个。前三个用于显示舵机转的度数,精确到每度。后三个用于显示距离,单位为厘米,精确到个位。
  2. 开关总计使用4个。用于表示自动扫描/固定扫描模式2个,自动扫描模式即180度自动扫描,固定扫描则可通过利用按键进行左右调整到某个方位。用于复位1个,距离探测控制开关1个。
  3. 按键总计使用2个。用于左右调整各1个。
  4. LED总计使用8个。用于4个开关状态的工作情况各1个。距离告警4个。

    5. 蜂鸣器使用2个。用于报警声,报警声在探测到目标时即响起,当目标接近时报警声频率音量改变,目标远离时消失。

Verilog 代码

十进制转BCD码模块

module decimalToBCD
( input [9:0] bin , // binary
output reg [11:0] bcd ); // bcd {...,thousands,hundreds,tens,ones}
always @(*) begin
case(bin)
10'd0:bcd=12'b000000000000;
10'd1:bcd=12'b000000000001;
// 同上,省略
10'd998:bcd=12'b100110011000;
10'd999:bcd=12'b100110011001;
endcase
end
endmodule

十进制转BCD码在高级代码语言是很简单的事,但在FPGA开发中有些麻烦,因为在FPGA开发中乘除法会占用一定的系统资源。通过查阅资料,有以下方法用于在Verilog语言下解决十进制转BCD码的问题:

  1. 传统的循环乘除法。不做过多介绍。
  2. 移位加 3 法。这种方法是数字逻辑里使用的方法,但在位数变化后,对代码需要做一定调整。
  3. 在数据源头上就使用 BCD 码处理数字,直接判断何时需要进位。这种方法只能解决一类问题,泛化性差。
  4. 通过 Python 生成 SwitchCase 语句,直接查表。这种方法简单有效,非常符合本次实验设计的需要。以下是相关的Python代码。
for i in range(1000):
num = str(i).zfill(3)
bcd = ''
for digit in num:
bcd += bin(int(digit))[2:].zfill(4)
print(' 10\'d{0}:bcd=12\'b{1}'.format(i,bcd))

数码管显示模块

修改了原有数字 9 的设计,把最下面的也点亮。

/* 数码管显示模块
*/
module SEG7_LUT(
input [3:0] iDIG, //BCD码
output reg [6:0] oSEG //数码管各段信号
); always @(iDIG) begin
case(iDIG)
4'h1:oSEG=7'b1111001;
4'h2:oSEG=7'b0100100;
4'h3:oSEG=7'b0110000;
4'h4:oSEG=7'b0011001;
4'h5:oSEG=7'b0010010;
4'h6:oSEG=7'b0000010;
4'h7:oSEG=7'b1111000;
4'h8:oSEG=7'b0000000;
4'h9:oSEG=7'b0010000;
4'h0:oSEG=7'b1000000;
endcase
end endmodule

数码管综合模块

该模块把输入的角度值和距离值,转化为BCD码,在转换为数字管输出信号。

 module Seg7_Display
(
input rst_n, //低电平有效
input [9:0] angle, //角度值,显示在前三个数码管
input [9:0] distance, //距离值,显示在后三个数码管 output [6:0] HEX0, //各数码管输出信号
output [6:0] HEX1,
output [6:0] HEX2,
output [6:0] HEX3,
output [6:0] HEX4,
output [6:0] HEX5
); wire [23:0] mSEG7_DIG;
wire [6:0] mHEX0,mHEX1,mHEX2,mHEX3,mHEX4,mHEX5; assign {HEX5,HEX4,HEX3,HEX2,HEX1,HEX0}=rst_n?{mHEX5,mHEX4,mHEX3,mHEX2,mHEX1,mHEX0}:42'h0; decimalToBCD b3(.bin(angle),.bcd(mSEG7_DIG[23:12]));
decimalToBCD b4(.bin(distance),.bcd(mSEG7_DIG[11:0])); SEG7_LUT u0(.oSEG(mHEX0),.iDIG(mSEG7_DIG[3:0]));
SEG7_LUT u1(.oSEG(mHEX1),.iDIG(mSEG7_DIG[7:4]));
SEG7_LUT u2(.oSEG(mHEX2),.iDIG(mSEG7_DIG[11:8]));
SEG7_LUT u3(.oSEG(mHEX3),.iDIG(mSEG7_DIG[15:12]));
SEG7_LUT u4(.oSEG(mHEX4),.iDIG(mSEG7_DIG[19:16]));
SEG7_LUT u5(.oSEG(mHEX5),.iDIG(mSEG7_DIG[23:20])); endmodule

按键去抖模块

通过延时20个时间单位再次检测,实现按键去抖的效果。

/*  按键去抖检测模块
*/
module debounce(
input clk, //时钟
input rst_n, //低电平复位
input btn, //原始按键信号
output reg btn_pressed //去抖后的按键信号
); parameter debounce_time = 20; // 设置去抖时间 reg [debounce_time - 1:0] counter;
reg btn_state, btn_sample; always @(posedge clk) begin
if (!rst_n) begin
btn_pressed <= 0;
btn_state <= 1;
counter <= 0;
end else begin
// 按键状态和采样值
btn_state <= btn;
btn_sample <= btn & btn_state;
if (counter == debounce_time - 1) begin
if (btn_sample == 0 && btn_state == 1) begin
// 去抖完成,并且检测到按键按下
btn_pressed <= 1;
end else begin
btn_pressed <= 0;
end
end else begin
// 倒计时减少
counter <= counter + 'd1;
end
end
end endmodule

舵机控制模块

这个模块总体实现不难,主要是了解控制舵机的原理和角度与占空比之间的关系,该模块的代码也大部分来自网络公开资料。

/* 舵机控制模块
*/
module Steering_Gear(
input sys_clk, //时钟
input rst_n, //低电平有效
input gear_req, //舵机转动请求
input[9:0] angle, //转动角度 最大值180 output gear_ack, //舵机转动完成信号
output gear //舵机IO口
); localparam T_20ms = 'd1000_000;// 周期20ms reg[20:0] T_cnt; // 周期计时器 reg gear_reg; assign gear = gear_reg;
assign gear_ack = ( T_cnt == T_20ms ) ? 1'b1 : 1'b0; //周期计数
always@(posedge sys_clk or negedge rst_n )
begin
if( rst_n == 1'b0 )
T_cnt <= 'd0;
else if( gear_ack == 1'b1 )
T_cnt <= 'd0;
else if( gear_req == 1'b1 )
T_cnt <= T_cnt + 1'b1;
else
T_cnt <= 'd0;
end //脉冲输出 根据度数转换为每 20ms 里高电平所占的时间。
always@(posedge sys_clk or negedge rst_n)
begin
if( rst_n == 1'b0 )
gear_reg <= 1'b0;
else if( gear_req == 1'b1 && T_cnt < ( angle * 'd555 + 'd2500) )
gear_reg <= 1'b1;
else
gear_reg <= 1'b0;
end endmodule

超声波测距模块

该模块的代码也大部分来自网络公开资料,但在距离换算上进行改动。原有的距离换算包括乘除法,为避免这种情况,可通过改变时钟频率,实现 1cm = 1 次计数,这样计数器的值就是距离,虽然失去一定精度,然而本身数字管显示的单位是CM,对最终结果影响并不大。17kHZ时钟的计算来源如下:

声速取 340 m/s ,设所需要的时钟频率为 P,(1/P) = (34000 / 2) cm/s

(1/17k)/(1/50M) 取 2940 。

同时,增加每隔一定时间检测的部分,避免超声信号发送和接受时的干扰。

/*  超声波测距模块
*/ module Ultrasonic(
input sys_clk, //时钟
input rst_n, //低电平复位 output trig, //超声波模块的触发信号
input echo, //超声波模块的回响信号 input trig_req, //超声波测距请求信号
output trig_ack, //超声波测距响应信号
output [9:0] distance //超声波测距结果,单位cm
); localparam trig_time = 'd2250; //触发时间计时 45us localparam S_IDLE = 'd0; //初始状态
localparam S_SEND_Trig = 'd1; //发送触发信号状态
localparam S_WATI_Echo = 'd2; //等待全部响应信号状态
localparam S_END = 'd3; //响应结束状态 reg[3:0] state, next_state; reg[31:0] request_cnt;
reg[21:0] trig_cnt; //触发信号计时器
reg[21:0] echo_cnt; //回响信号计时器
reg[21:0] clk_17k; //17kHZ时钟 reg echo_d0, echo_d1;
wire echo_posedge, echo_negedge; //回响信号的上下边沿 assign echo_posedge = echo_d0 & (~echo_d1);
assign echo_negedge = (~echo_d0) & echo_d1;
assign distance = (echo_cnt);
assign trig_ack = ( echo_negedge == 1'b1 ) ? 1'b1 : 1'b0;
assign trig = (state == S_SEND_Trig) ? 1'b1 : 1'b0; always@(posedge sys_clk or negedge rst_n )
begin
if( rst_n == 1'b0)
begin
echo_d0 <= 1'b0;
echo_d1 <= 1'b0;
end
else if( state == S_WATI_Echo )
begin
echo_d0 <= echo;
echo_d1 <= echo_d0;
end
else
begin
echo_d0 <= 1'b0;
echo_d1 <= 1'b0;
end end always@( posedge sys_clk or negedge rst_n)
begin
if ( rst_n == 1'b0 )
state <= S_IDLE;
else
state <= next_state;
end always@(*)
begin
case (state)
S_IDLE:
if(trig_req == 1'b1)
next_state <= S_SEND_Trig;
else
next_state <= S_IDLE;
S_SEND_Trig:
if(trig_cnt == trig_time)
next_state <= S_WATI_Echo;
else
next_state <= S_SEND_Trig;
S_WATI_Echo:
if(echo_negedge == 1'b1)
next_state <= S_END;
else
next_state <= S_WATI_Echo;
S_END:
next_state <= S_IDLE;
default: next_state <= S_IDLE;
endcase
end // 为保证返回信号不与发送信号冲突,需要间隔 60ms 以上发送下次触发信号。 always@(posedge sys_clk or negedge rst_n)
begin
if( rst_n == 1'b0) begin
trig_cnt <= 'd0;
request_cnt <= 'd0;
end else if (state == S_SEND_Trig & request_cnt < 'd5000000) begin
request_cnt <= request_cnt + 'd1;
trig_cnt <= 'd0;
end else if (state == S_SEND_Trig & request_cnt >= 'd5000000) begin
trig_cnt <= trig_cnt + 1'b1;
end else begin
trig_cnt <= 'd0;
request_cnt <= 'd0;
end
end // 使用17kHZ信号计算echo信号值,echo_cnt的值 = 距离,避免乘除运算导致电路复杂化。 always@(posedge sys_clk or negedge rst_n)
begin
if( rst_n == 1'b0)
begin
echo_cnt <= 'd0;
clk_17k <= 'd0;
end
else if(state == S_WATI_Echo && echo == 1'b1)
begin
if(clk_17k < 'd2940)
begin
clk_17k <= clk_17k + 1'b1;
end
else
begin
clk_17k <= 'b0;
echo_cnt <= echo_cnt + 1'b1;
end
end
else if(state == S_END) begin
echo_cnt <= echo_cnt;
clk_17k <= clk_17k;
end
else begin
echo_cnt <= 'd0;
clk_17k <= 'd0;
end
end endmodule

顶层模块

根据上述实验实现思路,编写顶层模块。

module RADAR(

	input		sys_clk,		//系统时钟
input [1:0] Key_in, //2 按键 1 - 0
input [3:0] Switch_on, //4 开关 3 - 0
output reg [7:0] LED, //8 LED 7 - 0 output trig, //超声波模块的触发信号
input echo, //超声波模块的回响信号
output signal_gear, //舵机驱动信号
output [6:0] THEX0, //6 数码管
output [6:0] THEX1,
output [6:0] THEX2,
output [6:0] THEX3,
output [6:0] THEX4,
output [6:0] THEX5
); Seg7_Display d1(.rst_n(rst_n_d1),.angle(ANGLE),.distance(DISTANCE),.HEX0(THEX0),.HEX1(THEX1),.HEX2(THEX2),.HEX3(THEX3),.HEX4(THEX4),.HEX5(THEX5));
Steering_Gear s1(.sys_clk(sys_clk),.rst_n(rst_n_s1),.gear_req(1'b1),.angle(ANGLE),.gear_ack(),.gear(signal_gear));
debounce b1(.clk(sys_clk),.rst_n(rst_n_b),.btn(Key_in[0]),.btn_pressed(left));
debounce b2(.clk(sys_clk),.rst_n(rst_n_b),.btn(Key_in[1]),.btn_pressed(right));
Ultrasonic u1(.sys_clk(sys_clk),.rst_n(rst_n_u),.trig(trig),.echo(echo),.trig_req(Switch_on[3]),.trig_ack(ACK_trig),.distance(distance_out)); wire [9:0] distance_out;
reg [9:0] ANGLE = 'd90;
reg [9:0] DISTANCE = 'd999;
reg [31:0] count = 'd0; wire right, left;
reg direction = 1'b0; always @(posedge sys_clk) begin
if (distance_out > 'd1) begin
DISTANCE <= distance_out; // 超声波模块信号输入至寄存器
end else begin
DISTANCE <= DISTANCE;
end // 在不同的距离区间下,LED 7 - 4 依次亮起提示 if (DISTANCE < 'd25 & DISTANCE >= 'd1) begin
LED[7] <= 1'b1;
end else begin
LED[7] <= 1'b0;
end
if (DISTANCE < 'd50 & DISTANCE >= 'd25) begin
LED[6] <= 1'b1;
end else begin
LED[6] <= 1'b0;
end
if (DISTANCE < 'd75 & DISTANCE >= 'd50) begin
LED[5] <= 1'b1;
end else begin
LED[5] <= 1'b0;
end
if (DISTANCE < 'd100 & DISTANCE >= 'd75) begin
LED[4] <= 1'b1;
end else begin
LED[4] <= 1'b0;
end // 开关 3 打开时,超声波模块不断探测;关闭时,超声波模块暂停探测。 if (Switch_on[3]) begin
LED[3] <= 1'b1;
end else begin
LED[3] <= 1'b0;
end
end // 依次为数码管模块,舵机模块,按键模块,超声波模块的复位信号
reg rst_n_d1 = 1'b1, rst_n_s1 = 1'b1, rst_n_b = 1'b1, rst_n_u = 1'b1; always @(posedge sys_clk) begin
if (Switch_on[0]) begin // 开关 0 打开时,各模块均低电平复位。 rst_n_d1 <= 1'b0;
rst_n_s1 <= 1'b0;
rst_n_b <= 1'b0;
rst_n_u <= 1'b0;
LED[2:0] <= 3'b001; // LED 0 亮起提示
count <= 'd0; end else if (Switch_on[1]) begin // 开关 1 打开时,自动扫描模式开启。 rst_n_d1 <= 1'b1;
rst_n_s1 <= 1'b1;
rst_n_b <= 1'b0; // 屏蔽按键模块
rst_n_u <= 1'b1;
LED[2:0] <= 3'b010; // LED 1 亮起提示 if (count == 'd8000000) begin //如果达到预定值,则执行下面的操作
count <= 'd0;
if (direction == 1'b0) begin //方向是递增
if (ANGLE + 'd1 <= 'd179) begin //如果当前角度小于 180 度,则将其递增 1 度
ANGLE <= ANGLE + 'd1;
end
if (ANGLE + 'd1 > 'd179) begin //否则,改变方向为递减
direction <= 2'b01;
end
end
if (direction == 2'b01) begin //方向是递减
if (ANGLE - 'd1 >= 'd30) begin //如果当前角度大于 30 度,则将其递增 1 度
ANGLE <= ANGLE - 'd1;
end
if (ANGLE - 'd1 < 'd30) begin //否则,改变方向为递增
direction <= 2'b00;
end
end
end else begin
count <= count + 'd1; //否则,继续递增计数器
end end else if (Switch_on[2]) begin // 开关 2 打开时,手动调整模式开启。 rst_n_d1 <= 1'b1;
rst_n_s1 <= 1'b1;
rst_n_b <= 1'b1;
rst_n_u <= 1'b1;
LED[2:0] <= 3'b100; // LED 2 亮起提示 if (right == 1'b1) begin // 按键 0 按下代表舵机角度递增
if (ANGLE + 'd1 <= 'd179 ) begin // 如果当前角度小于 180 度,则将其递增 1 度
ANGLE <= ANGLE + 'd1;
end
end if (left == 1'b1) begin // 按键 1 按下代表舵机角度递增
if (ANGLE - 'd1 >= 'd30) begin // 如果当前角度大于 30 度,则将其递增 1 度
ANGLE <= ANGLE - 'd1;
end
end
end else begin // 开关 2 - 0 均关闭时,舵机重置至 90 度。 rst_n_d1 <= 1'b1;
rst_n_s1 <= 1'b1;
rst_n_b <= 1'b0; // 按键屏蔽
rst_n_u <= 1'b1;
LED[2:0] <= 3'b000; ANGLE <= 'd90;
end
end endmodule

实现效果

在线仿真和调试



视频展示

点此查看

一些报错和实验心得整理

Error (10759): Verilog HDL error at LabFinal.v(20): object SINGAL_gear declared in a list of port declarations cannot be redeclared within the module body

在模块体内和模块声明中,不能重复定义。

Error (10170): Verilog HDL syntax error at LabFinal.v(140) near text: "and"; expecting ")". Check for and fix any syntax errors that appear immediately before or at the specified keyword. The Intel FPGA Knowledge Database contains many articles with specific details on how to resolve this error. Visit the Knowledge Database at https://www.altera.com/support/support-resources/knowledge-base/search.html and search for this specific error message number.

这个错误不一定出现在这行,可能出现在其他地方,需要仔细检查语法。只有敏感信号才用 andor,其他语句里是不能用的。Python 的习惯带过来了。

Error (10267): Verilog HDL Module Instantiation error at LabFinal.v(266): cannot connect instance ports both by order and by name

仔细检查模块对应的端口名称,确保对应。

Error (10734): Verilog HDL error at decimalToBCD.v(10): i is not a constant

位宽必须是个定值,在位宽内注意循环变量的使用。并注意bcd[i*4+3:i*4] = decimal % 10; genvar 的使用。

Error (10219): Verilog HDL Continuous Assignment error at LabFinal.v(34): object "LED" on left-hand side of assignment must have a net type

Error (10663): Verilog HDL Port Connection error at LabFinal.v(263): output or inout port "btn_pressed" must be connected to a structural net expression

模块input的端口,可以是wire也可是reg,但是output的端口必须是wire.

Error (12007): Top-level design entity "LabFinal" is undefined

确认顶层模块名称是否和项目设置对应。

Error (10028): Can't resolve multiple constant drivers for net "rst_neg_g" at LabFinal.v(64)

一个变量不能在多个always语句块内赋值,即使在设计中两个模块的赋值时并不会冲突

Error (10110): Verilog HDL error at LabFinal.v(222): variable "flag" has mixed blocking and nonblocking Procedural Assignments -- must be all blocking or all nonblocking assignments

一个变量要么在时序逻辑中,要么在组合逻辑中,不能混合存在。

  1. 所有位宽都要确认是不是能够满足所存的数,不能满足并不会报错!
  2. 所有数字都要写清楚位宽和表示方法,就算 + 1 也最好写成 + 'd1
  3. 在每一次更改代码后都要仔细检查语法错误,每编译一次都需要2分钟,考虑时间成本!
  4. 在从0开始构建项目时,一定要首先确保每个模块都正常,再考虑互相连接。切忌全部连接后在测试,否则全编译能过但根本不知道为什么出错

    点此查看

基于FPGA的超声波雷达感应预警系统 全过程记录的更多相关文章

  1. 基于FPGA的超声波测距(一)

    硬件平台:CycloneII EP2C5Q208C8+DYP-ME007 1:超声波原理 DYP-ME007超声波测距模块可提供3cm--3.5m的非接触式距离感测功能,图1为DYP-ME007外观, ...

  2. ADAS超声波雷达

    ADAS超声波雷达 在倒车入库,慢慢挪动车子的过程中,在驾驶室内能听到"滴滴滴"的声音,这些声音就是根据超声波雷达的检测距离给司机的反馈信息. 倒车雷达系统,英文全称为REVERS ...

  3. C语言单片机项目实战超声波雷达测距

    本实验是基于MSP430利用HC-SR04超声波传感器进行测距,测距范围是3-65cm,讲得到的数据显示在LCD 1602液晶屏上. 模块工作原理如下 (1)采用 IO 触发测距,给至少 10us 的 ...

  4. 基于FPGA的飞机的小游戏

    基于FPGA的飞机的小游戏 实验原理 该实验主要分为4个模块,采用至上而下的设计方法进行设计.由50M的晶振电路提供时钟源,VGA显示控制模块.图形显示控制模块.移动模块的时钟为25M,由时钟分频电路 ...

  5. 基于FPGA的音频信号的FIR滤波(Matlab+Modelsim验证)

    1 设计内容 本设计是基于FPGA的音频信号FIR低通滤波,根据要求,采用Matlab对WAV音频文件进行读取和添加噪声信号.FFT分析.FIR滤波处理,并分析滤波的效果.通过Matlab的分析验证滤 ...

  6. 10月12号 晚八点 Speed-BI 云平台-基于Excel数据源的管理驾驶舱构建全过程,腾讯课堂开课啦

    认真地做了一大摞一大摞的报表,老板没时间看?努力把能反馈的内容都融汇进图表里,老板嫌复杂?做了几个简单的报表,老板一眼就觉得信息不全面?每个报表都用了各种各样的图表,老板却毫无兴趣?明明很努力了,为什 ...

  7. 基于FPGA的图像去噪

    目录 结构图 其中FPGA 控制模块为核心,通过它实现视频图像数据的获取.缓存.处理和控制各模块间通讯[1].由CCD 相机对目标成像,高速图像数据由camera link 实时传输[2],经信号转换 ...

  8. 基于FPGA的线阵CCD图像测量系统研究——笔记

    本文是对基于FPGA的线阵CCD图像测量系统研究(作者:高尚)的阅读笔记 第一章绪论 1. 读读看 读了前面的摘要依然没有看懂作者要做什么.接着往下读....终于看到了一个字眼“基于机器视觉的图像测量 ...

  9. 基于FPGA的按键扫描程序

    最近在学习FPGA,就试着写了个按键扫描的程序.虽说有过基于单片机的按键扫描处理经验,对于按键的处理还是有一些概念.但是单片机程序的编写通常都采用C写,也有用汇编,而FPGA却是采用VHDL或者Ver ...

  10. 基于FPGA的DW8051移植(三)

    总结一下问题: 1) http://www.cnblogs.com/sepeng/p/4137405.html  基于FPGA的DW8051移植(一)里面用modelsim观测波形发现程序进入了ida ...

随机推荐

  1. Flink运行时架构

    一.运行时的组件和基本原理 1.作业管理器 (1)控制一个应用程序执行的主进程,也就是说,每个应用程序都会被一个不同的JobManager所控制执行. (2)JobManager会先接收到要执行的应用 ...

  2. Elasticsearch搜索引擎学习笔记(四)

    分词器 内置分词器 standard:默认分词,单词会被拆分,大小会转换为小写. simple:按照非字母分词.大写转为小写. whitespace:按照空格分词.忽略大小写. stop:去除无意义单 ...

  3. 实测windows系统使用cmd搜索包含某个关键词的代码及PHP自动生成数据字典

    1.windows系统下进入cmd窗口-->替换自己的路径,执行下面命令 findstr /s /i "carlist" D:\phpstudy_pro\WWW\wxx\*. ...

  4. 【MATLAB习题】曲柄滑块机构运动学分析

    曲柄滑块机构分享 1. 机构简图 2. 实例 3. matlab code function main %输入已知数据 clear; i1=100; i2=300; e=0; hd = pi/180; ...

  5. ocr识别过程中报错 tesseract is not installed

    这个问题无论在初始编译时或者在后来坏境变更调试时都会遇到的问题. 解决:问题原因是源码中的默认路径位置与文件位置不同,需要更改一下

  6. 0基础的人关于C++多态产生的一系列疑问

    之前在面试的时候被问过懂不懂C++,懂不懂"多态".我之前搞科研一直在用Python,不会C++.完全没听过"多态"这个词,只听说过"多模态" ...

  7. Detected non-NVML platform: could not load NVML: libnvidia-ml.so.1: cannot open shared object

    前言 在 kubernetes 中配置 https://github.com/NVIDIA/k8s-device-plugin 时, 报错:Detected non-NVML platform: co ...

  8. websocket 后台新订单通知 —— Laravel 5.8 workman PHPSocket.IO教程

    websocket 后台新订单通知 -- Laravel 5.8 Laravel-echo-server教程 PHPSocket.IO,PHP跨平台实时通讯框架 PHPSocket.IO是PHP版本的 ...

  9. git和github的入门操作

    之前因为工作中用的都是SVN版本控制工具,没接触过git和github,现在开始深入自学Django框架技术后,看到官网推荐使用git,然后这两天网上查阅了很多文章教程,学到入门操作需要学习的点,太多 ...

  10. 使用unity构建射击小游戏

    博客地址:https://www.cnblogs.com/zylyehuo/ 成果图 参考例程 www.manning.com/hocking 问题汇总 1.renderer.material 方法过 ...