在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 7962|回复: 23

[讨论] verilog语法中的for循环的应用

[复制链接]
发表于 2011-8-16 14:53:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
`timescale 10ns/10ns
module data_conv(clk,dat,units,tens,hundreds,thousands);

        input  clk;
        input[13:0] dat; //二进制输入数据
        output[3:0] units;
        output[3:0] tens;
        output[3:0] hundreds;
        output[3:0]        thousands;
       
        reg[3:0]  units_r,tens_r,hundreds_r,thousands_r;   //BCD数据输出寄存器
        reg[13:0] dat_r;
        reg[15:0] temp; //中间寄存器

                                integer i;
        assign units =  units_r;
        assign tens =  tens_r;
        assign hundreds = hundreds_r;
                                assign thousands = thousands_r;
                initial temp=16'b0;                //这个地方是该写在for里面还是外面???

        always @(posedge clk)
        begin
              dat_r = dat;
              for(i = 0;i < 15;i = i + 1) //循环15次,注意不是15次,因为第15次不需要修正
              begin
       
                     temp = {temp[14:0],dat_r[13]}; //左移一位
                     
                     if(temp[3:0] > 4'd4) //大于4,加三
                            temp[3:0] = temp[3:0]+4'd3;
                     if(temp[7:4] > 4'd4) //大于4,加三
                            temp[7:4] = temp[7:4]+4'd3;
                     if(temp[11:8] > 4'd4) //大于4,加三
                            temp[11:8] = temp[11:8]+4'd3;                 
                     if(temp[15:12] > 4'd4) //大于4,加三         
                                                     temp[15:12] = temp[15:12]+4'd3;
       
                     dat_r=dat_r<<1;  //最高变为原来dat_r的第14位
                     {thousands_r,hundreds_r,tens_r,units_r}={temp[14:0],dat[0]};//最后一次(第16次)不用修正
               end
        end


endmodule



这是一个二进制数转十进制BCD码的代码,我想实现0~9999的二进制数转换成BCD码,输入是14位的(输出肯定是16位),然后我随便给dat附了几个值,仿真了一下,但是出得结果不正确啊,难道是for语句出了问题,但是实在看不出来呢,还请高手们给以作答,谢谢。
加注:         initial temp=16'b0;如上红题字该写在for里面还是外面啊,结果好像也不一样啊,但是我感觉应该写在外面呢,可是结果更不对了,每当上升沿的时候个十百千四个数就发生变化了
发表于 2011-8-16 15:46:36 | 显示全部楼层
应该在FOR里面,如果你写外面,综合也许会出问题吧?
我见过VHDL语法里类似的初始赋值,然后再FOR运算,初始赋值包含在句子里面。
发表于 2011-8-16 18:44:01 | 显示全部楼层
没有格式看着有点累
 楼主| 发表于 2011-8-16 19:42:46 | 显示全部楼层
回复 2# eaglelsb



   写在里面是怎么理解啊,感觉写在外面才是赋初值啊,写在里面,难道每来一个上升沿都赋值吗??
我仿真了,写在外面的话结果肯定不对,不是太明白。即使是写在外面的话代码仿真出来的结果也不是正确的,不知什么原因呢??求解释。。
 楼主| 发表于 2011-8-16 19:44:31 | 显示全部楼层
回复 3# boy8585
没明白您的意思呢,什么格式啊
发表于 2011-8-17 01:00:42 | 显示全部楼层
回复 1# xiangeryong333


    是不是我没看懂。
你写的组合逻辑反馈,当然错啦。

                               
登录/注册后可看大图
       

                               
登录/注册后可看大图
       

                               
登录/注册后可看大图
 楼主| 发表于 2011-8-17 08:37:57 | 显示全部楼层
组合逻辑反馈?不是吧,这个模块的功能是实现14位二进制数转十进制BCD码0~9999,用了一个移位加3的算法,算法描述如下: 以8位二进制转换为3位BCD码为例,转换步骤是:将待转换的二进制码从最高位开始左移BCD的寄存器(从高位到低位排列),每移一次,检查每一位BCD码是否大于4,是则加上3,否则不变。左移8次后,即完成了转换。需要注意的是第八次移位后不需要检查是否大于5。我用了一个for语句进行移位,但是不知道为什么,逻辑上有错误,结果不正确。
发表于 2011-8-17 09:18:02 | 显示全部楼层
错得一塌糊涂,还是先看看课本吧。
发表于 2011-8-17 13:13:14 | 显示全部楼层
首先initial是不可综合的,这个解释了2楼为什么要让你现在always里面,最好是提供一个复位信号来做赋初值的操作,不要用initial,这个一般只用于仿真。另外内部这个for循环更多偏向于软件设计的思想,不知道你的仿真环境是基于源代码还是综合后的网表。
    我大概看了看,感觉倒是你最后一次的处理,不应该放到循环里面,应该是15次循环完成以后得到一个temp去和dat[0]进行拼接也许就是你要的结果了吧,不过这里似乎也没问题,反正你都是要最后一次的结果。就是这么写法完全都是软件设计的思想,看得人头疼。呵呵。
 楼主| 发表于 2011-8-17 13:40:37 | 显示全部楼层
回复 9# gaurson


呵呵,谢谢前辈指导啊
我这个代码就是先进行的仿真的,所以加了initial赋值,这样的话,只进行仿真该是放到里面外面啊?还有最后一行,如果每一次都执行一次的话没有逻辑上的错误吧?我是刚刚学习verilog语言,硬件设计思想还没有渗入,呵呵,让您见笑了,谢谢您的指导
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-13 04:16 , Processed in 0.027982 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表