登录 免费注册 首页 | 行业黑名单 | 帮助
维库电子市场网
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统
驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe

计数器到底能达到多高的频率--挑战各位大侠!

作者:hhblxm 栏目:EDA技术
计数器到底能达到多高的频率--挑战各位大侠!
如图示,我想实现的功能是:测量两秒脉冲上升沿之间的时间差,希望越精确越好,由于采用计数法来测量,而计数法存在正负一误差。所以要减少误差,测量精确,那么我希望测量的计数频率越高越好。
计数器限定为7位(至少都要6位,6位没有仿过)。测量完毕用notice_a通知外界来取,同时取flag以判断秒脉冲之间的先后关系。
现在遇到的困难:功能仿真过了,但是时序仿真(也就是ise里面的布局布线后仿真)过不了。仿真工具用的是modelsim 5.6.仿真时我用的计数频率是400m.器件用的是XILINX 的virtex2系列的xc2v40.
想请各位大侠帮忙,帮我仿仿真,看看时序仿真问题出在什么地方?因为是新手,是不是程序写得不好而导致频率上不去,还是其他地方有问题呢?我希望时序仿真能过,且计数频率越高越好,最好能上300m.不管用什么公司的fpga都可以。当然,器件最好是XILINX公司的。
另外,请各位大侠不要怀疑400m怎么得来的,很简单,用XILINX里面的两个DCM模块就可以得到了。外面是50m的输入,第一个dcm模块5倍频,第二个DCM模块2倍频。
下面贴出我的程序和testbench.各位大侠可以直接仿真了。
有兴趣的大侠请研究研究吧,也算是帮帮我啦。。

2楼: >>参与讨论
hhblxm
以下是程序.
 library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity cyc is
   PORT ( clk_cyc : in std_logic;  --计数时钟
std_1hz : in std_logic;  --秒脉冲
          fp_1hz_a : in std_logic;  --另一秒脉冲
          result : inout std_logic_vector(6 downto 0); --两秒脉冲上升沿之间的计数结果。
          notice_a : out std_logic;  --通知计数完成,可以取数。
          flag : inout std_logic  --秒脉冲上升沿之间的先后关系,std_lhz上升沿领先fp_1hz_a上升沿,则为1,反之则反。
);
end cyc;

architecture strcut of cyc is
signal res_state: std_logic_vector(3 downto 0):="0000";--复位状态。
signal std_temp0,std_temp1: std_logic;--判断std_1hz上升沿需要的采样信号
signal fp_temp0,fp_temp1: std_logic; --判断fp_1hz_a上升沿需要的采样信号
signal stop_count: std_logic:='0';--停止计数信号,为1停止计数,为0则开始计数。
begin

