其他分享
首页 > 其他分享> > 数字电路技术与设计实验

数字电路技术与设计实验

作者:互联网

数电实验

数字电路技术与设计实验vhdl设计

组合电路设计

4选1多路选择器

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY  X41 IS
    PORT(
        S0, S1, A, B, C, D : IN STD_LOGIC;
        Y   :   OUT STD_LOGIC);
END     X41;

ARCHITECTURE    BHV OF  X41 IS  BEGIN
    PROCESS(S0, S1) BEGIN
        if S0='0' AND S1='0' then
            Y <= A;
        end if;
        if S0='1' AND S1='0' then
            Y <= B;
        end if;
        if S1='1' AND S0='0' then
            Y <= C;
        end if;
        if S0='1' AND S1='1' then
            Y <= D;
        end if;
    END PROCESS;
END BHV;

4位全减器

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY SUB4 IS
	PORT ( AI, BI : IN STD_LOGIC_VECTOR(3 DOWNTO 0); --定义实体,两个4位的输入:被减数和减数, 一个4位的输出:结果,一个1位的输入:低四位的进/借位标志,一个1位的输出:往高4位的进/借位标志
			C0 : IN STD_LOGIC;
			C1 : OUT STD_LOGIC;
			RES : OUT STD_LOGIC_VECTOR(3 DOWNTO 0) ) ;
END ENTITY SUB4;

ARCHITECTURE S4 OF SUB4 IS
	COMPONENT FSUB   --调用1位全减器的声明语句
	PORT
	(
	--顺序可以和元件定义时不一样,但是端口名要一致
		BI		:	 IN STD_LOGIC;
		AI		:	 IN STD_LOGIC;
		CI		:	 IN STD_LOGIC;
		SUN		:	 OUT STD_LOGIC;
		CO		:	 OUT STD_LOGIC
	);
END COMPONENT;
	
	SIGNAL Q0, Q1, Q2 : STD_LOGIC; --分别为当前第0位,第1位,第2位是否向高1位借位的标志
	
	BEGIN
	U1: FSUB PORT MAP(C0, AI(0), BI(0), RES(0), Q0);
	U2: FSUB PORT MAP(Q0, AI(1), BI(1), RES(1), Q1);
	U3: FSUB PORT MAP(Q1, AI(2), BI(2), RES(2), Q2);
	U4: FSUB PORT MAP(Q2, AI(3), BI(3), RES(3), C1);
END ARCHITECTURE S4;
				

时序电路的设计

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY CNT10 IS
	PORT (CLK, RST, EN, UPDOWN: IN STD_LOGIC;
			DOUT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
			COUT : OUT STD_LOGIC 
			);
END CNT10;

ARCHITECTURE BHV OF CNT10 IS BEGIN
		PROCESS(CLK, EN, RST, UPDOWN) 
		VARIABLE Q : STD_LOGIC_VECTOR(3 DOWNTO 0); --对信号的赋值存在延迟,对变量赋值无延迟
		
		BEGIN
			IF RST = '1' THEN 					--异步复位
				IF UPDOWN = '1' THEN  --计数控制端为高电平,+1计数,初值为0;低电平-1计数,初值为9
					Q := (OTHERS => '0'); 
				ELSE
					Q := "1001";
				END IF;
			
			ELSE 
				IF CLK'EVENT AND CLK='1' THEN --上升沿
					IF EN = '1' THEN	--使能端有效
						IF UPDOWN = '1' THEN 
							IF Q < 9 THEN Q := Q + 1; 	
							ELSE Q := (OTHERS => '0');
							END IF;
						ELSE
							IF Q > 0 THEN Q := Q - 1;
							ELSE Q := "1001";
							END IF;
						END IF;
					END IF;
				END IF;
			END IF;
			
			IF UPDOWN = '1' THEN
				IF Q = "1001" THEN
					COUT <= '1'; --由于存在延迟,所以在当前位到9时进位就为1,下个时钟高位就将加上进位
				ELSE 
					COUT <= '0';
				END IF;
			ELSE
				IF Q = "0000" THEN
					COUT <= '1';
				ELSE
					COUT <= '0';
				END IF;
			END IF;
			
			DOUT <= Q;
			
			END PROCESS;
END BHV;
			

LPM_ROM的应用

LIBRARY	IEEE;
USE	IEEE.STD_LOGIC_1164.ALL;
USE	IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY	DAT	IS
	PORT(
			CLK, EN, RST	:	IN	STD_LOGIC;
			Q_OUT	:	OUT	STD_LOGIC_VECTOR(7 DOWNTO 0);
			C_OUT	:	OUT	STD_LOGIC
			);
END ENTITY	DAT;
    
