FPGA笔记4——IP核 实现计数器

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

重新保存~分析与综合 重新设置仿真工具链接
在这里插入图片描述
在这里插入图片描述
手动切换
开始仿真
在这里插入图片描述
在这里插入图片描述

发布了32 篇原创文章 · 获赞 2 · 访问量 645

猜你喜欢

转载自blog.csdn.net/helloworld573/article/details/104494471