|
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | 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 于 2005/1/22 14:37:00 发布:
以下是程序. 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 于 2005/1/22 14:39:00 发布:
以下是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 于 2005/1/22 20:22:00 发布:
程序太长,也看不懂。 一般LUT都是4输入的,所以7位计数器加一级流水的话,会提高速度。 * - 本贴最后修改时间:2005-1-22 20:23:38 修改者:xjg1111 |
5楼: | >>参与讨论 |
作者: AR3000A 于 2005/1/22 22:04:00 发布:
FLAG 判断先来后到的原理是什么? 按我的理解,同样周期性的两组脉冲无法判定哪一组超前。 |
6楼: | >>参与讨论 |
作者: 051127 于 2005/1/22 22:49:00 发布:
瞎写 你这也叫程序! 这么简单的东西,怎么让你一写就复杂的看不懂!程序不是这么写的! |
7楼: | >>参与讨论 |
作者: n3207 于 2005/1/23 10:26:00 发布:
提高频率的办法:供参考 1、代码设计流水 2、在synplify里减少fanout的系数 3、在synplify里使用pipline 4、在synplify里使用retiming 5、在synplify里对你要求的时钟进行必要的约束,多次尝试,直到极限 |
8楼: | >>参与讨论 |
作者: daiduohao 于 2005/1/23 19:57:00 发布:
RE 同意楼上。 楼主初学就用VirtexII,有米啊 采用流水线设计。 |
9楼: | >>参与讨论 |
作者: hhblxm 于 2005/1/24 15:57:00 发布:
回复大家的疑问-敬请大家关注,每天回复! 谢谢各位热心大侠帮助! 敬请大家留意,我每天会关注此帖,并和大家共同讨论. 1.流水是在哪个工具里面设置,还是在代码里面实现呢,哪里可以找到相关的文章呢?谢谢xjg1111大侠. 2.判断两秒脉冲先后的原理:因为要测量的上升沿差值不是太大,只有几百ns左右。而两秒脉冲的占空比都为1/2.所以当a 的上升沿领先b时,a的上升沿就对应于b的低电平,反之类似.谢谢ar3000a大侠. 3.051127大侠说程序不是这样写的,真的很感谢你,至少说明你是看了我的程序的。请问大侠程序是怎么写的呢?烦请指出错误和缺点吧. 4.n3207大侠谢谢你的建议.我用的是ise自带的综合xst,感觉你的意思是用synplify要好些,是吗?我会照你的方法试试的. 5.daiduohao大侠,我那有米呀.我现在在一个公司做毕业设计.你现在明白了吧. |
10楼: | >>参与讨论 |
作者: hhblxm 于 2005/1/24 16:00:00 发布:
补充.... 有人建议采用one-hot计数器比binary计数器可以提高计数器的频率.各位大侠是这样吗? 还有大侠客建议分成两个小的,我觉得7位已经够低了.需要这样做吗? 请各位大侠畅所欲言. 明天来看大家的讨论. |
11楼: | >>参与讨论 |
作者: n3207 于 2005/1/24 21:53:00 发布:
有人建议采用one-hot计数器比binary计数器可以提高计数器的频率 是的。专家也如此推荐。 |
12楼: | >>参与讨论 |
作者: picklAS 于 2005/1/24 22:25:00 发布:
RE 有一点我是不太明白,你的dcm能倍频到400M么?据我所知,v2的dcm倍频的上限是210M。 建议计数器用ipcore比你的编码效率高,全程时序分析,加时序约束,可以考虑面积约束,定位,再就是使用长线资源。 |
13楼: | >>参与讨论 |
作者: hhblxm 于 2005/1/25 19:04:00 发布:
回复picklas大侠! 1.可以用两个DCM串联就可以实现400M了. 2.用IPCORE我们实验了一下.还不如我们自己编写的程序.因为除了计数器还有一部分实现其他功能. |
14楼: | >>参与讨论 |
作者: hhblxm 于 2005/1/26 19:25:00 发布:
最新进展,共同学习.另外,请大家踊跃发言. 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 于 2005/1/27 20:20:00 发布:
V2的频率能跑到400M不能?我不是很了解XILINX的产品 |
16楼: | >>参与讨论 |
作者: hhblxm 于 2005/2/1 8:22:00 发布:
它的技术手册上面反正频率能倍到400M. |
17楼: | >>参与讨论 |
作者: a_tu01 于 2005/2/2 14:02:00 发布:
是笔误吗? if(res_state = "1111") then res_state <= "1111"; else res_state <= res_state + '1'; end if; 如果是这样,程序能运行吗? |
18楼: | >>参与讨论 |
作者: AR3000A 于 2005/2/23 10:10:00 发布:
hhblxm的贴子有始有终,支持一下。 |
19楼: | >>参与讨论 |
作者: AR3000A 于 2005/2/23 10:52:00 发布:
高精度测量时间差也有传统的办法 就是用鉴相器和A/D转换器,比起纯粹的数字逻辑要简单实用,而且非常便宜。 |
20楼: | >>参与讨论 |
作者: lzw225 于 2005/2/24 9:50:00 发布:
倍频? 请问ALTERA公司的CPLD和FPGA能倍频吗?怎么实现? |
21楼: | >>参与讨论 |
作者: yjf7492 于 2005/2/25 23:02:00 发布:
回a_tu01 可以,防溢出操作。 |
22楼: | >>参与讨论 |
作者: ar3000a 于 2005/3/2 23:05:00 发布:
搜索我的贴子 有个倍频的方法。 |
23楼: | >>参与讨论 |
作者: kely 于 2005/3/14 8:30:00 发布:
有关xillinx 建议使用ise7.1重新产生dcm.采样时钟最好用一个dcm产生。另外,v2的dcm好象在400m时达到极限(记不清了)。 如果设计中用到了锁相环建议还是使用ALTERA的片子。不是xillinx的片子不行,ise实在太差,尤其是在core支持上。 |
24楼: | >>参与讨论 |
作者: baoshuya 于 2005/3/26 9:31:00 发布:
楼主真是利害啊 V2跑最简单的与非门恐怕也到不了400M,你选择的器件延迟是多少ns? 据我看,这个程序能跑到100M就知足了 |
|
|
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入 |
Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号 |