8位16进制频率计设计实验--VHDL

5 篇文章 3 订阅

一、实验目的

(1)学习并掌握Quartus II的使用方法
(2)学习简单时序电路的设计和硬件测试。
(3)学习使用VHDL 语言方法进行逻辑设计输入
(4)学习设计8位16进制频率计,学习较复杂的数字系统设计方法,并在实验开发系统上熟悉运行输入及仿真步骤原理

二、实验仪器设备

(1) PC机一台。
(2)Quartus Ⅱ开发软件一套
(3)EDA实验开发系统一套(EP1C12Q240C8)

三、实验原理

频率计的工作原理是用一个频率稳定度高的频率源作为基准时钟,对比测量其他信号的频率,也就是周期性信号在单位时间内变化的次数。
频率计原理如图所示

被测信号
闸门
计数器
数据处理与显示
基准时钟
门控信号

输入待测信号经过脉冲形成电路后形成计数的窄脉冲,时基信号发生器产生计数闸门信号,待测信号通过闸门进入计数器计数,即可得到其频率。若闸门开启时间为T,待测信号频率为 f x f_x fx,在闸门时间T内计数器计数值为N,则待测信号频率为 f x f_x fx=N/T。闸门时间通常取为1s。
根据频率的定义和频率测量的基本原理,测定信号的频率必须有一个脉宽为1s的输入信号脉冲计数允许的信号;1s计数结束后,计数值被锁入锁存器,计数器清0,为下一测频计数周期做好准备。测频控制信号可以由一个独立的发生器来产生根据测频原理,测频控制时序如图所示。设计要求是:FTCTRL 的计数使能信号CNT_EN能产生一个1s 脉宽的周期信号,并对频率计中的32位二进制计数器COUNTER32B的 ENABL使能端进行同步控制。当CNT_EN高电平时允许计数,低电平时停止计数,并保持其所计的脉冲数。在停止计数期间,首先需要个锁存信号LOAD的上跳沿将计数收器在前1s的计数值锁存进锁存器REG32B 中,并由外部的16进制7段译码器译出,显示计数值。设置锁存器的好处是数据显示稳定,不会由于周期性的清0信号而不断闪烁。锁存信号后,必须有一清0信号RST_CNT对计数器进行清零,为下1s的计数操作做好准备。

四、实验内容

分别仿真测试模块例1、例2和例3,再结合例4完成频率计的完整设计和硬件实现,并给出其测频时序波形及其分析。建议选实验电路模式5;8个数码管以16进制形式显示测频输出;待测频率输入FIN 由 clock0输入,频率可4Hz、256Hz、3Hz、…、50MHz等;1Hz测频控制信号CLK1Hz可由 clock2输入(用跳线选1HZ)。注意,这时8个数码管的测控显示值是16进制的。

五、实验步骤

(1)启动Quartus II建立一个空白工程,然后命名为 FREQTEST.qpf。
(2)新建VHDL 源程序文件FREQTEST.vhd,输入程序代码并保存,进行综合编译,若编译过程中发现错误,则找出并更正错误,直至编译成功为止。
(3)选择目标器件并对相应的引脚进行锁定,在这里所选择的器件为Altera公司 Cyclone系列的EPIC12Q240C8芯片。将未使用的管脚设置为三态输入。则找出并更正错误,
(4)对该工程文件进行全程编译处理,若在编译过程中发现错误直至编译成功为止。接到PC机的打印机并口
(5)拿出 Altera Byte Blaster II下载电缆,并将此电缆的两端分别接到PC机的打印机并口和实验箱的JTAG下载口上,打开电源,执行下载命令,把程序下载到 FPGA器件中,观察数码管1~8的16进制显示状态。
实例代码:

LIBRARY IEEE;					--频率计顶层文件
USE IEEE.STD_LOGIC_1164.all;
ENTITY FREQTEST IS
PORT(CLK1HZ:IN STD_LOGIC;
			FSIN:IN STD_lOGIC;
			DOUT:OUT STD_LOGIC_VECTOR(31 downto 0));
