?? uart.vhd
字號:
ser_sig2<=ser_buf1;
elsif sample_count="010" then --第三個采樣點
ser_sig3<=ser_buf1;
elsif sample_count="011" then --第四個采樣點
ser_sig4<=ser_buf1;
elsif sample_count="100" then --第五個采樣點
ser_sig5<=ser_buf1;
end if;
--采樣結果值采樣或邏輯,即全為0時,sample為方為1
--采樣結果值應該在本狀態(tài)下給出,若在get_data中給出,因為信號賦值的延遲,
--將導致被判斷的采樣結果值不是當前值,而是前一個數(shù)值,導致錯誤.
sample<=ser_sig2 or ser_sig3 or ser_sig4 or ser_sig5;
elsif bit_count="1001" then --stop bit,停止位
if sample_count="001" then
ser_sig2<=ser_buf1;
elsif sample_count="010" then
ser_sig3<=ser_buf1;
elsif sample_count="011" then
ser_sig4<=ser_buf1;
elsif sample_count="100" then
ser_sig5<=ser_buf1;
end if;
sample<=ser_sig2 and ser_sig3 and ser_sig4 and ser_sig5;
else --有效數(shù)據(jù)位(8位)
if sample_count="011" then --第四個采樣點
ser_sig4<=ser_buf1;
elsif sample_count="100" then --第五個采樣點
ser_sig5<=ser_buf1;
elsif sample_count="101" then --第六個采樣點
ser_sig6<=ser_buf1;
end if;
--此處采用多數(shù)判斷原則,三個值中有兩個為同一值者,采樣結果為該值.
--所以采用兩兩相與,再彼此相或的方式,即若其中有兩值為1,則相與為1,或邏輯也為1,
--若有兩者為0,則三個相與邏輯均為0,或邏輯也為0.
sample<= ( ser_sig4 and ser_sig5 )
or( ser_sig4 and ser_sig6 )
or( ser_sig5 and ser_sig6 );
end if;
data_ready<='0';
data_buf<=data_buf;--采樣時數(shù)據(jù)緩沖不變
bit_count<=bit_count;--位計數(shù)器也不變,保證在同一個數(shù)據(jù)位下進行采樣
sample_count<=sample_count+"001";
if sample_count="110" then--第七個采樣點,進入get_data狀態(tài)
state<=get_data; --只要第六次采樣完畢,就已經(jīng)滿足了進入get_data的條件
end if; --觀察仿真圖,分析,采樣計數(shù)為110時,先執(zhí)行自加,此時值仍然為110,判斷,滿足IF條件,
--則下一狀態(tài)為get_data,執(zhí)行完該IF語句,進程掛起,計數(shù)值變化,為111.
--時鐘觸發(fā),進程再啟動,進入get_data狀態(tài),此時計數(shù)值不變化,為111.在此狀態(tài)下bit_count自加,
--即保證了在8個sample_count下bit_count加1,執(zhí)行完get_data后,若下一狀態(tài)為idle,因為idle狀態(tài)中
--設置了sample_count清零,若為sampling,則111加1,自動變成000,重新開始,所以sample_count值正確.
when get_data=>
if bit_count="0000" then --起始位
if sample='1' then --沒有檢測到起始位
state<=idle; --返回繼續(xù)等待
else --為0表示檢測到起始位
state<=sampling; --進行下一步采樣
end if;
elsif bit_count="1001" then --停止位
if sample='1' then --檢測到有效停止位
state<=data_ok; --進入data_ok,表示幀準備好
else --不是有效的停止位
state<=sampling; --繼續(xù)采樣,或者返回idle狀態(tài)也可以.
end if;
else --有效數(shù)據(jù)位
state<=sampling; --繼續(xù)下一次采樣
end if;
sample_count<="000"; --采樣計數(shù)器清0
data_ready<='0';
data_buf<=sample & data_buf(9 downto 1); --將得到的數(shù)據(jù)移位入數(shù)據(jù)緩存
bit_count<=bit_count+"0001"; --得到一位數(shù)據(jù)后,位計數(shù)器加1,判斷下一位
when data_ok=>
state<=idle;
data_ready<='1';--該狀態(tài)下發(fā)送數(shù)據(jù)
data_buf<=data_buf;
bit_count<=bit_count;
sample_count<=sample_count;
end case;
end if;
end process;
data_out<=data_buf(8 DOWNTO 1) WHEN data_ready='1' ELSE
"00000000";
END behav;
--testbench:tb4
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY tb4 IS
END tb4;
ARCHITECTURE be OF tb4 IS
COMPONENT uart_re IS
PORT(
rst: IN STD_LOGIC;
clk_in: IN STD_LOGIC;
ser_in: IN STD_LOGIC;
data_ready: INOUT STD_LOGIC;
data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
SIGNAL rst: STD_LOGIC;
SIGNAL clk_in: STD_LOGIC;
SIGNAL ser_in: STD_LOGIC;
SIGNAL data_ready: STD_LOGIC;
SIGNAL data_out: STD_LOGIC_VECTOR(7 DOWNTO 0);
CONSTANT clk_in_period: TIME:= 25ns;
CONSTANT clk_tx_period: TIME:= 52083ns;
BEGIN
uut: uart_re PORT MAP
(rst=>rst,clk_in=>clk_in,ser_in=>ser_in,data_ready=>data_ready,data_out=>data_out);
clk_in_gen: PROCESS
BEGIN
clk_in<='0';
WAIT FOR clk_in_period/2;
clk_in<='1';
WAIT FOR clk_in_period/2;
END PROCESS;
rst_gen: PROCESS
BEGIN
rst<='0';
WAIT FOR clk_tx_period;
rst<='1';
WAIT;
END PROCESS;
data_gen: PROCESS
BEGIN
ser_in<='1';
WAIT FOR clk_tx_period;
ser_in<='0';
WAIT FOR clk_tx_period; --start bit
ser_in<='1';
WAIT FOR clk_tx_period; --first bit
ser_in<='0';
WAIT FOR clk_tx_period; --second bit
ser_in<='1';
WAIT FOR clk_tx_period; --three bit
ser_in<='0';
WAIT FOR clk_tx_period; --four bit
ser_in<='1';
WAIT FOR clk_tx_period; --five bit
ser_in<='0';
WAIT FOR clk_tx_period; --six bit
ser_in<='1';
WAIT FOR clk_tx_period; --seven bit
ser_in<='0';
WAIT FOR clk_tx_period; --eight bit
ser_in<='1';
WAIT FOR clk_tx_period; --stop bit
ser_in<='1';
WAIT;
END PROCESS;
END be;
--模塊5 數(shù)碼管顯示模塊
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY segment IS
PORT(
rst: IN STD_LOGIC;
clk_in: IN STD_LOGIC;
data_en: IN STD_LOGIC; --數(shù)據(jù)是否準備好
data_in: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
wei: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--數(shù)碼管位選
data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)--數(shù)碼管段碼
);
END segment;
ARCHITECTURE behav OF segment IS
COMPONENT clock_tx IS
PORT(
clk_in: IN STD_LOGIC;
rst: IN STD_LOGIC;
clk_out: OUT STD_LOGIC
);
END COMPONENT;
SIGNAL data_temp: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL s: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL clk_out: STD_LOGIC;
SIGNAL wei_temp: STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
uut: clock_tx PORT MAP(clk_in=>clk_in,rst=>rst,clk_out=>clk_out);
PROCESS(rst,clk_in)--敏感信號為clk_in,是為了保證獲得data_en的高脈沖
BEGIN
IF rst='0' THEN
data_temp<="00000000";
wei_temp<="0000";--位選全開
ELSIF clk_in'EVENT AND clk_in='1' THEN
IF data_en='1' THEN --實際上,data_en高脈沖持續(xù)一個clk_re周期
data_temp<=data_in;
END IF;
END IF;
END PROCESS;
wei<=wei_temp;
PROCESS(data_temp)
BEGIN
CASE data_temp IS
WHEN "00000000" =>s<="11000000";
WHEN "00000001" =>s<="11111001";
WHEN "00000010" =>s<="10100100";
WHEN "00000011" =>s<="10110000";
WHEN "00000100" =>s<="10011001";
WHEN "00000101" =>s<="10010010";
WHEN "00000110" =>s<="10000010";
WHEN "00000111" =>s<="11111000";
WHEN "00001000" =>s<="10000000";
WHEN "00001001" =>s<="10010000"; --9
WHEN "00001010" =>s<="10001000";
WHEN "00001011" =>s<="10000011";
WHEN "00001100" =>s<="11000110";
WHEN "00001101" =>s<="10100001";
WHEN "10101010" =>s<="10000110";
WHEN "11111111" =>s<="10001110";
WHEN OTHERS =>s<="10111111"; -- ‘-’
END CASE;
END PROCESS;
data_out<=s;
END behav;
--testbench: tb5
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY tb5 IS
END tb5;
ARCHITECTURE be OF tb5 IS
COMPONENT segment IS
PORT(
rst: IN STD_LOGIC;
clk_in: IN STD_LOGIC;
data_in: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
SIGNAL clk_in: STD_LOGIC;
SIGNAL rst: STD_LOGIC;
SIGNAL data_in: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL data_out: STD_LOGIC_VECTOR(7 DOWNTO 0);
CONSTANT clk_period: time:=25 ns;
BEGIN
uut: segment PORT MAP
(rst=>rst,clk_in=>clk_in,data_in=>data_in,data_out=>data_out);
clk_gen: PROCESS
BEGIN
clk_in<='0';
WAIT FOR clk_period/2;
clk_in<='1';
WAIT FOR clk_period/2;
END PROCESS;
rst_gen: PROCESS
BEGIN
rst<='0';
WAIT FOR clk_period/2;
rst<='1';
WAIT;
END PROCESS;
others_gen: PROCESS
BEGIN
data_in<="00000000";
WAIT FOR clk_period;
data_in<="01010101";
WAIT;
END PROCESS;
END be;
--模塊6 頂層模塊
--通過串口調試助手,由PC發(fā)送數(shù)據(jù)給小系統(tǒng)板,板子接收到的數(shù)據(jù)在數(shù)碼管上即時顯示
--并且通過發(fā)送模塊發(fā)送回PC,在串口調試助手上顯示出來。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY uart_top IS
PORT(
rst: IN STD_LOGIC;
clk_in: IN STD_LOGIC;
rxd: IN STD_LOGIC; --uart接收,串行數(shù)據(jù)輸入
txd: OUT STD_LOGIC; --uart發(fā)送,串行數(shù)據(jù)輸出
led1: INOUT STD_LOGIC; --接收模塊數(shù)據(jù)準備好標志 data_ready
led2: OUT STD_LOGIC; --發(fā)送模塊忙標志 busy
wei: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--數(shù)碼管位選
disp: OUT STD_LOGIC_VECTOR(7 DOWNTO 0) --數(shù)碼管段選
);
END uart_top;
ARCHITECTURE behav OF uart_top IS
COMPONENT clock_tx IS
PORT(
clk_in: IN STD_LOGIC;
rst: IN STD_LOGIC;
clk_out: OUT STD_LOGIC
);
END COMPONENT;
COMPONENT uart_tx IS
PORT(
rst: IN STD_LOGIC;
clk_in: IN STD_LOGIC;
send_data: IN STD_LOGIC;
data_in: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
busy: OUT STD_LOGIC;
data_out: OUT STD_LOGIC
);
END COMPONENT;
COMPONENT clock_re IS
PORT(
rst: IN STD_LOGIC;
clk_in: IN STD_LOGIC;
clk_out: OUT STD_LOGIC
);
END COMPONENT;
COMPONENT uart_re IS
PORT(
rst: IN STD_LOGIC;
clk_in: IN STD_LOGIC;
ser_in: IN STD_LOGIC;
data_ready: INOUT STD_LOGIC;
data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
COMPONENT segment IS
PORT(
rst: IN STD_LOGIC;
clk_in: IN STD_LOGIC;
data_in: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
data_en: IN STD_LOGIC;
wei: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
SIGNAL clk_tx: STD_LOGIC;
SIGNAL data_reg: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL clk_re: STD_LOGIC;
SIGNAL led1_temp: STD_LOGIC;
SIGNAL led2_temp: STD_LOGIC;
BEGIN
led1<=not led1_temp;--取反賦值,根據(jù)板子上接法而定
led2<=not led2_temp;
uut1: clock_tx PORT MAP
(clk_in=>clk_in,rst=>rst,clk_out=>clk_tx);
uut2: uart_tx PORT MAP
(clk_in=>clk_in,rst=>rst,send_data=>led1_temp,data_in=>data_reg,busy=>led2_temp,data_out=>txd);
uut3: clock_re PORT MAP
(clk_in=>clk_in,rst=>rst,clk_out=>clk_re);
uut4: uart_re PORT MAP
(clk_in=>clk_in,rst=>rst,ser_in=>rxd,data_ready=>led1_temp,data_out=>data_reg);
uut5: segment PORT MAP
(clk_in=>clk_in,rst=>rst,data_en=>led1_temp,data_in=>data_reg,wei=>wei,data_out=>disp);
END behav;
--testbench:tb6
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY tb6 IS
END tb6;
ARCHITECTURE be OF tb6 IS
COMPONENT uart_top IS
PORT(
rst: IN STD_LOGIC;
clk_in: IN STD_LOGIC;
rxd: IN STD_LOGIC;
txd: OUT STD_LOGIC;
led1: INOUT STD_LOGIC;
led2: OUT STD_LOGIC;
disp: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
SIGNAL rst: STD_LOGIC;
SIGNAL clk_in: STD_LOGIC;
SIGNAL rxd: STD_LOGIC;
SIGNAL txd: STD_LOGIC;
SIGNAL led1: STD_LOGIC;
SIGNAL led2: STD_LOGIC;
SIGNAL disp: STD_LOGIC_VECTOR(7 DOWNTO 0);
CONSTANT clk_in_period: TIME:= 25ns;
CONSTANT clk_tx_period: TIME:= 52083ns;
CONSTANT clk_re_period: TIME:= 6510ns;
BEGIN
uut: uart_top PORT MAP
(rst=>rst,clk_in=>clk_in,rxd=>rxd,txd=>txd,led1=>led1,led2=>led2,disp=>disp);
clk_gen: PROCESS
BEGIN
clk_in<='0';
WAIT FOR clk_in_period/2;
clk_in<='1';
WAIT FOR clk_in_period/2;
END PROCESS;
rst_gen: PROCESS
BEGIN
rst<='0';
WAIT FOR clk_in_period;
rst<='1';
WAIT;
END PROCESS;
data_gen: PROCESS
BEGIN
rxd<='1';
WAIT FOR clk_tx_period;
rxd<='0';
WAIT FOR clk_tx_period; --start bit
rxd<='1';
WAIT FOR clk_tx_period; --first bit
rxd<='0';
WAIT FOR clk_tx_period; --second bit
rxd<='1';
WAIT FOR clk_tx_period; --three bit
rxd<='0';
WAIT FOR clk_tx_period; --four bit
rxd<='1';
WAIT FOR clk_tx_period; --five bit
rxd<='0';
WAIT FOR clk_tx_period; --six bit
rxd<='1';
WAIT FOR clk_tx_period; --seven bit
rxd<='0';
WAIT FOR clk_tx_period; --eight bit
rxd<='1';
WAIT FOR clk_tx_period; --stop bit
rxd<='0';
WAIT;
END PROCESS;
END be;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -