FPGA 电路开发入门实验一到四分析与总结

FPGA实验一 项目创建、编译和下载

项目名称和顶层设计的名称要一致
在这里插入图片描述
通过开发板原理图查找SW开关和LED灯和FPGA的管脚对应关系。

本次实验要求为一个拨码开关同时控制10个LED小灯的亮灭。
在这里插入图片描述
在这里插入图片描述
一个开关控制10个LED小灯点亮
首先对BDF文件进行编译,编译通过后,通过菜单Assignments中pin planner设定信号名称和管脚的对应关系。
在这里插入图片描述
设定不用的管脚为三态,然后编译下载
在这里插入图片描述
打开下载界面后需要先点击Hardware Setup选择FPGA所在的COM口,然后点击Start。

FPGA实验二 译码器组合逻辑

学生实验一

放置2个2-4译码器模块,则总共有2组SW,每组2个,2组LED,每组4个,每组SW分别控制其对应的LED组。

首先编写实验相应的Verilog代码,然后生成代码文件对应的模块

module dec_2to4(
IN  ,
OUT);
input  [1:0] IN  ;
output [3:0] OUT ;

reg [3:0] OUT ;

always @ (IN) begin
  case(IN)
    2'b00: OUT = 4'b 0001;
    2'b01: OUT = 4'b 0010;
    2'b10: OUT = 4'b 0100;
    2'b11: OUT = 4'b 1000;
  endcase
end

endmodule // module dec_2to4;

在这里插入图片描述
在BDF文件中可以添加刚才通过.v文件生成的自定义符号模块
在这里插入图片描述
按照实验一方法对其进行引脚的匹配
在这里插入图片描述
本次实验通过对导线的命名来进行连接,注意区别导线的命名方式
在这里插入图片描述
inW[0]、inW[1] 对应 inW[1…0], inW[2]、 inW[3] 对应 inW[3…2]
导线命名方法:导线上右键,properties -> name
线网的选择使用 两个点号" … "

学生实验二

参照代码,设计一个3-8译码器,完成类似的拨码开关实验。(注意代码中的信号宽度设定

module decoder
(
  IN,
  OUT
);

  input [2 : 0] IN;
  output [7 : 0] OUT;
  
  reg [7 : 0] OUT;
  
  always @ (IN)
    begin
      case (IN)
        3'b000: OUT = 8'b0000_0001;
        3'b001: OUT = 8'b0000_0010;
        3'b010: OUT = 8'b0000_0100;
        3'b011: OUT = 8'b0000_1000;
        3'b100: OUT = 8'b0001_0000;
        3'b101: OUT = 8'b0010_0000;
        3'b110: OUT = 8'b0100_0000;
        3'b111: OUT = 8'b1000_0000;
      endcase
    end

endmodule

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

学生实验三

自行查阅手册中的7段译码器管脚对应关系,用4个拨码开关控制一个7段译码器的数字,从0- 9-A-F,共16个数字和字母。
(1)先自定义所需要的逻辑模块,生成自定义模块

module dec_4to16
(
  IN,
  OUT  
);

  input [3 : 0] IN;
  output [6 : 0] OUT;
  
  reg [6 : 0] OUT;
  
  always @ (IN)
    begin
      case (IN)//gongyang 0youxiao 
        4'b0000: OUT = 7'b100_0000;//0
        4'b0001: OUT = 7'b111_1001;//1  
        4'b0010: OUT = 7'b010_0100;//2
        4'b0011: OUT = 7'b011_0000;//3
        4'b0100: OUT = 7'b001_1001;//4
        4'b0101: OUT = 7'b001_0010;//5
        4'b0110: OUT = 7'b000_0010;//6
        4'b0111: OUT = 7'b111_1000;//7
        
        4'b1000: OUT = 7'b000_0000;//8
        4'b1001: OUT = 7'b001_0000;//9
        4'b1010: OUT = 7'b000_1000;//A
        4'b1011: OUT = 7'b000_0011;//B
        4'b1100: OUT = 7'b100_0110;//C
        4'b1101: OUT = 7'b010_0001;//D
        4'b1110: OUT = 7'b000_0110;//E
        4'b1111: OUT = 7'b000_1110;//F
      endcase
    end

endmodule

在这里插入图片描述
(2)对照引脚图配置,配置前记得先编译
在这里插入图片描述

FPGA实验三 计数器、波形仿真、SignalTap

SignalTap仿真步骤及其注意事项

(1)例化的子模块的代码原型,即“.v”文件

//cnt_0to9
module cnt_0to9(
  CLK   ,   // clock
  CNTVAL,   // counter value
  OV    );  // overflow
input CLK;
output [4-1:0] CNTVAL;
output OV;

reg [4-1:0] CNTVAL;
reg OV;

always @ (posedge CLK) begin
  if(CNTVAL >= 9)
    CNTVAL <= 0;
  else
    CNTVAL <= CNTVAL + 1'b1;
end

always @ (CNTVAL) begin
  if(CNTVAL == 9)
    OV = 1'b1;
  else
    OV = 1'b0;
end

endmodule   // module cnt_0to9

(2)生成代码文件对应的符号模块,在BDF文件中调用(代码文件中要包含所使用的计数器Verilog代码)
在这里插入图片描述
(3)编译后,指派时钟管脚PIN_G21或者PIN_B12,由晶振提供50MHZ时钟,再编译
(4)观察RTL视图
(5)新建SignalTapll文件,添加到工程中
(6)setup页面添加采样时钟,filter项选择design entry(all name)选择CLK50,添加OUT, OV
(7)编译前先把程序下载到板子
在这里插入图片描述
显示结果
在这里插入图片描述

学生实验一

module cnt_0to17(
  CLK   ,   // clock
  CNTVAL,   // counter value
  OV    );  // overflow
input CLK;
output [6-1:0] CNTVAL;
output OV;

reg [6-1:0] CNTVAL;
reg OV;

always @ (posedge CLK) begin
  if(CNTVAL >= 17)
    CNTVAL <= 0;
  else
    CNTVAL <= CNTVAL + 1'b1;
end

always @ (CNTVAL) begin
  if(CNTVAL == 17)
    OV = 1'b1;
  else
    OV = 1'b0;
end

endmodule  

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

学生实验二

module cnt_0to17_1(
  CLK   ,   // clock
  CNTVAL,   // counter value
  OV    );  // overflow
input CLK;
output [6-1:0] CNTVAL;
output OV;

reg [6-1:0] CNTVAL;
reg OV;

always @ (posedge CLK) begin
  if(CNTVAL >= 17)
    CNTVAL <= 0;
  else
    CNTVAL <= CNTVAL + 1'b1;
end

always @ (CNTVAL) begin
  if(CNTVAL >= 9 && CNTVAL <= 17)
    OV = 1'b1;
  else
    OV = 1'b0;
end

endmodule   

在这里插入图片描述
在这里插入图片描述
在实验二的基础上,把OV接到一个LED上
在这里插入图片描述
没有观察到明显变化,因为OV输出频率大约为1,388,888Hz,肉眼观察不到变化

FPGA实验四 时间基准电路和带使能的多周期计数器

例题

时间基准电路介绍:定时发出一个窄脉冲的电路
本实验设计目标:
(1)设计时间基准电路和带使能的多周期计数器
(2)时间基准电路生成同步时间基准信号
(3)多周期 计数器对时间基准信号进行计数
本质上是一个两级计数器级联的电路结构
第一级计数器生成时间基准信号
第二级计数器用时间基准信号作为计数使能
符号模块代码

module cnt_sync(
  CLK   ,   // clock
  CNTVAL,   // counter value
  OV    );  // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 25_000_000;
reg [32-1:0] CNTVAL;
reg OV;

always @ (posedge CLK) begin
  if(CNTVAL >= MAX_VAL)
    CNTVAL <= 0;
  else
    CNTVAL <= CNTVAL + 1'b1;
end

always @ (CNTVAL) begin
  if(CNTVAL == MAX_VAL)
    OV = 1'b1;
  else
    OV = 1'b0;
end

endmodule   // module cnt_en_0to9
////////////////////////////////////////////////////////////////////////////////

module cnt_en_0to9(
  CLK   ,   // clock
  CNTVAL,   // counter value
  EN    ,
  OV    );  // overflow
input CLK;
input EN;
output [4-1:0] CNTVAL;
output OV;

reg [4-1:0] CNTVAL;
reg OV;

always @ (posedge CLK) begin
  if(EN) begin  // work enable
    if(CNTVAL >= 9)
      CNTVAL <= 0;
    else
      CNTVAL <= CNTVAL + 1'b1;
  end
  else
    CNTVAL <= CNTVAL ;  // hold same value
end

always @ (CNTVAL) begin
  if(CNTVAL == 9)
    OV = 1'b1;
  else
    OV = 1'b0;
end

endmodule   // module cnt_en_0to9

在这里插入图片描述
MAX_VAL代表最大计数个数,例如,时钟信号为50,000,000hz,计数器为25,000,000hz,所以每隔0.5秒给一次cnt_en_0to9使能EN,进而进行通过编译器cnt_en_0to9输出0-9
signaltap仿真波形,当val=5时
在这里插入图片描述
当val=25,000,000时,默认设置抓取不到out的跳变
在这里插入图片描述
使用高级触发方式,分段触发,选中segmented模式,8段16样点,选择en_out作为触发事件,采集其附近波形样点
在这里插入图片描述
在这里插入图片描述

学生实验一

题目:参照代码,把后级计数器范围改为0-15.

添加新的后级计数器

module cnt_en_0to15(
  CLK   ,   // clock
  CNTVAL,   // counter value
  EN    ,
  OV    );  // overflow
input CLK;
input EN;
output [5-1:0] CNTVAL;
output OV;

reg [5-1:0] CNTVAL;
reg OV;

always @ (posedge CLK) begin
  if(EN) begin  // work enable
    if(CNTVAL >= 15)
      CNTVAL <= 0;
    else
      CNTVAL <= CNTVAL + 1'b1;
  end
  else
    CNTVAL <= CNTVAL ;  // hold same value
end

always @ (CNTVAL) begin
  if(CNTVAL == 15)
    OV = 1'b1;
  else
    OV = 1'b0;
end

endmodule   // module cnt_en_0to9

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

学生实验二

题目:把计数器的0-15计数值经过译码,在DE0的HEX LED上显示成0-9-A-F的十六进制数。
添加数码管显示符号模块

module dec_4to16_HEX
(
  IN,
  OUT  
);

  input [5-1 : 0] IN;
  output [8-1 : 0] OUT;
  
  reg [8-1 : 0] OUT;
  
  always @ (IN)
    begin
      case (IN)//共阳极数码管 低电平有效
        4'b0000: OUT = 8'b1100_0000;//0
        4'b0001: OUT = 8'b1111_1001;//1  
        4'b0010: OUT = 8'b1010_0100;//2
        4'b0011: OUT = 8'b1011_0000;//3
        4'b0100: OUT = 8'b1001_1001;//4
        4'b0101: OUT = 8'b1001_0010;//5
        4'b0110: OUT = 8'b1000_0010;//6
        4'b0111: OUT = 8'b1111_1000;//7
        
        4'b1000: OUT = 8'b1000_0000;//8
        4'b1001: OUT = 8'b1001_0000;//9
        4'b1010: OUT = 8'b1000_1000;//A
        4'b1011: OUT = 8'b1000_0011;//B
        4'b1100: OUT = 8'b1100_0110;//C
        4'b1101: OUT = 8'b1010_0001;//D
        4'b1110: OUT = 8'b1000_0110;//E
        4'b1111: OUT = 8'b1000_1110;//F
      endcase
    end

endmodule

在这里插入图片描述
在这里插入图片描述
signaltap仿真波形正确

学生实验三

题目:修改时间基准发生器,设计一个使用2个HEX LED,精度为0.1秒,范围为0-9.9秒的计时秒表。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

学生实验四

题目:自行设计上面计时器的附加控制功能(清零、暂停)。
修改新手实验中的多功能计数器代码,生成模块

module duogongnengjishuqi(
  RST   , // 异步复位, 高有效
  CLK   , // 时钟,上升沿有效
  EN    , // 输入的计数使能,高有效
  CLR   , // 输入的清零信号,高有效
  LOAD  , // 输入的数据加载使能信号,高有效
  DATA  , // 输入的加载数据信号
  CNTVAL, // 输出的计数值信号
  PAUSE ,
  OV    );// 计数溢出信号,计数值为最大值时该信号为1

input RST   , CLK   , EN    , CLR   , LOAD  , PAUSE ;
input [3:0] DATA ;
output [3:0] CNTVAL;
output OV;   

reg [3:0] CNTVAL, cnt_next;
reg OV;
// 电路编译参数,最大计数值
parameter CNT_MAX_VAL = 9;

// 组合逻辑,生成cnt_next
// 计数使能最优先,清零第二优先,加载第三优先
always @(EN or LOAD or CLR or DATA or CNTVAL) begin
  if(EN) begin    // 使能有效
    if(CLR) begin // 清零有效
      cnt_next = 0;
    end
    else begin  // 清零无效
      if(LOAD) begin // 加载有效
        cnt_next = DATA;
      end
      else begin     // 加载无效,正常计数
		  // 使能有效,清零和加载都无效,根据当前计数值计算下一值
        if(CNTVAL < CNT_MAX_VAL) begin // 未计数到最大值, 下一值加1
          cnt_next = CNTVAL + 1'b1;
        end
        else begin // 计数到最大值,下一计数值为0
          cnt_next = 0;
        end
      end // else LOAD
    end  // else CLR
  end // if EN
  else begin  // 使能无效,计数值保持不动
    cnt_next = CNTVAL;
  end // else EN
end

// 时序逻辑 更新下一时钟周期的计数值
// CNTVAL 会被编译为D触发器
always @ (posedge CLK or posedge RST or posedge PAUSE or posedge CLR) begin
  if(RST) 
    CNTVAL <= 0;
  else if(PAUSE)
    CNTVAL <= CNTVAL;
  else if(CLR)
    CNTVAL <= 0;
  else
    CNTVAL <= cnt_next;
end

// 组合逻辑,生成OV
always @ (CNTVAL) begin
  if(CNTVAL == CNT_MAX_VAL) 
    OV = 1;
  else
    OV = 0;
end

endmodule

因为个位数需要小数点,新建一个带小数点的译码器符号模块

module dec_4to16_HEX1//带小数点
(
  IN,
  OUT  
);

  input [4-1 : 0] IN;
  output [8-1 : 0] OUT;
  
  reg [8-1 : 0] OUT;
  
  always @ (IN)
    begin
      case (IN)//共阳极数码管 低电平有效
        4'b0000: OUT = 8'b0100_0000;//0
        4'b0001: OUT = 8'b0111_1001;//1  
        4'b0010: OUT = 8'b0010_0100;//2
        4'b0011: OUT = 8'b0011_0000;//3
        4'b0100: OUT = 8'b0001_1001;//4
        4'b0101: OUT = 8'b0001_0010;//5
        4'b0110: OUT = 8'b0000_0010;//6
        4'b0111: OUT = 8'b0111_1000;//7
        
        4'b1000: OUT = 8'b0000_0000;//8
        4'b1001: OUT = 8'b0001_0000;//9
        4'b1010: OUT = 8'b0000_1000;//A
        4'b1011: OUT = 8'b0000_0011;//B
        4'b1100: OUT = 8'b0100_0110;//C
        4'b1101: OUT = 8'b0010_0001;//D
        4'b1110: OUT = 8'b0000_0110;//E
        4'b1111: OUT = 8'b0000_1110;//F
      endcase
    end

endmodule

在这里插入图片描述
可以实现按下SW0键清零,SW1键暂停,小数部分循环0-9一次LED0闪烁一次,个位数循环一次LED1闪烁一次。

发布了6 篇原创文章 · 获赞 0 · 访问量 273

猜你喜欢

转载自blog.csdn.net/szm1234/article/details/102615973