打印
[verilog]

【快乐分享】+Verilog之从流水灯学起

[复制链接]
4121|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wsdymg|  楼主 | 2013-8-11 16:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wsdymg 于 2013-8-11 16:22 编辑

为响应“原创征集第二波——快乐设计大本营”号召,将近期学习Verilog中遇到的问题跟大家分享下:
        本着“天下难事必作于易,天下大事必作于细”的思路指导,开始了我轰轰烈烈的CPLD开发板的学习,最经典的程序莫过于流水灯的程序了,因为以前有一些C语言的基础,想来VERILOG也不是什么难事,可是天不遂人愿,今早整整一天,我被流水灯程序虐的体无完肤啊,真捉急啊,真捉急啊,程序虐我千百遍,我待程序如初恋,不断实践,不断探索,终于皇天不负有心人啊:

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
本来最初的想法很简单,实现的功能无外乎:D4灯狂闪,D1、D2、D3灯实现流水灯的效果。
就是这个简简单单的愿望跟想法,却屡遭罹难,遇到的问题主要有:
1、D4闪烁效果无法实现,一直是暗的;流水灯效果正常。
2、大家看我贴的程序,会看到我注释掉了两条语句,不注释掉的话,流水灯的效果也无法实现,D1灯常亮,D2、D3灯常灭;


、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
实验最初的程序如下:

module mix_module (sys_clk,sys_rstn,led_out);

input sys_clk,sys_rstn;
output led_out;
reg [3:0] led_out;

parameter T48M=26'd48_000_000;
reg [25:0] Count;
reg[1:0] i;
reg led;

always@(posedge sys_clk or negedge sys_rstn)
begin
    if(!sys_rstn)
        Count<=26'b0;
    else
        if(Count==T48M)
            Count<=26'b0;
        else
            Count<=Count+1'b1;
end

always@(posedge sys_clk or negedge sys_rstn)
begin
    if(!sys_rstn)
        i<=2'b00;
    else
        begin
            if(Count==T48M)
                i<=i+1'b1;
            else
                i<=i;
            if(i==2'b11)
                i<=2'b00;
            //else
                //i<=i;
        end
end

always@(i)
begin
    led=~led;
    if(i==2'b00)
        led_out={led,3'b110};
    else if(i==2'b01)
        led_out={led,3'b101};
    else
        led_out={led,3'b011};
end   
endmodule

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
后来经过想网友@6-shark1234567,@KDY的请教跟学习,终于解决了问题:
修改后的程序如下:
版本一:
module mix_module (sys_clk,sys_rstn,led_out);

input sys_clk,sys_rstn;
output led_out;
reg [3:0] led_out;

parameter T48M=27'd48000_000;
reg [26:0] Count;
reg[1:0] i;
reg led;
initial led = 1'b1;

always@(posedge sys_clk or negedge sys_rstn)
begin
    if(!sys_rstn)
        Count<=27'b0;
    else
        if(Count==T48M)
            Count<=27'b0;
        else
            Count<=Count+1'b1;
end

always@(posedge sys_clk or negedge sys_rstn)
begin
    if(!sys_rstn)
        i<=2'b00;
    else
        begin
            if(Count==T48M)
                i<=i+1'b1;
            else
                i<=i;
            if(i==2'b11)
                i<=2'b00;
        end
end

always@(posedge sys_clk)
begin
if(Count==T48M)
    led=~led;
    if(i==2'b00)
        led_out={led,3'b110};
    else if(i==2'b01)
        led_out={led,3'b101};
    else
        led_out={led,3'b011};
end   
endmodule
版本二:
module mix_moduile (sys_clk,sys_rstn,led_out);

input sys_clk,sys_rstn;
output led_out;
reg [3:0] led_out;

parameter T48M=26'd48_000_000;
reg [25:0] Count;
reg[1:0] i;
reg led=1;

always@(posedge sys_clk or negedge sys_rstn)
        if(!sys_rstn)
                Count<=26'b0;
        else
                if(Count==T48M)
                    Count<=26'b0;
                else
                    Count<=Count+1'b1;


always@(posedge sys_clk or negedge sys_rstn)
if(!sys_rstn)
  led_out<=4'b0110;
else
if(Count==T48M)
begin
  led_out[3]<=~led_out[3];
  led_out[2:0]<={led_out[1],led_out[0],led_out[2]};
end

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
以上两个程序都很好的解决了我的问题,版本一来自于@KDY,版本二来自于@6-shark1234567,与我的程序相比,两位老师的程序都很好的采用了,同
步时序电路,而我采用的是always(i)异步触发的方式,虽然经过仿真的测试,时序图正确,但经过综合后却总是出错,所以在此向跟我一样,处在学习FPGA初级阶段的各位提个建议,那就是少用always()的异步电路,往往综合器比较坑!

在此将 KDY给我的建议列在下面,愿大家共同学习,共同进步!



相关帖子

沙发
shj23| | 2013-8-21 22:26 | 只看该作者

学习了,多谢分享,就像C语言的Hello World,以此入门了。

使用特权

评论回复
板凳
net_wolf| | 2013-8-22 12:59 | 只看该作者
多谢分享!

使用特权

评论回复
地板
dong_abc| | 2013-8-26 01:00 | 只看该作者
不懂,随便看看。

使用特权

评论回复
5
hero2009nj| | 2013-10-10 15:26 | 只看该作者
谢谢分享。

使用特权

评论回复
6
zloong| | 2013-11-12 22:15 | 只看该作者

使用特权

评论回复
7
Chaos_zc| | 2013-12-25 15:36 | 只看该作者
mark!!

使用特权

评论回复
8
lizhezhe1988| | 2013-12-30 16:42 | 只看该作者
感觉你在用学习单片机的方式去学习FPGA,个人感觉有点问题:FPGA设计是一种并行的设计思想,单片机呢,是一种顺序的设计思想。在你的程序中看到的还是一种顺序的编程思想,个人感觉进入了一个误区。

使用特权

评论回复
9
歼飞2012| | 2014-1-5 21:06 | 只看该作者
lizhezhe1988 发表于 2013-12-30 16:42
感觉你在用学习单片机的方式去学习FPGA,个人感觉有点问题:FPGA设计是一种并行的设计思想,单片机呢,是一 ...

并行的思想 ?何解

使用特权

评论回复
10
lizhezhe1988| | 2014-1-6 19:06 | 只看该作者
歼飞2012 发表于 2014-1-5 21:06
并行的思想 ?何解

其实就是将每个灯看做单独的一部分去控制,T1内第一个灯亮,T2内第二个灯亮,T3内第三个灯亮,T4内第四个灯亮。每个灯都能按照一条时钟线去跑,这样就并行了。你这样写呢,其实是四个灯的按照一个时钟线跑。试想这样一个问题你怎么解决:第一个灯以2hz的频率闪烁,第二个灯实现5hz的频率闪烁,第三个灯实现2hz和5hz交替闪烁,第四个灯实现从亮逐渐变暗,再由暗逐渐变亮。想想这样一个问题你怎么解决?如果再用你这种方法,应该比较困难。

使用特权

评论回复
11
king成1126| | 2014-11-3 22:10 | 只看该作者

使用特权

评论回复
12
liuchengan| | 2014-11-7 12:36 | 只看该作者
学习学习

使用特权

评论回复
13
zppzq| | 2014-12-2 15:49 | 只看该作者
学习学习

使用特权

评论回复
14
xianrentiao2015| | 2015-8-12 15:46 | 只看该作者
受益了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

267

帖子

6

粉丝