FPGA实验代码
- 格式:doc
- 大小:138.00 KB
- 文档页数:11
fpga计数代码FPGA(Field-Programmable Gate Array)是一种可编程逻辑设备,可以通过编写程序来定义其功能。
在FPGA中实现计数功能是一项常见的任务,可以通过组合逻辑或时序逻辑来实现。
以下是一个使用组合逻辑实现的简单计数器的参考代码:```verilogmodule Counter(input clock,input reset,output reg [3:0] count);always @(posedge clock or posedge reset)beginif (reset)count <= 4'b0000;elsecount <= count + 1;endendmodule```这是一个4位二进制计数器,每当输入时钟(clock)上升沿到来时,计数器会增加1。
同时,当复位信号(reset)为高电平时,计数器会被重置为0。
在这个例子中,我们使用了Verilog HDL来描述计数器的行为。
Verilog是一种硬件描述语言,常用于FPGA和ASIC (Application-Specific Integrated Circuit)设计。
计数器的`module`声明定义了一个Verilog模块,它有三个输入参数(时钟、复位信号和一个4位的计数器)和一个输出参数(4位计数器)。
`always @(posedge clock or posedge reset)`语句定义了一个`always`块,它描述了计数器如何根据时钟和复位信号的变化来进行操作。
当时钟上升沿或者复位信号上升沿到来时,`always`块的内容会被执行。
在这个例子中,`if (reset)`条件语句检查复位信号的状态。
如果复位信号为高电平,计数器被重置为0。
否则,计数器会增加1,通过`count <= count + 1`语句来实现。
以上是一个简单的计数器的Verilog代码示例。
基于fpga的计数器设计代码基于FPGA的计数器设计代码介绍:来自电子系统设计实验课程的一个项目,要求编写一段基于FPGA 的计数器设计代码,但是考虑到本实验课程源自一门免费的开源课程,因此无法提供实际的设备来验证此设计代码,但是可以通过模拟环境进行测试以确保实现正确设计功能,本文将介绍如何利用FPGA对计数器进行设计。
实现方法:1.首先需要确定将用哪种FPGA芯片来实现计数器功能,例如Xilinx Spartan-6的FPGA。
2.然后确定使用哪种电路来实现计数器功能,可以使用逻辑器件来实现,例如可以使用多路触发器、多变量单位、或是查找表等电路。
3.接下来就是根据前面两步的确定,开始编写实现计数器设计的代码,例如VHDL语言或Verilog语言。
4.最后进行代码仿真,使用设计的代码来仿真计数器的功能,以确保代码完全正确。
示例代码:下面是一段可以实现计数器设计的代码,采用的是VHDL语言:--计数器设计代码LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY COUNTER ISPORT (reset : IN STD_LOGIC;clk : IN STD_LOGIC;count : OUT STD_LOGIC_VECTOR (7 DOWNTO 0));END COUNTER;ARCHITECTURE RTL OF COUNTER ISBEGINPROCESS(clk, reset)BEGINIF (reset='1') THENcount <= '00000000'; --初始值为0ELSIF (clk='1' and clk'EVENT) THENcount <= count + 1; --正常的计数END IF;END PROCESS;END RTL;以上代码可以实现一个八位的计数器,当reset为高电平时,计数器初始值为0,每次当clk上升沿时,计数器递增1,当计数器到达最大值255时,再次上升时从0开始重复计数。
fpga计数代码FPGA 计数器是基于 FPGA 实现的计数器,主要用于对电路中的事件进行计数。
通过 FPGA 的可编程性,可以通过更改代码来实现计数器的不同规格和特性。
下面是FPGA计数代码的一些相关参考内容:一、计数器的工作原理FPGA 计数器是由一组寄存器组成的计数器。
它的工作原理就是通过不断地累加计数器中的数字来实现事件的计数。
当计数器达到设定的上限时,它会向下复位并重新开始计数。
二、FPGA 计数器的实现FPGA 计数器可以通过 VHDL 或 Verilog HDL 等编程语言来实现。
以下是 VHDL 代码示例:```library IEEE;use IEEE.STD_LOGIC_1164.ALL;entity cnt_4_bit isPort ( clk : in STD_LOGIC;rst : in STD_LOGIC;en : in STD_LOGIC;q : out STD_LOGIC_VECTOR (3 downto 0));end cnt_4_bit;architecture Behavioral of cnt_4_bit issignal cnt : STD_LOGIC_VECTOR (3 downto 0) := "0000"; beginprocess(clk, rst)beginif rst = '1' thencnt <= "0000";elsif rising_edge(clk) thenif en = '1' thencnt <= cnt + 1;end if;end if;end process;q <= cnt;end Behavioral;```在上面的代码中,四位计数器被定义为一个VHDL实体。
在计数器的行为结构中,产生了一个进程,该进程在时钟上升沿增加计数器的值。
fpga代码编写流程FPGA(现场可编程门阵列)代码编写流程主要包括以下几个步骤:1. 设计需求分析:首先明确FPGA项目的需求,包括功能、性能、接口等方面。
这一阶段可能涉及与硬件工程师、系统工程师等相关人员的沟通,以确保代码满足整个项目的需求。
2. 硬件描述语言(HDL)编写:根据设计需求,使用硬件描述语言(如Verilog或VHDL)编写FPGA代码。
这一阶段需要对硬件原理有一定了解,以便正确地实现逻辑功能。
同时,注意代码风格和规范,以提高代码的可读性和可维护性。
3. 仿真与验证:在编写完成代码后,需要对其进行仿真和验证。
使用仿真工具(如ModelSim、VCS等)对代码进行功能和时序分析,确保代码的正确性。
在仿真过程中,可能需要对代码进行迭代优化,以满足性能和资源需求。
4. 综合与布局规划:使用综合工具(如Synplify、XST等)将HDL代码转换为具体的FPGA器件布局规划。
这一阶段需要考虑器件选型、资源利用率、时序约束等因素,以实现最佳的性能和成本平衡。
5. 下载与测试:将生成的比特流(bitstream)下载到目标FPGA器件上,并进行实际测试。
测试过程中,需要使用调试工具(如Jungo、Actel等)进行在线调试,以解决可能出现的硬件故障。
6. 优化与迭代:根据测试结果,对代码进行进一步优化。
这一阶段可能涉及改进代码结构、调整时序约束、优化资源使用等方面,以提高整体项目的性能和可靠性。
7. 文件整理与文档编写:整理项目相关文件,包括HDL代码、仿真报告、布局规划等。
同时,编写项目文档,以便于后期的维护和升级。
总之,FPGA代码编写流程涉及从需求分析到实际测试的各个环节,需要程序员具备一定的硬件知识和编程能力。
在实际项目中,根据具体需求和条件,流程可能会有所调整。
然而,遵循上述基本流程有助于确保项目的顺利进行和成功完成。
LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;ENTITY i2c_slave ISGENERIC (WR_OP_MODE: STD_LOGIC :='1');PORT (----------I2C Bus--------scl : IN STD_LOGIC ;----I2C bus clksda : INOUT STD_LOGIC ;---------sys clk----addsys_clk : IN std_logic;reset : IN STD_LOGIC ;---------Logic Out-------i2c_addr : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);i2c_data_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);wrd : OUT STD_LOGIC ; ---0 write 1 readwrd_en : OUT STD_LOGIC ;---1 activei2c_scl_out : OUT STD_LOGIC ;----falling edge---------Logic In-------i2c_data_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--------dv_id in--------dv_id_in : IN STD_LOGIC_VECTOR(3 DOWNTO 0) );END i2c_slave;ARCHITECTURE beh OF i2c_slave ISCONSTANT RESET_ACTIVE : STD_LOGIC := '0';CONSTANT IDLE : STD_LOGIC_VECTOR :="0001";----Grad code CONSTANT HEADER : STD_LOGIC_VECTOR :="0011"; CONSTANT ACK_HEADER : STD_LOGIC_VECTOR :="0010"; CONSTANT RCV_REG_ADDR : S TD_LOGIC_VECTOR :="0110"; CONSTANT ACK_REG_ADDR : S TD_LOGIC_VECTOR :="0111"; CONSTANT RCV_DA TA : STD_LOGIC_VECTOR :="0101"; CONSTANT ACK_DA TA : STD_LOGIC_VECTOR :="0100"; CONSTANT XMIT_DA TA : STD_LOGIC_VECTOR :="1010"; CONSTANT W AIT_ACK : STD_LOGIC_VECTOR :="1011";----bit counter constantCONSTANT CNT_DONE : STD_LOGIC_VECTOR :="0111";---i2c signalSIGNAL sda_in : STD_LOGIC ;SIGNAL detect_start,detect_stop : STD_LOGIC;sIGNAL state : STD_LOGIC_VECTOR(3 DOWNTO 0);----bit counter 0 to 7SIGNAL bit_cnt : STD_LOGIC_VECTOR(3 DOWNTO 0);SIGNAL bit_cnt_ld,bit_cnt_en : STD_LOGIC ;SIGNAL addr_match : STD_LOGIC ;---header dataSIGNAL i2c_header : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL i2c_header_en : STD_LOGIC;---shift dataSIGNAL i2c_shift_data : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL i2c_shift_en : STD_LOGIC ;---addrSIGNAL addr_flag : STD_LOGIC ;SIGNAL addr_reg : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL get_data_flag : STD_LOGIC ;----slave_sdaSIGNAL slave_sda : STD_LOGIC ;SIGNAL sda_dir : STD_LOGIC ;---load dataSIGNAL load_data_reg_tem : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL load_data_flag,load_data_flag_dl : STD_LOGIC ;SIGNAL load_data_en : STD_LOGIC ;SIGNAL shift_out : STD_LOGIC ;--wrd_enSIGNAL wrd_en_reg,wrd_en_reg_dl : STD_LOGIC;signal scl_reg : std_logic;signal scl_reg_shift : std_logic_vector(5 downto 0);BEGIN------------jitter -----------------gen_scl_reg : PROCESS (sys_clk,reset) ISBEGINIF (reset=RESET_ACTIVE) THENscl_reg<='1';scl_reg_shift<=(others=>'1');ELSIF (sys_clk'EVENT AND sys_clk='1') THENscl_reg_shift<=scl_reg_shift(4 downto 0)&scl;if scl_reg_shift(5 downto 0)="111111" thenscl_reg<='1';elsif scl_reg_shift(5 downto 0)="000000" thenscl_reg<='0';elsescl_reg<=scl_reg;end if;END IF;END PROCESS gen_scl_reg;--************************Get Out**************************i2c_addr<=addr_reg;i2c_data_out<=i2c_shift_data;wrd<=i2c_header(0);--wrd_en<=wrd_en_reg AND wrd_en_reg_dl;wrd_en<=wrd_en_reg;i2c_scl_out<=scl_reg;gen_sda : PROCESS (sda_dir,slave_sda,sda) ISBEGINIF (sda_dir='1') THENsda<=slave_sda;ELSEsda_in<=sda;sda<='Z';END IF;END PROCESS gen_sda;wrd_en_reg<=get_data_flag OR load_data_flag;-- ************************ START/STOP Detect Process ************************ -- This process detects the start and stop conditions.-- by using SDA as a clock-------------------------------------start_det : PROCESS (sda_in,reset) ISBEGINIF (reset=RESET_ACTIVE OR state=HEADER) THENdetect_start<='0';--ELSIF (sda'EVENT AND sda='0') THENELSIF (sda'EVENT AND sda='0') THEN---change by lq 3.5IF (scl_reg='1') THEN ---or scl='1'??detect_start<='1';ELSEdetect_start<='0';END IF;END IF;END PROCESS start_det;stop_det : PROCESS (sda_in,reset,detect_start) ISBEGINIF (reset=RESET_ACTIVE OR detect_start='1') THENdetect_stop<='0';ELSIF (sda'EVENT AND sda/='0') THEN----IF (scl_reg='1') THEN ---or scl='1'??detect_stop<='1';ELSEdetect_stop<='0';END IF;END IF;END PROCESS stop_det;--******************I2C Header Process****************--i2c_header_en<='1' WHEN (detect_start='1' OR state=HEADER) ELSE '0'; i2c_header_en<='1' WHEN (state=HEADER) ELSE '0';gen_i2cheader : PROCESS (reset,scl_reg,detect_stop) ISBEGINIF (reset=RESET_ACTIVE OR detect_stop='1') THENi2c_header<=( OTHERS =>'0');----------------ELSIF (scl_reg'EVENT AND scl_reg='1') THEN -----rising_edge IF (i2c_header_en='1') THENi2c_header<=i2c_header(6 DOWNTO 0)&sda_in;END IF;END IF;END PROCESS gen_i2cheader;--******************Bit Counter Process******************gen_bit_cnter : PROCESS (reset,scl_reg) ISBEGINIF (reset=RESET_ACTIVE) THENbit_cnt<=( OTHERS =>'0');ELSIF (scl_reg'EVENT AND scl_reg='0') THEN -----falling_edgeIF (bit_cnt_ld='1') THENbit_cnt<=( OTHERS =>'0');ELSIF (bit_cnt_en='1') THENbit_cnt<=bit_cnt+1;ELSEbit_cnt<=( OTHERS =>'0');END IF;END IF;END PROCESS gen_bit_cnter;bit_cnt_ld<='1' WHEN (state=IDLE) OR (state=ACK_HEADER) OR (state=ACK_REG_ADDR) OR (state=ACK_DA TA) OR (state=W AIT_ACK) OR (detect_start='1')ELSE '0';bit_cnt_en<='1' WHEN (state=HEADER) OR (state=RCV_REG_ADDR) OR(state=RCV_DA TA)OR (state=XMIT_DA TA) ELSE '0';--*******************Addr Match Process******************addr_match<='1' WHEN i2c_header(7 DOWNTO 1)=("110"&dv_id_in) ELSE '0';--******************Shift data Process*******************get_shift_data : PROCESS (reset,scl_reg) ISBEGINIF (reset=RESET_ACTIVE) THENi2c_shift_data<=(OTHERS =>'0');ELSIF (scl_reg'EVENT AND scl_reg='1') THEN---change by lqIF (i2c_shift_en='1') THENi2c_shift_data<=i2c_shift_data(6 DOWNTO 0)&sda_in;END IF;END IF;END PROCESS get_shift_data;i2c_shift_en<='1' WHEN (state=RCV_REG_ADDR) OR (state=RCV_DA TA) ELSE '0';--******************Get addr Process******************addr_flag<='1' WHEN state=ACK_REG_ADDR ELSE '0';get_addr_reg : PROCESS (reset,scl_reg) ISBEGINIF (reset=RESET_ACTIVE) THENaddr_reg<=(OTHERS =>'0');ELSIF (scl_reg'EVENT AND scl_reg='0') THENIF (addr_flag='1') THENaddr_reg<=i2c_shift_data;END IF;END IF;END PROCESS get_addr_reg;get_data_flag<='1' WHEN state=ACK_DA TA ELSE '0';--******************Load Data Process****************gen_load : PROCESS (scl_reg,reset) ISBEGINIF (reset=RESET_ACTIVE) THENload_data_reg_tem<=( OTHERS =>'0');ELSIF (scl_reg'EVENT AND scl_reg='0') THENIF (load_data_flag='1') THENload_data_reg_tem<=i2c_data_in;ELSIF (load_data_en='1') THENload_data_reg_tem<=load_data_reg_tem(6 DOWNTO 0)&load_data_reg_tem(7);END IF;END IF;END PROCESS gen_load;--shift_out<=load_data_reg_tem(7) WHEN ((load_data_en='1') AND (load_data_flag_dl/='1')) ELSE i2c_data_in(7);shift_out<=load_data_reg_tem(7) ;-- WHEN ((load_data_en='1') AND (load_data_flag_dl/='1')) ELSE '0';load_data_en<='1' WHEN (state=XMIT_DA TA) ELSE '0';load_data_flag<='1' WHEN ((state=ACK_HEADER) AND (i2c_header(0)='1') AND (addr_match='1')) ELSE '0';get_load_flag_dl : PROCESS (reset,scl_reg) ISBEGINIF (reset=RESET_ACTIVE) THENload_data_flag_dl<='0';ELSIF (scl_reg'EVENT AND scl_reg='0') THENload_data_flag_dl<=load_data_flag;END IF;END PROCESS get_load_flag_dl;--***************Shift out Process**********************slave_sda<='0' WHEN ((state=ACK_HEADER) AND (addr_match='1')) OR (state=ACK_REG_ADDR) OR (state=ACK_DA TA)ELSE shift_out WHEN (state=XMIT_DA TA)ELSE '1';sda_dir<='1' WHEN ((state=ACK_HEADER) AND (addr_match='1')) OR (state=ACK_REG_ADDR) OR (state=ACK_DA TA)OR (state=XMIT_DA TA) ELSE '0';-- ************** Main State Machine Process ************state_machine : PROCESS (scl_reg,reset,detect_stop) ISBEGINIF (reset=RESET_ACTIVE OR detect_stop='1') THENstate <= IDLE;ELSIF (scl_reg'EVENT AND scl_reg='0') THENCASE (state) IS---------------IDLE STA TE--------WHEN IDLE => IF (detect_start='1') THENstate<=HEADER;END IF;---------------HEADER STA TE-------WHEN HEADER =>IF (bit_cnt=CNT_DONE) THENstate<=ACK_HEADER;END IF;---------------ACK_HEADER STA TE---WHEN ACK_HEADER => IF (addr_match='1') THENIF (i2c_header(0)='0') THEN---writestate<=RCV_REG_ADDR;ELSE ----readstate<=XMIT_DA TA;END IF;ELSEstate<=IDLE;END IF;--------------- RCV_REG_ADDR STA TE---WHEN RCV_REG_ADDR => IF (detect_start='1') THENstate<=HEADER;ELSIF (bit_cnt=CNT_DONE) THENstate<=ACK_REG_ADDR;END IF;----------------ACK_REG_ADDR STA TE--------WHEN ACK_REG_ADDR => state<=RCV_DA TA;--------------- RCV_DA TA STA TE--------WHEN RCV_DA TA => IF (detect_start='1') THENstate<=HEADER;ELSIF (bit_cnt=CNT_DONE) THENstate<=ACK_DA TA;END IF;--------------- ACK_DA TA STA TE-------WHEN ACK_DA TA => IF (WR_OP_MODE='1') THENstate<=RCV_REG_ADDR;ELSEstate<=RCV_DA TA;END IF;--------------- XMIT_DA TA STA TE------WHEN XMIT_DA TA => IF (detect_start='1') THENstate<=HEADER;ELSIF (bit_cnt=CNT_DONE) THENstate<=W AIT_ACK;END IF;--------------- W AIT_ACK STA TE-------WHEN WAIT_ACK => IF (sda_in='0') THENstate<= XMIT_DA TA;ELSEstate<= IDLE;END IF;WHEN OTHERS => state<= IDLE;-- i2c_header_en<='0';END CASE;END IF;END PROCESS state_machine;END beh;。
FPGA一位全加器设计实验报告
本实验的目的是学习使用FPGA设计一个全加器,通过实践掌握FPGA硬件描述语言和数字电路设计的一些基础知识和技能。
一、实验背景
数字逻辑电路是计算机硬件的基础,而硬件描述语言是数字电路设计的重要手段。
FPGA是可编程逻辑器件,它可以根据用户的需求进行编程,实现不同的数电逻辑电路。
全加器是组成加法器的重要单元,也是我们学习数字逻辑的重要基础。
二、实验设计
本实验我们将采用Verilog硬件描述语言来设计一个全加器。
代码如下:
module full_add(
input A,B,Cin,
output S,Cout
);
wire w1,w2,w3;
xor(S,w1,A^B);//A异或B
xor(Cout,w2,A&Cin);//A与Cin之后异或
xor(w3,B&Cin,A&Cin);//B与Cin之后异或
xor(Cout,Cout,w3);//再次异或
endmodule
三、测试结果
我们使用Quartus II软件进行仿真和综合。
通过对代码的仿真和波形分析,我们发现该全加器符合设计要求,并且可以正确地输出结果。
四、实验总结
本实验我们学习了FPGA硬件描述语言,掌握了数字电路设计的一些基础知识和技能。
通过设计全加器,我们更深入地理解了数字逻辑电路的原理和应用。
希望在今后的学习中,能够继续深入研究数字电路的知识,为我们掌握计算机硬件设计打下坚实的基础。
1、本课程的讲授目标:了解一种新技术EDA;掌握一种设计工具(器件:Altera FPGA软件:Quartus II);掌握一种语言Verilog HDL。
2、使用Quartus II进行逻辑设计,常用的设计思想的输入方式有:原理图、HDL 等。
3、高级语言C程序经过软件程序编译器形成cpu指令/数据代码流;Verilog HDL程序经过综合器形成电路网表文件4、CPLD是在PAL,GAL等类型器件的基础上发展起来的与或阵列型PLD器件,大多数FPGA采用了查找表结构,其物理结构是静态存储器SRAM.。
5、JTAG边界扫描技术用于对高密度、引脚密集的器件和系统进行测试,如:CPU,DSP,ARM,PLD 等。
同时,JTAG接口也被赋予了更多的功能:编程下载、在线逻辑分析。
6、使用Verilog HDL进行逻辑设计,变量的值有4种状态:0、1、x、z;7、定义逻辑功能的几种基本方法:用assign持续赋值语句定义、用always过程块定义、调用元件(元件例化)。
8、整数按如下方式书写:+/-<size> '<base><value> 即+/-<位宽>'<进制><数字>size 为对应二进制数的宽度;base为进制;value是基于进制的数字序列。
进制有如下4种表示形式:二进制(b或B)、十进制(d或D或缺省)、十六进制(h或H)、八进制(o或O)9、定义reg型标量型变量:reg qout;//变量名qout10、定义wire型向量:wire[7:0] databus;//databus的宽度是8位11、在状态机设计中使用一位热码定义5种状态,并定义状态变量:parameter s0=5’b00001,s1=5’b 00010,s2=5’b 00100,s3=5’b 01000,s4=5’b 10000;reg [4:0] state,next_state;12、在状态机设计中使用顺序码定义5种状态,并定义状态变量:parameter s0=3’b 000,s1=3’b 001,s2=3’b 010,s3=3’b 011,s4=3’b 100;reg [2:0] state,next_state;1、成为IEEE 标准的HDL 有( CD )A 、ABEL-HDLB 、AHDLC 、VHDLD 、Verilog HDL2、Quartus II 是 ( A )公司的( D )开发工具。
FPGA简易四位密码锁的代码一、概述在现代社会中,密码锁被广泛应用于各种场合,如家庭、商业和工业等。
密码锁的使用方便、安全性高,受到了人们的青睐。
FPGA (Field Programmable Gate Array)作为一种灵活可编程的硬件设备,可以用来实现各种数字逻辑电路,包括密码锁。
本文将介绍如何使用FPGA实现一个简易的四位密码锁,并提供相应的代码。
二、硬件设计1. 需要的硬件- FPGA开发板- 数字键盘- LED数码管2. 硬件连接- 将数字键盘通过连接线连接到FPGA开发板上的GPIO端口,用于输入密码;- 将LED数码管通过连接线连接到FPGA开发板上的GPIO端口,用于显示密码输入状态。
三、软件设计1. Verilog代码设计```verilog// 模块声明module password_lock (input wire clk, // 时钟信号input wire rst, // 复位信号input wire [3:0] key_in, // 数字键盘输入output reg [3:0] led_out // LED数码管输出);// 代码实现reg [3:0] password = 4'b1101; // 设定密码为1101always (posedge clk or posedge rst) beginif (rst) beginled_out <= 4'b1111; // 置LED数码管输出为1111end else beginif (key_in == password) beginled_out <= 4'b0000; // 如果输入密码正确,则LED数码管输出为0000end else beginled_out <= 4'b1111; // 如果输入密码错误,则LED数码管输出为1111endendendendmodule```2. 实现原理说明- 模块声明中指定了模块的输入和输出端口;- 代码实现中首先设定了一个四位的密码,然后在时钟信号的作用下判断输入的密码是否与设定的密码相匹配,如果匹配则将LED数码管输出为0000,表示密码正确;否则输出为1111,表示密码错误。
1、按键消抖实验1.module anjianxiaodou(clk,rst_n,sw1_n,sw2_n,sw3_n,led_d1,led_d2,led_d3);2.3.input clk; //主时钟信号,50MHZ4.input rst_n; //复位信号,低电平有效5.input sw1_n,sw2_n,sw3_n; //3个独立按键,低表示按下6.output led_d1,led_d2,led_d3; //发光二极管,分别由按键控制7.8.//----------------------------------------------------------9.10.reg[2:0] key_rst; //按键复位,低电平有效11.12.always @(posedge clk or negedge rst_n)13.if (!rst_n) key_rst <= 3'b111;14.else key_rst <= {sw3_n,sw2_n,sw1_n};15.16.reg[2:0] key_rst_r; //每个时钟周期的上升沿将key_rst信号所存到key_rst_r中17.18.always @(posedge clk or negedge rst_n)19.if(!rst_n) key_rst_r <= 3'b111;20.else key_rst_r <= key_rst; //key_rst_r为key_rst延迟一个时钟周期21.22.wire[2:0] key_an = key_rst_r & (~key_rst); //当寄存器key_rst由1变为0时,key_an的值为高并维持一个时钟周期,实际上时获取key_rst的下降沿23.24.//-------------------------------------------------------------25.26.reg[19:0] cnt; //计数寄存器2^20约等于10^627.28.always @ (posedge clk or negedge rst_n) //该always进程用来判断是抖动还是真的有按键按下,若真的按键按下,则计数会达到20‘hfffff29.if(!rst_n) cnt <= 20'd0; //异步复位30.else if (key_an) cnt <= 20'd0;//key_an为1可能是因为抖动产生,此处若是抖动,时间必定小于20ms,则计数清零,下面不锁存按键的值31.else cnt <= cnt + 1'b1;//(10^6)*20ns = 20ms,若是人为按下按键,按下持续时间必定大于20ms。
2014年EDA实验第一次实验:实验1:QII软件及实验板的使用;用图形输入法和语言输入法完成点灯实验(用两个按键控制两个灯的亮灭:灯的状态随按键状态改变而改变)。
完成软件仿真。
module simple_lightcon(input wire [1:0] key, output wire [1:0] led);assign led= key;endmodule实验2:联控点灯实验:用两个按键独立控制同一个灯亮灭,第三个按键同时控制该灯和另一个灯亮灭。
module com_lightcon(input wire [2:0] key, output wire [1:0] led);assign led[0]= key[0];assign led[1]= key[0]&( key[2]^ key[1]);endmodule实验3:流水灯实验:完成一个8路流水灯控制实验,要求有以下3种花型:1)8路灯同时亮灭;2)从左至右再从右至左逐个亮(每次只有1路亮);3)8路灯每次4路灯亮,4路灯灭,且亮灭相间,交替亮灭。
用3个按键控制3种花型。
按下花型按键就一直显示相应花型,再按该键可暂停。
可设置1个复位键关闭显示。
/*-------------------------------------------------------------------------------------------------Filename :waterlight.vAuthor :BassonData : 2014-11-21Version : V1.0Description : This file has the module of HDL top.Modification History:Data by Version Change Description=========================================================14/11/21 Basson V1.0 Original---------------------------------------------------------------------------------------------------*/module water_light(input wire sys_sclk, //时钟信号(输入信号)input wire srst_n, //复位信号(输入信号)input wire[2:0] key, //按键信号(输入信号)output reg [3:0] ledlight //输出接8个led灯(输出信号));//消抖动------------------------------------------------------------------reg [2:0] key_reg; //用于存储现有按键always @(posedge sys_sclk,negedge srst_n)beginif(srst_n==1'b0) key_reg<=3'b111;else key_reg<=key;endreg [2:0] key_reg_r; //用于存储前一按键always @(posedge sys_sclk,negedge srst_n)beginif(srst_n==1'b0) key_reg_r<=3'b111;else key_reg_r<=key_reg; //用于存储前一按键endwire[2:0] key_an=key_reg_r&(~key_reg); //用于存储按键下降沿//消抖时间设定为20ms左右-------------------------------------------------------------------parameter CCNTWITHD=20;reg [CCNTWITHD-1:0] ccnt;reg[2:0] keyout;always @(posedge sys_sclk,negedge srst_n)beginif(srst_n==1'b0)ccnt<=20'b0;else if(key_an)ccnt<=20'b0; //按键有抖动就清零--消除抖动的计数器else ccnt<=ccnt+1'b1; //没有抖动,消除抖动的计数器开始加1,延时20ms。
endreg [2:0] low_key; //用于记录消除抖动后的现有按键状态always @(posedge sys_sclk,negedge srst_n)beginif(srst_n==1'b0) low_key<=3'b111;else if(ccnt==20'hfffff)low_key<=key;end/*消抖动结束*//*流水灯控制部分程序--------------------------------------------------------------------------*///可按键标志位------------------------------------------------------------------reg [2:0] low_key_r; //用于记录消除抖动后的下一按键状态always @(posedge sys_sclk,negedge srst_n)beginif(srst_n==1'b0) low_key_r<=3'b111;elselow_key_r<=low_key;endwire [2:0] key_flag11=low_key_r&(~low_key); //消逗后按键下降沿个数,作为标志位//标志位------------------------------------------------------------------reg[2:0] key_flag1;always @(posedge sys_sclk ,negedge srst_n)beginif(srst_n==1'b0)beginkey_flag1<=3'b000;endelse//花型按键显示相应花型---有优先级电路设计代码begincase(key_flag11)3'b001:beginkey_flag1={2'b00,~key_flag1[0]};//奇数显示相应花型,偶数暂停end3'b010:beginkey_flag1={1'b0,~key_flag1[1],1'b0}; //奇数显示相应花型,偶数暂停end3'b100:beginkey_flag1={~key_flag1[2],2'b00};//奇数显示相应花型,偶数暂停endendcaseendendwire[2:0] key_flag=key_flag1;//50MHZ div_frequence to 1Hz ---------------------------------------------parameter COUNTWIDTH = 24;reg[COUNTWIDTH-1:0] ccount;// reg sclk;wire ssclk;always @(posedge sys_sclk, negedge srst_n)beginif(srst_n==1'b0) begin ccount[COUNTWIDTH-1:0]<='d0;endelse ccount<=ccount+1'b1;endassign ssclk=ccount[COUNTWIDTH-1];// 流水灯显示控制程序--------------------------------------------------------reg[7:0] s0;reg[7:0] s1;reg[7:0] s2;reg[3:0] count;always @(posedge ssclk ,negedge srst_n)beginif(srst_n==1'b0)begins0=4'b0000;s1=4'b1000;s2=4'b1010;count=4'b0;endelse//花型按键显示相应花型---有优先级电路设计代码begincase(key_flag)3'b001:beginledlight<=s0; //奇数显示相应花型,偶数暂停s0<=~s0;end3'b010:beginif(count<=4'b0111)beginledlight<=s1;s1<={s1[0],s1[3:1]}; //奇数显示相应花型,偶数暂停count<=count+1;endelse if(count>4'b0111)beginledlight<=s1;s1<={s1[2:0],s1[3]};count<=count+1;endend3'b100:beginledlight<=s2; //奇数显示相应花型,偶数暂停s2<=~s2;endendcaseendendendmodule第二次实验:实验4:数据分配器实验:用2个按键代表输入数据in(2位),用2个按键代表选择控制数据位s1s0,用四组发光管(每组2位)代表四路数据输出out0-out3。
当输入数据或控制数据改变时,要求输出数据进行相应变化(原理和真值表如下)。
s1 s0 out0 out1 out2 out3 0 0 in z z z0 1 z in z z1 0 z z in z 1 1 z z z inmodule mux_4(in, out0, out1, out2, out3, sel);input[1:0] sel;input[1:0] in;output reg[1:0] out0; //output reg[1:0] out1; //output reg[1:0] out2; //output reg[1:0] out3; //always @(in or sel)case(sel)2'b00:beginout0 = in;out1 = 2'bz;out2 = 2'bz;out3 = 2'bz;end2'b01:beginout0 = 2'bz;out1 = in;out2 = 2'bz;out3 = 2'bz;end2'b10:beginout0 = 2'bz;out1 = 2'bz;out2 = in;out3 = 2'bz;end2'b11:beginout0 = 2'bz;out1 = 2'bz;out2 = 2'bz;out3 = in;enddefault:beginout0 = 2'bz;out1 = 2'bz;out2 = 2'bz;out3 = 2'bz;endendcaseendmodule实验5:七段译码器实验:用一个按键代表数据输入,每按一次数据加一,从0开始到F,再到0,依次循环,相应数字在数码管上显示。