差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
流水灯 [2016/06/07 11:39]
anran [硬件连接]
流水灯 [2021/09/13 01:39] (当前版本)
gongyu
行 1: 行 1:
-=====流水灯=====+## 流水灯
  
 ====硬件平台==== ====硬件平台====
行 8: 行 8:
 ====设计要求==== ====设计要求====
 ------ ------
-  - 掌握分频功能的设计+  - 掌握任意数分频计数功能的设计
   - 掌握时序逻辑的设计   - 掌握时序逻辑的设计
   - 掌握case的基本语法   - 掌握case的基本语法
-  - 基于小脚丫STEP FPGA Base Board开发平台LED实现流水灯的功能,每个LED点亮时间为1秒+  - 基于小脚丫STEP FPGA Base Board开发平台LED实现流水灯的功能,总计8个LED灯,循环、轮流点亮,每个LED点亮时间为1秒
  
 ====工作原理==== ====工作原理====
行 18: 行 18:
 本设计为流水灯实验,我们需要结合使用的硬件平台实现[[STEP-Baseboard]]平台上的8个LED循环闪烁,每个LED灯点亮时间为1秒。 本设计为流水灯实验,我们需要结合使用的硬件平台实现[[STEP-Baseboard]]平台上的8个LED循环闪烁,每个LED灯点亮时间为1秒。
  
-LED也叫发光二极管,属于二极管的一种,具有二极管的单项导电性,使用时需要给LED上施加正向压差,产生电流(一般在20mA以内,具体参考设计中使用的LED的参数),点亮LED。+LED也叫发光二极管,属于二极管的一种,具有二极管的单项导电性,使用时需要给LED上施加正向压差,产生电流(一般在20mA以内,具体参考设计中使用的LED的参数),点亮LED。本平台使用的8个LED都是通过低电平点亮(参照电路图),因此控制该LED的FPGA的IO管脚输出“1“(高电平)时LED灭,输出”0“(低电平)时LED亮
  
-为了使每个LED点亮1秒的时间,我们需要一个1Hz的信号,因为硬件平台[[STEP-MXO2第一代]]上使用晶振为25MHz,2^25 = 33554432 > 25000000,所以我们需要做一个位宽为25的计数器。计数器初值为0,当计数到24999999时,总共计数25000000,也就是1秒时间。+为了使一个循环周期内每个LED点亮1秒的时间,我们需要一个持续时间为1秒低电平信号,这可以通过本硬件平台[[STEP-MXO2第一代]]上的25MHz主时钟得到,2^25 = 33554432 > 25000000,所以我们需要做一个位宽为25的计数器。计数器初值为0,当计数到24999999时,总共计数25000000,也就是1秒时间。
  
 为了实现流水的效果,我们需要一个寄存器,寄存器的值不同控制着不同的LED点亮,而寄存器的值在每次计数器计数到24999999时改变,这样每隔1秒时间,寄存器的值改变,对应控制8个LED按照同一方向循环闪烁,就实现了流水灯的功能。 为了实现流水的效果,我们需要一个寄存器,寄存器的值不同控制着不同的LED点亮,而寄存器的值在每次计数器计数到24999999时改变,这样每隔1秒时间,寄存器的值改变,对应控制8个LED按照同一方向循环闪烁,就实现了流水灯的功能。
行 38: 行 38:
 ===设计文件=== ===设计文件===
  
-{{ :38译码器程序设计框图.jpg |38译码器程序设计框图}}+{{ :流水灯程序设计.jpg |流水灯程序设计}}
  
-通过38译码器原理及程序设计框图,我们不难发现这是一个比较简单组合逻辑设计+为了实现对8个LED控制,我们设计了25位的计数器cnt进行1s周期的循环计数同时我们定义了一个3位寄存器led_cnt作为状态机状态控制流水灯的闪烁。状态机共有8个状态,每一个状态对应点亮一个LED灯
  
-正如我们在原理及硬连接中描述的,我们需要一路芯片使能端口、三路信号输入端口和八路信号输出端口。模块端口设计如下:+首先是计数器的设计,计数器的计数范围为0~CNT_NUM-1,为了实现每个LED灯1秒的点亮时间,设计文件代码中我们定义参数CNT_NUM为25000000,但是仿真文调用设计文件时,为了方便仿真,我们会将参数CNT_NUM重新赋值为10.
  
 <code verilog> <code verilog>
-module Decode38  +reg [24:0] cnt = 25'd0; 
-+always@(posedge clk_in or negedge rst_n_inbegin 
-input Enable, + if(!rst_n_in) begin 
-input [2:0] A_in, + cnt <= 25'd0; 
-output ​reg [7:0] Y_out + end else if(cnt>​=CNT_NUM-1) begin 
-);+ cnt <= 25'​d0;​ 
 + end else begin 
 + cnt <= cnt + 25'​d1;​ 
 + end 
 +end
 </​code>​ </​code>​
  
-逻辑部分,当芯片使能信号无效时,输出全部置高,当芯片使能信号有效时,根据三路信号输入状态译码控制八路信号输出+然后我们需要对状态机的状态进行控制,使得作为状态的寄存器led_cnt实现从0到7的循环加一操作
  
 <code verilog> <code verilog>
-always@(A_in or Enable) begin +reg [2:0] led_cnt = 3'​d0;​ 
-    if (Enable+always@(posedge clk_in ​or negedge rst_n_in) begin 
- case (A_in+ if(!rst_n_inbegin 
- 3'b000: Y_out 8'b11111110+ led_cnt <= 3'​d0;​ 
- 3'b001Y_out = 8'b11111101+ end else if(cnt==CNT_NUM-1begin 
- 3'b010Y_out = 8'b11111011+ if(led_cnt==3'd7) led_cnt <3'd0
- 3'b011Y_out = 8'b11110111+ else led_cnt <= led_cnt + 3'd1; 
- 3'b100Y_out = 8'b11101111+ end 
- 3'b101Y_out = 8'b11011111+end 
- 3'b110Y_out = 8'b10111111+</​code>​ 
- 3'b111Y_out = 8'b01111111+ 
- default:Y_out = 8'b11111111+最后是组合逻辑,根据led_cnt的不同状态控制不同的LED点亮。 
- endcase + 
-    else Y_out = 8'b11111111;+<code verilog>​ 
 +always@(led_cnt) begin 
 + case(led_cnt) 
 + 3'd0led_out ​= 8'b1111_1110
 + 3'd1led_out ​= 8'b1111_1101
 + 3'd2led_out ​= 8'b1111_1011
 + 3'd3led_out ​= 8'b1111_0111
 + 3'd4led_out ​= 8'b1110_1111
 + 3'd5led_out ​= 8'b1101_1111
 + 3'd6led_out ​= 8'b1011_1111
 + 3'd7led_out ​= 8'b0111_1111
 + default: led_out ​= 8'b1111_1111; 
 + endcase
 end end
 </​code>​ </​code>​
行 75: 行 91:
 ===测试文件=== ===测试文件===
  
-测试文件中我们要生成被测文件输入信号需要激励,我们设计Enable信号每隔200ns(200个时间单位)进行翻转,三路信号输入为每20ns取随机($random)。+测试文件中我们对设计文件参数CNT_NUM进行重新赋
  
 <code verilog> <code verilog>
-reg Enable+parameter CNT_NUM = 10
-reg [2:0] A_in; +Water_led #​(.CNT_NUM(CNT_NUM)) 
-initial +Water_led_uut 
- begin +( 
- Enable = 1'b0; +.clk_in(sys_clk),​ 
- A_in = 3'​b000;​ +.rst_n_in(sys_rst_n),​ 
- end +.led_out(led_out) 
-  +);
-always Enable = #200 ~Enable; +
-always A_in = #20 $random;+
 </​code>​ </​code>​
  
 引脚分配如下: 引脚分配如下:
  
-^ 管脚名称 | EnableA_in[0]| A_in[1] ​ | A_in[2]  ​Y_out[0]  |Y_out[1]  |Y_out[2]  |Y_out[3]  |Y_out[4]  |Y_out[5]  |Y_out[6]  |Y_out[7]  | +^ 管脚名称 | clk_inrst_n_in ​led_out[0]  |led_out[1]  |led_out[2]  |led_out[3]  |led_out[4]  |led_out[5]  |led_out[6]  |led_out[7]  | 
-^ FPGA管脚 | P12M13| M14  | N13  ​|B14  |C14  |E14  |F14  |G14  |J14  |K14  |L14  |+^ FPGA管脚 | C1 A2 |B14  |C14  |E14  |F14  |G14  |J14  |K14  |L14  |
 ====仿真结果==== ====仿真结果====
  
-{{:38译码器仿真.jpg|38译码器仿真}}+{{:流水灯仿真.jpg|流水灯仿真}}
 ====资源报告==== ====资源报告====
  
 ^ 资源 | 数量 ​ | 比例 ​ | 说明 ​ | ^ 资源 | 数量 ​ | 比例 ​ | 说明 ​ |
-^ LUTs |   | 1%   ​| ​  |  +^ LUTs | 27   | 4%   ​| ​  |  
-^ 寄存器 |    ​| ​0% |   |+^ 寄存器 | 28    ​| ​2% |   |
 ^ 存储器 | 0  | 0%   ​| ​   | ^ 存储器 | 0  | 0%   ​| ​   |
-^ IO管脚 ​  ​| ​12 |   ​| ​   |+^ IO管脚 ​  ​| ​10 |   ​| ​   |
 ^ 时钟频率 | 25MHz |   ​| ​   | ^ 时钟频率 | 25MHz |   ​| ​   |
  
 ====知识点==== ====知识点====
  
-  * 组合逻辑+  * 分频设计 
 +  * 时序控制 
 +  * 简单状态机
  
  
 ====参考文档==== ====参考文档====
 +  * [[点亮led灯]]
   * {{:​machxo2familydatasheet.pdf|Lattice MachXO2数据手册}}   * {{:​machxo2familydatasheet.pdf|Lattice MachXO2数据手册}}
 + 
  
 ====相关文档==== ====相关文档====
  
 ^ **文件名称** ​ | **功能** | ^ **文件名称** ​ | **功能** |
-^ **[[Decode38.v]]** | **38译码器** | +^ **[[Water_led.v]]** | **流水灯** | 
-^ **[[Decode38_test.v]]** | **测试文件** |+^ **[[Water_led_test.v]]** | **测试文件** |