⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myself_uart_vhdl.txt

📁 自己写的
💻 TXT
📖 第 1 页 / 共 2 页
字号:
						elsif sample_count="100" then --第五个采样点
							ser_sig5<=ser_buf1;
						elsif sample_count="101" then --第六个采样点
							ser_sig6<=ser_buf1;
						end if;
						--此处采用多数判断原则,三个值中有两个为同一值者,采样结果为该值.
						--所以采用两两相与,再彼此相或的方式,即若其中有两值为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;--采样时数据缓冲不变
					bit_count<=bit_count;--位计数器也不变,保证在同一个数据位下进行采样
					sample_count<=sample_count+"001";
					if sample_count="110" then--第七个采样点,进入get_data状态
						state<=get_data;				--只要第六次采样完毕,就已经满足了进入get_data的条件
					end if;										--观察仿真图,分析,采样计数为110时,先执行自加,此时值仍然为110,判断,满足IF条件,
																		--则下一状态为get_data,执行完该IF语句,进程挂起,计数值变化,为111.
																		--时钟触发,进程再启动,进入get_data状态,此时计数值不变化,为111.在此状态下bit_count自加,
																		--即保证了在8个sample_count下bit_count加1,执行完get_data后,若下一状态为idle,因为idle状态中
																		--设置了sample_count清零,若为sampling,则111加1,自动变成000,重新开始,所以sample_count值正确.
				when get_data=>							
					if bit_count="0000" then	--起始位
						if sample='1' then			--没有检测到起始位
							state<=idle;					--返回继续等待
						else										--为0表示检测到起始位
							state<=sampling;			--进行下一步采样
						end if;
					elsif bit_count="1001" then			--停止位
						if sample='1' then						--检测到有效停止位
							state<=data_ok;							--进入data_ok,表示帧准备好
						else													--不是有效的停止位
							state<=sampling;						--继续采样,或者返回idle状态也可以.
						end if;
					else														--有效数据位
						state<=sampling;							--继续下一次采样
					end if;
					sample_count<="000";						--采样计数器清0
					data_ready<='0';
					data_buf<=sample & data_buf(9 downto 1);	--将得到的数据移位入数据缓存
					bit_count<=bit_count+"0001";	--得到一位数据后,位计数器加1,判断下一位

				when data_ok=>
					state<=idle;
					data_ready<='1';--该状态下发送数据
					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:= 50064ns;

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 数码管显示模块
--08.07.22 整个程序运行正确
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;				--数据是否准备好				
					data_in: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
					wei: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--数码管位选
					data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)--数码管段码
	    );
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高脉冲持续一个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 "00001110" =>s<="10000110";
					WHEN "11111111" =>s<="10001110";
					WHEN OTHERS     =>s<="10111111";  -- ‘-’
			END CASE;
		END PROCESS;
	
	data_out<=s;
	
END behav;

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;

--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发送数据给小系统板,板子接收到的数据在数码管上即时显示
--并且通过发送模块发送回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接收,串行数据输入
						txd: OUT STD_LOGIC; --uart发送,串行数据输出
						led1: INOUT STD_LOGIC; --接收模块数据准备好标志 data_ready
						led2: OUT STD_LOGIC;  --发送模块忙标志 busy
						wei: OUT  STD_LOGIC_VECTOR(3 DOWNTO 0);--数码管位选
						disp: OUT STD_LOGIC_VECTOR(7 DOWNTO 0) --数码管段选
				);
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;--取反赋值,根据板子上接法而定
		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;  --?à¨a¨o??¨?¨o?¨o?¨¨?¨oy?Y?ê???¨?|ser_in
						txd: OUT STD_LOGIC; --?à¨a¨o??¤?é?¨a3?|ì?¨oy?Y?ê???¨?|data_out?ê?§uart_tx?ê?
						led1: INOUT STD_LOGIC; --?¨??¤?é1a?t??1¨1?ê??à¨a¨o?¨oy?Y?¨?¨o?¨a¨o?à?data_ready
						led2: OUT STD_LOGIC;  --?à¨a¨o?¨oy?Y?¤?é?¨a¨a¨o?à? busy
						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:= 50064ns;
CONSTANT clk_re_period: TIME:= 6288ns;

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 + -