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 lab4_mod_10_to_1 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) :="000000000000000000"; -- LEDr's, power up state OFF.
- ledg : OUT STD_LOGIC_VECTOR( 8 DOWNTO 0) :="000000000"; -- LEDg's, power up state OFF.
- hex0, hex2 : OUT STD_LOGIC_VECTOR( 6 DOWNTO 0) -- seven segments to display numbers
- );
- END lab4_mod_10_to_1;
- ARCHITECTURE SimpleCircuit OF lab4_mod_10_to_1 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 TenHzModCLK: STD_LOGIC; -- modulus 10 Hz clock
- SIGNAL OneHzModCLK: STD_LOGIC; -- modulus 1 Hz clock
- SIGNAL ten_mod_counter: UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE); -- reset modulus counter to zero
- SIGNAL one_mod_counter: UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE); --new signal for 1 Hz modulus clock.
- SIGNAL mod_terminal: UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE); -- reset terminal count of modulus counter to zero
- -- time_elpased is ONLY incremented on rising_edge of the clock.
- SIGNAL time_elapsed: UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE); -- this is a variable that counts the number of seconds have passed.
- SIGNAL flip : STD_LOGIC := '-1';
- TYPE STATES IS (STATE0, STATE1, STATE2, STATE3); -- list all the STATES
- SIGNAL state, next_state: STATES; -- current and next state signals of 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
- ----------------------------------------------------------------------------------------------------
- -- NOTE: SELECT SWITCHES IN THE RIGHT CONFIGURATION BEFORE PROGRAMMING ON FPGA/SIMULATION.
- -- NOTE 2: FOR 10Hz(final output) clock select sw(2 downto 0) in '001' config.
- -- EXTREMELY IMPORTANT: mod_terminal = half of desired clock.
- -- example: for 10 Hz final clock, you need 5Hz mod_terminal.
- -- How to Use?
- -- '001' : A modulus clock divider to create a 10Hz clock from the board's 50MHz clock input.
- ----------------------------------------------------------------------------------------------------
- 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 *** -- 25000000 MHz
- -- the below process creates a 10Hz Clock from 50MHz Clock.
- -- CAUTION: MAKE SURE YOU SELECT SWITCH CONFIG = '001' BEFORE PROCEEDING ANY FURTHER!
- ModCLK10: PROCESS(clock_50)
- BEGIN
- IF (rising_edge(clock_50)) THEN -- modulus counter increments on rising clock edge
- IF (ten_mod_counter = mod_terminal) THEN -- half period
- TenHzModCLK <= NOT TenHzModCLK; -- toggle
- ten_mod_counter <= to_unsigned(0,CLK_DIV_SIZE); -- reset counter
- ELSE
- ten_mod_counter <= ten_mod_counter + 1; -- otherwise keep incrementing until half-period
- END IF;
- END IF;
- END PROCESS;
- LEDG(0) <= TenHzModCLK;
- -- the below process creates a 1Hz Clock from 10Hz Clock.
- -- 1Hz clock can be produced by 10Hz by selecting a mod_terminal value of 10.
- -- "0000000000000000000001001" = 9 and this would be mod_terminal-1.
- ModCLK01: PROCESS(TenHzModCLK)
- BEGIN
- IF (rising_edge(TenHzModCLK)) THEN --modulus counter increments only on rising clock edge
- IF (one_mod_counter = "0000000000000000000001001") THEN -- we only need to go uptil 9, at 10 we reset. -- half period
- OneHzModCLK <= NOT OneHzModCLK; -- toggle.
- one_mod_counter <= to_unsigned(0,CLK_DIV_SIZE); -- reset counter
- ELSE
- one_mod_counter <= one_mod_counter + 1; -- otherwise keep incrementing until half-period.
- END IF;
- END IF;
- END PROCESS;
- LEDG(1) <= OneHzModCLK;
- ----------------------------------------------------------------------------------------------------
- Main1HzCLK <= OneHzModCLK; -- assigns modulus clock as main clock.
- ----------------------------------------------------------------------------------------------------
- -- STATE0 : GFLASH FOR 2 SECONDS
- -- STATE1 : GSOLID FOR 5 SECONDS
- -- STATE2 : RFLASH FOR 3 SECONDS
- -- STATE3 : RSOLID FOR 6 SECONDS
- FSM: PROCESS(state, rising_edge(Main1HzCLK), falling_edge(Main1HzCLK)) -- main FSM
- BEGIN
- next_state <= state; -- The only purpose of this line is to give initial value to the signal 'next_state' in order to avoid latch creation.
- CASE state IS
- WHEN STATE0 =>
- state_number <= "0000";
- ledr(11) <= '0'; -- turn ledr(11) to OFF.
- IF (rising_edge(Main1HzCLK)) THEN -- change on every rising edge.
- IF(time_elapsed <= 0000000000000000000000002) THEN -- but only remain here if it's [0,2] seconds
- next_state <= STATE0; -- remain here.
- time_elapsed <= time_elapsed + 1; -- increment time by +1 seconds. ONLY AT RISING EDGE!
- ledg(8) <= '1'; -- toggle ledg(8).
- ELSE -- GFLASH IS OVER, 2 seconds have passed.
- next_state <= STATE1; -- Go to GSOLID.
- time_elapsed <= time_elapsed + 1; -- increment time by +1 seconds. ONLY AT RISING EDGE!
- ledg(8) <= '1'; -- assign for constant green solid. ON.
- END IF;
- ELSE -- falling edge condition
- IF(time_elapsed <= 0000000000000000000000002) THEN -- but only remain here if it's [0,2] seconds [IS NOT REQ, SINCE IT WILL BE EQUAL]
- next_state <= STATE0; -- remain here.
- ledg(8) <= '0'; -- toggle ledg(8).
- END IF;
- END IF;
- WHEN STATE1 =>
- state_number <= "0001";
- ledr(11) <= '0'; -- turn ledr(11) to OFF.
- IF (rising_edge(Main1HzCLK)) THEN -- change on every rising edge.
- IF(time_elapsed <= 0000000000000000000000007) THEN -- but only remain here if it's [3,7] seconds
- next_state <= STATE1; -- remain here.
- time_elapsed <= time_elapsed + 1; -- increment time by +1 seconds. ONLY AT RISING EDGE!
- ledg(8) <= '1'; -- assign for constant green solid. ON.
- ELSE -- GSOLID IS OVER, 7 seconds have passed.
- next_state <= STATE2; -- Go to RFLASH.
- time_elapsed <= time_elapsed + 1; -- increment time by +1 seconds. ONLY AT RISING EDGE!
- ledg(8) <= '0'; -- turn OFF ledg(8) now.
- ledr(11) <= '1'; -- turn ON ledr(11) now.
- END IF;
- ELSE -- falling edge condition
- IF(time_elapsed <= 0000000000000000000000007) THEN -- but only remain here if it's [3,7] seconds [IS NOT REQ, SINCE IT WILL BE EQUAL]
- next_state <= STATE0; -- remain here.
- ledg(8) <= '1'; -- assign for constant green solid. ON.
- END IF;
- END IF;
- WHEN STATE2 =>
- state_number <= "0010";
- ledg(8) <= '0'; -- turn ledg(8) to OFF.
- IF (rising_edge(Main1HzCLK)) THEN -- change on every rising edge.
- IF(time_elapsed <= 0000000000000000000000010) THEN -- but only remain here if it's [7,10] seconds
- next_state <= STATE2; -- remain here.
- time_elapsed <= time_elapsed + 1; -- increment time by +1 seconds. ONLY AT RISING EDGE!
- ledr(11) <= '1'; -- toggle ledr(11).
- ELSE -- RFLASH IS OVER, 3 seconds have passed.
- next_state <= STATE3; -- Go to RSOLID.
- time_elapsed <= time_elapsed + 1; -- increment time by +1 seconds. ONLY AT RISING EDGE!
- ledr(11) <= '1'; -- assign for constant red solid. ON.
- END IF;
- ELSE -- falling edge condition
- IF(time_elapsed <= 0000000000000000000000010) THEN -- but only remain here if it's [7,10] seconds
- next_state <= STATE2; -- remain here.
- ledr(11) <= '0'; -- toggle ledr(11).
- END IF;
- END IF;
- WHEN STATE3 => -- STATE3
- state_number <= "0011";
- ledg(8) <= '0'; -- turn ledg(8) to OFF.
- IF (rising_edge(Main1HzCLK)) THEN -- change on every rising edge.
- IF(time_elapsed <= 0000000000000000000000016) THEN -- but only remain here if it's [10,16] seconds
- next_state <= STATE3; -- remain here.
- time_elapsed <= time_elapsed + 1; -- increment time by +1 seconds. ONLY AT RISING EDGE!
- ledr(11) <= '1'; -- assign for constant red solid. ON.
- ELSE -- RSOLID IS OVER, 6 seconds have passed.
- next_state <= STATE2; -- Go to GFLASH.
- time_elapsed <= time_elapsed + 1; -- increment time by +1 seconds. ONLY AT RISING EDGE!
- ledr(11) <= '0'; -- turn OFF ledr(11) now.
- ledg(8) <= '1'; -- turn ON ledg(8) now.
- END IF;
- ELSE -- falling edge condition
- IF(time_elapsed <= 0000000000000000000000016) THEN -- but only remain here if it's [10,16] seconds [IS NOT REQ, SINCE IT WILL BE EQUAL]
- next_state <= STATE3; -- remain here.
- ledr(11) <= '1'; -- assign for constant red solid. ON.
- END IF;
- END IF;
- END CASE;
- END PROCESS;
- ----------------------------------------------------------------------------------------------------
- SeqLogic: PROCESS(Main1HzCLK, state) -- creats sequential logic to latch the state
- BEGIN
- IF (rising_edge(Main1HzCLK)) THEN
- state <= next_state; -- on the rising edge of clock the current state is updated with next state
- IF (state = STATE1) THEN
- state_counter <= state_counter + 1; -- on the rising edge of clock the current counter is incremented if state is STATE1
- END IF;
- END IF;
- END PROCESS;
- ----------------------------------------------------------------------------------------------------
- D7S0: SevenSegment PORT MAP( state_number, '0', hex0 );
- D7S4: SevenSegment PORT MAP( std_logic_vector(state_counter), '0', hex2 );
- END SimpleCircuit;
Add Comment
Please, Sign In to add comment