FPGA学习心得

关于赋值的一些说明

<==

<=在不同的情况下可以表达不同的意思
在条件判断的时候即(a <= 5)中是小于等于的意思
在()之外的是非阻塞型赋值语句例如 a <= 5是赋值的含义
且表示为赋值的时候是非阻塞赋值语
即后面的相关语句同时执行,可以理解为并行执行。

=为阻塞赋值语句,是在这句之后所有语句执行之前执行的
也就是这句没有执行的话后面的语句就无法执行,这也是“阻塞”的意思。
可以理解为为顺序执行

举个例子初始值a=0,b=1,c=1
begin a=b;b=c;c=aend结果是a=1;b=1;c=a=1
(此时a=1已经有效了)
begin a<=b;b<=C;c<=a;end 结果是a=1;b=1;c=O
(a=1在当前begin-end内是无效的,整体执行完后,才有效)
组合逻辑用=,时序逻辑用<
=

关于一些符号的含义

命名规则: reg[n-1:0] 存储器名[m-1:0]
说明: 这是m个n位的存储器 该存储器的地址范围是0- (m-1)
举例: reg[7:0] DiG[3:0];
说明: 这是16个8位存储器,该存储器地址范围是0-15


命名规则: n'hm n位十六进制值为m
说明: 这是 n位十六进制值为m的一个数据值,其中h可换位b标志二进制,换为o为八进制。
举例: 1’b1
说明: 这是1位二进制值为1的数
举例: 4’h12
说明: 这是4位十六进制值为12的数


初始化一些设定

  • 在有输出端口的时候,为了能把一个输出信号赋给输出端口,必须要设定一个和输出端口名一样的reg寄存器,这样才能够将输出信号输出到端口
    reg[1:0] Key_Value; output[1:0] Key_Value;
    不然就会报错的:
    Error (10137): Verilog HDL Procedural Assignment error at TimeSystem.v(121): object “Key_Value” on left-hand side of assignment must have a variable data type
    (输入端口没有这个问题)

  • 可以将初始化的值直接写在寄存器后面
    reg [12:0] CNT_R0 = 5;


分频

分为两种方式,一种是分屏数刚好为2的次方,还有一种不是2的次方

  1. 为2的次方
reg  [5:0]   Cnt_R0;
always @(posedge Clk)  //64分频
begin
   if(Cnt_R0 < 32)
   begin
      Clk_1M <= 0;
   end
   else
   begin
      Clk_1M <= 1;
   end
   Cnt_R0 <= Cnt_R0 + 1;
end
  1. 不是2的次方
reg  [6:0]   Cnt_R0;//128 = 31 + 97
always @(posedge Clk)   
begin
   if(Cnt_R0 < 31)   //31分频
   begin
      Cnt_R0 = Cnt_R0 + 1;
      Clk_1M = 0;   
   end   
	else
	begin
      Cnt_R0 = Cnt_R0 + 97;     
      Clk_1M = 1; 
	end 
end

制作mif表

mif_Maker下载
下载完后
在这里插入图片描述
首先选择全局参数,根据需要设定宽度以及长度等,然后选定波形
在这里插入图片描述
最后点击另存为即可
在这里插入图片描述
然后添加到quartus中
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果是在别人已有的代码下更改一定要注意更改代码中
i
地址的宽度,不然可能你的波形明明点的是正弦波结果出来的是方波等…

always语句的使用

always语句其实就是一个敏感函数,只要其后的敏感型号量符合其特性,即可调用此函数
posedge上升沿
negedge下降沿
比如:

//Clk上升沿即可激活
lways @(posedge Clk)    //分频创建Clk_Scan信号
begin
   CNT_R0 <= CNT_R0 + 1'b1;
   
   if(CNT_R0 < 4095)
   begin
      Clk_Scan <= 1;
   end
   else
   begin
      Clk_Scan <= 0;
   end
end

并且还可以通过or来添加其可以激活的敏感信号量

