Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- LIBRARY ieee;
- USE ieee.std_logic_1164.ALL;
- USE ieee.numeric_std.ALL;
- --
- -- 7-segment display driver. It displays a 4-bit number on 7-segments
- -- This is created as an entity so that it can be reused many times easily
- --
- ENTITY SevenSegment IS PORT (
- dataIn : IN std_logic_vector(3 DOWNTO 0); -- The 4 bit data to be displayed
- blanking : IN std_logic; -- This bit turns off all segments
- segmentsOut : OUT std_logic_vector(6 DOWNTO 0) -- 7-bit outputs to a 7-segment
- );
- END SevenSegment;
- ARCHITECTURE Behavioral OF SevenSegment IS
- --
- -- The following statements convert a 4-bit input, called dataIn to a pattern of 7 bits
- -- The segment turns on when it is '0' otherwise '1'
- -- The blanking input is added to turns off the all segments
- --
- BEGIN
- with blanking & dataIn SELECT -- gfedcba b3210 -- D7S
- segmentsOut(6 DOWNTO 0) <= "1000000" WHEN "00000", -- [0]
- "1111001" WHEN "00001", -- [1]
- "0100100" WHEN "00010", -- [2] +---- a ----+
- "0110000" WHEN "00011", -- [3] | |
- "0011001" WHEN "00100", -- [4] | |
- "0010010" WHEN "00101", -- [5] f b
- "0000010" WHEN "00110", -- [6] | |
- "1111000" WHEN "00111", -- [7] | |
- "0000000" WHEN "01000", -- [8] +---- g ----+
- "0010000" WHEN "01001", -- [9] | |
- "0001000" WHEN "01010", -- [A] | |
- "0000011" WHEN "01011", -- [b] e c
- "0100111" WHEN "01100", -- [c] | |
- "0100001" WHEN "01101", -- [d] | |
- "0000110" WHEN "01110", -- [E] +---- d ----+
- "0001110" WHEN "01111", -- [F]
- "1111111" WHEN OTHERS; -- [ ]
- END Behavioral;
- --------------------------------------------------------------------------------
- -- Main entity
- --------------------------------------------------------------------------------
- LIBRARY ieee;
- USE ieee.std_logic_1164.ALL;
- USE ieee.numeric_std.ALL;
- ENTITY Lab4B IS
- PORT(
- clock_50 : IN STD_LOGIC;
- sw : IN STD_LOGIC_VECTOR(17 DOWNTO 0); -- 18 dip switches on the board
- ledr : OUT STD_LOGIC_VECTOR(17 DOWNTO 0); -- LEDs, many Red ones are available
- ledg : OUT STD_LOGIC_VECTOR( 8 DOWNTO 0); -- LEDs, many Green ones are available
- hex0, hex2, hex4, hex6 : OUT STD_LOGIC_VECTOR( 6 DOWNTO 0) -- seven segments to display numbers
- );
- END Lab4B;
- ARCHITECTURE SimpleCircuit OF Lab4B IS
- --------------------------------------------------------------------------------
- -- In order to use the "SevenSegment" entity, we should declare it with first
- --------------------------------------------------------------------------------
- COMPONENT SevenSegment PORT( -- Declare the 7 segment component to be used
- dataIn : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
- blanking : IN STD_LOGIC;
- segmentsOut : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)
- );
- END COMPONENT;
- ----------------------------------------------------------------------------------------------------
- CONSTANT CLK_DIV_SIZE: INTEGER := 25; -- size of vectors for the counters
- SIGNAL Main1HzCLK: STD_LOGIC; -- main 1Hz clock to drive FSM
- -- SIGNAL OneHzBinCLK: STD_LOGIC; -- binary 1 Hz clock
- SIGNAL OneHzModCLK , TenHzModCLK: STD_LOGIC;
- -- SIGNAL bin_counter: UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE); -- reset binary counter to zero
- SIGNAL mod_counter: UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE); -- reset modulus counter to zero
- SIGNAL mod_terminal: UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE); -- reset terminal count of modulus counter to zero
- TYPE STATES IS (STATE0, STATE1, STATE2, STATE3, STATE4, STATE5); -- list all the STATES
- SIGNAL state, next_state: STATES; -- current and next state signals od type STATES
- SIGNAL state_number: STD_LOGIC_VECTOR(3 DOWNTO 0); -- binary state number to display on seven-segment
- SIGNAL state_counter: UNSIGNED(3 DOWNTO 0); -- binary state counter to display on seven-segment
- SIGNAL nightMode: STD_LOGIC;
- SIGNAL defaultSide: STD_LOGIC;
- SIGNAL sensorNS: STD_LOGIC;
- SIGNAL sensorEW: STD_LOGIC;
- SIGNAL isCarDetected: STD_LOGIC;
- SIGNAL timer: UNSIGNED(3 downto 0) := "0000"; -- counter for changes in light
- SIGNAL RedNS: STD_LOGIC; -- red light for NS
- SIGNAL RedEW: STD_LOGIC; -- red light for EW
- SIGNAL GreenNS: STD_LOGIC; -- green light for NS
- SIGNAL GreenEW: STD_LOGIC; -- green light for EW
- SIGNAL waitCounterNS UNSIGNED(3 downto 0) := "0000"; -- waitCounter for NS
- SIGNAL waitCounterEW UNSIGNED(3 downto 0) := "0000"; -- waitCounter for EW
- SIGNAL onemod_counter, tenmod_counter: UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE);
- ----------------------------------------------------------------------------------------------------
- BEGIN
- WITH sw(2 DOWNTO 0) SELECT -- terminal count for modulus counter for F0= 50 MHz clock input (T0 = 20 ns)
- mod_terminal <= "1011111010111100000111111" WHEN "000", -- F = 1 Hz, T/2 = 25000000 * T0
- "0010011000100101100111111" WHEN "001", -- F = 5 Hz, T/2 = 5000000 * T0
- "0001001100010010110011111" WHEN "010", -- F = 10 Hz, T/2 = 2500000 * T0
- "0000000111101000010001111" WHEN "011", -- F = 100 Hz, T/2 = 250000 * T0
- "1011111010111100000111111" WHEN OTHERS; -- *** default ***
- ModTenClk: PROCESS(clock_50)
- BEGIN
- IF (rising_edge(clock_50)) THEN -- modulus counter increments on rising clock edge
- IF (tenmod_counter = "0001001100010010110011111") THEN -- 2499999 (Terminal Value for reset))
- tenmod_counter <= to_unsigned(0,CLK_DIV_SIZE); -- reset counter
- TenHzModCLK <= NOT TenHzModCLK; -- toggle clock
- ELSE
- tenmod_counter <= tenmod_counter + 1; -- increment clock
- END IF;
- END IF;
- END PROCESS;
- ----------------------------------------------------------------------------------------------------
- ModOneClk: PROCESS(TenHzModCLK)
- BEGIN
- IF (rising_edge(TenHzModCLK)) THEN -- modulus counter increments on rising clock edge
- IF (onemod_counter = "0000000000000000000000101") THEN -- half period
- OneHzModCLK <= NOT OneHzModCLK; -- toggle
- onemod_counter <= to_unsigned(0,CLK_DIV_SIZE); -- reset counter
- ELSE
- onemod_counter <= onemod_counter + 1;
- END IF;
- END IF;
- END PROCESS;
- ------------------------------------------------------------------------------------------------------
- sensorNS <= sw(15);
- sensorEW <= sw(14);
- nightMode <= sw(17);
- defaultSide <= sw(16);
- ledr(11) <= RedNS; -- RedNS is assigned to ledr11
- ledg(8) <= GreenNS; -- GreenNS is assigned to ledg8
- ledr(0) <= RedEW; -- RedEW is assigned to ledr0
- ledg(7) <= GreenEW; -- GreenEW is assigned to ledg7
- ------------------------------------------------------------------------------------------------------
- -- BinCLK: PROCESS(clock_50)
- -- BEGIN
- -- IF (rising_edge(clock_50)) THEN -- binary counter increments on rising clock edge
- -- bin_counter <= bin_counter + 1;
- -- END IF;
- -- END PROCESS;
- -- OneHzBinCLK <= std_logic(bin_counter(CLK_DIV_SIZE-1)); -- binary counter MSB
- -- LEDG(2) <= OneHzBinCLK;
- ------------------------------------------------------------------------------------------------------
- FSM: PROCESS(state, sw)
- BEGIN
- IF ((sensorNS='1' AND defaultSide='1') OR (sensorEW='1' AND defaultSide='0') ) THEN -- Condition to check if a car is detected on the Non-Default Side
- isCarDetected <= '1'; -- If detected, assign '1' to isCarDetected variable
- ELSE
- isCarDetected <= '0'; -- Else, '0'
- END IF;
- IF (nightMode ='1' AND isCarDetected = '0') THEN -- Check if OperationMode = nightMode and a car is detected on ND side
- next_state <=STATE0; -- Day Mode -- If yes, then go to State 0 (Day Mode)
- ELSE
- next_state <=STATE3; --Green-Amber (Red Flashing) on Default Side -- If no, then go to State 3 (Green Amber flashing) on Default Side
- END IF;
- CASE state IS
- WHEN STATE0 =>
- state_number <= "0000";
- next_state <= STATE1;
- IF (defaultSide = '1') THEN -- DefaultSide: EW
- RedNS <='1'; -- RedNS ON
- GreenNS <='0'; -- Green NS OFF
- RedEW <='0'; -- RedEW OFF
- GreenEW <=TenHzModCLK; -- GreenNS Flashing
- ELSE -- DefaultSide: NS
- RedNS <='0'; -- RedNS OFF
- GreenNS <=TenHzModCLK; -- GreenNS Flashing
- RedEW <='1'; -- RedEW ON
- GreenEW <='0'; -- GreenEW
- END IF;
- WHEN STATE1 =>
- state_number <= "0001";
- next_state <= STATE2;
- IF (DefaultSide = '1') THEN -- DefaultSide: EW
- RedNS <='1'; -- RedNS ON
- GreenNS <='0'; -- GreenNS OFF
- RedEW <='0'; -- RedEW OFF
- GreenEW <='1'; -- GreenEW ON
- ELSE -- DefaultSide: NS
- RedNS <='0'; -- RedNS OFF
- GreenNS <='1'; -- GreenNS ON
- RedEW <='1'; -- RedEW ON
- GreenEW <='0'; -- GreenEW OFF
- END IF;
- WHEN STATE2 =>
- state_number <= "0010";
- IF (DefaultSide = '1') THEN -- DefaultSide: EW
- RedNS <='1'; -- RedNS ON
- GreenNS <='0'; -- GreenNS OFF
- RedEW <=TenHzModCLK; -- RedEW Flashing
- GreenEW <='0'; -- GreenEW OFF
- ELSE
- RedNS <=TenHzModCLK; -- RedNS Flashing
- GreenNS <='0'; -- GreenNS OFF
- RedEW <='1'; -- RedEW ON
- GreenEW <='0'; -- GreenEW OFF
- END IF;
- WHEN STATE3 =>
- state_number <= "0011";
- next_state <= STATE4;
- IF (DefaultSide = '1') THEN -- DefaultSide: EW
- RedNS <='0'; -- RedNS OFF
- GreenNS <=TenHzModCLK; -- GreenNS Flashing
- RedEW <='1'; -- RedEW ON
- GreenEW <='0'; -- GreenEW Flashing
- ELSE -- DefaultSide: NS
- RedNS <='1'; -- RedNS ON
- GreenNS <='0'; -- GreenNS OFF
- RedEW <='0'; -- RedEW OFF
- GreenEW <=TenHzModCLK; -- GreenEW Flashing
- END IF;
- WHEN STATE4 =>
- state_number <= "0100" ;
- next_state <=STATE5;
- IF (DefaultSide = '1') THEN -- DefaultSide: EW
- RedNS <='0'; -- RedNS OFF
- GreenNS <='1'; -- GreenNS ON
- RedEW <='1'; -- RedEW ON
- GreenEW <='0'; -- GreenEW OFF
- ELSE -- DefaultSide: NS
- RedNS <='1'; -- RedNS ON
- GreenNS <='0'; -- GreenNS OFF
- RedEW <='0'; -- RedEW OFF
- GreenEW <='1'; -- GreenEW ON
- END IF;
- WHEN STATE5 =>
- state_number <= "0101";
- next_state <= STATE0;
- IF (DefaultSide = '1') THEN -- DefaultSide: EW
- RedNS <=TenHzModCLK; -- RedNS Flashing
- GreenNS <='0'; -- GreenNS OFF
- RedEW <='1'; -- RedEW ON
- GreenEW <='0'; -- GreenEW OFF
- ELSE -- DefaultSide: NS
- RedNS <='1'; -- RedNS ON
- GreenNS <='0'; -- GreenNS OFF
- RedEW <=TenHzModCLK; -- RedEW Flashing
- GreenEW <='0'; -- GreenEW O
- END IF;
- END CASE;
- END PROCESS;
- ------------------------------------------------------------------------------------------------------
- SeqLogic: PROCESS (OneHzModCLK, state)
- BEGIN
- IF(rising_edge(OneHzModCLK)) THEN
- timer <= timer +1; -- on rising edge of clock, increment timer by 1
- state_counter <= state_counter + 1; -- on rising edge of clock, increment state_counter by 1
- IF(timer = "0001") THEN -- at 1.0s, go to next state
- state <= next_state;
- ELSIF(timer = "0101") THEN -- at 5.0s, go to next state
- state <= next_state;
- ELSIF(timer = "0111") THEN -- at 7.0s, go to next state
- state <= next_state;
- ELSIF(timer = "1001") THEN -- at 9.0s, go to next state
- state <= next_state;
- ELSIF(timer = "1101") THEN -- at 13.0s, go to next state
- state <= next_state;
- ELSIF(timer = "1111") THEN -- at 15.0s, go to next state
- state <= next_state;
- timer <= "0000"; -- now, reset the timer, so that at 15.0s, next state is state0
- state_counter <= "0000"; -- reset the counter as well, so another new sequence can be started
- IF (waitCounterNS = '1' AND redNS = '1') THEN
- waitCounterNS <= waitCounterNS + 1;
- ELSE
- waitCounterNS <= "0000";
- END IF;
- IF (waitCounterEW = '1' AND redEW = '1') THEN
- waitCounterEW <= waitCounterEW + 1;
- ELSE
- waitCounterEW <= "0000";
- END IF;
- END IF;
- END IF;
- END PROCESS;
- ------------------------------------------------------------------------------------------------------
- D7S0: SevenSegment PORT MAP( state_number, '0', hex0 ); -- Show state number
- D7S2: SevenSegment PORT MAP( std_logic_vector(state_counter), '0', hex2 ); -- Show timer
- D7S4: SevenSegment PORT MAP( std_logic_vector(waitCounterNS), '0', hex4 ); -- Show wait counter for NS
- D7S6: SevenSegment PORT MAP( std_logic_vector(waitCounterEW), '0', hex6 ); -- Show wait counter for EW
- END SimpleCircuit;
Add Comment
Please, Sign In to add comment