1.Abstract

    前几天做了一个呼吸灯,觉得确实挺有意思的;可惜的是只有一个灯管亮,板子上有四个灯,要是能让这些灯有序地亮起来,那应该更有趣味了!跟传统的一样,逻辑上做成一个流水灯的样式,这种带有PWM调光的吸引样式,真可谓是超级流水灯了。

    做这个是在已做好的呼吸灯的基础上进行添加功能的,整理好了也在随笔里边,这里就直接引用出来。

    基于Verilog的PWM呼吸灯:http://www.cnblogs.com/hechengfei/p/4106538.html

2.Content

  2.1 总体设计

    PWM的原理在呼吸灯的那部分已经整理好了,这里就省去了原理分析一部分了,把做好的作为底层的一个小模块,主要关注顶层逻辑的设计了。

    要使灯顺序的流水起来,自然是一个时序逻辑,最佳的方法就是采用状态机,预先将各个状态分配好,然后让各个状态有序地切换,时序逻辑就清晰得被表达出来。板子上有4个灯,依次流水过去然后再回来,然后循环这样的逻辑;用图表示或许直观些。

FIG2.1 总体逻辑

    在途中,蓝色线表示向右流水,红色线表示向左流水。一次完整的流水执行下来,如绿色箭头指示;首先是LED0表演,完毕后,转至LED1表演,完毕后,再转至LED2表演,依次下去,直至回到LED0表演。

    根据上述的逻辑,将所有的逻辑状态分配出来;将总体逻辑平铺开,去掉多余的状态,就有8-2 = 6个状态(首尾的两个状态各重了一次)。分别用S0到S7八个状态表示(多余的两个状态直接转到S0),用状态表来说明一下。

表2.1 总体状态转换表

当前状态

转换条件

下一状态

S0

!RST 或者 !END0

S0

S0

RST&END0

S1

S1

!RST

S0

S1

RST & (!END1)

S1

S1

RST & END1

S2

S2

!RST

S0

S2

RST & (!END2)

S2

S2

RST & END2

S3

S3

!RST

S0

S3

RST & (!END3)

S3

S3

RST & END3

S4

S4

!RST

S0

S4

RST & (!END2)

S4

S4

RST & END2

S5

S5

!RST | END1

S0

S5

RST & (!END1)

S5

S6

*(Unconditional)

S0

S7

*(Unconditional)

S0

    用状态装换图表示可能更直观一些。

FIG2.2 总体状态转换图

    图中,绿色部分表示正常状态转换,红色部分表示控制信号强制转换。用状态转换图的方法虽然画得比较复杂,线比较多,但更容易理解和便于编写状态机。

    完成信号END的产生。在PWM呼吸灯中,它也是一个状态转换的实例,END信号的产生是由内部寄存器存储和操作的,用作子模块以后,最后的状态应该作为端口输出出来,以便顶层模块检测和顶层状态切换处理。顾只需要在原来的模块中添加一个END信号,在PWM一个周期输出完成以后,将此信号输出出来。

  2.2 顶层整合

    顶层的整合就是将所有模块连接起来,既可以采用Block块的方式,也可以用文本的方式。顶层块连接了控制模块和子状态控制块模块,各自逻辑描述如下。

    顶层块的描述:

module breath(LED,CLK,RST);
output [3:0] LED; input CLK;
input RST; wire S_END0;
wire S_END1;
wire S_END2;
wire S_END3; wire RST_LED0;
wire RST_LED1;
wire RST_LED2;
wire RST_LED3; breath_state M0 (.RST_LED0(RST_LED0), .RST_LED1(RST_LED1), .RST_LED2(RST_LED2), .RST_LED3(RST_LED3),
.S_END0(S_END0), .S_END1(S_END1), .S_END2(S_END2), .S_END3(S_END3),
.CLK(CLK), .RST(RST)); breath_led M1 (.LED(LED[0]), .S_END(S_END0), .CLK(CLK), .RST(RST_LED0));
breath_led M2 (.LED(LED[1]), .S_END(S_END1), .CLK(CLK), .RST(RST_LED1));
breath_led M3 (.LED(LED[2]), .S_END(S_END2), .CLK(CLK), .RST(RST_LED2));
breath_led M4 (.LED(LED[3]), .S_END(S_END3), .CLK(CLK), .RST(RST_LED3)); endmodule

    状态控制块的描述:

module breath_state(RST_LED0, RST_LED1, RST_LED2, RST_LED3,
S_END0, S_END1, S_END2, S_END3,
CLK,RST); input S_END0;
input S_END1;
input S_END2;
input S_END3; output reg RST_LED0 = 1'b0;
output reg RST_LED1 = 1'b0;
output reg RST_LED2 = 1'b0;
output reg RST_LED3 = 1'b0; input CLK;
input RST; parameter S0 = 3'd0,
S1 = 3'd1,
S2 = 3'd2,
S3 = 3'd3,
S4 = 3'd4,
S5 = 3'd5,
S6 = 3'd6,
S7 = 3'd7; reg [2:0] state = 3'd0; always @(posedge CLK)
begin
if(!RST)
begin
state = S0; RST_LED0 = 1'b0; //熄灭所有灯
RST_LED1 = 1'b0;
RST_LED2 = 1'b0;
RST_LED3 = 1'b0;
end
else
begin
case(state)
S0: begin
if(S_END0) begin state <= S1; end
else begin
RST_LED0 <= 1'b1; // 仅LED0表演
RST_LED1 <= 1'b0;
RST_LED2 <= 1'b0;
RST_LED3 <= 1'b0;
end
end
S1: begin
if(S_END1) begin state <= S2; end
else begin
RST_LED0 <= 1'b0;
RST_LED1 <= 1'b1; // 仅LED1表演
RST_LED2 <= 1'b0;
RST_LED3 <= 1'b0;
end
end
S2: begin
if(S_END2) begin state <= S3; end
else begin
RST_LED0 <= 1'b0;
RST_LED1 <= 1'b0;
RST_LED2 <= 1'b1; // 仅LED2表演
RST_LED3 <= 1'b0;
end
end
S3: begin
if(S_END3) begin state <= S4; end
else begin
RST_LED0 <= 1'b0;
RST_LED1 <= 1'b0;
RST_LED2 <= 1'b0;
RST_LED3 <= 1'b1; // 仅LED3表演
end
end
S4: begin
if(S_END2) begin state <= S5; end
else begin
RST_LED0 <= 1'b0;
RST_LED1 <= 1'b0;
RST_LED2 <= 1'b1; // 仅LED2表演
RST_LED3 <= 1'b0;
end
end
S5: begin
if(S_END1) begin state <= S0; end
else begin
RST_LED0 <= 1'b0;
RST_LED1 <= 1'b1; // 仅LED1表演
RST_LED2 <= 1'b0;
RST_LED3 <= 1'b0;
end
end
S6: begin
state <= S0; // 多余状态,无条件返回
end
S7: begin
state <= S0; // 多余状态,无条件返回
end
endcase
end end endmodule

  2.3 逻辑验证

    整理好各个模块以后,编译一下,看看生成出来的逻辑。

FIG2.3综合后的RTL视图网表

    顶层只做连接各个模块,那么在RTL视图中就是几个绿色的小方块儿表示了;排列的还是非常整齐的,对照连线,确定一下所有的线连接是正确的。再就是检查一下状态转换图。

FIG2.4 综合后的状态机视图

    对照视图下边的状态转换表,选中某根连线就可以在表格中直接高亮显示转换的初始状态,转换条件,下一状态等丰富信息。因为生成的状态机和预期的是一样的,所以就不再验证它的正确性了;配置好芯片引脚,将编程文件下载到实际电路板中,看看效果。

    因为博客中不能插入视频,所以将拍好的视频上传到专门的视频网站,生成一个链接,点击进去就可以观看了,也非常方便。

    实际效果:http://v.youku.com/v_show/id_XODMxOTY0MzQ0.html

3.Conclusion

    对于时序逻辑,采用状态机的方法至关重要!逻辑的设计需要非常清晰,对于状态机的设计,可以先画出状态转换图,然后再进行编写文件;对于逻辑还不清晰的地方,需要认真在草稿纸上画画。

    关于编码的规范;对逻辑设计我也是刚刚起步,才学不到一年,更加关注的是逻辑综合后电路的正确性,所以没有对编码进行统一的规范;这方面我也会多多去学习,尽量将文件写的好一点,通用一点。

    写一点感受。逻辑设计和编写程序确实有很大的差别,也是各有所长吧;逻辑电路从大的范围来讲,分为组合逻辑和时序逻辑,有各自实现的方式,对于一个要求实现的逻辑,首先要做的就是把它完全分析清楚,将它们的波形都给画出来,然后再考虑哪部分使用组合逻辑,哪部分使用时序逻辑,最后就是将这些小块块连接起来做整合,设计采用的是自顶向下,而实现的方法可以是自下而上。相对逻辑设计,编程就显得不那么精准了,但是灵活性很高,特别适合做复杂的事情,而且总体看来它就是一个时序的,写好的指令是一步步往下走的,对硬件的理解要求不会太高,从而将注意力转移到如何实现上来。我觉得没有必要将它们严格的区分开来,也没有必要将它们混为一谈来对待,它们各自有优缺点,使用的时候只是转变一下逻辑而已。

4.Reference

[1] Verilog 数字系统设计教程(第二版) 夏宇闻

[2] Verilog HDL 高级数字设计(第二版) Michael D.Ciletti

5. Platform

1).Quartus II Version 9.1 Build 222

2).Microsoft Office Visio Professional 2003 SP3

6.Attachment

工程附录文件:http://i.cnblogs.com/Files.aspx

