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开始可能真的很难,难不要紧,只要想学好,下一下功夫可能奇迹就能出现了,有些东西可能初看起来很大,弄的我们是老虎吞天,不知道从哪下手,那么这时就要静下心来好好分析了,看看它有几大块组成,然后一块一块的蚕食,慢慢就搞定了,嘻嘻,就像这个简单的频率计,包括显示部分,计数部分……
好了,显示部分我以前已搞定了,现在不用怕了,那么计数部分,我再想一想计数原理,慢慢就弄出来了,呵呵,数字电路就是一个一个门电路组成的,静下心来,慢慢肢解它,慢慢的蚕食它,总会找到突破点……
呵呵,不早了,该睡觉了,还是俺那句口号:
每天进步一点点,开心多一点^_^
用户224258 2010-5-14 17:18