华为云FPGA设计教程:实现模可变计数器的设计与验证
在华为云FPGA开发环境中,我们将通过Verilog编程来实现模可变计数器的设计。通过本次实验,您将能够掌握FPGA在组合逻辑电路和时序电路中的实现方法,并熟悉华为云FPGA开发环境的使用技巧。以下是实验的具体要求和步骤:
一、实验目的
- 掌握组合逻辑电
一、实验目的
- 掌握组合逻辑电路和时序电路在华为云FPGA上的实现方法。
- 熟悉华为云FPGA开发环境和相关工具的使用方法。
- 学习静态数码管的使用以及7段数码显示译码器的设计方法。
- 理解时钟在时序电路中的重要作用。
- 掌握分频电路的实现原理和方法。
二、实验要求
在本实验中,我们将设计一个模值可变的BCD计数器。您可以选择任意模值(最大模值至少3位),并通过3位数码管显示计数结果。为了满足实验要求,您需要完成以下任务:
- 使用Verilog编程语言设计模值可变的BCD计数器。计数结果需通过3位数码管显示BCD码。
- 提供该设计的仿真波形,以证明其正确性。
- 在华为云FPGA开发环境中验证此计数器的功能。
- 设计一个模值可变的输入端口,允许用户通过输入模值和设置信号来改变计数器的模值。
- 使用1个开关作为使能控制,使用1个按键作为异步清0功能。
- 实现进位输出功能,并通过LED灯显示进位输出。
- 熟悉华为云FPGA开发环境和相关工具的使用方法。
- 学习静态数码管的使用以及7段数码显示译码器的设计方法。
- 理解时钟在时序电路中的重要作用。
- 掌握分频电路的实现原理和方法。
二、实验要求
在本实验中,我们将设计一个模值可变的BCD计数器。您可以选择任意模值(最大模值至少3位),并通过3位数码管显示计数结果。为了满足实验要求,您需要完成以下任务:
- 使用Verilog编程语言设计模值可变的BCD计数器。计数结果需通过3位数码管显示BCD码。
- 提供该设计的仿真波形,以证明其正确性。
- 在华为云FPGA开发环境中验证此计数器的功能。
- 设计一个模值可变的输入端口,允许用户通过输入模值和设置信号来改变计数器的模值。
- 使用1个开关作为使能控制,使用1个按键作为异步清0功能。
- 实现进位输出功能,并通过LED灯显示进位输出。
三、实验代码
在"mycounter_2"的Verilog模块中,具有多个输入和输出端口,包括时钟信号(clk)、复位信号(rst)、使能信号(en)、设置信号(set)、模数输入(m)以及多位输出信号(dout, cout, data)。
在这个模块内部,根据时钟信号(clk)的上升沿或复位信号(rst)的下降沿,执行相应的逻辑操作。当复位信号有效时,输出信号dout被清零,进行一次系统复位。而在其他情况下,如果使能信号有效,则根据g和s的值,分别设置BCD_OUT0和BCD_OUT1的值。
此外,当时钟信号上升沿或复位信号下降沿到来时,还进行另一段逻辑处理。在系统复位或接收到设置信号的情况下,计数器dout被清零。如果使能信号有效,并且dout的值等于m_set,计数器也会被清零。否则,每当时钟信号到来,计数器dout的值会加1。
最后一段逻辑是在dout的值发生变化时执行的。当dout的值等于m_set时,输出信号cout被设置为1;否则,cout被设置为0。
通过以上的逻辑操作,该模块实现了根据输入信号的变化来控制和调整输出的功能。它在数字电路中扮演了重要的角色,能够完成计数、显示以及其他逻辑操作。这段代码的逻辑结构和设计思路都经过精心考虑,以实现预期的功能和性能。
module mycounter_2(
input clk,
input en,
//开关
input rst, //复位
input [7:0] m,
input set,
output reg [7:0] dout,
output reg cout,
output reg [10:0] data
);
reg [8:0]m_set;
reg [6:0]BCD_OUT0;
reg [6:0]BCD_OUT1;
reg [6:0]m_OUT0;
reg [6:0]m_OUT1;
wire [3:0]g;
wire [3:0]s;
wire [3:0]mg;
wire [3:0]ms;
assign g=dout%10;
//前一个单位的个位
assign s=dout%100/10;
//前一个单位的十位
assign mg=m%10;
assign ms=m%100/10;5
reg [19:0]count=0;
reg [30:0]count2=0;
reg [3:0] sel=0;
//数码管地址选择
parameter T1MS=50000;
//m 模数设置与显示
always@(posedge set)
begin
begin
m_set<=m;
case(mg)
//转化为数码管显示 个位
0:m_OUT0<=7'b0000001; 1:m_OUT0<=7'b1001111;
2:m_OUT0<=7'b0010010; 3:m_OUT0<=7'b0000110;
4:m_OUT0<=7'b1001100; 5:m_OUT0<=7'b0100100;
6:m_OUT0<=7'b0100000; 7:m_OUT0<=7'b0001111;
8:m_OUT0<=7'b0000000; 9:m_OUT0<=7'b0000100;
default:m_OUT0<=7'B0000001;
endcase
case(ms)
0:m_OUT1<=7'b0000001; 1:m_OUT1<=7'b1001111;
2:m_OUT1<=7'b0010010; 3:m_OUT1<=7'b0000110;
4:m_OUT1<=7'b1001100; 5:m_OUT1<=7'b0100100;
6:m_OUT1<=7'b0100000; 7:m_OUT1<=7'b0001111;
8:m_OUT1<=7'b0000000; 9:m_OUT1<=7'b0000100;
default:m_OUT1<=7'B0000001;
endcase
begin
case(sel)
2:data<=11'b0111_0000000 + m_OUT0;
3:data<=11'b1110_0000000 + m_OUT1;
endcase
end
end
end
//多位数码管显示
always@(posedge clk) //上升沿 clk
begin
if(!rst)
begin
case(sel)
0:data<=11'b0111_1001111 + BCD_OUT0;
1:data<=11'b1011_0010010 + BCD_OUT0;
default:data<=11'b1111_1111111;
endcase
end
else
begin
case(sel)
0:data<=11'b1110_1001111;
1:data<=11'b1101_0010010;
default:data<=11'b1111_1111111;
endcase
end
end
always@(posedge clk)
begin6
count<=count+1;
if(count==T1MS)
begin
count<=0;
sel<=sel+1;
if(sel==2)
sel<=0;
end
end
reg clk1;
always @(posedge clk)
begin count2=count2+1;
if(count2/10000000%2==1) begin clk1=1'b1; count2=0;end
else clk1=1'b0;
end
always@(posedge clk or negedge rst)
begin
if(!rst)
begin
dout<=0;
end
else if(en)
begin
case(g)
0:BCD_OUT0<=7'b0000001; 1:BCD_OUT0<=7'b1001111;
2:BCD_OUT0<=7'b0010010; 3:BCD_OUT0<=7'b0000110;
4:BCD_OUT0<=7'b1001100; 5:BCD_OUT0<=7'b0100100;
6:BCD_OUT0<=7'b0100000; 7:BCD_OUT0<=7'b0001111;
8:BCD_OUT0<=7'b0000000; 9:BCD_OUT0<=7'b0000100;
default:BCD_OUT0<=7'B0000001;
endcase
case(s)
0:BCD_OUT1<=7'b0000001; 1:BCD_OUT1<=7'b1001111;
2:BCD_OUT1<=7'b0010010; 3:BCD_OUT1<=7'b0000110;
4:BCD_OUT1<=7'b1001100; 5:BCD_OUT1<=7'b0100100;
6:BCD_OUT1<=7'b0100000; 7:BCD_OUT1<=7'b0001111;
8:BCD_OUT1<=7'b0000000; 9:BCD_OUT1<=7'b0000100;
default:BCD_OUT1<=7'B0000001;
endcase
end
end
always@(posedge clk or negedge rst)
begin
if(!rst||set)
dout <= 8'b00000000;
//系统复位,计数器清零
else if(en)
if(dout == m_set)
//计数值达到 m 时,计数器清零
dout <= 8'b00000000;
else
dout <= dout + 8'b00000001; //否则,计数器加 1
else
dout <= dout;
end
always@(dout)if(dout==m_set)
cout<=1'b1;
else cout<=1'b0;
endmodule
//仿真文件
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2023/03/16 21:54:56
// Design Name:
// Module Name: sim_CNT
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ps
module sim_CNT();
reg SW1,KEY1;
reg [9:0]M_SET;
wire [9:0] cnt_count;
wire [10:0] display_segout;
wire LED_OUT;
reg clk1;
initial
begin
clk1= 1'b0;
SW1 = 1'b0;
#2 KEY1 = 1'b1;
M_SET =10'b0000001111;
#2 KEY1 = 1'b0;
#2 KEY1 = 1'b1; SW1 = 1'b1; //计数使能信号有效,且不复位
end
always
begin
#10 clk1 = ~clk1;
end
CNT uu1(clk1,SW1,KEY1,M_SET,cnt_count,display_segout,LED_OUT);
endmodule
四、实验结果及分析该项目基于Verilog语言编写,实现了一个功能强大的计数器模块。通过与华为云的结合,该项目能够进一步发挥其作用和价值。
华为云提供了强大的云计算和存储能力,为该项目提供了可靠的运行环境和数据存储解决方案。在项目中,我们可以利用华为云的计算资源,进行电路仿真和验证,加快设计迭代的速度。同时,华为云提供的存储服务可用于保存和共享项目文件,促进团队协作和版本控制。
此外,华为云还提供了各种开发工具和服务,使项目开发和调试更加方便高效。通过华为云的在线开发环境,团队成员可以远程访问代码编辑器、编译器和调试工具,实现实时编码和测试。而且,华为云还提供了丰富的文档和社区支持,帮助团队成员解决遇到的问题和学习新知识。
综上所述,该项目与华为云的结合将带来诸多优势和便利。华为云提供了强大的计算、存储和开发工具支持,为项目的开发、测试和部署提供了全方位的支持。这种结合将促进项目的高效开发,提升团队的生产力,并加速项目的成功实施。
- 点赞
- 收藏
- 关注作者
评论(0)