ARCHITECTURE	BHV OF	DAT IS
	COMPONENT ROM78 IS  --使用内置模块生成的ROM
		PORT
		(
			address		: IN STD_LOGIC_VECTOR (6 DOWNTO 0);
			inclock		: IN STD_LOGIC  := '1';
			q		: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
		);
	END COMPONENT;

	COMPONENT CNT7B IS --使用内置模块生成的计数器
		PORT
		(
			aclr		: IN STD_LOGIC ;
			clk_en		: IN STD_LOGIC ;
			clock		: IN STD_LOGIC ;
			cout		: OUT STD_LOGIC ;
			q		: OUT STD_LOGIC_VECTOR (6 DOWNTO 0)
		);
	END COMPONENT;
	
COMPONENT FRE is  --毛老师的分频
  generic(N: integer:=100);      --rate=N,N是偶数
  port(
        clkin: IN std_logic;
        clkout: OUT std_logic
        );
End COMPONENT;
	SIGNAL	TEMP	: STD_LOGIC_VECTOR(6 DOWNTO 0);
	SIGNAL 	TMP_CLK	: STD_LOGIC;

BEGIN
	F1:FRE	PORT	MAP(CLK, TMP_CLK);
	C7:CNT7B	PORT 	MAP(RST, EN, TMP_CLK, C_OUT, TEMP);
	R7:ROM78	PORT	MAP(TEMP, TMP_CLK, Q_OUT);
END	BHV;
	
	

image-20210612114532649

状态机设计

分频模块

Library ieee;
Use ieee.std_logic_1164.all;
Use ieee.std_logic_unsigned.all;
Use ieee.std_logic_arith.all;

Entity FRE is
  generic(N: integer:=10);      --rate=N,N是偶数
  port(
        clkin: IN std_logic;
        clkout: OUT std_logic
        );
End FRE;
Architecture a of FRE is
  signal cnt: integer range 0 to n-1;