END;
ARCHITECTURE BEHAV OF FREQTEST is
	COMPONENT FTCTRL
		PORT(CLKK:	IN STD_LOGIC;		--1HZ
			CNT_EN: OUT STD_LOGIC;		--计数器时钟使能
  			RST_CNT:OUT STD_LOGIC;		--计数器清零
  			LOAD : 	OUT STD_LOGIC);		--输出锁存信号
	END COMPONENT;
	COMPONENT COUNTER32B
  		PORT(FIN: 	IN STD_LOGIC;		--时钟信号
     		ENABL:	IN STD_LOGIC;		--清零信号
      		CLR :	IN STD_LOGIC;		--计数使能信号
			DOUT: 	OUT STD_LOGIC_VECTOR(31 DOWNTO 0));		--计数结果输出
 	END COMPONENT;
	COMPONENT REG32B
		 PORT(LK:	IN STD_LOGIC;
    		DIN: 	IN STD_LOGIC_VECTOR(31 downto 0);
   			DOUT:	OUT STD_LOGIC_VECTOR(31 downto 0));
	END COMPONENT;
	SIGNAl TSTEN1:	STD_LOGIC;
	SIGNAl CLR_CNT1:STD_LOGIC;
	SIGNAl LOAD1:	STD_LOGIC;
	SIGNAl DTO1:	STD_LOGIC_VECTOR(31 DOWNTO 0);
	SIGNAl CARRY_OUT1:STD_LOGIC_VECTOR(6 DOWNTO 0);
BEGIN
u1: FTCTRL PORT MAP (CLKK=>CLK1HZ,CNT_EN=>TSTEN1,RST_CNT=>CLR_CNT1,LOAD=>LOAD1);			--例化
U2: REG32B PORT MAP(LK=>LOAD1,DIN=>DTO1,DOUT=>DOUT);		--例化
U3:COUNTER32B PORT MAP(FIN => FSIN,CLR => CLR_CNT1,ENABL=> TSTEN1,DOUT=>DTO1);		--例化
END BEHAV;
LIBRARY IEEE;								--测频控制电路
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY FTCTRL IS
   PORT (CLKK : IN STD_LOGIC;				--1HZ
       	CNT_EN :OUT STD_LOGIC;				--计数器使能控制
      	RST_CNT:OUT STD_LOGIC;				--计数器清零端
       	Load: 	OUT STD_LOGIC );				--输出锁存信号
END FTCTRL;
ARCHITECTURE BEHAV OF FTCTRL IS
   SIGNAL Div2CLK : STD_LOGIC;
BEGIN
   PROCESS(CLKK)
   BEGIN
      IF CLKK'EVENT AND CLKK = '1' THEN				--1HZ时钟2分频
         Div2CLK <= NOT Div2CLK;
      END IF;
   END PROCESS;
   PROCESS(CLKK, Div2CLK)
   BEGIN
      IF CLKK='0' AND Div2CLK='0' THEN RST_CNT<='1';    --产生清零计数
        ELSE RST_CNT <= '0';
      END IF;
   END PROCESS;
   Load <= NOT Div2CLK;
   CNT_EN <= Div2CLK;
END BEHAV;
LIBRARY IEEE;								--32位锁存器
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY REG32B IS
   PORT(LK: IN STD_LOGIC; 
       DIN: IN STD_LOGIC_VECTOR(31 downto 0);
	  DOUT: OUT STD_LOGIC_VECTOR(31 downto 0));
   END REG32B;
ARCHITECTURE BEHAV OF REG32B IS
BEGIN
   PROCESS(LK,DIN)
   BEGIN
   IF LK'EVENT AND LK='1' THEN DOUT<=DIN;
       END IF;
   END PROCESS;
END BEHAV;
LIBRARY IEEE;								--32位计数器
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY COUNTER32B IS
   PORT(FIN:IN STD_LOGIC;  --时钟信号
	    CLR:IN STD_LOGIC;  --清零信号
	  ENABL:IN STD_LOGIC;  --计数使能信号
       DOUT:OUT STD_LOGIC_VECTOR(31 DOWNTO 0) );
END COUNTER32B;
ARCHITECTURE BEHAV OF COUNTER32B  IS
    SIGNAL CQI :  STD_LOGIC_VECTOR(31 DOWNTO 0);
 BEGIN
   PROCESS(FIN,CLR,ENABL)
     BEGIN
       IF CLR='1' THEN CQI<=(OTHERS=>'0'); 		--清零
       	ELSIF FIN'EVENT AND FIN='1' THEN
         IF ENABL='1' THEN CQI<=CQI+1;END IF;
       END IF;
       END PROCESS;
       DOUT<=CQI;
  END BEHAV;

QUARTUS II代码展示图
QUARTUS II代码展示图

频率计仿真图如图所示
频率计仿真图
频率计仿真图

六、实验要求

