verilog语法进阶,时钟原语

2023-12-17 04:59:26

概述:

内容

1. 时钟缓冲

2. 输入时钟缓冲

3. ODDR2作为输出时钟缓冲

1. 输入时钟缓冲 BUFGP

verilog c代码,clk作为触发器的边沿触发,会自动将clk综合成时钟信号。

module primitive1(
	input clk,
	input a,
	output reg y
    );
always @ (posedge clk)
	y <= a;
	
endmodule

verilog原语代码


module primitive1 (
  clk, a, y
);
  input clk;
  input a;
  output y;
  wire a_IBUF_1;
  wire clk_BUFGP_3;
  wire y_OBUF_5;
  FD   y_1 (
    .C(clk_BUFGP_3),
    .D(a_IBUF_1),
    .Q(y_OBUF_5)
  );
  IBUF   a_IBUF (
    .I(a),
    .O(a_IBUF_1)
  );
  OBUF   y_OBUF (
    .I(y_OBUF_5),
    .O(y)
  );
  BUFGP   clk_BUFGP (
    .I(clk),
    .O(clk_BUFGP_3)
  );
endmodule

时钟信号可以去驱动触发器,时钟信号需要走时钟线路,通过一个BUFGP或者IBUFG进入时钟线路。通过时钟缓冲后,就可以去驱动触发器FD的时钟.C端口了。

RTL结构图,这是一个简单的时钟驱动触发器fd的示例

技术原理图

2. 输入时钟缓冲 IBUFG

原语代码


module primitive1 (
  clk, a, y
);
  input clk;
  input a;
  output y;
  wire a_IBUF_1;
  wire clk_BUFGP_3;
  wire y_OBUF_5;
  FD   y_1 (
    .C(clk_BUFGP_3),
    .D(a_IBUF_1),
    .Q(y_OBUF_5)
  );
  IBUF   a_IBUF (
    .I(a),
    .O(a_IBUF_1)
  );
  OBUF   y_OBUF (
    .I(y_OBUF_5),
    .O(y)
  );
  IBUFG  clk_BUFGP (
    .I(clk),
    .O(clk_BUFGP_3)
  );
endmodule

技术原理图,在输入端口除了可以用BUFGP外,还可以使用IBUFG

3. 输出时钟缓冲 ODDR2

ODDR2的工作原理

代码

module primitive1(
	input clk,
	output clk_o
    );

   ODDR2 #(
      .DDR_ALIGNMENT("NONE"), // Sets output alignment to "NONE", "C0" or "C1" 
      .INIT(1'b0),    // Sets initial state of the Q output to 1'b0 or 1'b1
      .SRTYPE("SYNC") // Specifies "SYNC" or "ASYNC" set/reset
   ) ODDR2_inst (
      .Q(clk_o),   // 1-bit DDR output data
      .C0(clk),   // 1-bit clock input
      .C1(~clk),   // 1-bit clock input
      .CE(1'b1), // 1-bit clock enable input
      .D0(1'b1), // 1-bit data input (associated with C0)
      .D1(1'b0), // 1-bit data input (associated with C1)
      .R(1'b0),   // 1-bit reset input
      .S(1'b0)    // 1-bit set input
   );
 
endmodule

原语代码,使用GND原语产生一个地线,使用VCC原语产生一个电源线,用于绑定固定点位输入端口。ODDR2有两个输入数据端口,两个时钟端口,时钟端口有180度相位差。时钟同时作为选择器输入端口,分别将两个触发器的输出选择输出出去。在输出端口就可以看到双速率输出的数据,这里把双速率输出的数据作为方波时钟使用。


module primitive1 (
  clk, clk_o
);
  input clk;
  output clk_o;
  wire N0;
  wire N1;
  wire ODDR2_inst_not0000;
  wire clk_BUFGP_4;
  wire clk_o_OBUF_6;
  GND   XST_GND (
    .G(N0)
  );
  VCC   XST_VCC (
    .P(N1)
  );
  ODDR2 #(
    .DDR_ALIGNMENT ( "NONE" ),
    .SRTYPE ( "SYNC" ),
    .INIT ( 1'b0 ))
  ODDR2_inst (
    .D0(N1),
    .D1(N0),
    .C0(clk_BUFGP_4),
    .C1(ODDR2_inst_not0000),
    .CE(N1),
    .R(N0),
    .S(N0),
    .Q(clk_o_OBUF_6)
  );
  OBUF   clk_o_OBUF (
    .I(clk_o_OBUF_6),
    .O(clk_o)
  );
  BUFGP   clk_BUFGP (
    .I(clk),
    .O(clk_BUFGP_4)
  );
  INV   ODDR2_inst_not00001_INV_0 (
    .I(clk_BUFGP_4),
    .O(ODDR2_inst_not0000)
  );
endmodule

RTL结构图,使用了一个ODDR2原语模块。

技术原理图

4. 总结

1. 时钟原语包含输入时钟原语与输出时钟原语,其中输出时钟原语使用ODDR2作为输出,官方说这个性能更加优越

2. 时钟用于驱动触发器的时钟,他需要走专门的时钟线,通过时钟缓冲输入到时钟线中。

文章来源:https://blog.csdn.net/q511951451/article/details/135028754
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。