always @(posedge Clk_Scan or negedge nRST)
begin
   if(nRST == 0)
	begin
	   Key_Flag_Clear <=	1'b0;
	end
	else
	begin
	   if((Key_Flag == 1) && (Key_Flag_Clear == 0))
	   begin
	      SEG_M[0]       <= SEG_M[0] +1'b1;
		   Key_Flag_Clear <=	1'b1;
	   end
		else if(Key_Flag == 2'h0)
		begin
		   Key_Flag_Clear <=	1'b0;
		end
	end	
end

但是其敏感信号量不能超过三个!
否则会报错

always语句中,已经被赋值的寄存器是不能够在其他always语句中再次使用赋值语句的!
否则,会报错:
Error (10028): Can't resolve multiple constant drivers for net "K_freq[3]" at DDS.v(196)
不过可以使用其寄存器进行逻辑的判断等,也就是说不能写,只能读
只有再使用一个寄存器作为中间量来进行赋值。

当有两个及以上的敏感量的时候,一定要在程序后面处理当中用if以及else等去判断到底是哪个敏感量来了做什么事情,才是正确的做法,而不是想当然的直接将处理程序写在后面,不做处理
如果不做处理,其报错如下:
Error (12153): Can't elaborate top-level user hierarchy
错误程序如下
在这里插入图片描述
正确如下
在这里插入图片描述


注释和宏定义

  • 注释:
    Verilog有两种注释方式,一种以/*开始 */结束 ,还有一种就是双反斜杠//
  • 宏定义:
    宏定义方式为
    define on 1'b1
    define OFF 1'b0

软核

QSYS集成开发工具创建使用的软核(CPU)

软核资源确定
首先要确定软核需要使用到哪些资源的外设,才方便从FPGA开发板上面给软核进行资源分配。

软核类型选择
点击Tools→Qsys,创建Qsys模块。
进入后,点击右方Library子框中的Embedded Processors项,然后点击此项目中的Nios II Processor创建软核处理器,然后会弹出窗口让我们选择软核的一些属性
首先要选择内核的类型,这里提供了三种类型,需要用户根据设计的需求和设计所用到的芯片资源来决定,这里选择Nios II/f。
在这里插入图片描述

系统ID选择
在Library子窗口中选择Peripherals -> Debug and Performance -> System ID Peripheral设定系统ID,点击后选择Finish结束选择
在这里插入图片描述

添加On-Chip ROM和RAM
点击Library子窗口中Memories and Memory Controllers -> On-Chip -> On-Chip Memory (RAM or ROM)
RAM:
在这里插入图片描述
ROM:
在这里插入图片描述

同时在创建完一个需要点击System Contents子窗口中的onchip_memory2_0选中刚才创建的rom or ram右键rename修改名字,方便后面的使用不至于混乱,如果设置的rom就修改为onchip_rom,如果设置的ram就修改为onchip_ram
在这里插入图片描述

添加定时器
在Library子窗口点击Peripherals -> Microcontroller Peripherals -> Interval Timer添加定时器模块,定时时间设置为1ms
在这里插入图片描述

自动生成中断号以及基地址
点击QSYS栏上方菜单栏System -> Assign Base Addresses自动生成基地址
点击System -> Assign Interrupt Numbers自动生成中断号

在这里插入图片描述

数据端口添加
按键数据端口:
根据设计方案,数据端口选择1个2bit输入数据口,点击Peripherals -> Microcontroller Peripherals -> PIO进行IO的选择
在这里插入图片描述

数码管数据端口选择:
根据分析数码管数据端口需要6个4bit的数据输出IO。

在这里插入图片描述

蜂鸣器数据端口选择:
根据分析需要1个1bit输出IO即可。

模块连接
将各个模块之间的线连接起来
在这里插入图片描述

确定复位源以及IO外部连接号

在这里插入图片描述

点击reset_n确定复位输入
在这里插入图片描述

将其中的Reset vectir memory 以及 Exception vector memory 确定为rom
在所有IO选择完毕后,选择IO中的external_connection确定其号,每个IO根据其名字更改即可

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

保存并编译
将其保存后,点击菜单栏Generate,编译软核CPU
在这里插入图片描述

FPGA设计部分

FPGA设计部分即为底层驱动部分,其中包含数码管驱动、蜂鸣器驱动以及按键的驱动,设计需要使用Verilog语言来完成这三个部分的程序编写。
5.2.1 创建工程
点击Home子窗口中的New Project Wizard创建工程
在这里插入图片描述

将其保存在工程文件夹中,并Next,添加设备
在这里插入图片描述

然后点击Finish的完成添加工程。
编写FPGA部分代码
点击File -> New
在这里插入图片描述

点击创建Verilog程序,编写数码管驱动、蜂鸣器驱动以及按键驱动程序。
在这里插入图片描述

然后分配引脚
在这里插入图片描述

完成后,点击Processing -> Start Compilation,编译。
编译通过后,点击Files ->Create Symbol Files for Current File生成原理图文件
在这里插入图片描述

连接软核CPU以及所生成的底层模块
新建一个原理图文件File -> New->Block Diagram/Schematic File
点击文件夹,添加刚才的软核cpu_info.qsys
在原理图中添加TimeSystem以及cpu_info两个模块,并相连,连接完成后进行编译。
在这里插入图片描述

完成后,连接开发板,将FPGA端程序烧录进去。

猜你喜欢

转载自blog.csdn.net/qq_37429313/article/details/108843607
今日推荐