做360全景的网站,aspcms 生成网站地图,甘肃建设投资集团控股有限网站,网站建站建设联系电话对于FPGA几个与LED相关的实验#xff08;包括按键点灯、流水灯、呼吸灯等#xff09;的记录#xff0c;方便日后查看。这世界上就又多了一个FPGA点灯工程师了#x1f60f; 成为一个FPGA点灯工程师分三步#xff1a;一、按键点灯1、按键点灯程序2、硬件实现二、流水灯1、流…对于FPGA几个与LED相关的实验包括按键点灯、流水灯、呼吸灯等的记录方便日后查看。这世界上就又多了一个FPGA点灯工程师了 成为一个FPGA点灯工程师分三步一、按键点灯1、按键点灯程序2、硬件实现二、流水灯1、流水灯程序2、仿真3、硬件实现三、呼吸灯1、先“吸”2、再“呼吸”3、最后大口地呼吸一、按键点灯
按键点灯程序比较简单就不搞仿真了直接上机
1、按键点灯程序
module led(input wire key_1,output reg led_1);always*led_1!key_1;endmodule由程序得到的RTL图 2、硬件实现
1引脚分配与接线 引脚分配如下记得引脚分配后再编译一次不然可能没有现象。 上述引脚分配对应的接线JX22连接到JP5JX5连接到JP1。 为什么要这样接线可以参考《【FPGA实验2】二进制转为格雷码》中的【三、实验箱实验】➡️【3、引脚分配】。 2实验现象
具体的实验现象可观看下方的视频
二、流水灯
学了点状态机的内容决定用状态机来写一下这个流水灯的代码。 感谢正点原子的视频用了一个很好理解的例子讲了状态机是怎么样的一个东西并总结了写状态机主要有四个步骤也称四段论 1状态空间定义定义各个状态 2状态跳转告诉FPGA你要跳转。让FPGA知道在什么条件下你要从现在状态跳转到下一个状态 3下个状态的判断告诉FPGA你要怎么跳。给FPGA一个地图判断现在的情况是什么然后根据地图确定下一个要跳转的状态 4各个状态下的动作我理解为状态对应信息的输出
1、流水灯程序
module WaterLED(input wire clk,input wire rst_n,output wire [7:0]led_data);//空间状态定义parameter S18b10000000;parameter S28b01000000;parameter S38b00100000;parameter S48b00010000;parameter S58b00001000;parameter S68b00000100;parameter S78b00000010;parameter S88b00000001;reg [7:0]current_state;reg[7:0]next_state;//状态跳转always (posedge clk or negedge rst_n) beginif(! rst_n) current_stateS1; //复位从状态S1开始else current_statenext_state; //不是复位的情况下到达时钟的上升沿就转到下一个状态end//状态判断always (current_state) begincase(current_state) S1:next_stateS2;S2:next_stateS3;S3:next_stateS4;S4:next_stateS5;S5:next_stateS6;S6:next_stateS7;S7:next_stateS8;default:next_stateS1;endcaseend//各个状态下的动作assign led_datacurrent_state;endmodule得到的RTL图如下
2、仿真
流水灯的仿真程序如下
timescale 1ns/100ps
module tb_WaterLED;reg clk_1;reg rst_n_1;wire [7:0] led_data_1;parameter PERIOD10;always #(PERIOD/2) clk_1~clk_1;initial beginclk_10;#200 $stop;endtask task_rst;begin rst_n_10;repeat(2) (negedge clk_1);//两个时钟负跳变之后rst_n_11;endendtaskWaterLED WD_1(.clk(clk_1),.rst_n(rst_n_1),.led_data(led_data_1));initial begintask_rst;$display(task_rst ok!!!);endendmodule【如何将仿真程序加入到工程中以及如何仿真可以看上一篇《【FPGA实验0】Quartus建立工程文件以及仿真》】
仿真结果如下 在两个时钟下降沿之后复位线RST置高之后随着每一个时钟上升沿的到来开始状态的转换。 3、硬件实现
在实际的硬件实现中需要注意两个点
1时钟信号 在仿真中两个状态之间的切换是在时钟信号的上升沿因而每个状态保持的时间是一个时钟信号周期在上的仿真中一个时钟信号的周期是10ns。而如果在实际中要实现流水灯的效果这样的间隔太小了由于眼睛的暂存作用我们看懂的现象是8个LED灯一直在同时亮着没有流水灯的效果因而我们必须将时钟周期改得大一点。
选择实验箱最大时钟12MHz接线的话将左侧12M对应的时钟和右侧的任意一个引脚接起来即可定义一个计数器计数2400000个时钟周期一个时钟频率为12MHz一个时钟周期为83.33ns2400000个时钟周期就是0.2秒。 reg [23:0] counter; //计数器对系统时钟计数计时0.2秒always (posedge clk or negedge rst_n) beginif (!rst_n)counter 24d0;else if (counter 24d2400_000) //仿真的时候可以改为 24d0000_0010,下同counter counter 1b1;elsecounter 24d0;end同时状态跳变部分增加一个条件修改为
//状态跳转
always (posedge clk or negedge rst_n) beginif(! rst_n) current_stateS1; //复位从状态S1开始else if (counter24d2400_000) current_statenext_state; //不是复位的情况下到达时钟的上升沿就转到下一个状态else ;
end2复位键如何使用
复位键一开始需要置1打到开的位置 之后置0下降沿产生出发条件同时rst0状态为初始状态S1 完成复位后置1使此刻的状态在触发之后能跳转到下一个状态。
整个硬件实现的程序
module WaterLED(input wire clk,input wire rst_n,output wire [7:0]led_data);//空间状态定义parameter S18b10000000;parameter S28b01000000;parameter S38b00100000;parameter S48b00010000;parameter S58b00001000;parameter S68b00000100;parameter S78b00000010;parameter S88b00000001;reg [7:0]current_state;reg[7:0]next_state;reg [23:0] counter;//计数器对系统时钟计数计时0.2秒always (posedge clk or negedge rst_n) beginif (!rst_n)counter 24d0;else if (counter 24d2400_000) //仿真的时候可以改为 24d0000_0010,下同counter counter 1b1;elsecounter 24d0;end//状态跳转always (posedge clk or negedge rst_n) beginif(! rst_n) current_stateS1; //复位从状态S1开始else if (counter24d2400_000) current_statenext_state; //不是复位的情况下到达时钟的上升沿就转到下一个状态else ;end//状态判断always (current_state) begincase(current_state) S1:next_stateS2;S2:next_stateS3;S3:next_stateS4;S4:next_stateS5;S5:next_stateS6;S6:next_stateS7;S7:next_stateS8;default:next_stateS1;endcaseend//各个状态下的动作assign led_data~current_state;//灯为0时亮起为1时变暗endmodule对应的RTL图
引脚分配与接线
按之前的接线即可key8为复位键。
上述引脚分配对应的接线JX22连接到JP5JX5连接到JP1。 为什么要这样接线可以参考《【FPGA实验2】二进制转为格雷码》中的【三、实验箱实验】➡️【3、引脚分配】。
时钟引脚左侧的12M时钟引脚接到右侧任意一个引脚即可。总的接线图如下 具体现象可以看文末的视频
三、呼吸灯
呼吸灯就是灯的亮度由暗变亮再由亮变暗像人的呼吸一样。
1、先“吸”
1代码
module PWM( input wire clk,output wire[9:0] pwma,output wire pwmb);reg [3:0]counter10,counter20;reg [9:0]pwm_110b0000_0000_00;reg[0:0] pwm_2;always(posedge clk) beginif(counter24d9) beginif(counter14d9) begincounter10;pwm_110b0000_0000_00; endelse counter1counter11; pwm_1[counter1]1;counter20;endelse counter2counter21;pwm_2pwm_1[counter2];endassign pwmapwm_1;assign pwmbpwm_2;endmodule2仿真文件
timescale 1ns/100ps
module tb_PWM;reg clk;wire [9:0]pwma;wire [0:0]pwmb;parameter PERIOD10;always #(PERIOD/2) clk~clk;initial beginclk0;# 3000 $stop;endPWM PWM_1(.clk(clk),.pwma(pwma), .pwmb(pwmb));endmodule3仿真结果
2、再“呼吸”
1代码
module PWM(input wire clk,output wire[9:0] pwma,output wire pwmb);reg [4:0]counter10;reg [3:0]counter20;reg [9:0]pwm_110b0000_0000_00;reg[0:0] pwm_2;always(posedge clk) beginif(counter24d9) beginif(counter15d17) counter10;else counter1counter11; $display(counter1: ,counter1);case(counter1)5d0 : pwm_110b0000_0000_01;5d1 : pwm_110b0000_0000_11;5d2 : pwm_110b0000_0001_11;5d3 : pwm_110b0000_0011_11;5d4 : pwm_110b0000_0111_11;5d5 : pwm_110b0000_1111_11;5d6 : pwm_110b0001_1111_11;5d7 : pwm_110b0011_1111_11;5d8 : pwm_110b0111_1111_11;5d9 : pwm_110b1111_1111_11;5d10 : pwm_110b0111_1111_11;5d11 : pwm_110b0011_1111_11;5d12 : pwm_110b0001_1111_11;5d13 : pwm_110b0000_1111_11;5d14 : pwm_110b0000_0111_11;5d15 : pwm_110b0000_0011_11;5d16 : pwm_110b0000_0001_11;5d17 : pwm_110b0000_0000_11;endcase$display(pwm_1: ,pwm_1);counter20;endelse counter2counter21;pwm_2pwm_1[counter2];endassign pwmapwm_1;assign pwmbpwm_2;endmodule
2tb文件
timescale 1ns/100ps
module tb_PWM;reg clk;wire [9:0]pwma;wire [0:0]pwmb;parameter PERIOD10;always #(PERIOD/2) clk~clk;initial beginclk0;# 3000 $stop;endPWM PWM_1(.clk(clk),.pwma(pwma), .pwmb(pwmb));endmodule
3仿真结果 3、最后大口地呼吸
呼吸灯的硬件实现和流水灯的硬件实现一样原理如果每个亮度的时间跟仿真的时候一样的话那我们是看不出亮度变化所以在硬件实现的时候需要在每一个亮度延长一定的时间。具体的实现如下
1代码
module PWM(input wire clk,output wire led0,output wire led1,output wire led2,output wire led3,output wire led4,output wire led5,output wire led6,output wire led7);reg [4:0]counter10;reg [3:0]counter20;reg [9:0]pwm_110b0000_0000_00;reg[0:0] pwm_2;reg [20:0] cnt_base;parameter T_6ms 21d2000_000;always (posedge clk ) beginif(cnt_base T_6ms - 1b1)begincnt_base cnt_base 1b1;pwm_2pwm_1[cnt_base%10];endelse begincnt_base 21d0;if(counter15d17) counter10;else counter1counter11; case(counter1)5d0 : pwm_110b0000_0000_01;5d1 : pwm_110b0000_0000_11;5d2 : pwm_110b0000_0001_11;5d3 : pwm_110b0000_0011_11;5d4 : pwm_110b0000_0111_11;5d5 : pwm_110b0000_1111_11;5d6 : pwm_110b0001_1111_11;5d7 : pwm_110b0011_1111_11;5d8 : pwm_110b0111_1111_11;5d9 : pwm_110b1111_1111_11;5d10 : pwm_110b0111_1111_11;5d11 : pwm_110b0011_1111_11;5d12 : pwm_110b0001_1111_11;5d13 : pwm_110b0000_1111_11;5d14 : pwm_110b0000_0111_11;5d15 : pwm_110b0000_0011_11;5d16 : pwm_110b0000_0001_11;5d17 : pwm_110b0000_0000_11;endcaseendendassign led0pwm_2;assign led1pwm_2;assign led2pwm_2;assign led3pwm_2;assign led4pwm_2;assign led5pwm_2;assign led6pwm_2;assign led7pwm_2;endmodule
2对应的RTL图 3引脚分配与接线 接线同上流水灯的接线。
4实验现象 具体实验现象可以看文末 FPGA点灯工程师养成记Forever young,always tearful.