原创 VHDL学习日志(六)--简单频率计

2010-4-4 23:03 3442 5 6 分类: FPGA/CPLD

2010年04月04日                              星期日                                                        阴


           有点惭愧,真是有点惭愧,说是学FPAG,但是这周基本上没有动手写代码,一方面由于工作上的事有点多,得先把本职工作做好,另一方面自己时间没有安排好,所以导致上周很累,但又感觉没有学到什么东西,昨天是周六,狠命的睡了睡懒觉,一直到下午1点才起床,还好起床后确实一周的疲惫真的少了很多,今天上午早早的起床,打了会篮球,感觉真好,突然又想起了学生时代那种快乐的时光,该学习时就学习,该玩时就疯狂的玩又舒服又有激情,可是工作的就不一样了,平时整天都耗在工作上了,周末了想出去运动一下,可是在这个寸土寸金的地方好像找个篮球场还真是不容易,所以有时很怀疑自己到四十岁时还会有这样健康吗?


        嗯,算了,以后再好好安排一下自己的时间吧,好了,还是开始俺的FPGA学习吧,毕竟它可能就是俺的饭碗呀……


       下面是这个简单频率计的代码:


--------------------------------------------------------------------------------------------
--                         每天进步一点点,开心一大点^_^
--函数名称:plj.vhd
--函数功能:频率计。具有4位显示,能自动根据7位十进制计数的结果,自动选择有效数据的。
--          高4位进行动态显示。小数点表示是千位,即KHz。
--作    者:萤火虫II号
--创建日期:2010.04.04
--------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;


entity plj is
 port( start: in std_logic; --复位信号
     clk  : in std_logic; --系统时钟信号
     clk1 : in std_logic; --被测时钟信号
     yy1  : out std_logic_vector(7 downto 0); --八段数码管
     w1   : out std_logic_vector(3 downto 0)  --数码管位选
    );
end plj;


architecture behav of plj is
 signal b1,b2,b3,b4,b5,b6,b7: std_logic_vector(3 downto 0); --十进制计数器
 signal bcd: std_logic_vector(3 downto 0);   --BCD码寄存器
 signal q : integer range 0 to 49999999 ;   --秒分频系数
 signal qq: integer range 0 to 499999 ;   --动态扫描分频系数
 signal en,bclk : std_logic;  --使能信号,有效被测信号
 signal sss : std_logic_vector(3 downto 0); --小数点
 signal bcd0,bcd1,bcd2,bcd3 : std_logic_vector(3 downto 0); --寄存7位十位计数器中有效的高4位数据
 
begin
second: process(clk)   --此进程产生一个持续时间为一秒的的闸门信号
 begin          
 if start='1' then q<=0;     --也就是一个分频信号
 elsif clk'event and clk='1' then
    if q<49999999 then q<=q+1;
    else q<=49999999;
    end if;
 end if;
 if q<49999999 and start='0' then en<='1';
 else en<='0';
 end if;
end process;


and2: process(en,clk1)   --此进程得到7位十进制计数器的计数脉冲
 begin
  bclk<=clk1 and en;
 end process;


com:process(start,bclk)
 begin
  if start='1' then     --复位
   b1<="0000";b2<="0000";b3<="0000";b4<="0000";b5<="0000";b6<="0000";b7<="0000";
  elsif bclk'event and bclk='1' then
   if b1="1001" then b1<="0000";     --个位十进制计数
    if b2="1001" then b1<="0000";     --十位十进制计数
     if b3="1001" then b1<="0000";     --百位十进制计数
      if b4="1001" then b1<="0000";     --千位十进制计数
       if b5="1001" then b1<="0000";     --万位十进制计数
        if b6="1001" then b1<="0000";     --十万位十进制计数
         if b7="1001" then b1<="0000";     --百万位十进制计数
           else b7<=b7+1;
           end if;
          else b6<=b6+1;
          end if;
         else b5<=b5+1;
         end if;
        else b4<=b4+1;
        end if;
       else b3<=b3+1;
       end if;
      else b2<=b2+1;
      end if;
     else b1<=b1+1;
     end if;
   end if;
 end process;


