一、LED流水灯实现
1. 基本要求
- 用状态机思想写一个 LED流水灯的FPGA代码
- 写出仿真测试代码,用Modelsim进行仿真分析
- DE2-115板上验证
2. 状态机思想
用状态机思想的话,流水灯通常可以用几个状态来表示不同的LED亮的位置。
比如,每个状态对应一个LED亮,然后通过状态转移来实现流动的效果。由于我们流水灯是8个灯亮,所以对应8个状态。
所以,状态机的状态定义可能如下:
状态S0: LED[0]亮
状态S1: LED[1]亮
…
状态S7: LED[7]亮
流水灯就是一个状态连续一段时间再进入下一个状态。
3. 关键代码
- // File: led_flow.v
- module led_flow(
- input clk, // 50MHz时钟 (DE2-115 PIN_Y2)
- input rst_n, // 复位信号 (低电平有效)
- output reg [7:0] led// LED输出 (DE2-115 LEDG7-LEDG0)
- );
- // 状态定义
- localparam S0 = 3'b000; // 初始状态:LED0亮
- localparam S1 = 3'b001;
- localparam S2 = 3'b010;
- localparam S3 = 3'b011;
- localparam S4 = 3'b100;
- localparam S5 = 3'b101;
- localparam S6 = 3'b110;
- localparam S7 = 3'b111;
- // 内部信号
- reg [2:0] state; // 当前状态
- reg [24:0] cnt; // 分频计数器
- wire en; // 状态切换使能(0.5Hz)
- // 0.5Hz分频(0.5秒切换)
- assign en = (cnt == 25'd24_999_999); // 50MHz/(25M+1) ≈ 0.5Hz
- // 分频计数器
- always @(posedge clk or negedge rst_n) begin
- if(!rst_n) cnt <= 0;
- else if(en) cnt <= 0;
- else cnt <= cnt + 1;
- end
- // 状态机主逻辑
- always @(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- state <= S0;
- led <= 8'b0000_0001; // 初始状态
- end
- else if(en) begin
- case(state)
- S0: begin led <= 8'b0000_0010; state <= S1; end
- S1: begin led <= 8'b0000_0100; state <= S2; end
- S2: begin led <= 8'b0000_1000; state <= S3; end
- S3: begin led <= 8'b0001_0000; state <= S4; end
- S4: begin led <= 8'b0010_0000; state <= S5; end
- S5: begin led <= 8'b0100_0000; state <= S6; end
- S6: begin led <= 8'b1000_0000; state <= S7; end
- S7: begin led <= 8'b0000_0001; state <= S0; end
- default: state <= S0;
- endcase
- end
- end
- endmodule
复制代码 4. 仿真测试
写完代码后,参考毗连博客进行仿真。
Quartus使用步调及联合Modelsim仿真教程-
知安的小白
操纵步调这篇博客讲的很清楚了,一同操纵后的效果截图如下
仿真代码(tb_led_flow.v)
- // File: tb_led_flow.v
- `timescale 1ns/1ps
- module tb_led_flow();
- reg clk;
- reg rst_n;
- wire [7:0] led;
- // 实例化被测模块
- led_flow uut(
- .clk(clk),
- .rst_n(rst_n),
- .led(led)
- );
- // 生成50MHz时钟
- initial begin
- clk = 0;
- forever #10 clk = ~clk; // 20ns周期=50MHz
- end
- // 测试激励
- initial begin
- // 初始化
- rst_n = 0;
- #100;
- rst_n = 1;
-
- // 观察10个状态周期
- #100000000; // 仿真10ms(实际应仿真更长时间)
- $stop;
- end
- endmodule
复制代码 下面是仿真波形:
5. 效果演示
[FPGA]状态机思想回顾流水灯演示效果
二、CPLD和FPGA
1. 技术区别
特性特性FPGA布局乘积项逻辑查找表(LUT)布局逻辑容量通常<10万门可达数百万逻辑单位布线布局固定互联可编程互联时序特性确定延迟布线依赖延迟存储资源有限包罗专用Block RAM配置方式非易失,上电即用通常需要外部配置芯片功耗低静态功耗高动态功耗适用场景胶合逻辑、状态机复杂算法、并行处理 2. 应用场景
- CPLD典型应用:
接口协议转换(UART、SPI)
简单状态机控制
地址译码电路
上电时序管理
- FPGA典型应用:
数字信号处理(FIR滤波器)
高速接口(PCIe、DDR)
图像处理流水线
协议加速(TCP/IP Offload)
三、HDLbits组合逻辑题目
HDLbits问题集(Verilog)精选题目及解答
题目1:Exams/m2014 q4g
- module top_module (
- input in1,
- input in2,
- input in3,
- output out);
- assign out = (~(in1^in2)^in3);
- endmodule
复制代码 题目2:Gates
Module Declaration
module top_module(
input a, b,
output out_and,
output out_or,
output out_xor,
output out_nand,
output out_nor,
output out_xnor,
output out_anotb
);
大概意思就是写个逻辑语句实现名称。
- module top_module(
- input a, b,
- output out_and,
- output out_or,
- output out_xor,
- output out_nand,
- output out_nor,
- output out_xnor,
- output out_anotb
- );
- assign out_and=a&b;
- assign out_or=a|b;
- assign out_xor=a^b;
- assign out_nand=~(a&b);
- assign out_nor=~(a|b);
- assign out_xnor=~(a^b);
- assign out_anotb=a&(~b);
- endmodule
复制代码 题目3:Arithmetic Circuits–Adder(加法器设计)
- module top_module (
- input [3:0] x,
- input [3:0] y,
- output [4:0] sum);
- assign sum = x + y;
- endmodule
复制代码 题目4:7420
74LS20芯片内部逻辑电路如下,由两个nand(与非门)组成。需要写个语句实现7420功能。
- module top_module (
- input p1a, p1b, p1c, p1d,
- output p1y,
- input p2a, p2b, p2c, p2d,
- output p2y );
- assign p1y=~(p1a&p1b&p1c&p1d);
- assign p2y=~(p2a&p2b&p2c&p2d);
- endmodule
复制代码 题目5:Truthtable1
按真值表实现电路。
如果数电学的不好不知道怎么办的话,可以用logisim,点击Project->Analyze Circuit->Table:
再点击Build Circuit就生成电路图了。
- module top_module(
- input x3,
- input x2,
- input x1, // three inputs
- output f // one output
- );
- assign f=((~x3)&x2)|(x1&x3);
- endmodule
复制代码 四、实验总结
本次实验把握了状态机编程思想,究竟上,状态机思想也更浅易更轻易想到。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |