Guest User

Untitled

a guest
Sep 7th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VHDL 13.94 KB | None | 0 0
  1. LIBRARY ieee;
  2. USE ieee.std_logic_1164.ALL;
  3. USE ieee.numeric_std.ALL;
  4.  
  5. --
  6. -- 7-segment display driver. It displays a 4-bit number on 7-segments
  7. -- This is created as an entity so that it can be reused many times easily
  8. --
  9.  
  10. ENTITY SevenSegment IS PORT (
  11.    
  12.    dataIn      :  IN  std_logic_vector(3 DOWNTO 0);   -- The 4 bit data to be displayed
  13.    blanking    :  IN  std_logic;                      -- This bit turns off all segments
  14.    
  15.    segmentsOut :  OUT std_logic_vector(6 DOWNTO 0)    -- 7-bit outputs to a 7-segment
  16. );
  17. END SevenSegment;
  18.  
  19. ARCHITECTURE Behavioral OF SevenSegment IS
  20.  
  21. --
  22. -- The following statements convert a 4-bit input, called dataIn to a pattern of 7 bits
  23. -- The segment turns on when it is '0' otherwise '1'
  24. -- The blanking input is added to turns off the all segments
  25. --
  26.  
  27. BEGIN
  28.  
  29.    with blanking & dataIn SELECT --  gfedcba        b3210      -- D7S
  30.       segmentsOut(6 DOWNTO 0) <=    "1000000" WHEN "00000",    -- [0]
  31.                                     "1111001" WHEN "00001",    -- [1]
  32.                                     "0100100" WHEN "00010",    -- [2]      +---- a ----+
  33.                                     "0110000" WHEN "00011",    -- [3]      |           |
  34.                                     "0011001" WHEN "00100",    -- [4]      |           |
  35.                                     "0010010" WHEN "00101",    -- [5]      f           b
  36.                                     "0000010" WHEN "00110",    -- [6]      |           |
  37.                                     "1111000" WHEN "00111",    -- [7]      |           |
  38.                                     "0000000" WHEN "01000",    -- [8]      +---- g ----+
  39.                                     "0010000" WHEN "01001",    -- [9]      |           |
  40.                                     "0001000" WHEN "01010",    -- [A]      |           |
  41.                                     "0000011" WHEN "01011",    -- [b]      e           c
  42.                                     "0100111" WHEN "01100",    -- [c]      |           |
  43.                                     "0100001" WHEN "01101",    -- [d]      |           |
  44.                                     "0000110" WHEN "01110",    -- [E]      +---- d ----+
  45.                                     "0001110" WHEN "01111",    -- [F]
  46.                                     "1111111" WHEN OTHERS;     -- [ ]
  47.  
  48. END Behavioral;
  49.  
  50. --------------------------------------------------------------------------------
  51. -- Main entity
  52. --------------------------------------------------------------------------------
  53.  
  54. LIBRARY ieee;
  55. USE ieee.std_logic_1164.ALL;
  56. USE ieee.numeric_std.ALL;
  57.  
  58. ENTITY lab4_mod_10_to_1 IS
  59.    PORT(
  60.      
  61.       clock_50   : IN  STD_LOGIC;
  62.       sw         : IN  STD_LOGIC_VECTOR(17 DOWNTO 0); -- 18 dip switches on the board
  63.  
  64.       ledr       : OUT STD_LOGIC_VECTOR(17 DOWNTO 0) :="000000000000000000"; -- LEDr's, power up state OFF.
  65.       ledg       : OUT STD_LOGIC_VECTOR( 8 DOWNTO 0) :="000000000"; -- LEDg's, power up state OFF.
  66.       hex0, hex2 : OUT STD_LOGIC_VECTOR( 6 DOWNTO 0)  -- seven segments to display numbers
  67. );
  68. END lab4_mod_10_to_1;
  69.  
  70. ARCHITECTURE SimpleCircuit OF lab4_mod_10_to_1 IS
  71.  
  72. --
  73. -- In order to use the "SevenSegment" entity, we should declare it with first
  74. --
  75.  
  76.    COMPONENT SevenSegment PORT(        -- Declare the 7 segment component to be used
  77.       dataIn      : IN  STD_LOGIC_VECTOR(3 DOWNTO 0);
  78.       blanking    : IN  STD_LOGIC;
  79.       segmentsOut : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)
  80.    );
  81.    END COMPONENT;
  82. ----------------------------------------------------------------------------------------------------
  83.    CONSTANT CLK_DIV_SIZE: INTEGER := 25;     -- size of vectors for the counters
  84.  
  85.    SIGNAL Main1HzCLK:   STD_LOGIC; -- main 1Hz clock to drive FSM
  86.  
  87.    SIGNAL TenHzModCLK:  STD_LOGIC; -- modulus 10 Hz clock
  88.    SIGNAL OneHzModCLK:  STD_LOGIC; -- modulus  1 Hz clock
  89.  
  90.    SIGNAL ten_mod_counter:  UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE); -- reset modulus counter to zero
  91.    SIGNAL one_mod_counter:  UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE); --new signal for 1 Hz modulus clock.
  92.    SIGNAL mod_terminal: UNSIGNED(CLK_DIV_SIZE-1 DOWNTO 0) := to_unsigned(0,CLK_DIV_SIZE); -- reset terminal count of modulus counter to zero
  93.    
  94.    -- time_elpased is ONLY incremented on rising_edge of the clock.
  95.    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.
  96.    
  97.    SIGNAL flip : STD_LOGIC := '-1';
  98.    
  99.    TYPE STATES IS (STATE0, STATE1, STATE2, STATE3);   -- list all the STATES
  100.    SIGNAL state, next_state:  STATES;                 -- current and next state signals of type STATES
  101.    
  102.    SIGNAL state_number: STD_LOGIC_VECTOR(3 DOWNTO 0); -- binary state number to display on seven-segment
  103.  
  104.    SIGNAL state_counter: UNSIGNED(3 DOWNTO 0);        -- binary state counter to display on seven-segment
  105. ----------------------------------------------------------------------------------------------------
  106.  
  107. -- NOTE: SELECT SWITCHES IN THE RIGHT CONFIGURATION BEFORE PROGRAMMING ON FPGA/SIMULATION.
  108. -- NOTE 2: FOR 10Hz(final output) clock select sw(2 downto 0) in '001' config.
  109.  
  110. -- EXTREMELY IMPORTANT: mod_terminal = half of desired clock.
  111. -- example: for 10 Hz final clock, you need 5Hz mod_terminal.
  112.  
  113. -- How to Use?
  114. -- '001' : A modulus clock divider to create a 10Hz clock from the board's 50MHz clock input.
  115.  
  116.   ----------------------------------------------------------------------------------------------------
  117.   BEGIN
  118.  
  119.    WITH sw(2 DOWNTO 0) SELECT -- terminal count for modulus counter for F0= 50 MHz clock input (T0 = 20 ns)
  120.       mod_terminal <= "1011111010111100000111111" WHEN "000",  -- F =   1 Hz, T/2 = 25000000 * T0
  121.                       "0010011000100101100111111" WHEN "001",  -- F =   5 Hz, T/2 =  5000000 * T0
  122.                       "0001001100010010110011111" WHEN "010",  -- F =  10 Hz, T/2 =  2500000 * T0
  123.                       "0000000111101000010001111" WHEN "011",  -- F = 100 Hz, T/2 =   250000 * T0
  124.                       "1011111010111100000111111" WHEN OTHERS; -- *** default ***  -- 25000000 MHz
  125.  
  126.  
  127.  -- the below process creates a 10Hz Clock from 50MHz Clock.
  128.  -- CAUTION: MAKE SURE YOU SELECT SWITCH CONFIG = '001' BEFORE PROCEEDING ANY FURTHER!
  129.  
  130.    ModCLK10: PROCESS(clock_50)
  131.    BEGIN
  132.       IF (rising_edge(clock_50)) THEN -- modulus counter increments on rising clock edge
  133.          IF (ten_mod_counter = mod_terminal) THEN       -- half period
  134.             TenHzModCLK <= NOT TenHzModCLK;                 -- toggle
  135.             ten_mod_counter <= to_unsigned(0,CLK_DIV_SIZE); -- reset counter
  136.          ELSE
  137.             ten_mod_counter <= ten_mod_counter + 1;  -- otherwise keep incrementing until half-period
  138.          END IF;
  139.       END IF;
  140.    END PROCESS;
  141.    LEDG(0) <= TenHzModCLK;
  142.    
  143.   -- the below process creates a 1Hz Clock from 10Hz Clock.
  144.   -- 1Hz clock can be produced by 10Hz by selecting a mod_terminal value of 10.
  145.   -- "0000000000000000000001001" = 9 and this would be mod_terminal-1.
  146.    ModCLK01: PROCESS(TenHzModCLK)
  147.    BEGIN
  148.       IF (rising_edge(TenHzModCLK)) THEN --modulus counter increments only on rising clock edge
  149.           IF (one_mod_counter = "0000000000000000000001001") THEN -- we only need to go uptil 9, at 10 we reset. -- half period
  150.              OneHzModCLK <= NOT OneHzModCLK;                      -- toggle.
  151.              one_mod_counter <= to_unsigned(0,CLK_DIV_SIZE);      -- reset counter
  152.           ELSE
  153.              one_mod_counter <= one_mod_counter + 1;              -- otherwise keep incrementing until half-period.
  154.           END IF;
  155.       END IF;
  156.    END PROCESS;
  157.    LEDG(1) <= OneHzModCLK;
  158.          
  159.          
  160. ----------------------------------------------------------------------------------------------------
  161.    Main1HzCLK <= OneHzModCLK; -- assigns modulus clock as main clock.
  162.  
  163. ----------------------------------------------------------------------------------------------------
  164.  
  165. -- STATE0 : GFLASH FOR 2 SECONDS
  166. -- STATE1 : GSOLID FOR 5 SECONDS
  167. -- STATE2 : RFLASH FOR 3 SECONDS
  168. -- STATE3 : RSOLID FOR 6 SECONDS
  169.  
  170.    FSM: PROCESS(state, rising_edge(Main1HzCLK), falling_edge(Main1HzCLK)) -- main FSM
  171.    BEGIN
  172.       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.
  173.  
  174.     CASE state IS
  175.          WHEN STATE0 =>
  176.             state_number <= "0000";
  177.             ledr(11) <= '0';                                                -- turn ledr(11) to OFF.
  178.             IF (rising_edge(Main1HzCLK)) THEN                               -- change on every rising edge.
  179.                IF(time_elapsed <= 0000000000000000000000002) THEN           -- but only remain here if it's [0,2] seconds
  180.                   next_state <= STATE0;                                     -- remain here.
  181.                   time_elapsed <= time_elapsed + 1;                         -- increment time by +1 seconds. ONLY AT RISING EDGE!
  182.                   ledg(8) <= '1';                                           -- toggle ledg(8).
  183.                
  184.                ELSE                                                         -- GFLASH IS OVER, 2 seconds have passed.
  185.                   next_state <= STATE1;                                     -- Go to GSOLID.
  186.                   time_elapsed <= time_elapsed + 1;                         -- increment time by +1 seconds. ONLY AT RISING EDGE!
  187.                   ledg(8) <= '1';                                           -- assign for constant green solid. ON.
  188.                END IF;
  189.             ELSE                                                            -- falling edge condition
  190.                IF(time_elapsed <= 0000000000000000000000002) THEN           -- but only remain here if it's [0,2] seconds [IS NOT REQ, SINCE IT WILL BE EQUAL]
  191.                   next_state <= STATE0;                                     -- remain here.
  192.                   ledg(8) <= '0';                                           -- toggle ledg(8).
  193.                END IF;
  194.             END IF;
  195.          WHEN STATE1 =>
  196.             state_number <= "0001";
  197.             ledr(11) <= '0';                                                -- turn ledr(11) to OFF.
  198.             IF (rising_edge(Main1HzCLK)) THEN                               -- change on every rising edge.
  199.                 IF(time_elapsed <= 0000000000000000000000007) THEN      -- but only remain here if it's [3,7] seconds
  200.                   next_state <= STATE1;                                     -- remain here.
  201.                   time_elapsed <= time_elapsed + 1;                         -- increment time by +1 seconds. ONLY AT RISING EDGE!
  202.                   ledg(8) <= '1';                                           -- assign for constant green solid. ON.
  203.                                
  204.                 ELSE                                                        -- GSOLID IS OVER, 7 seconds have passed.
  205.                   next_state <= STATE2;                                     -- Go to RFLASH.
  206.                   time_elapsed <= time_elapsed + 1;                         -- increment time by +1 seconds. ONLY AT RISING EDGE!
  207.                   ledg(8)  <= '0';                                          -- turn OFF ledg(8) now.
  208.                   ledr(11) <= '1';                                          -- turn ON  ledr(11) now.
  209.                 END IF;
  210.             ELSE                                                            -- falling edge condition
  211.                IF(time_elapsed <= 0000000000000000000000007) THEN           -- but only remain here if it's [3,7] seconds [IS NOT REQ, SINCE IT WILL BE EQUAL]
  212.                   next_state <= STATE0;                                     -- remain here.
  213.                   ledg(8) <= '1';                                           -- assign for constant green solid. ON.
  214.                END IF;
  215.             END IF;
  216.          WHEN STATE2 =>
  217.             state_number <= "0010";
  218.             ledg(8) <= '0';                                                 -- turn ledg(8) to OFF.
  219.             IF (rising_edge(Main1HzCLK)) THEN                               -- change on every rising edge.
  220.                IF(time_elapsed <= 0000000000000000000000010) THEN           -- but only remain here if it's [7,10] seconds
  221.                   next_state <= STATE2;                                     -- remain here.
  222.                   time_elapsed <= time_elapsed + 1;                         -- increment time by +1 seconds. ONLY AT RISING EDGE!
  223.                   ledr(11) <= '1';                                  -- toggle ledr(11).
  224.                
  225.                ELSE                                                         -- RFLASH IS OVER, 3 seconds have passed.
  226.                   next_state <= STATE3;                                     -- Go to RSOLID.
  227.                   time_elapsed <= time_elapsed + 1;                         -- increment time by +1 seconds. ONLY AT RISING EDGE!
  228.                   ledr(11) <= '1';                                          -- assign for constant red solid. ON.
  229.                END IF;
  230.             ELSE                                                            -- falling edge condition
  231.                IF(time_elapsed <= 0000000000000000000000010) THEN           -- but only remain here if it's [7,10] seconds
  232.                   next_state <= STATE2;                                     -- remain here.
  233.                   ledr(11) <= '0';                                  -- toggle ledr(11).
  234.                END IF;
  235.             END IF;
  236.          WHEN STATE3 => -- STATE3
  237.             state_number <= "0011";
  238.             ledg(8) <= '0';                                                 -- turn ledg(8) to OFF.
  239.             IF (rising_edge(Main1HzCLK)) THEN                               -- change on every rising edge.
  240.                 IF(time_elapsed <= 0000000000000000000000016) THEN      -- but only remain here if it's [10,16] seconds
  241.                   next_state <= STATE3;                                     -- remain here.
  242.                   time_elapsed <= time_elapsed + 1;                         -- increment time by +1 seconds. ONLY AT RISING EDGE!
  243.                   ledr(11) <= '1';                                          -- assign for constant red solid. ON.
  244.                                
  245.                 ELSE                                                        -- RSOLID IS OVER, 6 seconds have passed.
  246.                   next_state <= STATE2;                                     -- Go to GFLASH.
  247.                   time_elapsed <= time_elapsed + 1;                         -- increment time by +1 seconds. ONLY AT RISING EDGE!
  248.                   ledr(11)  <= '0';                                         -- turn OFF ledr(11) now.
  249.                   ledg(8)   <= '1';                                         -- turn ON  ledg(8) now.
  250.                 END IF;
  251.             ELSE                                                            -- falling edge condition
  252.                IF(time_elapsed <= 0000000000000000000000016) THEN           -- but only remain here if it's [10,16] seconds [IS NOT REQ, SINCE IT WILL BE EQUAL]
  253.                   next_state <= STATE3;                                     -- remain here.
  254.                   ledr(11) <= '1';                                          -- assign for constant red solid. ON.
  255.                END IF;
  256.             END IF;
  257.     END CASE;
  258.    END PROCESS;
  259. ----------------------------------------------------------------------------------------------------
  260.    SeqLogic: PROCESS(Main1HzCLK, state) -- creats sequential logic to latch the state
  261.    BEGIN
  262.       IF (rising_edge(Main1HzCLK)) THEN
  263.          
  264.          state <= next_state;                      -- on the rising edge of clock the current state is updated with next state
  265.          
  266.          IF (state = STATE1) THEN
  267.             state_counter <= state_counter + 1;    -- on the rising edge of clock the current counter is incremented if state is STATE1
  268.          END IF;
  269.       END IF;
  270.    END PROCESS;
  271. ----------------------------------------------------------------------------------------------------
  272.    D7S0: SevenSegment PORT MAP( state_number, '0', hex0 );
  273.    D7S4: SevenSegment PORT MAP( std_logic_vector(state_counter), '0', hex2 );
  274.  
  275. END SimpleCircuit;
Add Comment
Please, Sign In to add comment