sd:process(clk)   --此进程把7位十进制计数器有效的高4位数据送如bcd0~3;并得到小数点信息
   begin
  if rising_edge(clk) then
   if en='0' then
    if    b7 > "0000" then bcd3<=b7;bcd2<=b6;bcd1<=b5;bcd0<=b4;sss<="1110";
    elsif b6 > "0000" then bcd3<=b6;bcd2<=b5;bcd1<=b4;bcd0<=b3;sss<="1101";
    elsif b5 > "0000" then bcd3<=b5;bcd2<=b4;bcd1<=b3;bcd0<=b2;sss<="1011";
    else  bcd3<=b4;bcd2<=b3;bcd1<=b2;bcd0<=bcd1;sss<="1111";
    end if;
    end if;
  end if;
end process;


weixuan:process(clk)            --此进程完成数据的动态显示
begin           --数码管位选加有PMP三极驱动,位选接在射极,当为0时选通位选
  if clk'event and clk='1' then
        if qq< 99999 then qq<=qq+1;bcd<=bcd3; w1<="0111";
        if sss="0111" then yy1(0)<='0';
     else yy1(0)<='1';
     end if;
        elsif qq<199999 then qq<=qq+1;bcd<=bcd2; w1<="1011";
        if sss="1011" then yy1(0)<='0';
     else yy1(0)<='1';
     end if;
        elsif qq<299999 then qq<=qq+1;bcd<=bcd1; w1<="1101";
        if sss="1101" then yy1(0)<='0';
        else yy1(0)<='1';
        end if;
        elsif qq<399999 then qq<=qq+1;bcd<=bcd0; w1<="1110";
           if sss="1110" then yy1(0)<='0';
           else yy1(0)<='1';
           end if;
        else  qq<=0;
        end if;
  end if;
end process;


m0:process(bcd)
 begin
  case bcd is
   when"0000"=>yy1(7 downto 1)<="0000001"; --共阳极数码管显示0,对应关系为:--|a b c d e f g|--
   when"0001"=>yy1(7 downto 1)<="1001111"; --显示1                          --|7 6 5 4 3 2 1|--
   when"0010"=>yy1(7 downto 1)<="0010010"; --显示2  
   when"0011"=>yy1(7 downto 1)<="0000110"; --显示3  
   when"0100"=>yy1(7 downto 1)<="1001100"; --显示4  
   when"0101"=>yy1(7 downto 1)<="0100100"; --显示5  
   when"0110"=>yy1(7 downto 1)<="1100000"; --显示6  
   when"0111"=>yy1(7 downto 1)<="0001111"; --显示7  
   when"1000"=>yy1(7 downto 1)<="0000000"; --显示8  
   when"1001"=>yy1(7 downto 1)<="0001100"; --显示9  
   when others=>yy1(7 downto 1)<="1111111";
     end case;
end process;
end behav; --这句千万不要忘了呀^_^


          呵呵,看起来代码有一点点长,不过设计FPGA一定要头脑清醒,头脑清醒了,逻辑也就清晰了,逻辑清晰了,一切就好办了,学VHDL开始可能真的很难,难不要紧,只要想学好,下一下功夫可能奇迹就能出现了,有些东西可能初看起来很大,弄的我们是老虎吞天,不知道从哪下手,那么这时就要静下心来好好分析了,看看它有几大块组成,然后一块一块的蚕食,慢慢就搞定了,嘻嘻,就像这个简单的频率计,包括显示部分,计数部分……


         好了,显示部分我以前已搞定了,现在不用怕了,那么计数部分,我再想一想计数原理,慢慢就弄出来了,呵呵,数字电路就是一个一个门电路组成的,静下心来,慢慢肢解它,慢慢的蚕食它,总会找到突破点……


        呵呵,不早了,该睡觉了,还是俺那句口号:


      每天进步一点点,开心多一点^_^
  

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户224258 2010-5-14 17:18

