Notes
Notes - notes.io |
-- Custom D Flip-Flop (Atomic Module - Structural)
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity my_dff is
Port ( D : in STD_LOGIC;
CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
Q : out STD_LOGIC);
end my_dff;
architecture structural of my_dff is
component nand_gate
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
component not_gate
Port ( A : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
signal s1, s2, s3, s4, s5, s6, s7 : STD_LOGIC;
signal clk_bar, reset_bar : STD_LOGIC;
signal q_internal, qbar_internal : STD_LOGIC;
begin
-- Inverters
not1: not_gate port map (A => CLK, Y => clk_bar);
not2: not_gate port map (A => RESET, Y => reset_bar);
-- Master latch
nand1: nand_gate port map (A => D, B => s2, Y => s1);
nand2: nand_gate port map (A => s1, B => clk_bar, Y => s2);
nand3: nand_gate port map (A => s2, B => clk_bar, Y => s3);
nand4: nand_gate port map (A => s3, B => s1, Y => s4);
-- Slave latch with reset
nand5: nand_gate port map (A => s4, B => CLK, Y => s5);
nand6: nand_gate port map (A => s5, B => reset_bar, Y => s6);
nand7: nand_gate port map (A => s6, B => CLK, Y => q_internal);
-- Create QBAR internally
not3: not_gate port map (A => q_internal, Y => qbar_internal);
-- Output assignments
Q <= q_internal;
end structural;
-- ==================================================
-- Basic Logic Gates (Atomic Modules)
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity not_gate is
Port ( A : in STD_LOGIC;
Y : out STD_LOGIC);
end not_gate;
architecture structural of not_gate is
begin
Y <= not A;
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity and_gate is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end and_gate;
architecture structural of and_gate is
begin
Y <= A and B;
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity or_gate is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end or_gate;
architecture structural of or_gate is
begin
Y <= A or B;
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity nand_gate is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end nand_gate;
architecture structural of nand_gate is
begin
Y <= A nand B;
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity nor_gate is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end nor_gate;
architecture structural of nor_gate is
begin
Y <= A nor B;
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity xor_gate is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end xor_gate;
architecture structural of xor_gate is
begin
Y <= A xor B;
end structural;
-- ==================================================
-- 3-Input AND Gate
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity and3_gate is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
Y : out STD_LOGIC);
end and3_gate;
architecture structural of and3_gate is
component and_gate
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
signal temp : STD_LOGIC;
begin
and1: and_gate port map (A => A, B => B, Y => temp);
and2: and_gate port map (A => temp, B => C, Y => Y);
end structural;
-- ==================================================
-- 4-Input AND Gate
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity and4_gate is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
D : in STD_LOGIC;
Y : out STD_LOGIC);
end and4_gate;
architecture structural of and4_gate is
component and_gate
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
signal temp1, temp2 : STD_LOGIC;
begin
and1: and_gate port map (A => A, B => B, Y => temp1);
and2: and_gate port map (A => C, B => D, Y => temp2);
and3: and_gate port map (A => temp1, B => temp2, Y => Y);
end structural;
-- ==================================================
-- 8-Input NOR Gate (for zero detection)
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity nor8_gate is
Port ( A : in STD_LOGIC_VECTOR(7 downto 0);
Y : out STD_LOGIC);
end nor8_gate;
architecture structural of nor8_gate is
component or_gate
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
component not_gate
Port ( A : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
signal temp1, temp2, temp3, temp4, temp5, temp6, temp_final : STD_LOGIC;
begin
or1: or_gate port map (A => A(0), B => A(1), Y => temp1);
or2: or_gate port map (A => A(2), B => A(3), Y => temp2);
or3: or_gate port map (A => A(4), B => A(5), Y => temp3);
or4: or_gate port map (A => A(6), B => A(7), Y => temp4);
or5: or_gate port map (A => temp1, B => temp2, Y => temp5);
or6: or_gate port map (A => temp3, B => temp4, Y => temp6);
or7: or_gate port map (A => temp5, B => temp6, Y => temp_final);
not1: not_gate port map (A => temp_final, Y => Y);
end structural;
-- ==================================================
-- 2-to-1 Multiplexer
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux2to1 is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
SEL : in STD_LOGIC;
Y : out STD_LOGIC);
end mux2to1;
architecture structural of mux2to1 is
component and_gate
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
component or_gate
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
component not_gate
Port ( A : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
signal sel_bar, temp1, temp2 : STD_LOGIC;
begin
not1: not_gate port map (A => SEL, Y => sel_bar);
and1: and_gate port map (A => A, B => sel_bar, Y => temp1);
and2: and_gate port map (A => B, B => SEL, Y => temp2);
or1: or_gate port map (A => temp1, B => temp2, Y => Y);
end structural;
-- ==================================================
-- 4-to-1 Multiplexer
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux4to1 is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
D : in STD_LOGIC;
SEL : in STD_LOGIC_VECTOR(1 downto 0);
Y : out STD_LOGIC);
end mux4to1;
architecture structural of mux4to1 is
component mux2to1
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
SEL : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
signal temp1, temp2 : STD_LOGIC;
begin
mux1: mux2to1 port map (A => A, B => B, SEL => SEL(0), Y => temp1);
mux2: mux2to1 port map (A => C, B => D, SEL => SEL(0), Y => temp2);
mux3: mux2to1 port map (A => temp1, B => temp2, SEL => SEL(1), Y => Y);
end structural;
-- ==================================================
-- 8-bit 4-to-1 Multiplexer
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux4to1_8bit is
Port ( A : in STD_LOGIC_VECTOR(7 downto 0);
B : in STD_LOGIC_VECTOR(7 downto 0);
C : in STD_LOGIC_VECTOR(7 downto 0);
D : in STD_LOGIC_VECTOR(7 downto 0);
SEL : in STD_LOGIC_VECTOR(1 downto 0);
Y : out STD_LOGIC_VECTOR(7 downto 0));
end mux4to1_8bit;
architecture structural of mux4to1_8bit is
component mux4to1
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
D : in STD_LOGIC;
SEL : in STD_LOGIC_VECTOR(1 downto 0);
Y : out STD_LOGIC);
end component;
begin
gen_mux: for i in 0 to 7 generate
mux_inst: mux4to1 port map (
A => A(i),
B => B(i),
C => C(i),
D => D(i),
SEL => SEL,
Y => Y(i)
);
end generate;
end structural;
-- ==================================================
-- 8-bit Register using D Flip-Flops
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity reg8bit is
Port ( D : in STD_LOGIC_VECTOR(7 downto 0);
CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
ENABLE : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR(7 downto 0));
end reg8bit;
architecture structural of reg8bit is
component my_dff
Port ( D : in STD_LOGIC;
CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
Q : out STD_LOGIC);
end component;
component and_gate
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
component mux2to1
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
SEL : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
signal q_internal : STD_LOGIC_VECTOR(7 downto 0);
signal d_muxed : STD_LOGIC_VECTOR(7 downto 0);
begin
gen_reg: for i in 0 to 7 generate
mux_enable: mux2to1 port map (
A => q_internal(i),
B => D(i),
SEL => ENABLE,
Y => d_muxed(i)
);
dff_inst: my_dff port map (
D => d_muxed(i),
CLK => CLK,
RESET => RESET,
Q => q_internal(i)
);
end generate;
Q <= q_internal;
end structural;
-- ==================================================
-- 8-bit OR Gate
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity or_gate_8bit is
Port ( A : in STD_LOGIC_VECTOR(7 downto 0);
B : in STD_LOGIC_VECTOR(7 downto 0);
Y : out STD_LOGIC_VECTOR(7 downto 0));
end or_gate_8bit;
architecture structural of or_gate_8bit is
component or_gate
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
begin
gen_or: for i in 0 to 7 generate
or_inst: or_gate port map (
A => A(i),
B => B(i),
Y => Y(i)
);
end generate;
end structural;
-- ==================================================
-- Clock Divider (Simplified for Simulation)
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity clock_divider is
Port ( CLK_IN : in STD_LOGIC;
RESET : in STD_LOGIC;
CLK_OUT : out STD_LOGIC);
end clock_divider;
architecture structural of clock_divider is
signal counter : integer range 0 to 7 := 0;
signal slow_clk : STD_LOGIC := '0';
begin
process(CLK_IN, RESET)
begin
if RESET = '1' then
counter <= 0;
slow_clk <= '0';
elsif rising_edge(CLK_IN) then
if counter = 7 then -- Divide by 8 for simulation
counter <= 0;
slow_clk <= not slow_clk;
else
counter <= counter + 1;
end if;
end if;
end process;
CLK_OUT <= slow_clk;
end structural;
-- ==================================================
-- State Register (3-bit for 6 states)
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity state_register is
Port ( D : in STD_LOGIC_VECTOR(2 downto 0);
CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR(2 downto 0));
end state_register;
architecture structural of state_register is
component my_dff
Port ( D : in STD_LOGIC;
CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
Q : out STD_LOGIC);
end component;
begin
gen_state_reg: for i in 0 to 2 generate
dff_inst: my_dff port map (
D => D(i),
CLK => CLK,
RESET => RESET,
Q => Q(i)
);
end generate;
end structural;
-- ==================================================
-- State Decoder (3-to-8)
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity state_decoder is
Port ( STATE : in STD_LOGIC_VECTOR(2 downto 0);
IDLE : out STD_LOGIC;
CHECK : out STD_LOGIC;
BOTH : out STD_LOGIC;
LEFT_ONLY : out STD_LOGIC;
RIGHT_ONLY : out STD_LOGIC);
end state_decoder;
architecture structural of state_decoder is
component and3_gate
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
component not_gate
Port ( A : in STD_LOGIC;
Y : out STD_LOGIC);
end component;
signal state_bar : STD_LOGIC_VECTOR(2 downto 0);
begin
-- Generate inverted state signals
gen_not: for i in 0 to 2 generate
not_inst: not_gate port map (A => STATE(i), Y => state_bar(i));
end generate;
-- State decoding (using binary encoding)
-- IDLE = 000
idle_and: and3_gate port map (A => state_bar(2), B => state_bar(1), C => state_bar(0), Y => IDLE);
-- CHECK = 001
check_and: and3_gate port map (A => state_bar(2), B => state_bar(1), C => STATE(0), Y => CHECK);
-- BOTH = 010
both_and: and3_gate port map (A => state_bar(2), B => STATE(1), C => state_bar(0), Y => BOTH);
-- LEFT_ONLY = 011
left_and: and3_gate port map (A => state_bar(2), B => STATE(1), C => STATE(0), Y => LEFT_ONLY);
-- RIGHT_ONLY = 100
right_and: and3_gate port map (A => STATE(2), B => state_bar(1), C => state_bar(0), Y => RIGHT_ONLY);
end structural;
-- ==================================================
-- Control Logic (Next State and Outputs) - Simplified
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity control_logic is
Port ( CURRENT_STATE : in STD_LOGIC_VECTOR(2 downto 0);
LEFT : in STD_LOGIC;
RIGHT : in STD_LOGIC;
LMASK_ZERO : in STD_LOGIC;
RMASK_ZERO : in STD_LOGIC;
NEXT_STATE : out STD_LOGIC_VECTOR(2 downto 0);
DISPLAY_SEL : out STD_LOGIC_VECTOR(1 downto 0);
LMASK_EN : out STD_LOGIC;
RMASK_EN : out STD_LOGIC;
DISPLAY_EN : out STD_LOGIC;
LMASK_SHIFT : out STD_LOGIC;
RMASK_SHIFT : out STD_LOGIC;
LMASK_RESET : out STD_LOGIC;
RMASK_RESET : out STD_LOGIC);
end control_logic;
architecture structural of control_logic is
signal idle, check, both, left_only, right_only : STD_LOGIC;
begin
-- Simple state decoding
idle <= '1' when CURRENT_STATE = "000" else '0';
check <= '1' when CURRENT_STATE = "001" else '0';
both <= '1' when CURRENT_STATE = "010" else '0';
left_only <= '1' when CURRENT_STATE = "011" else '0';
right_only <= '1' when CURRENT_STATE = "100" else '0';
-- Next state logic (simplified)
process(CURRENT_STATE, LEFT, RIGHT, LMASK_ZERO, RMASK_ZERO)
begin
case CURRENT_STATE is
when "000" => -- IDLE
NEXT_STATE <= "001"; -- Go to CHECK
when "001" => -- CHECK
if LEFT = '1' and RIGHT = '1' then
NEXT_STATE <= "010"; -- BOTH
elsif LEFT = '1' then
NEXT_STATE <= "011"; -- LEFT_ONLY
elsif RIGHT = '1' then
NEXT_STATE <= "100"; -- RIGHT_ONLY
else
NEXT_STATE <= "001"; -- Stay in CHECK
end if;
when "010" => -- BOTH
if LMASK_ZERO = '1' or RMASK_ZERO = '1' then
NEXT_STATE <= "000"; -- Back to IDLE
else
NEXT_STATE <= "001"; -- Back to CHECK
end if;
when "011" => -- LEFT_ONLY
if LMASK_ZERO = '1' then
NEXT_STATE <= "000"; -- Back to IDLE
else
NEXT_STATE <= "001"; -- Back to CHECK
end if;
when "100" => -- RIGHT_ONLY
if RMASK_ZERO = '1' then
NEXT_STATE <= "000"; -- Back to IDLE
else
NEXT_STATE <= "001"; -- Back to CHECK
end if;
when others =>
NEXT_STATE <= "000"; -- Default to IDLE
end case;
end process;
-- Output logic
LMASK_RESET <= idle;
RMASK_RESET <= idle;
LMASK_EN <= both or left_only;
RMASK_EN <= both or right_only;
DISPLAY_EN <= '1';
LMASK_SHIFT <= both or left_only;
RMASK_SHIFT <= both or right_only;
-- Display select
DISPLAY_SEL <= "00" when check = '1' and LEFT = '0' and RIGHT = '0' else
"01" when left_only = '1' else
"10" when right_only = '1' else
"11" when both = '1' else
"00";
end structural;
-- ==================================================
-- Control Unit (Simplified State Machine)
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity control_unit is
Port ( CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
LEFT : in STD_LOGIC;
RIGHT : in STD_LOGIC;
LMASK_ZERO : in STD_LOGIC;
RMASK_ZERO : in STD_LOGIC;
DISPLAY_SEL : out STD_LOGIC_VECTOR(1 downto 0);
LMASK_EN : out STD_LOGIC;
RMASK_EN : out STD_LOGIC;
DISPLAY_EN : out STD_LOGIC;
LMASK_SHIFT : out STD_LOGIC;
RMASK_SHIFT : out STD_LOGIC;
LMASK_RESET : out STD_LOGIC;
RMASK_RESET : out STD_LOGIC);
end control_unit;
architecture structural of control_unit is
signal current_state, next_state : STD_LOGIC_VECTOR(2 downto 0);
begin
-- State register with initialization
process(CLK, RESET)
begin
if RESET = '1' then
current_state <= "000"; -- Start in IDLE state
elsif rising_edge(CLK) then
current_state <= next_state;
end if;
end process;
-- Next state and output logic
process(current_state, LEFT, RIGHT, LMASK_ZERO, RMASK_ZERO)
begin
-- Default outputs
DISPLAY_SEL <= "00";
LMASK_EN <= '0';
RMASK_EN <= '0';
DISPLAY_EN <= '1';
LMASK_SHIFT <= '0';
RMASK_SHIFT <= '0';
LMASK_RESET <= '0';
RMASK_RESET <= '0';
case current_state is
when "000" => -- IDLE
LMASK_RESET <= '1';
RMASK_RESET <= '1';
next_state <= "001";
when "001" => -- CHECK_INPUTS
if LEFT = '1' and RIGHT = '1' then
next_state <= "010"; -- BOTH_ACTIVE
elsif LEFT = '1' then
next_state <= "011"; -- LEFT_ACTIVE
elsif RIGHT = '1' then
next_state <= "100"; -- RIGHT_ACTIVE
else
DISPLAY_SEL <= "00"; -- Display zeros
next_state <= "001"; -- Stay in CHECK
end if;
when "010" => -- BOTH_ACTIVE
DISPLAY_SEL <= "11"; -- Display LMASK OR RMASK
LMASK_SHIFT <= '1';
RMASK_SHIFT <= '1';
LMASK_EN <= '1';
RMASK_EN <= '1';
if LMASK_ZERO = '1' or RMASK_ZERO = '1' then
next_state <= "000"; -- Back to IDLE
else
next_state <= "001"; -- Back to CHECK
end if;
when "011" => -- LEFT_ACTIVE
DISPLAY_SEL <= "01"; -- Display LMASK
LMASK_SHIFT <= '1';
LMASK_EN <= '1';
if LMASK_ZERO = '1' then
next_state <= "000"; -- Back to IDLE
else
next_state <= "001"; -- Back to CHECK
end if;
when "100" => -- RIGHT_ACTIVE
DISPLAY_SEL <= "10"; -- Display RMASK
RMASK_SHIFT <= '1';
RMASK_EN <= '1';
if RMASK_ZERO = '1' then
next_state <= "000"; -- Back to IDLE
else
next_state <= "001"; -- Back to CHECK
end if;
when others =>
next_state <= "000"; -- Default to IDLE
end case;
end process;
end structural;ASK_EN => LMASK_EN,
RMASK_EN => RMASK_EN,
DISPLAY_EN => DISPLAY_EN,
LMASK_SHIFT => LMASK_SHIFT,
RMASK_SHIFT => RMASK_SHIFT,
LMASK_RESET => LMASK_RESET,
RMASK_RESET => RMASK_RESET
);
end structural;
-- ==================================================
-- Datapath Unit (Simplified for Simulation)
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity datapath is
Port ( CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
DISPLAY_SEL : in STD_LOGIC_VECTOR(1 downto 0);
LMASK_EN : in STD_LOGIC;
RMASK_EN : in STD_LOGIC;
DISPLAY_EN : in STD_LOGIC;
LMASK_SHIFT : in STD_LOGIC;
RMASK_SHIFT : in STD_LOGIC;
LMASK_RESET : in STD_LOGIC;
RMASK_RESET : in STD_LOGIC;
LMASK_ZERO : out STD_LOGIC;
RMASK_ZERO : out STD_LOGIC;
DISPLAY_OUT : out STD_LOGIC_VECTOR(7 downto 0));
end datapath;
architecture structural of datapath is
signal lmask_reg, rmask_reg, display_reg : STD_LOGIC_VECTOR(7 downto 0);
signal lmask_shifted, rmask_shifted, lmask_or_rmask : STD_LOGIC_VECTOR(7 downto 0);
signal lmask_next, rmask_next, display_next : STD_LOGIC_VECTOR(7 downto 0);
begin
-- LMASK register with initialization
process(CLK, RESET)
begin
if RESET = '1' or LMASK_RESET = '1' then
lmask_reg <= "00000001"; -- Initialize to starting value
elsif rising_edge(CLK) then
if LMASK_EN = '1' then
if LMASK_SHIFT = '1' then
-- Shift left
lmask_reg <= lmask_reg(6 downto 0) & '0';
end if;
end if;
end if;
end process;
-- RMASK register with initialization
process(CLK, RESET)
begin
if RESET = '1' or RMASK_RESET = '1' then
rmask_reg <= "10000000"; -- Initialize to starting value
elsif rising_edge(CLK) then
if RMASK_EN = '1' then
if RMASK_SHIFT = '1' then
-- Shift right
rmask_reg <= '0' & rmask_reg(7 downto 1);
end if;
end if;
end if;
end process;
-- OR gate for combining LMASK and RMASK
lmask_or_rmask <= lmask_reg or rmask_reg;
-- Display multiplexer
process(DISPLAY_SEL, lmask_reg, rmask_reg, lmask_or_rmask)
begin
case DISPLAY_SEL is
when "00" => display_next <= "00000000"; -- All zeros
when "01" => display_next <= lmask_reg; -- LMASK only
when "10" => display_next <= rmask_reg; -- RMASK only
when "11" => display_next <= lmask_or_rmask; -- LMASK OR RMASK
when others => display_next <= "00000000";
end case;
end process;
-- DISPLAY register
process(CLK, RESET)
begin
if RESET = '1' then
display_reg <= "00000000";
elsif rising_edge(CLK) then
if DISPLAY_EN = '1' then
display_reg <= display_next;
end if;
end if;
end process;
-- Zero detectors
LMASK_ZERO <= '1' when lmask_reg = "00000000" else '0';
RMASK_ZERO <= '1' when rmask_reg = "00000000" else '0';
-- Output
DISPLAY_OUT <= display_reg;
end structural;
-- ==================================================
-- Top Level Entity (DE-2 Board Pin Assignments)
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity led_controller_top is
Port ( CLOCK_50 : in STD_LOGIC; -- PIN_Y2 - 50MHz system clock
KEY : in STD_LOGIC_VECTOR(3 downto 0); -- PIN_M23, PIN_M21, PIN_N21, PIN_R24 - Push buttons
SW : in STD_LOGIC_VECTOR(17 downto 0); -- PIN_AB28 to PIN_Y23 - DIP switches
LEDR : out STD_LOGIC_VECTOR(7 downto 0)); -- PIN_G19, PIN_F19, PIN_E19, PIN_F21, PIN_F18, PIN_E18, PIN_J19, PIN_H19 - Red LEDs
end led_controller_top;
architecture structural of led_controller_top is
component control_unit
Port ( CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
LEFT : in STD_LOGIC;
RIGHT : in STD_LOGIC;
LMASK_ZERO : in STD_LOGIC;
RMASK_ZERO : in STD_LOGIC;
DISPLAY_SEL : out STD_LOGIC_VECTOR(1 downto 0);
LMASK_EN : out STD_LOGIC;
RMASK_EN : out STD_LOGIC;
DISPLAY_EN : out STD_LOGIC;
LMASK_SHIFT : out STD_LOGIC;
RMASK_SHIFT : out STD_LOGIC;
LMASK_RESET : out STD_LOGIC;
RMASK_RESET : out STD_LOGIC);
end component;
component datapath
Port ( CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
DISPLAY_SEL : in STD_LOGIC_VECTOR(1 downto 0);
LMASK_EN : in STD_LOGIC;
RMASK_EN : in STD_LOGIC;
DISPLAY_EN : in STD_LOGIC;
LMASK_SHIFT : in STD_LOGIC;
RMASK_SHIFT : in STD_LOGIC;
LMASK_RESET : in STD_LOGIC;
RMASK_RESET : in STD_LOGIC;
LMASK_ZERO : out STD_LOGIC;
RMASK_ZERO : out STD_LOGIC;
DISPLAY_OUT : out STD_LOGIC_VECTOR(7 downto 0));
end component;
component clock_divider
Port ( CLK_IN : in STD_LOGIC;
RESET : in STD_LOGIC;
CLK_OUT : out STD_LOGIC);
end component;
-- Internal signals
signal slow_clk : STD_LOGIC;
signal display_sel : STD_LOGIC_VECTOR(1 downto 0);
signal lmask_en, rmask_en, display_en : STD_LOGIC;
signal lmask_shift, rmask_shift : STD_LOGIC;
signal lmask_reset, rmask_reset : STD_LOGIC;
signal lmask_zero, rmask_zero : STD_LOGIC;
signal display_out : STD_LOGIC_VECTOR(7 downto 0);
-- DE-2 board interface signals
signal reset_sig : STD_LOGIC;
signal left_sig : STD_LOGIC;
signal right_sig : STD_LOGIC;
begin
-- DE-2 Board Interface Mapping:
-- KEY(0) is used as RESET (active low, so invert it)
-- SW(0) is used as LEFT input
-- SW(1) is used as RIGHT input
-- LEDR(7:0) displays the LED pattern
reset_sig <= not KEY(0); -- KEY(0) is active low, convert to active high
left_sig <= SW(0); -- SW(0) for LEFT input
right_sig <= SW(1); -- SW(1) for RIGHT input
-- Clock divider for human-visible operation
clk_div_inst: clock_divider port map (
CLK_IN => CLOCK_50,
RESET => reset_sig,
CLK_OUT => slow_clk
);
-- Control Unit
ctrl_unit: control_unit port map (
CLK => slow_clk,
RESET => reset_sig,
LEFT => left_sig,
RIGHT => right_sig,
LMASK_ZERO => lmask_zero,
RMASK_ZERO => rmask_zero,
DISPLAY_SEL => display_sel,
LMASK_EN => lmask_en,
RMASK_EN => rmask_en,
DISPLAY_EN => display_en,
LMASK_SHIFT => lmask_shift,
RMASK_SHIFT => rmask_shift,
LMASK_RESET => lmask_reset,
RMASK_RESET => rmask_reset
);
-- Datapath
datapath_inst: datapath port map (
CLK => slow_clk,
RESET => reset_sig,
DISPLAY_SEL => display_sel,
LMASK_EN => lmask_en,
RMASK_EN => rmask_en,
DISPLAY_EN => display_en,
LMASK_SHIFT => lmask_shift,
RMASK_SHIFT => rmask_shift,
LMASK_RESET => lmask_reset,
RMASK_RESET => rmask_reset,
LMASK_ZERO => lmask_zero,
RMASK_ZERO => rmask_zero,
DISPLAY_OUT => display_out
);
-- Output mapping to red LEDs
LEDR <= display_out;
end structural;
-- ==================================================
-- Testbench for ModelSim Simulation
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_led_controller is
end tb_led_controller;
architecture structural of tb_led_controller is
component led_controller_top
Port ( CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
LEFT : in STD_LOGIC;
RIGHT : in STD_LOGIC;
DISPLAY_OUT : out STD_LOGIC_VECTOR(7 downto 0));
end component;
-- Test signals
signal clk_tb : STD_LOGIC := '0';
signal reset_tb : STD_LOGIC := '1';
signal left_tb : STD_LOGIC := '0';
signal right_tb : STD_LOGIC := '0';
signal display_out_tb : STD_LOGIC_VECTOR(7 downto 0);
-- Clock period for simulation (much faster than real clock)
constant CLK_PERIOD : time := 20 ns; -- 50MHz clock
begin
-- Instantiate Unit Under Test (UUT)
uut: led_controller_top port map (
CLK => clk_tb,
RESET => reset_tb,
LEFT => left_tb,
RIGHT => right_tb,
DISPLAY_OUT => display_out_tb
);
-- Clock generation process
clk_process: process
begin
while true loop
clk_tb <= '0';
wait for CLK_PERIOD/2;
clk_tb <= '1';
wait for CLK_PERIOD/2;
end loop;
end process;
-- Stimulus process
stimulus_process: process
begin
-- Initial reset
reset_tb <= '1';
left_tb <= '0';
right_tb <= '0';
wait for 100 ns;
-- Release reset
reset_tb <= '0';
wait for 100 ns;
-- Test Case 1: LEFT switch only
report "Testing LEFT switch only";
left_tb <= '1';
right_tb <= '0';
wait for 2 us; -- Wait for several clock cycles
-- Test Case 2: RIGHT switch only
report "Testing RIGHT switch only";
left_tb <= '0';
right_tb <= '1';
wait for 2 us;
-- Test Case 3: Both switches
report "Testing BOTH switches";
left_tb <= '1';
right_tb <= '1';
wait for 2 us;
-- Test Case 4: No switches (should show all zeros)
report "Testing NO switches";
left_tb <= '0';
right_tb <= '0';
wait for 2 us;
-- Test Case 5: Longer test with LEFT to see shifting
report "Long test with LEFT switch";
left_tb <= '1';
right_tb <= '0';
wait for 10 us; -- Longer wait to see multiple shifts
-- Test Case 6: Reset during operation
report "Testing RESET during operation";
reset_tb <= '1';
wait for 100 ns;
reset_tb <= '0';
wait for 1 us;
-- End simulation
report "Simulation completed successfully";
wait;
end process;
-- Monitor process (optional - prints values during simulation)
monitor_process: process(display_out_tb, left_tb, right_tb)
begin
report "LEFT=" & std_logic'image(left_tb) &
" RIGHT=" & std_logic'image(right_tb) &
" DISPLAY=" & integer'image(to_integer(unsigned(display_out_tb)));
end process;
end structural;
-- ==================================================
-- Fast Clock Divider for Simulation
-- ==================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity fast_clk_div is
Port ( clock_25Mhz : in STD_LOGIC;
clock_1MHz : out STD_LOGIC;
clock_100KHz : out STD_LOGIC;
clock_10KHz : out STD_LOGIC;
clock_1KHz : out STD_LOGIC;
clock_100Hz : out STD_LOGIC;
clock_10Hz : out STD_LOGIC;
clock_1Hz : out STD_LOGIC);
end fast_clk_div;
architecture structural of fast_clk_div is
signal counter : integer range 0 to 15 := 0;
signal fast_clock : STD_LOGIC := '0';
begin
-- Very fast clock divider for simulation
process(clock_25Mhz)
begin
if rising_edge(clock_25Mhz) then
if counter = 15 then -- Divide by 16 instead of 25000000
counter <= 0;
fast_clock <= not fast_clock;
else
counter <= counter + 1;
end if;
end if;
end process;
-- All outputs get the same fast clock for simulation
clock_1MHz <= fast_clock;
clock_100KHz <= fast_clock;
clock_10KHz <= fast_clock;
clock_1KHz <= fast_clock;
clock_100Hz <= fast_clock;
clock_10Hz <= fast_clock;
clock_1Hz <= fast_clock; -- This is what gets used
end structural;
![]() |
Notes is a web-based application for online taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000+ notes created and continuing...
With notes.io;
- * You can take a note from anywhere and any device with internet connection.
- * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
- * You can quickly share your contents without website, blog and e-mail.
- * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
- * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.
Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.
Easy: Notes.io doesn’t require installation. Just write and share note!
Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )
Free: Notes.io works for 14 years and has been free since the day it was started.
You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;
Email: [email protected]
Twitter: http://twitter.com/notesio
Instagram: http://instagram.com/notes.io
Facebook: http://facebook.com/notesio
Regards;
Notes.io Team