(原创)基于FPGA的调光流水灯(Verilog,CPLD/FPGA)的更多相关文章

  1. (原创)基于MCU的频率可调,占空比可调的PWM实现(MCU,MCS-51/MSP430)

    1.Abstract     做这个是受朋友之邀,用在控制电机转动的方面.他刚好在一家好的单位实习,手头工作比较多,无暇分身,所以找我帮忙做个模型.要求很明晰,PWM的频率在0~1KHz范围内,占空比 ...

  2. 基于MATLAB2016b图形化设计自动生成Verilog语言的积分模块及其应用

    在电力电子变流器设备中,常常需要计算发电量,由于电力电子变流器设备一般是高频变流设备,所以发电量的计算几乎时实时功率的积分,此时就会用到一个积分模块.发电量计算的公式如下:Q=∫P. FPGA由于其并 ...

  3. cpld fpga 区别

    cpld fpga 区别 系统的比较,与大家共享: 尽管FPGA和CPLD都是可编程ASIC器件,有很多共同特点,但由于CPLD和FPGA结构上的差异,具有各自的特点: ①CPLD更适合完成各种算法和 ...

  4. 《FPGA全程进阶---实战演练》第一章之FPGA介绍

    1 什么是FPGA FPGA也即是Field Programmable Gate Array的缩写,翻译成中文就是现场可编程门阵列.FPGA是在PAL.GAL.CPLD等可编程器件的基础上发展起来的新 ...

  5. FPGA的EPCS 配置的2种方法 FPGA下载程序的方法(EPCS)

    使用主动串行配置模式对Cyclone FPGA进行配置前,必须将配置文件写入串行配置器件EPCS.将配置文件写入EPCS的方法有三种: (1)在Quartus II的Programmer中,通过专门与 ...

  6. FPGA中改善时序性能的方法_advanced FPGA design

    本文内容摘自<advanced FPGA design>对应中文版是 <高级FPGA设计,结构,实现,和优化>第一章中的内容 FPGA中改善时序,我相信也是大家最关心的话题之一 ...

  7. CPLD/FPGA厂商概述 .

    随着可编程逻辑器件应用的日益广泛,许多IC制造厂家涉足PLD/FPGA领域.目前世界上有十几家生产CPLD/FPGA的公司,最大的三家是:ALTERA,XILINX,Lattice,其中ALTERA和 ...

  8. (原创)用Verilog实现一个参数化的呼吸灯(Verilog,CPLD/FPGA)

    1.Abstract     观察到一个有趣的现象,每当把Apple笔记本合上的时候,那个白色的呼吸灯就会反复地由暗渐明,然后又由明渐暗,乍一看就像Apple笔记本在打盹休息一样,十分可爱!于是突发奇 ...

  9. (原创)defparam的应用(Verilog,CPLD/FPGA)

    1.Abstract     在同一个模块被多次例化的时候,改变参数构建不同的硬件实体是一个很好的选择.特别是今天帮一个朋友调试一个比较复杂的逻辑,深有体会.这个也是一个小技巧,回来也查了许多资料,强 ...

随机推荐

  1. 【转载】Fast Inserts to PostgreSQL with JDBC and COPY FROM

    source: http://rostislav-matl.blogspot.com/2011/08/fast-inserts-to-postgresql-with-jdbc.html Thanks ...

  2. maven仓库有jar包,还是找不到类

    开始,网上的所有方法都没用. 我用的eclipse-32位的,jdk也是.然后今天换了个sts和jdk.64位的.然后就没有那个问题了.

  3. ftp服务器远程拷贝命令

    xiamense@xiamense-testserver:~$ ftp 218.5.82.40 输入账户密码 get 远程文件路径 本机服务器路径get pa20160927.xml /home/xi ...

  4. zookeeper节点失效重连机制

    http://www.blogjava.net/xylz/archive/2011/12/05/365578.html http://blog.csdn.net/tswisdom/article/de ...

  5. XidianOJ 1120 Gold of Orz Pandas

    题目描述 Orz Panda is addicted to one RPG game. To make his character stronger, he have to fulfil tasks ...

  6. app.js ejs 转换为html

    var express = require('express');var path = require('path');var favicon = require('serve-favicon');v ...

  7. 8.9 CSS知识点2

    4.关系选择符 包含选择符(Descendant combinator) E F  选择所有被E元素包含的F元素 <style type="text/css"> h1 ...

  8. JQuery中ajax请求写法

    $.ajax({ type: "POST", url: "ygdwController.do?getonygdw", data : "id=" ...

  9. HDU 2222 Keywords Search(AC自动机入门)

    题意:给出若干个单词和一段文本,问有多少个单词出现在其中.如果两个单词是相同的,得算两个单词的贡献. 分析:直接就是AC自动机的模板了. 具体见代码: #include <stdio.h> ...

  10. 三天没有写题了,罪过!--Hash Table Start

    (1)Island Perimeter 解题思路: 在矩阵上循环并记录岛(1)的个数;如果当前节点是岛,则检查其是否具有任何右邻居或下邻居,有的话邻居计数加1 ;岛的周长结果为islands * 4 ...