(1)选择实验电路模式5
(2)设计仿真文件,进行软件验证
(3)用VHDL程序设计方法实现8位16进制频率计设计
(4)通过下载线下载到实验系统上进行硬件测试验证

七、实验扩展

实验内容2:将频率计改为8位10进制频率计,注意此设计电路的计数器必须是8个4位的10进制计数器,而不是1个。此外注意在测频速度上给予优化。
八位十进制频率计顶层文件:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY FREQTEST8_10 IS
PORT(FSIN:IN STD_LOGIC;
    CLK1HZ:IN STD_LOGIC;
    DOUT:OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
END ENTITY FREQTEST8_10;
ARCHITECTURE BEHAV OF FREQTEST8_10 IS
COMPONENT CNT10 IS
PORT(FIN,CLR,ENA:IN STD_LOGIC;
    CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
    COUT:OUT STD_LOGIC);
END COMPONENT CNT10;
COMPONENT REG32B IS
PORT(LOAD:IN STD_LOGIC;
    DIN:IN STD_LOGIC_VECTOR(31 DOWNTO 0);
    DOUT:OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
END COMPONENT REG32B;
COMPONENT FTCTRL IS
PORT(CLKK:IN STD_LOGIC;
    CNT_EN:OUT STD_LOGIC;
    RST_CNT:OUT STD_LOGIC;
    LOAD:OUT STD_LOGIC);
END COMPONENT FTCTRL;
	SIGNAL EN,CL,LD:STD_LOGIC;
	SIGNAL CNT1,CNT2,CNT3,CNT4,CNT5,CNT6,CNT7,CNT8:STD_LOGIC;
	SIGNAL DQ:STD_LOGIC_VECTOR(31 DOWNTO 0);
BEGIN
	U0:FTCTRL PORT MAP(CLKK=>CLK1HZ,CNT_EN=>EN,RST_CNT=>CL,LOAD=>LD);
	U1:CNT10 PORT MAP(FIN=>FSIN,CLR=>CL,ENA=>EN,CQ=>DQ(3 DOWNTO 0),COUT=>CNT1);
	U2:CNT10 PORT MAP(CNT1,CL,EN,DQ(7 DOWNTO 4),CNT2);
	U3:CNT10 PORT MAP(CNT2,CL,EN,DQ(11 DOWNTO 8),CNT3);
	U4:CNT10 PORT MAP(CNT3,CL,EN,DQ(15 DOWNTO 12),CNT4);
	U5:CNT10 PORT MAP(CNT4,CL,EN,DQ(19 DOWNTO 16),CNT5);
	U6:CNT10 PORT MAP(CNT5,CL,EN,DQ(23 DOWNTO 20),CNT6);
	U7:CNT10 PORT MAP(CNT6,CL,EN,DQ(27 DOWNTO 24),CNT7);
	U8:CNT10 PORT MAP(CNT7,CL,EN,DQ(31 DOWNTO 28),CNT8);
	U9:REG32B PORT MAP(LOAD=>LD,DIN=>DQ(31 DOWNTO 0),DOUT=>DOUT);
END ARCHITECTURE BEHAV;

十进制计数器示例程序:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY CNT10 IS
PORT(FIN:IN STD_LOGIC;
	CLR:IN STD_LOGIC;
	ENA:IN STD_LOGIC;
	CQ:OUT INTEGER RANGE 0 TO 15;
	COUT:OUT STD_LOGIC);
END ENTITY CNT10;
ARCHITECTURE BEHAV OF CNT10 IS
	SIGNAL CQI:INTEGER RANGE 0 TO 15;
	BEGIN
	PROCESS(FIN,CLR,ENA)IS
	BEGIN
	IF CLR='1'THEN CQI<=0;
	ELSIF FIN'EVENT AND FIN='1'THEN
			IF ENA='1'THEN
				IF CQI<9 THEN CQI<=CQI+1;
				ELSE CQI<=0;
				END IF;
			END IF;
	END IF;
	END PROCESS;
PROCESS(CQI) IS
	BEGIN
	IF CQI=9 THEN COUT<='1';
	ELSE COUT<='0';END IF;
	END PROCESS;
	CQ<=CQI;
END ARCHITECTURE BEHAV;

测频控制电路示例程序:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY FTCTRL IS
   PORT (CLKK : IN STD_LOGIC;
       CNT_EN : OUT STD_LOGIC;
       RST_CNT : OUT STD_LOGIC;
       LOAD: OUT STD_LOGIC );
END FTCTRL;
ARCHITECTURE BEHAV OF FTCTRL IS
   SIGNAL Div2CLK : STD_LOGIC;
BEGIN
   PROCESS( CLKK )
   BEGIN
      IF CLKK'EVENT AND CLKK = '1' THEN
         Div2CLK <= NOT Div2CLK;
      END IF;
   END PROCESS;
   PROCESS(CLKK, Div2CLK)
   BEGIN
      IF CLKK='0' AND Div2CLK='0' THEN RST_CNT<='1';
        ELSE RST_CNT <= '0';
      END IF;
   END PROCESS;
   LOAD <= NOT Div2CLK;
   CNT_EN <= Div2CLK;
END BEHAV;


32位锁存器示例代码:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY REG32B IS
	PORT(LOAD:IN STD_LOGIC;
     DIN:IN STD_LOGIC_VECTOR(31 DOWNTO 0);
     DOUT:OUT STD_LOGIC_VECTOR(31 DOWNTO 0));
END ENTITY REG32B;
ARCHITECTURE BEHAV OF REG32B IS
	BEGIN
	PROCESS(LOAD,DIN) IS
	BEGIN
	IF LOAD'EVENT AND LOAD='1' THEN DOUT<=DIN;
	END IF;
	END PROCESS;
END ARCHITECTURE BEHAV;

8位10进制频率计仿真波形图
8位10进制频率计仿真波形图
管脚定义实况:
管脚定义实况

后续有时间会加更ing…

工程文件下载:
8位16进制频率计设计源代码
8位10进制频率计设计源代码

  • 23
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
以下是一个简单的Verilog代码示例,将两个十进制数用数码管显示。其中使用了一个数字显示模块,该模块接收一个4位的二进制数作为输入,并输出对应的7段数码管显示信息。 ```verilog module display( input clk, input [7:0] num1, // 第一个十进制数 input [7:0] num2, // 第二个十进制数 output reg [3:0] seg1, // 第一个数码管的输出 output reg [3:0] seg2 // 第二个数码管的输出 ); // 数字显示模块 module num_display( input [3:0] num, output reg [6:0] seg ); always @(*) begin case(num) 4'b0000: seg = 7'b1000000; // 0 4'b0001: seg = 7'b1111001; // 1 4'b0010: seg = 7'b0100100; // 2 4'b0011: seg = 7'b0110000; // 3 4'b0100: seg = 7'b0011001; // 4 4'b0101: seg = 7'b0010010; // 5 4'b0110: seg = 7'b0000010; // 6 4'b0111: seg = 7'b1111000; // 7 4'b1000: seg = 7'b0000000; // 8 4'b1001: seg = 7'b0010000; // 9 default: seg = 7'b1111111; // 显示空白 endcase end reg [7:0] count = 8'h00; // 计数器,用于取出十进制数的每一位 reg [3:0] digit1 = 4'b0000; // 第一个数码管的当前位数 reg [3:0] digit2 = 4'b0000; // 第二个数码管的当前位数 always @(posedge clk) begin if(count == 8'h08) begin count <= 8'h00; // 重新开始计数 digit1 <= digit1 + 4'b0001; // 切换到下一个数码管位 if(digit1 == 4'b1000) digit1 <= 4'b0000; // 循环回到第一位 digit2 <= digit2 + 4'b0001; if(digit2 == 4'b1000) digit2 <= 4'b0000; end else begin count <= count + 8'h01; // 继续计数,处理下一位 end end num_display disp1(.num(num1[digit1:digit1-4]), .seg(seg1)); // 第一个数码管 num_display disp2(.num(num2[digit2:digit2-4]), .seg(seg2)); // 第二个数码管 endmodule ``` 在主模块中,我们定义了两个8位的输入端口num1和num2,它们将被分别用于显示两个十进制数。我们还定义了两个4位的输出端口seg1和seg2,它们将与数码管的控制电路相连,实现数码管的显示功能。 在always块中,我们定义了一个计数器count,用于取出输入端口中的一位十进制数。对于每个数码管,我们分别定义了一个4位的变量digit1和digit2,它们表示当前显示的位数。我们使用num_display模块将每个十进制数的当前位数传递给数字显示模块,以获取对应的数码管输出。我们通过clk信号控制always块的执行,以实现数码管的动态显示。 请注意,在此Verilog代码示例中使用的数字显示模块是一个简单的示例,仅用于演示目的。在实际应用中,您可能需要使用更复杂的数字显示模块,以实现更广泛的数码管显示功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易安寄云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值