搜索
bottom↓
回复: 10

【点滴积累FPGA】例说reg

[复制链接]

出0入0汤圆

发表于 2011-7-11 16:07:58 | 显示全部楼层 |阅读模式
在VERILOG语言里面,几乎每个代码中出现最多的应该是reg这个关键字,如果问reg是什么,很多初学者会很爽快的回答是寄存器,因为书本上就是这么写的。应该再想想有没有别的补充?下面我就用几个例子说明这个回答不完全正确,同时引出多种不同的reg用法:

1,reg生成寄存器:

module my_dff(
input clk,
input d,
output q,
);
reg q;
always @ (posedge clk) q<=d;
endmodule

2,起到wire的作用
module my_and(
input a,
input b,
output c,
);
reg c;
always @*  c<=a&b;
endmodule

3,生成了锁存器

module my_lacth(
input d,
input e,
output q
);
always @* if(e)q=d;
endmodule



简单做做分析:

1,reg生成寄存器 flip-flop 是有条件的,就是在时钟的边缘触发赋值。

2,在电平触发进程中(一个always块 一般叫做一个进程)reg可能被综合成一根线(例子2 my_and)也可能被综合成一个LATCH锁存器,这取决于reg赋值条件是否全部被罗列出,在例子2中,赋值条件被全部罗列出,任何一个条件都对应一个reg的输出,因此只起到一个连线作用;在例子3中,赋值条件没有被全部列出,具体说在e为0的情况下没有输出明确列出,编译器认为在e==0情况下保存原来数据不变化,所以就生成的锁存器。

3,在例子2中,这种使用reg代替wire或是输出的写法很普遍,也很灵活。

4,  在例子3中,我们这里是故意生成的latch锁存器,有时候很多情况下应为条件没有罗列完整而生成了我们不需要的锁存器。如何在编程中避免生成不需要的latch呢,很简单,在电平触发进程中,有一个if 就配合上一个else,有个case 就配合上一个default.这是用一种形式保障内容的不出错。

5,在verilog中reg的生成的是什么,再次回答这个问题,我们有了更多的答案,但是更重要是理解生成时候生成什么。

6,我还总结出一种reg生成RAM块的应用,等专门做介绍。

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出50入0汤圆

发表于 2011-7-11 16:09:28 | 显示全部楼层
等待下文

出0入0汤圆

 楼主| 发表于 2011-7-11 17:37:03 | 显示全部楼层
关于REG生成RAM,先给个例子,以后专门详细论述:

采用reg的形式定义一些寄存器组,之后在代码中FPGA厂家提供的RAM块时序,这样综合器就能知道你是要用一块RAM块,就会分配过来。以下我给出一个模块,是从我的mips处理器内核中提取出来的,是个单口写双口读并且带有冲突检测和前递通路的寄存器组,用来实现MIPS兼容处理器里面的R0-R31寄存器组,每个寄存器是32位,实际生成RAM块。这部分大家随便看看,知道有这么回事,等自己用的时候能考虑到就行了。

module reg_array(
        data,
        wraddress,
        rdaddress_a,
        rdaddress_b,
        wren,
        clock,
        qa,
        qb,
        rd_clk_cls,
    //    bank_sel
    );

    input [31:0]  data;
    input [4:0]  wraddress;
    input [4:0]  rdaddress_a;
    input [4:0]  rdaddress_b;
   // input bank_sel;
    input rd_clk_cls;
    input wren;

    reg [31:0]  r_data;
    reg [4:0]  r_wraddress;
    reg [4:0]  r_rdaddress_a;
    reg [4:0]  r_rdaddress_b;

    reg r_wren;
    input clock;
    output [31:0]  qa;
    output [31:0]  qb;
    reg [31:0]reg_bank[0:31];

    integer i;
    initial
    begin
        for(i=0;i<32;i=i+1)
            reg_bank=0;
    end

    always@(posedge clock)
    begin
        r_data <=data;
        r_wraddress<=wraddress;//这些的时序都是为了迎合ALTERA RAM宏单元的时序。
        r_wren<=wren;
    end

     always@(posedge clock)
        if (~rd_clk_cls)
        begin
            r_rdaddress_a <=rdaddress_a; //这些的时序都是为了迎合ALTERA RAM宏单元的时序。
            r_rdaddress_b <=rdaddress_b;//这些的时序都是为了迎合ALTERA RAM宏单元的时序。

        end

    always@(posedge clock)
        if (r_wren)
            reg_bank[r_wraddress] <= r_data ;

    assign qa=(r_rdaddress_a[4:0]==0)?0:
           ((r_wraddress==r_rdaddress_a)&&(1==r_wren))?r_data:
           reg_bank[r_rdaddress_a];//解决读写冲突

    assign qb=(r_rdaddress_b[4:0]==0)?0:
           ((r_wraddress==r_rdaddress_b)&&(1==r_wren))?r_data:
           reg_bank[r_rdaddress_b];//解决读写冲突

endmodule

出0入0汤圆

发表于 2011-7-11 17:38:33 | 显示全部楼层
嗯。期待后文。

出0入0汤圆

发表于 2011-7-11 23:26:48 | 显示全部楼层
verilog里面reg其实就是一个保存数值的变量

出0入0汤圆

发表于 2011-7-11 23:28:49 | 显示全部楼层
很佩服楼主的学习态度,受教了。谢谢

出0入0汤圆

发表于 2011-7-11 23:47:22 | 显示全部楼层
。谢谢

出0入0汤圆

发表于 2011-7-12 00:10:29 | 显示全部楼层
支持

出0入0汤圆

发表于 2011-7-13 23:52:02 | 显示全部楼层
楼主什么时候能不能把你的这个系列整理好后全部上传上来,很好的东西

出0入0汤圆

发表于 2011-7-14 09:56:22 | 显示全部楼层
楼主的说法不易理解,个人觉得还是按教科书的描述好理解。

出0入0汤圆

发表于 2011-7-14 15:32:07 | 显示全部楼层
reg就是寄存器,其他一切都是 综合器智能化的结果,怕用户乱用,所以没什么好总结的,还不如总结代码风格
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 13:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表