FPGA设计方式有以下几种:
1.原理图(不推荐)
2.Verilog HDL 设计方式
3.IP核输入方式
新建文件(count_ip)——》选择代码next——》选择器件——》选择仿真工具和语言 工程创建完毕
Tools——》megawizard(魔术棒)——》
找到arithmetic 里的counter ip核
路径选择 我们创建的工程文件夹下的ip文件夹
取个名字:counter——》next
弹出参数配置界面
后面默认即可
效果 生成了.qip文件 描述了 这个IP核的信息
右键 file 选择
选择counter.v 然后 手动点击add
打开counter.v
我们不需要关心其他内容 只需要 关心端口列表,把它复制下来
然后再例化到我们用户自己的设计当中
module counter (
cin,
clock,
cout
q);
把counter.v置为顶层 对它进行测试
——》分析与综合
——》查看由ip核实现的计数器的电路结构
双击
比我们自己设计的 更加接近于真实FPGA的电路结构
我们自己设计的类似于电路原理图
写testbench 进行仿真
新建 Verilog HDL File
`time 1ns/1ns
`define shizhongzhouqi 20 //宏定义 设置时钟周期 为20ns (周期50hz)
module counter_tb
reg cin1; // 进位输入
reg clock1; // 基准时钟
wire cout1; // 进位输出
wire [3:0] q1;// 计数器输出
counter u1(
.cin(cin1),
.clock(clock1),
.cout(cout1),
.q(q1)
);
clk1 = 1;
always #(shizhongzhouqi/2)
clk = ~clk; //产生系统时钟
initial begin
repeat(5)begin //repeat 相当于for 循环 循环五次
cin = 0;
#(`shizhongzhouqi*5) cin = 1;
#(`shizhongzhouqi) cin = 0;
//高电平保持一个时钟周期
//低电平 保持五个时钟周期
//这样就产生了脉冲
end
#(`shizhongzhouqi*200);//延时200个周期
$stop;
end
endmodule
保存到testbench文件夹下 test_tb ——》分析与综合
——》连接两个文件
——》进行仿真
计数器 平时是不计数的 只有cin=1 的时候 计数器的值才会+1 并输出
因为我们在代码中写道: repeat(5) 所以我们的循环只进行五次 cin只有效了5次 也就只有五次输出 因为我们在前面选择的是最大计数值为10 所以 要进行十次循环 才会产生cout信号 ,下面我们对代码进行修改
repeat(20)
重新分析与综合 关闭仿真 重新仿真
那么 我们在上面 如果选择的是普通计数模式呢?
那么 它的最大值 就随着 前面定的位数而决定
四位 1111 最大就是15
你看
我们如果想实现八位计数器 该如何实现呢?
第一种办法:返回前面的IP核设置 设置成八位
第二种方法:进行四位计数器的级联
原理:计数器选择普通模式计数 四位计数器计满一次 cout就输出一次有效电平 而计数器2的in端口 与计数器1 的out端相连 计数器1 需要计满一次 计数器2 才会计一次 这样 把计数器1 的输出 作为低四位 计数器2 的输出作为高 4位 八位计数器就诞生了
实现:
记得修改为计数器的普通模式
新建一个Verilog HDL File
module counter_top(cin1 clk cout2 q,cout1);
//顶层文件 我们的最终目的是用两个四
//位计数器实现一个
//八位计数器 (记得开启计数器的普通
//模式)
input cin1;
input clk;
output cout2;
output [7:0]q;
wire cout1;
counter c1(
.cin(cin1),
.clock(clk),
.cout(cout1),
.q(q[3:0])
);
counter c2(
.cin(cout1),
.clock(clk),
.cout(cout2),
.q(q[4:7])
);
endmodule
//底层模块就像是一个类一样 就像这个IP核的计数器 我在顶层模块中调用了两个计数器,只需要起两个名字就可以了
保存counter_top
分析与综合
将其设置为顶层文件
查看他的电路图RTL:
test bench 的编写
新建 counter_top_tb
`time 1ns/1ns
`define shizhongzhouqi 20 //宏定义 设置时钟周期 为20ns (周期50hz)
module counter_top_tb
reg cin1; // 进位输入
reg clock1; // 基准时钟
wire cout1; // 进位输出
wire [7:0] q1;// 计数器输出
counter_top u1(
.cin(cin1),
.clk(clock1),
.cout(cout1),
.q(q1)
);
clk1 = 1;
always #(shizhongzhouqi/2)
clk = ~clk; //产生系统时钟
initial begin
repeat(300)begin //repeat 相当于for 循环 循环五次
cin = 0;
#(`shizhongzhouqi*5) cin = 1;
#(`shizhongzhouqi) cin = 0;
//高电平保持一个时钟周期
//低电平 保持五个时钟周期
//这样就产生了脉冲
end
#(`shizhongzhouqi*200);//延时200个周期
$stop;
end
endmodule
重新保存~分析与综合 重新设置仿真工具链接
手动切换
开始仿真