Begin
  process(clkin)  --计数
  begin
      if(clkin'event and clkin='1') then
          if(cnt<n-1) then
              cnt <= cnt+1;
          else
              cnt <= 0;
          end if;
      end if;
  end process;

  process(cnt)  --根据计数值,控制输出时钟脉冲的高、低电平
  begin
      if(cnt<n/2) then
          clkout <= '1';
      else
          clkout <= '0';
      end if;
  end process;

End a;

LED显示模块

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY LED IS
	PORT (Q : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
			SEGMENT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END LED;

ARCHITECTURE BHV OF LED IS BEGIN
	PROCESS(Q) BEGIN
		CASE Q IS
			WHEN "0000" => SEGMENT <= "00111111";
			WHEN "0001" => SEGMENT <= "00000110";
			WHEN "0010" => SEGMENT <= "01011011";
			WHEN "0011" => SEGMENT <= "01001111";
			WHEN "0100" => SEGMENT <= "01100110";
			WHEN "0101" => SEGMENT <= "01101101";
			WHEN "0110" => SEGMENT <= "01111101";
			WHEN "0111" => SEGMENT <= "00000111";
			WHEN "1000" => SEGMENT <= "01111111";
			WHEN "1001" => SEGMENT <= "01101111";
			WHEN OTHERS => SEGMENT <= "01000000";
		END CASE;
	END PROCESS;
END BHV;

状态机模块

LIBRARY	IEEE;
USE	IEEE.STD_LOGIC_1164.ALL;
USE	IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY	JTD	IS
	PORT(
			CLK, RST	:	IN	STD_LOGIC; --状态机工作时钟和复位信号
			TIME_LEFT_H, TIME_LEFT_L	:	BUFFER	STD_LOGIC_VECTOR(3 DOWNTO 0); --输出到数码显示单元的时间高低位信号 8421码
			RYG1, RYG2	:	OUT	STD_LOGIC_VECTOR(2 DOWNTO 0); --1是横向交通灯信号,2是纵向
			SEG_WEI	:	OUT	STD_LOGIC_VECTOR(3 DOWNTO 0) --LED位选控制信号
			);
END	JTD;
ARCHITECTURE	BHV	OF	JTD	IS
TYPE	DIY_ST	IS	(S1, S2, S3, S4, S5, S6); --定义六种状态
SIGNAL	C_ST, NEXT_ST	:	DIY_ST; --将现态和次态定义为上面的类型
SIGNAL	FIRST	: STD_LOGIC	:= '0';
BEGIN	
	REG:	PROCESS(RST, CLK)	BEGIN --主控时序进程,负责状态的切换
		IF	RST = '0'	THEN	C_ST <= S1; --检测到异步复位信号,将现态变成S1
		ELSIF	CLK = '1' AND CLK'EVENT	THEN	
			CASE	C_ST	IS
				WHEN	S1	=>
					IF	FIRST = '0'	THEN
						RYG1 <= "001"; --横向亮绿灯,纵向亮红灯
						RYG2 <= "100";	
						TIME_LEFT_H <= "0011"; --30S
						TIME_LEFT_L <= "0000";
						FIRST	<=	'1';
						SEG_WEI <= "0011";
					ELSE
						IF	TIME_LEFT_L = "0000"	THEN --低位是0
							IF	TIME_LEFT_H = "0000"	THEN --高位也是0,则切换到下个状态,并把FIRST复位
								C_ST <= NEXT_ST;
								FIRST <= '0';
							ELSE --否则向高位借位
								TIME_LEFT_H <= TIME_LEFT_H - 1;
								TIME_LEFT_L <= "1001";
							END	IF;
						ELSE
							TIME_LEFT_L <= TIME_LEFT_L - 1;
						END	IF;
						IF	TIME_LEFT_H = "0001"	AND TIME_LEFT_L = "0000" THEN
							SEG_WEI <= "0001";
						END IF;
					END IF;
					
				WHEN	S2	=>
					IF	FIRST = '0'	THEN	
						RYG1 <= "010";
						RYG2 <= "010";	
						TIME_LEFT_H <= "0001";
						TIME_LEFT_L <= "0101";
						FIRST	<=	'1';
						SEG_WEI <= "0011";
					ELSE
						IF	TIME_LEFT_L = "0000"	THEN --低位是0
							IF	TIME_LEFT_H = "0000"	THEN --高位也是0,则切换到下个状态
								C_ST <= NEXT_ST;
								FIRST <= '0';
							ELSE --否则向高位借位
								TIME_LEFT_H <= TIME_LEFT_H - 1;
								TIME_LEFT_L <= "1001";
							END	IF;
						ELSE
							TIME_LEFT_L <= TIME_LEFT_L - 1;
						END	IF;
						IF	TIME_LEFT_H = "0001"	AND TIME_LEFT_L = "0000" THEN
							SEG_WEI <= "0001";
						END	IF;
					END IF;
					
				WHEN	S3	=>
					IF	FIRST = '0'	THEN	
						RYG1 <= "100";
						RYG2 <= "001";	
						TIME_LEFT_H <= "0011";
						TIME_LEFT_L <= "0000";
						FIRST	<=	'1';
						SEG_WEI <= "0011";
					ELSE
						IF	TIME_LEFT_L = "0000"	THEN --低位是0
							IF	TIME_LEFT_H = "0000"	THEN --高位也是0,则切换到下个状态
								C_ST <= NEXT_ST;
								FIRST <= '0';
							ELSE --否则向高位借位
								TIME_LEFT_H <= TIME_LEFT_H - 1;
								TIME_LEFT_L <= "1001";
							END	IF;
						ELSE
							TIME_LEFT_L <= TIME_LEFT_L - 1;
						END	IF;
						IF	TIME_LEFT_H = "0001"	AND TIME_LEFT_L = "0000" THEN
							SEG_WEI <= "0001";
						END	IF;
					END IF;
					
				WHEN	S4	=>
					IF	FIRST = '0'	THEN	
						RYG1 <= "010";
						RYG2 <= "010";
						TIME_LEFT_H <= "0001";
						TIME_LEFT_L <= "0101";
						FIRST	<=	'1';
						SEG_WEI <= "0011";
					ELSE
						IF	TIME_LEFT_L = "0000"	THEN --低位是0
							IF	TIME_LEFT_H = "0000"	THEN --高位也是0,则切换到下个状态
								C_ST <= NEXT_ST;
								FIRST <= '0';
							ELSE --否则向高位借位
								TIME_LEFT_H <= TIME_LEFT_H - 1;
								TIME_LEFT_L <= "1001";
							END	IF;
						ELSE
							TIME_LEFT_L <= TIME_LEFT_L - 1;
						END	IF;
						IF	TIME_LEFT_H = "0001" AND TIME_LEFT_L = "0000" THEN
							SEG_WEI <= "0001";
						END	IF;
					END IF;
					
				WHEN	S5	=>
					IF	FIRST = '0'	THEN
						RYG1 <= "001";
						RYG2 <= "001";	
						TIME_LEFT_H <= "0011";
						TIME_LEFT_L <= "0000";
						FIRST	<=	'1';
						SEG_WEI <= "0011";
					ELSE
						IF	TIME_LEFT_L = "0000"	THEN --低位是0
							IF	TIME_LEFT_H = "0000"	THEN --高位也是0,则切换到下个状态
								C_ST <= NEXT_ST;
								FIRST <= '0';
							ELSE --否则向高位借位
								TIME_LEFT_H <= TIME_LEFT_H - 1;
								TIME_LEFT_L <= "1001";
							END	IF;
						ELSE
							TIME_LEFT_L <= TIME_LEFT_L - 1;
						END	IF;
						IF	TIME_LEFT_H = "0001"	AND TIME_LEFT_L = "0000" THEN
							SEG_WEI <= "0001";
						END	IF;
					END IF;
					
				WHEN	S6	=>
					IF	FIRST = '0'	THEN	
						RYG1 <= "010";
						RYG2 <= "010";		
						TIME_LEFT_H <= "0001";
						TIME_LEFT_L <= "0101";
						FIRST	<=	'1';
						SEG_WEI <= "0011";
					ELSE
						IF	TIME_LEFT_L = "0000"	THEN --低位是0
							IF	TIME_LEFT_H = "0000"	THEN --高位也是0,则切换到下个状态
								C_ST <= NEXT_ST;
								FIRST <= '0';
							ELSE --否则向高位借位
								TIME_LEFT_H <= TIME_LEFT_H - 1;
								TIME_LEFT_L <= "1001";
							END	IF;
						ELSE
							TIME_LEFT_L <= TIME_LEFT_L - 1;
						END	IF;
						IF	TIME_LEFT_H = "0001"	AND TIME_LEFT_L = "0000" THEN
							SEG_WEI <= "0001";
						END	IF;
					END IF;
					
			END	CASE;
		END	IF;
	END	PROCESS	REG;
	
	COM:	PROCESS(C_ST, NEXT_ST)	BEGIN --主控组合进程,负责根据判断当前状态输出不同的值
				CASE	C_ST	IS
					WHEN	S1 => 
						NEXT_ST <= S2;
					WHEN	S2 =>	
						NEXT_ST <= S3;
					WHEN	S3 =>
						NEXT_ST <= S4;
					WHEN	S4 =>
						NEXT_ST <= S5;
					WHEN	S5 =>		
						NEXT_ST <= S6;
					WHEN	S6 =>
						NEXT_ST <= S1;
					WHEN	OTHERS =>	NEXT_ST <= S1;
				END	CASE;
			END PROCESS;
END	BHV;

顶层设计模块

LIBRARY IEEE;
USE	IEEE.STD_LOGIC_1164.ALL;
USE	IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY	JTDALL	IS
	PORT(
			CLK, RST : IN STD_LOGIC;
			SEG	:	OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
			RYG1, RYG2	: OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
			LED1, LED2	: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
			);
END ENTITY;
ARCHITECTURE	BHV	OF JTDALL IS

COMPONENT LED IS
	PORT (Q : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
			SEGMENT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END COMPONENT;

COMPONENT	JTD	IS
	PORT(
			CLK, RST	:	IN	STD_LOGIC; --状态机工作时钟和复位信号
			TIME_LEFT_H, TIME_LEFT_L	:	BUFFER	STD_LOGIC_VECTOR(3 DOWNTO 0); --输出到数码显示单元的时间高低位信号 8421码
			RYG1, RYG2	:	OUT	STD_LOGIC_VECTOR(2 DOWNTO 0); --1是横向交通灯信号,2是纵向
			SEG_WEI	:	OUT	STD_LOGIC_VECTOR(3 DOWNTO 0) --LED位选控制信号
			);
END	COMPONENT;

COMPONENT FRE is
  generic(N: integer:=10);      --rate=N,N是偶数
  port(
        clkin: IN std_logic;
        clkout: OUT std_logic
        );
End COMPONENT;

SIGNAL	TEMP_H, TEMP_L : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL	TEMP_CLK	: STD_LOGIC;
BEGIN	
	J1: JTD PORT MAP(TEMP_CLK, RST, TEMP_H, TEMP_L, RYG1, RYG2, SEG);
	L1: LED PORT MAP(TEMP_H, LED1);
	L2: LED PORT MAP(TEMP_L, LED2);
	F1: FRE PORT MAP(CLK, TEMP_CLK);
END BHV;

: OUT STD_LOGIC_VECTOR(3 DOWNTO 0) --LED位选控制信号
);
END COMPONENT;

COMPONENT FRE is
generic(N: integer:=10); --rate=N,N是偶数
port(
clkin: IN std_logic;
clkout: OUT std_logic
);
End COMPONENT;

SIGNAL TEMP_H, TEMP_L : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL TEMP_CLK : STD_LOGIC;
BEGIN
J1: JTD PORT MAP(TEMP_CLK, RST, TEMP_H, TEMP_L, RYG1, RYG2, SEG);
L1: LED PORT MAP(TEMP_H, LED1);
L2: LED PORT MAP(TEMP_L, LED2);
F1: FRE PORT MAP(CLK, TEMP_CLK);
END BHV;

标签:STD,--,数字电路,DOWNTO,实验,LOGIC,设计,PORT,OUT
来源: https://blog.csdn.net/m0_46106777/article/details/118032817