notice_a <= stop_count;
PROCESS(clk_cyc)
begin
  if(clk_cyc'event and clk_cyc = '1') then--当res_state为1111时开始正常工作。
    if(res_state = "1111") then
      res_state <= "1111";
    else
      res_state <= res_state + '1';
    end if;

    std_temp0 <= std_1hz;--对std_1hz采样
    std_temp1 <= std_temp0;
    fp_temp0 <= fp_1hz_a;--对fp_1hz_a采样
    fp_temp1 <= fp_temp0;

    if(res_state = "1111") then
    if(std_temp0 = '1' and std_temp1 = '0' and fp_1hz_a = '0') then--状态A: std_1hz上升沿领先fp_1hz_a上升沿。
       flag <= '1' ;    --flag为1表示A状态。
       stop_count <= '0';
       result <= "0000000";
    end if;
    if(fp_temp0 = '1' and fp_temp1 = '0' and std_1hz = '0') then--状态B: fp_1hz_a上升沿领先std_1hz上升沿。
       flag <= '0';
       stop_count <= '0';
       result <= "0000000";
       end if;
       if(flag = '1' and fp_temp0 = '1' and fp_temp1 = '0' and std_1hz = '1') then--如果是A状态且fp_1hz_a上升沿到来时那么停止计数。
         stop_count <= '1';
       end if;
       if(flag = '0' and std_temp0 = '1' and std_temp1 = '0') then --如果是B状态且std_1hz上升沿到来时那么停止计数。
if(fp_1hz_a = '1') then --不加这个条件程序会出错。
  stop_count <= '1';
end if;
       end if;

       if(flag = '1') then --当std_1hz的上升沿领先fp_1hz_a的上升沿时
if(stop_count = '0') then
  result <= result + '1';
end if;
       end if;


       if(flag = '0') then --当fp_1hz_a的上升沿领先std_1hz的上升沿时
if(stop_count = '0') then
  result <= result + '1';
end if;
      end if;
     else   --当处于复位状态时。          result <= "0000000";
     end if;
end if;
end PROCESS;

end strcut;


 

3楼: >>参与讨论
hhblxm
以下是testbench.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;

ARCHITECTURE testbench_arch OF cyc_tb IS
-- If you get a compiler error on the following LINE.html">LINE,
-- from the menu do Options->Configuration SELECT VHDL 87
FILE RESULTS: TEXT OPEN WRITE_MODE IS "results.txt";
COMPONENT cyc
PORT (
clk_cyc : In  std_logic;
std_1hz : In  std_logic;
fp_1hz_a : In  std_logic;
result : InOut  std_logic_vector (6 DOWNTO 0);
notice_a : Out  std_logic;
flag : InOut  std_logic
);
END COMPONENT;

SIGNAL clk_cyc : std_logic;
SIGNAL std_1hz : std_logic;
SIGNAL fp_1hz_a : std_logic;
SIGNAL result : std_logic_vector (6 DOWNTO 0);
SIGNAL notice_a : std_logic;
SIGNAL flag : std_logic;
BEGIN
UUT : cyc
  PORT MAP (
clk_cyc => clk_cyc,
std_1hz => std_1hz,
fp_1hz_a => fp_1hz_a,
result => result,
notice_a => notice_a,
flag => flag
);

PROCESS -- clock PROCESS for clk_cyc,此处设置为400M
begin
clk_cyc <= transport '0';
WAIT FOR 2.5 ns;
clk_cyc <= transport '1';
WAIT FOR 2.5 ns;
END PROCESS;

PROCESS   -- PROCESS for clk_cyc
VARIABLE TX_OUT : LINE;
VARIABLE TX_ERROR : INTEGER := 0;

PROCEDURE CHECK_notice_a(
next_notice_a : std_logic;
TX_TIME : INTEGER
) IS
VARIABLE TX_STR : String(1 to 4096);
VARIABLE TX_LOC : LINE;
BEGIN
-- If compiler error ("/=" is ambiguous) occurs in the next LINE.html">LINE of code
-- change compiler settings to use explicit declarations ONLY
IF (notice_a /= next_notice_a) THEN
     STD.TEXTIO.write(TX_LOC,string'("Error at time="));
STD.TEXTIO.write(TX_LOC, TX_TIME);
STD.TEXTIO.write(TX_LOC,string'("ns notice_a="));
IEEE.STD_LOGIC_TEXTIO.write(TX_LOC, notice_a);
STD.TEXTIO.write(TX_LOC, string'(", Expected = "));
IEEE.STD_LOGIC_TEXTIO.write(TX_LOC, next_notice_a);
STD.TEXTIO.write(TX_LOC, string'(" "));
TX_STR(TX_LOC.all'range) := TX_LOC.all;
STD.TEXTIO.writeLINE.html">LINE(results, TX_LOC);
STD.TEXTIO.Deallocate(TX_LOC);
ASSERT (FALSE) REPORT TX_STR SEVERITY ERROR;
TX_ERROR := TX_ERROR + 1;
END IF;
END;

PROCEDURE CHECK_result(
next_result : std_logic_vector (6 DOWNTO 0);
TX_TIME : INTEGER
) IS
VARIABLE TX_STR : String(1 to 4096);
VARIABLE TX_LOC : LINE;
BEGIN
-- If compiler error ("/=" is ambiguous) occurs in the next LINE.html">LINE of code
-- change compiler settings to use explicit declarations ONLY
IF (result /= next_result) THEN
STD.TEXTIO.write(TX_LOC,string'("Error at time="));
STD.TEXTIO.write(TX_LOC, TX_TIME);
STD.TEXTIO.write(TX_LOC,string'("ns result="));
IEEE.STD_LOGIC_TEXTIO.write(TX_LOC, result);
STD.TEXTIO.write(TX_LOC, string'(", Expected = "));
IEEE.STD_LOGIC_TEXTIO.write(TX_LOC, next_result);
STD.TEXTIO.write(TX_LOC, string'(" "));
TX_STR(TX_LOC.all'range) := TX_LOC.all;
STD.TEXTIO.writeLINE.html">LINE(results, TX_LOC);
STD.TEXTIO.Deallocate(TX_LOC);
ASSERT (FALSE) REPORT TX_STR SEVERITY ERROR;
TX_ERROR := TX_ERROR + 1;
END IF;
END;

PROCEDURE CHECK_flag(
next_flag : std_logic;
TX_TIME : INTEGER
) IS
VARIABLE TX_STR : String(1 to 4096);
VARIABLE TX_LOC : LINE;
BEGIN
-- If compiler error ("/=" is ambiguous) occurs in the next LINE.html">LINE of code
-- change compiler settings to use explicit declarations ONLY
IF (flag /= next_flag) THEN
STD.TEXTIO.write(TX_LOC,string'("Error at time="));
STD.TEXTIO.write(TX_LOC, TX_TIME);
STD.TEXTIO.write(TX_LOC,string'("ns flag="));
IEEE.STD_LOGIC_TEXTIO.write(TX_LOC, flag);
STD.TEXTIO.write(TX_LOC, string'(", Expected = "));
IEEE.STD_LOGIC_TEXTIO.write(TX_LOC, next_flag);
STD.TEXTIO.write(TX_LOC, string'(" "));
TX_STR(TX_LOC.all'range) := TX_LOC.all;
STD.TEXTIO.writeLINE.html">LINE(results, TX_LOC);
STD.TEXTIO.Deallocate(TX_LOC);
ASSERT (FALSE) REPORT TX_STR SEVERITY ERROR;
TX_ERROR := TX_ERROR + 1;
END IF;
END;

BEGIN
-- --------------------
std_1hz <= transport '0';
fp_1hz_a <= transport '0';
-- --------------------
WAIT FOR 200 ns; -- Time=40 ns
std_1hz <= transport '1';
-- --------------------
WAIT FOR 20 ns; -- Time=60 ns
fp_1hz_a <= transport '1';
wait for 10 ns;
std_1hz <= transport '0';

-- --------------------
WAIT FOR 20 ns; -- Time=80 ns
fp_1hz_a <= transport '0';
wait for 20 ns;
std_1hz <= transport '1';

wait for 30 ns;
fp_1hz_a <= transport '1';

wait for 20 ns;
std_1hz <= transport '0';
wait for 20 ns;
fp_1hz_a <= transport '0';

wait for 20 ns;
fp_1hz_a <= transport '1';
wait for 20 ns;
std_1hz <= transport '1';

wait for 20 ns;
std_1hz <= transport '0';
wait for 20 ns;
fp_1hz_a <= transport '0';

wait for 20 ns;
std_1hz <= transport '1';
wait for 30 ns;
fp_1hz_a <= transport '1';

wait for 20 ns;
std_1hz <= transport '0';
wait for 20 ns;
fp_1hz_a <= transport '0';

wait for 20 ns;
fp_1hz_a <= transport '1';
wait for 20 ns;
std_1hz <= transport '1';

wait for 20 ns;
std_1hz <= transport '0';
wait for 20 ns;
fp_1hz_a <= transport '0';

wait for 20 ns;
fp_1hz_a <= transport '1';
wait for 30 ns;
std_1hz <= transport '1';

wait for 20 ns;
std_1hz <= transport '0';
wait for 20 ns;
fp_1hz_a <= transport '0';

wait for 20 ns;
std_1hz <= transport '1';
wait for 20 ns;
fp_1hz_a <= transport '1';

wait for 20 ns;
std_1hz <= transport '0';
wait for 20 ns;
fp_1hz_a <= transport '0';

wait for 20 ns;
std_1hz <= transport '1';
wait for 30 ns;
fp_1hz_a <= transport '1';
-- --------------------
WAIT FOR 1 us; -- Time=181 ns
-- --------------------
-- --------------------

IF (TX_ERROR = 0) THEN
STD.TEXTIO.write(TX_OUT,string'("No errors or warnings"));
STD.TEXTIO.writeLINE.html">LINE(results, TX_OUT);
ASSERT (FALSE) REPORT
"Simulation successful (not a failure).  No problems detected. "
SEVERITY FAILURE;
ELSE
STD.TEXTIO.write(TX_OUT, TX_ERROR);
STD.TEXTIO.write(TX_OUT, string'(" errors found in simulation"));
STD.TEXTIO.writeLINE.html">LINE(results, TX_OUT);
ASSERT (FALSE) REPORT
"Errors found during simulation"
SEVERITY FAILURE;
END IF;
END PROCESS;
END testbench_arch;

CONFIGURATION cyc_cfg OF cyc_tb IS
FOR testbench_arch
END FOR;
END cyc_cfg;



4楼: >>参与讨论
xjg1111
程序太长,也看不懂。
一般LUT都是4输入的,所以7位计数器加一级流水的话,会提高速度。

* - 本贴最后修改时间:2005-1-22 20:23:38 修改者:xjg1111

5楼: >>参与讨论
AR3000A
FLAG
判断先来后到的原理是什么? 按我的理解,同样周期性的两组脉冲无法判定哪一组超前。

6楼: >>参与讨论
051127
瞎写
你这也叫程序!
这么简单的东西,怎么让你一写就复杂的看不懂!程序不是这么写的!

7楼: >>参与讨论
n3207
提高频率的办法:供参考
1、代码设计流水
2、在synplify里减少fanout的系数
3、在synplify里使用pipline
4、在synplify里使用retiming
5、在synplify里对你要求的时钟进行必要的约束,多次尝试,直到极限

8楼: >>参与讨论
daiduohao
RE
同意楼上。
楼主初学就用VirtexII,有米啊
采用流水线设计。

9楼: >>参与讨论
hhblxm
回复大家的疑问-敬请大家关注,每天回复!
谢谢各位热心大侠帮助!
敬请大家留意,我每天会关注此帖,并和大家共同讨论.
1.流水是在哪个工具里面设置,还是在代码里面实现呢,哪里可以找到相关的文章呢?谢谢xjg1111大侠.
2.判断两秒脉冲先后的原理:因为要测量的上升沿差值不是太大,只有几百ns左右。而两秒脉冲的占空比都为1/2.所以当a 的上升沿领先b时,a的上升沿就对应于b的低电平,反之类似.谢谢ar3000a大侠.
3.051127大侠说程序不是这样写的,真的很感谢你,至少说明你是看了我的程序的。请问大侠程序是怎么写的呢?烦请指出错误和缺点吧.
4.n3207大侠谢谢你的建议.我用的是ise自带的综合xst,感觉你的意思是用synplify要好些,是吗?我会照你的方法试试的.
5.daiduohao大侠,我那有米呀.我现在在一个公司做毕业设计.你现在明白了吧.

10楼: >>参与讨论
hhblxm
补充....
有人建议采用one-hot计数器比binary计数器可以提高计数器的频率.各位大侠是这样吗?
还有大侠客建议分成两个小的,我觉得7位已经够低了.需要这样做吗?
请各位大侠畅所欲言.
明天来看大家的讨论.

11楼: >>参与讨论
n3207
有人建议采用one-hot计数器比binary计数器可以提高计数器的频率
是的。专家也如此推荐。

12楼: >>参与讨论
picklAS
RE
有一点我是不太明白,你的dcm能倍频到400M么?据我所知,v2的dcm倍频的上限是210M
建议计数器用ipcore比你的编码效率高,全程时序分析,加时序约束,可以考虑面积约束,定位,再就是使用长线资源。

13楼: >>参与讨论
hhblxm
回复picklas大侠!
1.可以用两个DCM串联就可以实现400M了.
2.用IPCORE我们实验了一下.还不如我们自己编写的程序.因为除了计数器还有一部分实现其他功能.

14楼: >>参与讨论
hhblxm
最新进展,共同学习.另外,请大家踊跃发言.
http://www.edacn.net/cgi-bin/topic.cgi?forum=7&topic=5992&show=0
http://www.edacn.net/cgi-bin/topic.cgi?forum=13&topic=4202&show=0

15楼: >>参与讨论
avlicht
V2的频率能跑到400M不能?我不是很了解XILINX的产品
 
16楼: >>参与讨论
hhblxm
它的技术手册上面反正频率能倍到400M.
 
17楼: >>参与讨论
a_tu01
是笔误吗?
if(res_state = "1111") then
      res_state <= "1111";
    else
      res_state <= res_state + '1';
    end if;

如果是这样,程序能运行吗?


18楼: >>参与讨论
AR3000A
hhblxm的贴子有始有终,支持一下。
 
19楼: >>参与讨论
AR3000A
高精度测量时间差也有传统的办法
就是用鉴相器和A/D转换器,比起纯粹的数字逻辑要简单实用,而且非常便宜。

20楼: >>参与讨论
lzw225
倍频?
请问ALTERA公司的CPLD和FPGA能倍频吗?怎么实现?

21楼: >>参与讨论
yjf7492
回a_tu01
可以,防溢出操作。

22楼: >>参与讨论
ar3000a
搜索我的贴子
有个倍频的方法。

23楼: >>参与讨论
kely
有关xillinx
建议使用ise7.1重新产生dcm.采样时钟最好用一个dcm产生。另外,v2的dcm好象在400m时达到极限(记不清了)。
如果设计中用到了锁相环建议还是使用ALTERA的片子。不是xillinx的片子不行,ise实在太差,尤其是在core支持上。

24楼: >>参与讨论
baoshuya
楼主真是利害啊
V2跑最简单的与非门恐怕也到不了400M,你选择的器件延迟是多少ns?
据我看,这个程序能跑到100M就知足了

参与讨论
昵称:
讨论内容:
 
 
相关帖子
两美元的FPGA?
关于ALTERA,CPLD的输出电压接口,请看这三张图,
各位大哥,帮帮小弟呀!
求助!EPF10K10的下载问题?
如何使用FPGA中的双端口RAM
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入


Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号