一、設(shè)計(jì)任務(wù)要求
- 1. 設(shè)計(jì)并實(shí)現(xiàn)一個(gè)隨機(jī)數(shù)生成電路,每 2 秒 隨機(jī)生成一個(gè) 0~999 之間的數(shù) 字,并在數(shù)碼管上顯示生成的隨機(jī)數(shù)。
- 2. 為系統(tǒng)設(shè)置一個(gè)復(fù)位鍵,復(fù)位后數(shù)碼管顯示“000”,2 秒后再開始每 2 秒 生成并顯示隨機(jī)數(shù),要求使用按鍵復(fù)位。
- 3. 實(shí)驗(yàn)板上輸入時(shí)鐘選擇 1kHz 或更高的頻率。
-
二、設(shè)計(jì)思路
隨機(jī)數(shù)產(chǎn)生:設(shè)一個(gè)變量f為vector(5 downto 0),隨時(shí)鐘進(jìn)行計(jì)數(shù),其中的,每次抽取其中四位進(jìn)行相鄰位異或運(yùn)算產(chǎn)生新的數(shù)作為這一位數(shù)。
如第一個(gè)數(shù)的有四位,則取f的0~3位,第二個(gè)數(shù),則取f的1~4位,第三個(gè)數(shù),則取f的2~5位。
第一位數(shù)有四位,如第一位數(shù)的第0位,則為從取出來的f的0~3位的第0位和第1位異或,第1位,則為從f中取出來的第1位和第2位異或,第2位則為從f中取出來的第2位和第3位異或,第三位則為第3位和第0位異或;第二位數(shù)有四位,第0位,則為從取出來的f的1~4位的,第1位和第2位異或,第1位,則為從f中取出來的第2位和第3位異或,第2位則為從f中取出來的第3位和第4位異或,第三位則為第4位和第1位異或;其他以此類推產(chǎn)生隨機(jī)數(shù)。
在譯碼電路通過對(duì)譯碼電路的的10~15進(jìn)行賦值0~9,使得16個(gè)數(shù)都有對(duì)應(yīng)的值。
2.1總體電路為:
輸入信號(hào)1kHz,對(duì)時(shí)鐘信號(hào)進(jìn)行2000分頻,使得數(shù)碼管能保持2秒不變,通過隨機(jī)數(shù)產(chǎn)生后,通過譯碼電路,使用時(shí)鐘頻率1kHz進(jìn)行掃描,使三個(gè)數(shù)碼管交替變亮讓肉眼覺得是三個(gè)同時(shí)亮。
2.2模塊劃分
?2.3總體框圖
三、VHDL代碼
?3.1 2000分頻模塊
library ieee; --庫(kù)和程序包聲明
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity div2000 is --2000分頻器實(shí)體描述
port(
clk: in std_logic; --時(shí)鐘輸入端口
clear: in std_logic; --復(fù)位鍵輸入端口
clk_out:out std_logic); --時(shí)鐘分頻后輸出端口
end div2000;
architecture a of div2000 is --結(jié)構(gòu)體描述
signal tmp: integer range 0 to 999; --整型數(shù),用來記錄分頻
signal clktmp: std_logic; --信號(hào)定義,只能是儲(chǔ)存時(shí)鐘信號(hào)
begin
process(clear,clk)
begin
if clear='1' then --如果按下復(fù)位鍵,分頻計(jì)數(shù)歸零,重新開始計(jì)數(shù)
tmp<=0;
elsif clk'event and clk='1' then
if tmp=999 then --從0計(jì)數(shù)到999,則信號(hào)反轉(zhuǎn)一下
tmp<=0;clktmp<=not clktmp;
else
tmp<=tmp+1;
end if;
end if;
end process;
clk_out<=clktmp;
end a;
3.2 防抖模塊
此防抖電路為計(jì)數(shù)型防抖電路。人按動(dòng)按鈕時(shí),相對(duì)于高速的時(shí)鐘頻率來說很慢,而抖動(dòng)則很快,可以通過計(jì)數(shù)來消除抖動(dòng),當(dāng)按動(dòng)持續(xù)一定時(shí)間,則輸出正脈沖;若持續(xù)時(shí)間過短,則為抖動(dòng)不進(jìn)行輸出。
library ieee; --庫(kù)和程序包聲明
use ieee.std_logic_1164.all;
entity antisk is --防抖電路實(shí)體描述
port(clk:in std_logic; --時(shí)鐘信號(hào)
input:in std_logic; --按鈕輸入端口
output:out std_logic --輸出端口
);
end antisk;
architecture a of antisk is
signal a:std_logic;
signal count:integer range 0 to 9;
begin
process(clk)
begin
if input='0' then
count<=0;
elsif (clk'event and clk='1') then --當(dāng)按鈕輸入時(shí)
if count=9 then --當(dāng)按鈕按動(dòng)持續(xù)一定時(shí)間
count<=count;
else count<=count+1;
end if;
end if;
if count=8 then a<='1'; --則輸出為正
else a<='0';
end if;
end process;
output<=a;
end;
3.3 隨機(jī)數(shù)生成模塊
使用時(shí)鐘頻率1KHz進(jìn)行三個(gè)數(shù)碼管掃描輸出,使人眼以為同時(shí)亮。
因?yàn)槊恳粋€(gè)三位的隨機(jī)數(shù)要保持2秒,所以產(chǎn)生的隨機(jī)數(shù)只要2秒變一回就可以。產(chǎn)生隨機(jī)數(shù)的思路是,設(shè)一個(gè)6位向量,三個(gè)數(shù),每一個(gè)是4位的向量,從6位向量里面依次取出4位,然后四位進(jìn)行異或運(yùn)算,得出新的四位數(shù)作為輸出。
library ieee; --庫(kù)和程序包
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity random is
port (clk1000:in std_logic; --時(shí)鐘輸入1KHz
clk2:in std_logic; --時(shí)鐘輸入0.5Hz
clear:in std_logic; --復(fù)位
f1_out:std_logic_vector(3 downto 0); --第一個(gè)隨機(jī)數(shù)(為了波形能看到)
f2_out:std_logic_vector(3 downto 0); --第二個(gè)隨機(jī)數(shù)(為了波形能看到)
f3_out:std_logic_vector(3 downto 0); --第三個(gè)隨機(jī)數(shù)(為了波形能看到)
shu:out std_logic_vector(3 downto 0);--送給譯碼電路譯碼
cat:out std_logic_vector(7 downto 0));--數(shù)碼管亮還是不亮控制
end entity;
architecture a of random is
signal tmp:integer range 0 to 2; --用來循環(huán)讓三個(gè)數(shù)碼管依次亮起
signal f:std_logic_vector(5 downto 0); --計(jì)數(shù)增加
signal f0:std_logic_vector(5 downto 0); --從f中取數(shù),供以產(chǎn)生三個(gè)隨機(jī)數(shù)
signal f1:std_logic_vector(3 downto 0); --第一個(gè)隨機(jī)數(shù)
signal f2:std_logic_vector(3 downto 0); --第一個(gè)隨機(jī)數(shù)
signal f3:std_logic_vector(3 downto 0); --第一個(gè)隨機(jī)數(shù)
begin
process(clk1000,clk2,clear) --開始進(jìn)程,以時(shí)鐘clk1000,
begin --和時(shí)鐘clk2,復(fù)位清除clear為敏感信號(hào)
if (clk2'event and clk2='1') then f<=f+3; end if; --f每2秒變一回
if clear='1' then f0<="000000"; --當(dāng)復(fù)位信號(hào)來了,f0賦值為0
elsif (clk2'event and clk2='1') then --如果復(fù)位信號(hào)沒有來,每?jī)擅? f0<=f; --將f的值賦給f0
end if;
f1(0)<=f0(0) xor f0(1); --第一位數(shù)的第0位是f0的第0位與第1位異或
f1(1)<=f0(1) xor f0(2); --第一位數(shù)的第1位是f0的第1位與第2位異或
f1(2)<=f0(2) xor f0(3); --第一位數(shù)的第2位是f0的第2位與第3位異或
f1(3)<=f0(3) xor f0(0); --第一位數(shù)的第3位是f0的第3位與第0位異或
f2(0)<=f0(1) xor f0(2); --第二位數(shù)的第0位是f0的第1位與第2位異或
f2(1)<=f0(2) xor f0(3); --第二位數(shù)的第0位是f0的第2位與第3位異或
f2(2)<=f0(3) xor f0(4); --第二位數(shù)的第0位是f0的第3位與第4位異或
f2(3)<=f0(4) xor f0(1); --第二位數(shù)的第0位是f0的第4位與第1位異或
f3(0)<=f0(2) xor f1(3); --第三位數(shù)的第0位是f0的第2位與第3位異或
f3(1)<=f0(3) xor f0(4); --第三位數(shù)的第1位是f0的第3位與第4位異或
f3(2)<=f0(4) xor f0(5); --第三位數(shù)的第2位是f0的第4位與第5位異或
f3(0)<=f0(5) xor f0(2); --第三位數(shù)的第3位是f0的第5位與第2位異或
if (clk1000'event and clk1000='1') then --用來判斷刷新三個(gè)數(shù)碼管
if tmp=2 then tmp<=0 ;else tmp<=tmp+1;--刷新的頻率大于50Hz
end if;end if; --人眼看到就不會(huì)抖動(dòng)
case tmp is
when 0=> shu<=f1;cat<="11110111"; --tmp=0,第3個(gè)數(shù)碼管亮
when 1=> shu<=f2;cat<="11111011"; --tmp=1,第2個(gè)數(shù)碼管亮
when 2=> shu<=f3;cat<="11111101"; --tmp=2,第1個(gè)數(shù)碼管亮
end case;
f1_out<=f1;f2_out<=f2;f3_out<=f3; --看最后總體的輸出波形使用
end process;
end;
3.4 數(shù)碼管譯碼電路
由于一個(gè)數(shù)碼管只能顯示數(shù)字0~9,而四位二進(jìn)制數(shù)能顯示0~15,所以對(duì)于超過10的數(shù)進(jìn)行重新賦值顯示
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY seg IS
PORT(
a:IN STD_LOGIC_VECTOR(3 DOWNTO 0); --輸入端口
b:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); --輸出端口
END seg;
ARCHITECTURE seg7_1_arch OF seg IS
BEGIN
PROCESS(a)
BEGIN
CASE a IS
WHEN "0000" => b <= "1111110"; --輸入是0,則顯示0
WHEN "0001" => b <= "0110000"; --輸入是1,則顯示1
WHEN "0010" => b <= "1101101"; --輸入是2,則顯示2
WHEN "0011" => b <= "1111001"; --輸入是3,則顯示3
WHEN "0100" => b <= "0110011"; --輸入是4,則顯示4
WHEN "0101" => b <= "1011011"; --輸入是5,則顯示5
WHEN "0110" => b <= "1011111"; --輸入是6,則顯示6
WHEN "0111" => b <= "1110000"; --輸入是7,則顯示7
WHEN "1000" => b <= "1111111"; --輸入是8,則顯示8
WHEN "1001" => b <= "1111011"; --輸入是9,則顯示9
WHEN "1010" => b <= "1110000"; --輸入是10,則顯示7
WHEN "1011" => b <= "0110000"; --輸入是11,則顯示1
WHEN "1100" => b <= "0110011"; --輸入是12,則顯示4
WHEN "1101" => b <= "1111111"; --輸入是13,則顯示8
WHEN "1110" => b <= "1011111"; --輸入是14,則顯示6
WHEN "1111" => b <= "1111110"; --輸入是15,則顯示0
END CASE;
END PROCESS;
END;
3.5 總體電路連接模塊
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity whole is
port (clock,key:in std_logic; --時(shí)鐘和復(fù)位信號(hào)
seg0:out std_logic_vector(6 downto 0); --數(shù)碼管
shu:out std_logic_vector(3 downto 0); --數(shù)碼管此時(shí)譯碼的數(shù)
f1:out std_logic_vector(3 downto 0); --第一個(gè)隨機(jī)數(shù)(為了波形看見)
f2:out std_logic_vector(3 downto 0); --第一個(gè)隨機(jī)數(shù)(為了波形看見)
f3:out std_logic_vector(3 downto 0); --第一個(gè)隨機(jī)數(shù)(為了波形看見)
cat0:out std_logic_vector(7 downto 0));--數(shù)碼管顯示控制
end entity whole;
architecture a of whole is
component div2000 --2000分頻器組件聲明
port(
clk: in std_logic;
clear: in std_logic;
clk_out:out std_logic);
end component;
component random --隨機(jī)數(shù)組件聲明
port (
clk1000:in std_logic;
clk2:in std_logic;
clear:in std_logic;
f1_out:out std_logic_vector(3 downto 0);
f2_out:out std_logic_vector(3 downto 0);
f3_out:out std_logic_vector(3 downto 0);
shu:out std_logic_vector(3 downto 0);
cat:out std_logic_vector(7 downto 0));
end component;
component antisk --防抖電路組件聲明
port(clk:in std_logic;
input:in std_logic;
output:out std_logic);
end component;
component seg --譯碼電路組件聲明
port (
a:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
b:OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
END component;
signal clea,cp1000,cp2:std_logic;
signal yi:std_logic_vector(3 downto 0);
begin --電路連接
shu<=yi;
u1:div2000 port map (clk=>clock,clear=>clea,clk_out=>cp2);
u2:antisk port map(clk=>clock,input=>key,output=>clea);
u3:random
port map
(clk1000=>clock,clk2=>cp2,clear=>clea,cat=>cat0,shu=>yi,f1_out=>f1,f2_out=>f2,f3_out=>f3);
u4:seg port map (a=>yi,b=>seg0);
end;
四、仿真波形分析
4.1 2000分頻器
圖1
?圖2
?圖3
?圖4
?仿真波形分析:
如圖所示,圖1為整體波形,圖2為圖1的第一個(gè)上升沿到來時(shí)的放大圖,圖3是圖1的第一個(gè)下降沿到來時(shí)的放大圖,圖4是圖一的clear復(fù)位信號(hào)部分的放大圖。
由圖2和圖3可知,每當(dāng)計(jì)數(shù)信號(hào)tmp從0計(jì)數(shù)到999時(shí),輸出信號(hào)就進(jìn)行一次反轉(zhuǎn),總體一個(gè)周期就是從0計(jì)數(shù)到1999進(jìn)行一次反轉(zhuǎn),即把輸入信號(hào)進(jìn)行了2000分頻,且占空比為50%。
由圖4可知當(dāng)復(fù)位信號(hào)出現(xiàn)時(shí),計(jì)數(shù)信號(hào)tmp馬上異步清零,重新開始計(jì)數(shù)。所以,clear為異步復(fù)位鍵。
4.2 防抖電路模塊
?圖1
?圖2
仿真波形分析:
如圖所示,圖1為整體仿真波形圖,前面較為寬的模擬人手按下按鍵,后面較為窄的表示機(jī)械按鍵的抖動(dòng)。圖1共表示了按鍵按動(dòng)了4次;圖2為第一次按鍵的放大圖。
圖2,當(dāng)沒有按鍵時(shí),即input一直是低電平,則計(jì)數(shù)信號(hào)count的值一直是0,當(dāng)由按鍵信號(hào)時(shí),且持續(xù)時(shí)間按足夠長(zhǎng),即計(jì)數(shù)信號(hào)計(jì)數(shù)到8時(shí),輸出信號(hào)output才輸出高電平,當(dāng)計(jì)數(shù)信號(hào)持續(xù)時(shí)間不夠長(zhǎng),即后面產(chǎn)生的毛刺,則輸出信號(hào)不進(jìn)行高電平輸出。由此,不帶有毛刺的輸出波形進(jìn)行了防抖動(dòng)。
4.3 隨機(jī)數(shù)生成模塊
?圖1
?圖2
?圖3
仿真波形分析:
如圖所示,圖1為整體波形仿真,輸出信號(hào)隨clk2每?jī)擅胱円换?,送給譯碼電路的信號(hào)shu和控制哪個(gè)數(shù)碼管亮的信號(hào)cat變化速度很快,隨clk1000進(jìn)行變化.
圖2圖1的clk2的第二個(gè)上升沿到來時(shí)的放大圖。由圖可知,此時(shí)的f1=10,f2=9,f3=0.cat和送給譯碼電路的shu在f1、f2、f3之間循環(huán)切換輸出。
圖3是圖1的復(fù)位信號(hào)clear到來時(shí)的放大圖。復(fù)位信號(hào)到來,此時(shí)f0馬上轉(zhuǎn)換為0,相應(yīng)的f1、f2、f3都轉(zhuǎn)換為零。而且轉(zhuǎn)換的時(shí)間不是在時(shí)鐘上升沿到來的時(shí)候,是隨復(fù)位信號(hào)出現(xiàn)而進(jìn)行轉(zhuǎn)變,則可以說明,復(fù)位信號(hào)是異步復(fù)位的。
4.4 譯碼電路模塊
?仿真波形分析:
如圖所示,當(dāng)給輸入信號(hào)a不同的值,則輸出信號(hào)會(huì)有不同的譯碼輸出。b的輸出是按照數(shù)碼管的a、b、c、d、e、f、g進(jìn)行譯碼輸出。當(dāng)a的值超過9后,10的譯碼輸出和7一樣,11的譯碼輸出和1一樣,12的譯碼輸出和4一樣,13的譯碼輸出和8一樣,14的譯碼輸出和6一樣,15的譯碼輸出和0一樣。這樣,無(wú)論前面隨機(jī)出傳進(jìn)來的數(shù)是多少,最后的譯碼電路總能譯出一個(gè)數(shù)。
4.5 電路綜合
?圖1
?圖2
仿真波形分析:
如圖所示,圖1生成的隨機(jī)信號(hào)f1、f2、f3、每?jī)擅胱円换兀?dāng)復(fù)位信號(hào)key按動(dòng)時(shí),則f1、f2、f3馬上變回0,且能持續(xù)兩秒,還能說明key是異步信號(hào)。
圖2為clktmp的第二個(gè)上升沿附近的放大圖。由圖可知,隨著clk1000的變化,shu 在f1、f2、f3之間安來回切換,cat0也是與之相對(duì)應(yīng)的切換,告訴變化可以達(dá)到迷惑人眼的效果,這樣就能最終達(dá)到人眼看到的是3個(gè)數(shù)碼管同時(shí)亮。
五、故障及問題分析
- 最后電路綜合仿真的時(shí)候,想要出現(xiàn)的引腳沒有。解決方法,最后加上一個(gè)輸出引腳,這樣最后的仿真波形的選項(xiàng)最后就能出現(xiàn)所要選擇的。
- 隨機(jī)數(shù)生成電路,最開始設(shè)計(jì)的時(shí)候一按復(fù)位鍵,然后出現(xiàn)的數(shù)字都是固定的。要解決這樣的問題,可以把計(jì)數(shù)信號(hào),和給最后的進(jìn)行運(yùn)算變換的信號(hào)分開,這樣即使運(yùn)算變換的信號(hào)變?yōu)?,計(jì)數(shù)信號(hào)不是0,這樣最后就能達(dá)到復(fù)位之后,下一個(gè)數(shù)字不是0的效果。
- 譯碼的時(shí)候要考慮到二進(jìn)制和十進(jìn)制之間的區(qū)別,把所有的情況都考慮一遍,就是把10~15的情況思考清楚。
六、總結(jié)
隨機(jī)數(shù)產(chǎn)生,用電路做出來的最終結(jié)果都是偽隨機(jī),當(dāng)時(shí)間足夠長(zhǎng)的時(shí)候都會(huì)進(jìn)行循環(huán)。文章來源:http://www.zghlxwxcb.cn/news/detail-475253.html
到由多個(gè)時(shí)鐘信號(hào)輸入進(jìn)來的時(shí)候,要有清晰的認(rèn)識(shí),那個(gè)時(shí)鐘是干什么的,否則會(huì)產(chǎn)生很多冗余的代碼。且一個(gè)信號(hào)的最后決定它變化的只能有一個(gè),不能同時(shí)多個(gè)判斷,這樣編譯會(huì)不通過。文章來源地址http://www.zghlxwxcb.cn/news/detail-475253.html
到了這里,關(guān)于【數(shù)電實(shí)驗(yàn)】隨機(jī)數(shù)生成電路的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!