数字电路技术与设计实验
作者:互联网
数电实验
数字电路技术与设计实验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;
状态机设计
分频模块
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