7

关于投票
基于FPGA的时序及同步设计

FPGA/CPLD重要设计思想及工程应用

时序及同步设计篇

 

       这是昨晚的课程,主要讲时钟同步,课上做了一个实验仿真的对比。(08.4.24

概述

数字电路中,时钟是整个电路最重要、最特殊的信号。

第一, 系统内大部分器件的动作都是在时钟的跳变沿上进行, 这就要求时钟信号时延差要非常小, 否则就可能造成时序逻辑状态出错.

第二, 时钟信号通常是系统中频率最高的信号.

第三, 时钟信号通常是负载最重的信号, 所以要合理分配负载。出于这样的考虑在FPGA这类可编程器件内部一般都设有数量不等的专门用于系统时钟驱动的全局时钟网络。这类网络的特点是:一、负载能力特别强, 任何一个全局时钟驱动线都可以驱动芯片内部的触发器; 二是时延差特别小; 三是时钟信号波形畸变小, 工作可靠性好。

因此, FPGA设计中最好的时钟方案是: 由专用的全局时钟输入引脚驱动单个主时钟去控制设计项目中的每一个触发器。同步设计时, 全局时钟输入一般都接在器件的时钟端, 否则会使其性能受到影响。

对于需要多时钟的时序电路, 最好选用一个频率是它们的时钟频率公倍数的高频主时钟。

各个功能模块要使用统一的复位电路。在使用带时钟的触发器、计数器等有复位端的库器件时, 一般应尽量使用有同步复位的器件。注意复位时保证各个器件都能复位, 以避免某些寄存器的初始状态不确定而引起系统工作不可靠。

 

若想掌握时钟设计方法首先需要了解建立时间和保持时间的概念。

建立时间(setup time):是指在触发器的时钟信号上升沿到来以前,数据稳定不变的时间,如果建立时间不够,数据将不能在这个时钟上升沿被打入触发器;保持时间(hold time):是指在触发器的时钟信号上升沿到来以后,数据稳定不变的时间,如果保持时间不够,数据同样不能被打入触发器。

 

对于一个设计项目来说,全局时钟(或同步时钟)是最简单和最可预测的时钟。在CPLD/FPGA设计中最好的时钟方案是:由专用的全局时钟输入引脚驱动的单个主时钟去钟控设计项目中的每一个触发器。只要可能就应尽量在设计项目中采用全局时钟。CPLD/FPGA都具有专门的全局时钟引脚,它直接连到器件中的每一个寄存器。这种全局时钟提供器件中最短的时钟到输出的延时。

 

在许多应用中只将异步信号同步化还是不够的,当系统中有两个或两个以上非同源时钟的时候,数据的建立和保持时间很难得到保证,我们将面临复杂的时间问题,那么这个时候怎么办呢?

最好的方法是将所有非同源时钟同步化,那么又怎么样将非同源时钟同步化呢?

我们可以使用带使能端的D触发器,并引入一个高频时钟(频率高于系统中的所有源时钟),便可以达到使系统中所有源时钟同步的效果。

 

 

 

 

       系统时钟设计:

系统有两个不同源时钟,一个为3MHz,一个为5MHz,不同的触发器使用不同的时钟。为了系统稳定,假设我们引入一个20MHz时钟,那么这个20MHz的时钟怎么才能将3M5M时钟同步化呢?

 

 

20M的高频时钟将作为系统时钟,输入到所有触发器的的时钟端。3M_EN 5M_EN将控制所有触发器的使能端。即原来接3M时钟的触发器,接20M时钟,同时3M_EN 将控制该触发器使能,原接5M时钟的触发器,也接20M时钟,同时5M_EN 将控制该触发器使能。这样我们就可以将任何非同源时钟同步化。

异步信号输入总是无法满足数据的建立保持时间,所以建议大家把所有异步输入都先经过双触发器进行同步化。

 

 

       下面是用20MHz的时钟作为同步时钟得出的功能仿真波形:(下面一个小波形是将上面一个图的EN_3信号的局部放大,可以明显看出黄线前后两个时钟大小相差了一个主时钟周期,这是因为20/3不为整数导致一个EN_3的脉冲周期有可能6个也有可能7个主时钟周期)

 

点击看大图

 

 

 

       15MHz的同步时钟功能仿真波形,可以得到一致的EN_3EN_5的脉冲,其高电平保持都为1/20M的时间。

 

点击看大图 

 

       综合后的原理图:

点击看大图

 

在通常的FPGA设计中对时钟偏差的控制主要有以下几种方法:

1、控制时钟信号尽量走可编程器件的的全局时钟网络。在可编程器件中一般都有专门的时钟驱动器及全局时钟网络,不同种类、型号的可编程器件,它们中的全局时钟网络数量不同,因此要根据不同的设计需要选择含有合适数量全局时钟网络的可编程器件。一般来说,走全局时钟网络的时钟信号到各使能端的延时小,时钟偏差很小,基本可以忽略不计。

2、若设计中时钟信号数量很多,无法让所有的信号都走全局时钟网络,那么可以通过在设计中加约束的方法,控制不能走全局时钟网络的时钟信号的时钟偏差。

3、异步接口时序裕度要足够大局部同步电路之间接口都可以看成是异步接口,比较典型的是设计中的高低频电路接口、I/O接口,那么接口电路中后一级触发器的建立-保持时间要满足要求,时序裕度要足够大。

4、在系统时钟大于30MHz时,设计难度有所加大,建议采用流水线等设计方法。

5、要保证电路设计的理论最高工作频率大于电路的实际工作频率。

 

       复位和置位信号处理:

在设计时应尽量保证有一全局复位信号,或保证触发器、计数器在使用前已经正确清零状态。在设计寄存器的清除和置位信号时,应尽量直接从器件的专用引脚驱动。另外,要考虑到有些器件上电时,触发器处于一种不确定的状态,系统设计时应加入全局复位/Reset

这样主复位引脚就可以给设计中的每一个触发器馈送清除或置位信号,保证系统处于一个确定的初始状态。需要注意的一点是:不要对寄存器的置位和清除端同时施加不同信号产生的控制,因为如果出现两个信号同时有效的意外情况,会使寄存器进入不定状态。

系统分类: CPLD/FPGA
用户分类: FPGA
标签: 无标签
来源: 原创
发表评论 阅读全文(712) | 回复(0)

0

关于投票
基于FPGA的流水线设计

FPGA/CPLD重要设计思想及工程应用

流水线设计篇

 

概述

流水线设计是高速电路设计中的一个常用设计手段。如果某个设计的处理流程分为若干步骤,而且整个数据处理是“单流向”的,即没有反馈或者迭代运算,前一个步骤的输出是下一个步骤的输入,则可以考虑采用流水线设计方法来提高系统的工作频率。

 

流水线处理的应用

在很多领域的高速电子系统中都运用了流水线处理的方法,如高速通信系统、高速采集系统、高速导航系统、高速搜索系统等等。流水线处理方式之所以能够很大程度上提高数据流的处理速度,是因为复制了处理模块,它是面积换取速度思想的又一种具体体现。

 

流水线设计应用实验

假设该设计为某实时通信系统的一个模块,该系统采样频率为5MHz,采样精度为32位。我们需要设计的内容为:对采样数据先进行加减偏移量的运算,假设需要加十六进制数00000077h的偏移量,然后把该数据压缩为16位数据,便于采样后的信号处理运算,压缩数据时保持精度相对高些。这里我们假设信号处理运算很简单,就是将压缩后的数据先减去十六进制数00ffh,然后取差值的低八位数据值做为该设计的输出。

 

在程序里,进行了四步的流水线作业。所以在功能仿真出来的波形图中可以看到,在en使能(粗黄线)后的三个时钟周期(也即第四个时钟上升沿)后(细黄线)en_out拉高了,dout端开始有输出的数据,而且输出的数据是每一个时钟周期来一个,和输入的数据是同步的。所谓流水作业,在实际硬件电路中就是把一个大的组合逻辑分成各个小的组合逻辑,每一个输入的信号都必须顺次通过各个阶段的操作,而各个阶段的操作又是同步进行的,这就像工厂的生产流水线一样,会有源源不断的数据信号从输出端送出。另外,从这个实验中也可以更深刻的体会到Verilog的并行性。

点击看大图

另外从综合后的RTL视图中可以看到四级的流水结构:

点击看大图

 

程序:

module liu_shui(clk,rst,data,en,en_out,dout);

       input clk;//时钟信号

       input rst;//复位信号

       input[31:0] data;//输入信号

       input en;//输入信号使能,如果为1说明有信号输入

       output en_out;//输出信号使能,如果为1说明输出经过处理的信号

      output[7:0] dout;//输出信号

 

       wire en_1,en_2,en_3;

       wire[31:0] dout_1;

       wire[15:0] dout_2,dout_3;

 

       liu_1 liu_1(clk,rst,data,en,en_1,dout_1);

       liu_2 liu_2(clk,rst,dout_1,en_1,en_2,dout_2);

       liu_3 liu_3(clk,rst,dout_2,en_2,en_3,dout_3);

       liu_4 liu_4(clk,rst,dout_3,en_3,en_out,dout);

 

endmodule

 

 

module liu_1(clk,rst,data,en,en_1,dout_1);

       input clk;

       input rst;

       input[31:0] data;

       input en;

       output en_1;

       output[31:0] dout_1;

      

       reg[31:0] dout_1;

       reg en_1;

 

       always@(posedge clk)

       begin

              if(!rst) begin dout_1 <= 32'h00000000;en_1 <= 0; end

              else if(en) begin dout_1 <= data+32'h00000077;en_1 <= 1; end

              else en_1 <= 0;

       end

 

endmodule

 

 

module liu_2(clk,rst,dout_1,en_1,en_2,dout_2);

       input clk;

       input rst;

       input[31:0] dout_1;

       input en_1;

       output en_2;

       output[15:0] dout_2;

      

       reg[15:0] dout_2;

       reg en_2;

 

       always@(posedge clk)

       begin

              if(!rst) begin dout_2 <= 16'h0000;en_2 <= 0; end

              else if(en_1) begin dout_2 <= dout_1[31:16];en_2 <= 1; end

              else en_2 <= 0;

       end

 

endmodule

 

 

module liu_3(clk,rst,dout_2,en_2,en_3,dout_3);

       input clk;

       input rst;

       input[15:0] dout_2;

       input en_2;

       output en_3;

       output[15:0] dout_3;

      

       reg[15:0] dout_3;

       reg en_3;

       parameter num="16"'h00ff;

 

       always@(posedge clk)

       begin

              if(!rst) begin dout_3 <= 16'h0000;en_3 <= 0; end

              else if(en_2) begin dout_3 <= dout_2-num;en_3 <= 1; end

              else en_3 <= 0;

       end

 

endmodule

 

 

module liu_4(clk,rst,dout_3,en_3,en_out,dout);

       input clk;

       input rst;

       input[15:0] dout_3;

       input en_3;

       output en_out;

       output[7:0] dout;

      

       reg[7:0] dout;

       reg en_out;

 

       always@(posedge clk)

       begin

              if(!rst) begin dout <= 8'h00;en_out <= 0; end

              else if(en_3) begin dout <= dout_3[7:0];en_out <= 1; end

              else en_out <= 0;

       end

 

endmodule

系统分类: CPLD/FPGA
用户分类: FPGA
标签: 无标签
来源: 无分类
发表评论 阅读全文(149) | 回复(0)
总共 , 当前 /