您好,我现在也在做频率计,是通过等精度的方法实现的。用多位串行BCD码除法运算的时候程序有错,花了很长时间都无果。希望能帮我看看啊,谢谢!! library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity div is Port (clk,rst:in std_logic; bei,chu:in std_logic_vector(31 downto 0); shang:out std_logic_vector(31 downto 0); dian:out integer range -10 to 10 ); end div; architecture Behavioral of div is type ss is array (1 to 8) of std_logic_vector(3 downto 0); signal s:ss; signal a,b:std_logic_vector(31 downto 0); signal n:integer range -10 to 10; signal c:integer range 0 to 8; signal k:integer range 1 to 7; signal d:integer range 0 to 1; begin process(clk,k,n,c,s,bei,chu,a,b,rst) variable cnt:integer range 0 to 31; variable m:std_logic_vector(3 downto 0); begin if rst='0' then k<=5;n<=7;c<=8;cnt:=0;m:="0000";s<=(("0000"),("0000"),("0000"),("0000"),("0000"),("0000"),("0000"),("0000")); shang<=(others=>'0'); elsif rising_edge(clk) then case k is when 1=>if b(31 downto 28)=0 then b<=b(27 downto 0)&"0000"; if n<10 then n<=n+1; else k<=5; n<=7; end if; else k<=2; end if; when 2=>if a(3 downto 0)=0 then b<="0000"&b(31 downto 4); n<=n-1; else if n=0 then k<=5; n<=7; else k<=3; end if; end if; when 3=> if a(cnt+3 downto cnt)>=b(cnt+3 downto cnt)+d then a(cnt+3 downto cnt)<=a(cnt+3 downto cnt)-b(cnt+3 downto cnt)-d; d<=0; else a(cnt+3 downto cnt)<=a(cnt+3 downto cnt)+10-b(cnt+03 downto cnt)-d; d<=1; end if; if cnt<28 then cnt:=cnt+4; k<=3; else k<=4; end if; when 4=> m:=m+1; cnt:=0; d<=0; if a<=b then s(c)<=m; m:="0000"; if c=1 then k<=5; else k<=7; c<=c-1; if a(31 downto 28)=0 then a<=a(27 downto 0)&"0000"; else b<="0000"&b(31 downto 4); end if; end if; else k<=3; end if; when 7=>if a>=b then k<=3; else a<=a(27 downto 0)&"0000"; s(c)<=m; if c>=2 then c<=c-1; else k<=5; end if; end if; when 5=>a<=bei; b<=chu; shang<=s(8)&s(7)&s(6)&s(5)&s(4)&s(3)&s(2)&s(1); k<=6; dian<=n; n<=7; m:="0000"; c<=8; cnt:=0; when 6=>if a(31 downto 28)=0 then a<=a(27 downto 0)&"0000"; if n>=0 then n<=n-1; else n<=7; k<=5; end if; else k<=1; end if; when others=>k<=5; end case; end if; end process; end Behavioral;
相关推荐阅读
xucun915_925777961 2013-04-28 11:31
毕业后的五年拉开大家差距的原因在哪里?【转】
  有人工作,有人继续上学,大家千万不要错过这篇文章,能看到这篇文章也是一种幸运,真的受益匪浅,对我有很大启迪,这篇文章将会改变我的一生,真的太好了,希望与有缘人分享,也希望对有缘人有所帮助!...
xucun915_925777961 2013-03-31 20:28
职场大牛精彩总结:职场上,如何做人做事做管理【转】(文/张子阳)
      大道至简,越是根源和基本的问题,道理实际上越简单。关于如何做人、做事、做管理的书很多,我看得不多,但是我觉得这些书更多是侧重技术和实现细节上的,而很少从人的思想和观念去讲。实际...
xucun915_925777961 2013-03-28 14:03
介绍几种优秀的UML工具
统一建模语言(UML是 Unified Modeling Language的缩写)是用来对软件密集系统进行可视化建模的一种语言。UML为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言...
xucun915_925777961 2013-03-27 18:05
IAR EW FOR 8051 修改工程名称的方法
        近段时间一直在搞蓝牙4.0的开发任务,所以用到了IAR编译器,话说IAR编译器用途蛮广,可以编译MSP430,ARM,还有TI的51核芯片,当然,这要不同的版本,我现在用的是for...
xucun915_925777961 2013-03-26 16:40
Cortex-M3学习日志(八)-- TFT实验Part(a)
    自己用的LPC1768的开板带有一块2.4寸的TFT彩色液晶屏,虽然自己工作中还用不过显示屏,但是晚上闲着也是闲着,于是继续玩咱的LPC1768吧。 我的开发板上的液晶屏的用的是SPI接口,当...
xucun915_925777961 2013-03-25 20:48
说说那几款查看源代码的工具
说说那几款查看代码的工具 今天给大家介绍几款单片机工程师所喜欢的几款查看源代码的工具,这几款工具在懒猫的日常工作中可是帮了不少忙。 一、 Source Insight     Source Insig...
EE直播间
更多
我要评论
1
5
关闭 站长推荐上一条 /3 下一条