mcupro 发表于 2011-7-11 16:07:58

【点滴积累FPGA】例说reg

在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块的应用,等专门做介绍。

yuzr 发表于 2011-7-11 16:09:28

等待下文

mcupro 发表于 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 data;
    input wraddress;
    input rdaddress_a;
    input rdaddress_b;
   // input bank_sel;
    input rd_clk_cls;
    input wren;

    reg r_data;
    reg r_wraddress;
    reg r_rdaddress_a;
    reg r_rdaddress_b;

    reg r_wren;
    input clock;
    output qa;
    output qb;
    reg reg_bank;

    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_data ;

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

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

endmodule

yuphone 发表于 2011-7-11 17:38:33

嗯。期待后文。

chenming1989 发表于 2011-7-11 23:26:48

verilog里面reg其实就是一个保存数值的变量

chenming1989 发表于 2011-7-11 23:28:49

很佩服楼主的学习态度,受教了。谢谢

ababvic 发表于 2011-7-11 23:47:22

。谢谢

qwerttt 发表于 2011-7-12 00:10:29

支持

txl843227021 发表于 2011-7-13 23:52:02

楼主什么时候能不能把你的这个系列整理好后全部上传上来,很好的东西

wd8031 发表于 2011-7-14 09:56:22

楼主的说法不易理解,个人觉得还是按教科书的描述好理解。

cwfboy 发表于 2011-7-14 15:32:07

reg就是寄存器,其他一切都是 综合器智能化的结果,怕用户乱用,所以没什么好总结的,还不如总结代码风格
页: [1]
查看完整版本: 【点滴积累FPGA】例说reg