FPGA时钟篇(三) MRCC和SRCC的区别

我们前面的两篇文章讲了7系列的时钟结构和clock region内部具体组成,这篇文章我们来讨论下MRCC和SRCC的区别。只有7系列的FPGA中才有MRCC和SRCC的说法,到了UltraScale系列,都是叫GC。

  看了上一篇文章的同学应该清楚MRCC就是Multi Region的CC,从该管脚输入的时钟可以access到不同的clock region,而SRCC就是Single Region的CC,从该管脚输入的时钟只能access当前clock region。

  所以有同学就会觉得,如果想使用全局时钟,就必须将时钟接到MRCC,而不能是SRCC。但这种理解是错误的,下面我们会详细解释。

  手册中对MRCC驱动多个clock region的说明如下:

MRCCs can access multiple clock regions and the global clock tree. MRCCs function the  same as SRCCs and can additionally drive multi-clock region buffers (BUFMR) to access  up to three clock regions

MRCC通过BUFMR来access最多三个clock region,从下面的图也可以看出,已经用红色的线将MRCC的路径都标出来,可以看到,MRCC通过了BUFMR到达了CMT Backbone(如果对CMT Backbone不理解,可以看前面两篇文章),然后就可以access其他的clock region了。

image-20220407215828708

从上面这个图可以看出,MRCC可以直接驱动BUFR和BUFIO,也可以先经过BUFMR后再驱动BUFIO和BUFR。

SRCC的路径在下面的图中用红色的线标识出来,可看到,它的路径只在当前的clock region里面。

image-20220407215904803

An MRCC pin pair can drive a specific  BUFMR, which in turn can drive BUFIOs and BUFRs in the same and adjacent regions  facilitating multi-region/bank interfaces. Similarly, a GT quad can also drive the BUFMRs

下面这个表格解释的就更加清晰了,MRCC和SRCC都是由外部的时钟驱动,而且MRCC和SRCC的区别就在于MRCC可以驱动BUFMR,SRCC不行。其他基本都一样,它们都可以驱动四个BUFIO、四个BUFR、一个CMT、上下相邻的CMT、16个BUFG和BUFH。

其中有一点很关键,就是它们都可以驱动BUFG和BUFH,这就意味着,从MRCC和SRCC进来的时钟都可以access全局时钟树,也就都可以当做全局时钟。

Clock-capable inputs are organized as 2 MRCC and 2 SRCC pairs in each I/O bank. SRCCs  access a single clock region and the global clock tree, as well as other CMTs above and  below in the same column. SRCCs can drive: 
    • Regional clocks lines (BUFR, BUFH, BUFIO) within the same clock region 
    • CMTs in the same clock region and adjacent clock regions. 
    • Global clocks lines (BUFG) in the same top/bottom half of the device.

MRCCs can access multiple clock regions and the global clock tree. MRCCs function the  same as SRCCs and can additionally drive multi-clock region buffers (BUFMR) to access  up to three clock regions.

所以,SRCC进来的时钟,虽然不能直接驱动其他clock region,但接到BUFG上之后,仍然可以通过BUFG来驱动其他的clock region。

最后我们多提一点,在手册中一些表达可能对于很多同学不好理解。比如上面那张表里描述的:

MRCCs that are located in the same clock region and on the same left/right side of the device drive:

字面意思很好理解,也没有什么生僻单词。同一个clock region里的MRCC可以驱动下面那些模块,那为什么又提到the same left/right side呢?如果看了第一篇文章的同学可能比较好理解,因为FPGA里面有个纵向的Clock Backbone,以这个为间隔分成了左右两部分,所有的全局时钟都在这个Clock Backbone里面。

这个表里面还提到一句:

MRCCs within the same half top/bottom drive:
• 16 BUFGs

这里为什么又要求是上下了呢?这个问题的答案还是在第一篇文章,FPGA里面有个Horizontal Center,将FPGA的BUFG分割成上下相等的两部分,上下各有16个BUFG。

  • 8
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是完整的Verilog HDL代码及测试代码,实现输出时钟周期为1s的分频时钟信号,通过LED灯显示秒数,可对9s内的秒数进行计数,当按下复位按键时重新开始计数。 ```verilog module Divider( input clk, //时钟信号 input rst, //复位信号 output reg clk_out, //输出分频后的时钟信号 output reg [3:0] sec //输出秒数 ); reg [26:0] count = 0; //计数器,用于计算1s的时钟周期 reg [3:0] sec_count = 0; //秒数计数器,用于计算秒数 always @(posedge clk or posedge rst) begin if (rst) begin clk_out <= 0; count <= 0; sec_count <= 0; sec <= 0; end else begin count <= count + 1; if (count >= 25000000) begin //1s的时钟周期 count <= 0; clk_out <= ~clk_out; //分频后的时钟信号 sec_count <= sec_count + 1; if (sec_count >= 10) begin //1秒 sec_count <= 0; sec <= sec + 1; if (sec >= 9) begin //9秒 sec <= 0; end end end end end endmodule ``` 测试代码: ```verilog module Divider_tb; reg clk; reg rst; wire clk_out; wire [3:0] sec; Divider dut( .clk(clk), .rst(rst), .clk_out(clk_out), .sec(sec) ); initial begin clk = 0; rst = 0; #10 rst = 1; //复位信号 #10 rst = 0; repeat(100) begin //100s测试时间 #5 clk = ~clk; $display("clk_out=%b, sec=%d", clk_out, sec); end $finish; end endmodule ``` 在测试代码中,我们将时钟信号和复位信号赋值给模块的输入端口,然后通过输出端口读取分频后的时钟信号和秒数,再将其打印出来。在测试代码中,我们对复位信号进行了一次置位和复位操作,以模拟复位的情况。在测试过程中,我们将时钟信号翻转,以模拟时钟信号的变化,然后通过$display语句打印出分频后的时钟信号和秒数。最后,我们使用$finish语句结束测试。 为了显示秒数,我们需要使用LED灯,将其与sec端口连接起来,并通过板子或仿真器进行测试。下面是完整的代码,包括LED灯的连接和约束文件。 ```verilog module Divider( input clk, //时钟信号 input rst, //复位信号 output reg clk_out, //输出分频后的时钟信号 output reg [3:0] sec //输出秒数 ); reg [26:0] count = 0; //计数器,用于计算1s的时钟周期 reg [3:0] sec_count = 0; //秒数计数器,用于计算秒数 always @(posedge clk or posedge rst) begin if (rst) begin clk_out <= 0; count <= 0; sec_count <= 0; sec <= 0; end else begin count <= count + 1; if (count >= 25000000) begin //1s的时钟周期 count <= 0; clk_out <= ~clk_out; //分频后的时钟信号 sec_count <= sec_count + 1; if (sec_count >= 10) begin //1秒 sec_count <= 0; sec <= sec + 1; if (sec >= 9) begin //9秒 sec <= 0; end end end end end endmodule module Divider_tb; reg clk; reg rst; wire clk_out; wire [3:0] sec; Divider dut( .clk(clk), .rst(rst), .clk_out(clk_out), .sec(sec) ); initial begin clk = 0; rst = 0; #10 rst = 1; //复位信号 #10 rst = 0; repeat(100) begin //100s测试时间 #5 clk = ~clk; $display("clk_out=%b, sec=%d", clk_out, sec); end $finish; end endmodule module LED( input clk, //时钟信号 input [3:0] sec, //秒数 output [3:0] led //LED灯 ); reg [3:0] count = 0; //计数器,用于计算1s的时钟周期 always @(posedge clk) begin count <= count + 1; if (count >= 25000000) begin //1s的时钟周期 count <= 0; led <= sec; end end endmodule module top( input clk, //时钟信号 input rst, //复位信号 output [3:0] led //LED灯 ); wire [3:0] sec; wire clk_out; Divider divider( .clk(clk), .rst(rst), .clk_out(clk_out), .sec(sec) ); LED led( .clk(clk_out), .sec(sec), .led(led) ); endmodule ``` 约束文件: ``` set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L13P_T2_MRCC_35 Sch=led[0] set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L12N_T1_MRCC_35 Sch=led[1] set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L7N_T1_D08_35 Sch=led[2] set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L7P_T1_D07_35 Sch=led[3] set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L5N_T0_D00_M00_A00_35 Sch=clk set_property -dict { PACKAGE_PIN C3 IOSTANDARD LVCMOS33 } [get_ports { rst }]; #IO_L4N_T0_D00_M00_A00_35 Sch=rst ``` 其中,LED灯的连接方式和约束文件需要根据硬件平台进行修改。在本例中,我们假设LED灯的连接方式为共阳极,即正极连接到VCC,负极连接到FPGA引脚,LED灯的引脚分别连接到FPGA的G17、G16、F15、F16引脚。 希望这个完整的代码能够帮到你,实现了输出时钟周期为1s的分频时钟信号,通过LED灯显示秒数,可对9s内的秒数进行计数,当按下复位按键时重新开始计数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值