Sunday, 19 November 2017

FPGA VHDL & Verilog 4x4 Key matrix seven segment display multiplexer and Clock divider Waveshare development board




CONTROLLER TOP MODULE


library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.Vcomponents.ALL;

entity key is
   port ( GCLKP1 : in    std_logic; 
          RESET  : in    std_logic; 
          ROW    : in    std_logic_vector (3 downto 0); 
          COL    : out   std_logic_vector (3 downto 0); 
          DIGIT  : out   std_logic_vector (2 downto 0); 
          LED    : out   std_logic_vector (7 downto 0));
end key;

architecture BEHAVIORAL of key is
   signal XLXN_1  : std_logic;
   signal XLXN_2  : std_logic;
   signal XLXN_10 : std_logic_vector (3 downto 0);
   component Frequency
      port ( RESET     : in    std_logic; 
             GCLKP1    : in    std_logic; 
             ClockScan : out   std_logic; 
             KeyScan   : out   std_logic);
   end component;
   
   component LED8
      port ( RESET       : in    std_logic; 
             ClockScan   : in    std_logic; 
             LED1        : in    std_logic_vector (3 downto 0); 
             LED2        : in    std_logic_vector (3 downto 0); 
             LED3        : in    std_logic_vector (3 downto 0); 
             LED4        : in    std_logic_vector (3 downto 0); 
             LED5        : in    std_logic_vector (3 downto 0); 
             LED6        : in    std_logic_vector (3 downto 0); 
             LED7        : in    std_logic_vector (3 downto 0); 
             LED8        : in    std_logic_vector (3 downto 0); 
             light       : out   std_logic_vector (7 downto 0); 
             LEDOut      : out   std_logic_vector (7 downto 0); 
             DigitSelect : out   std_logic_vector (2 downto 0));
   end component;
   
   component key44
      port ( sys_clk : in    std_logic; 
             rst     : in    std_logic; 
             row     : in    std_logic_vector (3 downto 0); 
             valid   : out   std_logic; 
             code    : out   std_logic_vector (3 downto 0); 
             col     : out   std_logic_vector (3 downto 0));
   end component;
   
begin
   XLXI_1 : Frequency
      port map (GCLKP1=>GCLKP1,
                RESET=>RESET,
                ClockScan=>XLXN_1,
                KeyScan=>XLXN_2);
   
   XLXI_2 : LED8
      port map (ClockScan=>XLXN_1,
                LED1(3 downto 0)=>XLXN_10(3 downto 0),
                LED2(3 downto 0)=>XLXN_10(3 downto 0),
                LED3(3 downto 0)=>XLXN_10(3 downto 0),
                LED4(3 downto 0)=>XLXN_10(3 downto 0),
                LED5(3 downto 0)=>XLXN_10(3 downto 0),
                LED6(3 downto 0)=>XLXN_10(3 downto 0),
                LED7(3 downto 0)=>XLXN_10(3 downto 0),
                LED8(3 downto 0)=>XLXN_10(3 downto 0),
                RESET=>RESET,
                DigitSelect(2 downto 0)=>DIGIT(2 downto 0),
                LEDOut(7 downto 0)=>LED(7 downto 0),
                light=>open);
   
   XLXI_3 : key44
      port map (row(3 downto 0)=>ROW(3 downto 0),
                rst=>RESET,
                sys_clk=>XLXN_2,
                code(3 downto 0)=>XLXN_10(3 downto 0),
                col(3 downto 0)=>COL(3 downto 0),
                valid=>open);
   
end BEHAVIORAL;

FREQUENCY DIVIDER

---------------------------------------------------------------------------------------------------
--*************************************************************************************************
--  CreateDate  :  2009-03-24 
--  ModifData   :  2009-03-24 
--  Description :  Frequency For KeyBoard 
--  Author      :  Explorer01 
--  Version     :  V1.0  
--*************************************************************************************************
---------------------------------------------------------------------------------------------------

-- VHDL library Declarations 
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.std_logic_unsigned.ALL;

---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- The Entity Declarations 
ENTITY Frequency IS
 PORT 
 (
  RESET:   IN STD_LOGIC; 
  GCLKP1:  IN STD_LOGIC;   -- 50 MHz 
  
  ClockScan: OUT STD_LOGIC;
  KeyScan: OUT STD_LOGIC
 );
END Frequency;

---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- The Architecture of Entity Declarations 
ARCHITECTURE Frequency_arch OF Frequency IS
 --Clock: 
 SIGNAL Period1uS: STD_LOGIC;
BEGIN
 
 -------------------------------------------------
 -- GCLK: 1MHz(1uS), 1KHz(1mS), 1Hz(1S) 
 CLK: PROCESS( RESET, GCLKP1, Period1uS )
  VARIABLE Count  : STD_LOGIC_VECTOR(5 DOWNTO 0);
  VARIABLE Count1 : STD_LOGIC_VECTOR(9 DOWNTO 0);
 BEGIN 
  ------------------------------------
  --Period: 1uS (Period1uS <= GCLKP1; )
  IF( GCLKP1'EVENT AND GCLKP1='1' ) THEN 
   -- 1/50Mhz = 2x10E-8 --- 2x10E-8 /20x10e-3 = 1/1Mhz    -- 1/50 = 20ms
   IF( Count>"110000" ) THEN  Count := "000000";
   ELSE                    Count := Count + 1;
   END IF;
   
   Period1uS <= Count(5);  -- 1MHz 
  END IF;
  
  KeyScan <= Period1uS; --scan keys around 20ms
  
  ------------------------------------
  --Period: 1mS 
  IF( Period1uS'EVENT AND Period1uS='1' ) THEN 
                  --1/3920 = 40ms
   IF( Count1>"1011101100100000" ) THEN  Count1 := "0000000000";
   ELSE                     Count1 := Count1 + 1;
   END IF;
  END IF;
  
  ClockScan <= Count1(8); 
  
 END PROCESS;
 
END Frequency_arch;

7 SEGMENT DISPLAY MULTIPLEXER

---------------------------------------------------------------------------------------------------
--*
--* File                : keyboard.vhd
--* Hardware Environment:
--* Build Environment   : Quartus II Version 9.1
--* Version             : 
--* By                  : Su Wei Feng
--*
--*                                  (c) Copyright 2005-2011, WaveShare
--*                                       http://www.waveshare.net
--*                                          All Rights Reserved
--*
---------------------------------------------------------------------------------------------------

-- VHDL library Declarations 
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;

---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- The Entity Declarations 
ENTITY LED8 IS
 PORT 
 (
  -----------------------------------------------
  -- Reset & Clock Signal 
  RESET:   IN STD_LOGIC; 
  ClockScan: IN STD_LOGIC;
  
  --LED0:  IN STD_LOGIC_VECTOR(3 downto 0);
  
  LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8:  IN STD_LOGIC_VECTOR(3 downto 0);
  
  -----------------------------------------------
  -- Eight Green LED PIN 
  light:  OUT std_logic_vector(7 DOWNTO 0);
  
  -- LED8 PIN 
  LEDOut:   OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- LED Segment 
  DigitSelect: OUT STD_LOGIC_VECTOR(2 DOWNTO 0) -- LED Digit 
 );
END LED8;

---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- The Architecture of Entity Declarations 
ARCHITECTURE LED8_arch OF LED8 IS
 SIGNAL LED: STD_LOGIC_VECTOR(3 downto 0);
 SIGNAL Refresh: STD_LOGIC_VECTOR(2 downto 0);
BEGIN
 
 -------------------------------------------------
 -- Encoder 
 -------------------------------------------------
 -- HEX-to-seven-segment decoder 
 -- segment encoding 
 --      0 
 --     ---  
 --  5 |   | 1
 --     ---   <- ---="" --="" 2="" 3="" 4="" 6="" begin="" case="" is="" led="" process="" when="">LEDOut<= "11000000";    --'0'
   when "0001"=>LEDOut<= "11111001";    --'1'
   when "0010"=>LEDOut<= "10100100";    --'2'
   when "0011"=>LEDOut<= "10110000";    --'3'
   when "0100"=>LEDOut<= "10011001";    --'4'
   when "0101"=>LEDOut<= "10010010";    --'5'
   when "0110"=>LEDOut<= "10000010";    --'6'
   when "0111"=>LEDOut<= "11111000";    --'7'
   when "1000"=>LEDOut<= "10000000";    --'8'
   when "1001"=>LEDOut<= "10010000";    --'9'
   when "1010"=>LEDOut<= "10001000";    --'A'
   when "1011"=>LEDOut<= "10000011";    --'b'
   when "1100"=>LEDOut<= "11000110";    --'C'
   when "1101"=>LEDOut<= "10100001";    --'d'
   when "1110"=>LEDOut<= "10000110";    --'E'
   when "1111"=>LEDOut<= "10001110";    --'F'
   when others=>LEDOut<= "XXXXXXXX";    --' '
  END CASE;
 END PROCESS;
 
 -------------------------------------------------
 -- clock 
 PROCESS( ClockScan, Refresh )   
 BEGIN
  IF( ClockScan'EVENT AND ClockScan = '1' )THEN 
   Refresh <= Refresh + 1; 
  END IF; 
  
  -------------------------------------------------
  --  LED Digit Select 
  DigitSelect <= Refresh; 
 END PROCESS;
 
 -------------------------------------------------
 -- MUX 
 LED <= --LED0;
 LED1 when( Refresh=0 ) else
 LED2 when( Refresh=1 ) else
 LED3 when( Refresh=2 ) else
 LED4 when( Refresh=3 ) else
 LED5 when( Refresh=4 ) else
 LED6 when( Refresh=5 ) else
 LED7 when( Refresh=6 ) else
 LED8;
 
 -------------------------------------------------
 -- 
 Light <= NOT(LED1 & LED2); 
 --Light <= LED0;
END LED8_arch;


KEY MULTIPLEXER FINITE STATE MACHINE

//-------------------------------------------------------------------------------------------------
//*************************************************************************************************
//  CreateDate  :  2009-03-29 
//  ModifData   :  2009-03-30 
//  Description :  KeyBoard ( Verilog HDL )
//  Author      :  Explorer01 
//  Version     :  V1.1  
//*************************************************************************************************
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
// Module declaration 
module key44
(
 code      ,
 col       ,
 valid     ,
 row       ,
 sys_clk   ,
 rst  
);

//-------------------------------------------------------------------------------------------------
// Port declaration 
output  [3:0]  col     ;
output         valid   ;
output  [3:0]  code    ;

input   [3:0]  row     ;
input          sys_clk,rst ;

//-------------------------------------------------------------------------------------------------
// 
reg     [3:0]  col,code;
reg     [5:0]  state,next_state;

parameter  S_0 = 6'b000001,
           S_1 = 6'b000010,
           S_2 = 6'b000100,
           S_3 = 6'b001000,
           S_4 = 6'b010000,
           S_5 = 6'b100000;
reg        S_row ; 
reg [3:0] count,row_reg,col_reg;
reg       clk2,clk4;
 
 
reg [4:0] Mega_cnt;
wire      clk;

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
// 
always @( posedge sys_clk, negedge rst )
begin
 if(!rst) Mega_cnt<=0;
 else  Mega_cnt<=Mega_cnt+1;
end

assign clk = Mega_cnt[4];

//-------------------------------------------------------------------------------------------------
// Frequency Division Two 
always @( posedge clk )
clk2 <= ~clk2;

// A quarter of the clk 
always @( posedge clk2 )
clk4 <= ~clk4;

//-------------------------------------------------------------------------------------------------
// Check the Key 
//-------------------------------------------------------------------------------------------------
always @( posedge clk4, negedge rst )
if(!rst)
 begin
  count <= 0;
  S_row <= 0;
 end
else
 begin
  if(!(row[0]&row[1]&row[2]&row[3]))
   begin
    if(count < 'd4) count <= count + 1;  // Filter 
    else   S_row <= 1;
   end
 // else if(state[5]||state[0])
  else if((state == S_0) || (state == S_5))
   begin
    count <= 0;
    S_row <= 0;
   end
 end

assign valid = ((state == S_1)||(state == S_2)||(state == S_3)||(state == S_4)) &&  (!(row[3]&row[2]&row[1]&row[0]));

//-------------------------------------------------------------------------------------------------
// Save the value of row and col 
always @( negedge clk )
if( valid )
 begin
  row_reg <= row ;
  col_reg <= col ;
 end
/*
else
 begin
  row_reg <= row_reg ;
  col_reg <= col_reg ;
 end*/

//-------------------------------------------------------------------------------------------------
// Decode the Key 
always @( row_reg, col_reg, clk )
 case( {row_reg,col_reg} )
  8'B1110_1110: code = 4'hd;
  8'B1110_1101: code = 4'h9;
  8'B1110_1011: code = 4'h5;
  8'B1110_0111: code = 4'h1;
  
  8'B1101_1110: code = 4'he;
  8'B1101_1101: code = 4'ha;
  8'B1101_1011: code = 4'h6;
  8'B1101_0111: code = 4'h2;
  
  8'B1011_1110: code = 4'hf;
  8'B1011_1101: code = 4'hb;
  8'B1011_1011: code = 4'h7;
  8'B1011_0111: code = 4'h3;
  
  8'B0111_1110: code = 4'h0;
  8'B0111_1101: code = 4'hc;
  8'B0111_1011: code = 4'h8;
  8'B0111_0111: code = 4'h4;
  default  : code = 4'h0;
 endcase
 
//-------------------------------------------------------------------------------------------------
// State Machine : Mealy 
//-------------------------------------------------------------------------------------------------
always @( posedge clk4, negedge rst )
 if( !rst )
  state <= S_0 ;
 else
  state <= next_state ;

//-------------------------------------------------------------------------------------------------
always @( state, row, S_row )
begin
 col = 0;
 //----------------------------------------------
 case( state )
 S_0 :  begin
   col = 4'b0000;
   if(S_row) next_state = S_1;
   else  next_state = S_0;
  end
 //----------------------------------------------
 // Decoding... 
 S_1 :  begin
   col = 4'b1110;
   if(row!='hf) next_state = S_5;
   else   next_state = S_2;
  end
 S_2 :  begin
   col = 4'b1101;
   if(row!='hf) next_state = S_5;
   else   next_state = S_3;
  end 
 S_3 :  begin
   col = 4'b1011;
   if(row!='hf) next_state = S_5;
   else   next_state = S_4;
  end  
 S_4 :  begin
   col = 4'b0111;
   if(row!='hf) next_state = S_5;
   else   next_state = S_0;
  end  
 //----------------------------------------------
 S_5 :  begin
   col = 4'b0000;
   if(row == 4'b1111)  next_state = S_0;
   else     next_state = S_5;
  end
 default: next_state = S_0;
 endcase
end

endmodule

CONSTRAINTS

NET "GCLKP1"  LOC = "p129"  ;

NET "RESET"  LOC = "p69"  ;

NET "COL[0]"  LOC = "p94"  ;
NET "COL[1]"  LOC = "p93"  ;
NET "COL[2]"  LOC = "p92"  ;
NET "COL[3]"  LOC = "p91"  ;
NET "ROW[0]"  LOC = "p88"  ;
NET "ROW[1]"  LOC = "p87"  ;
NET "ROW[2]"  LOC = "p86"  ;
NET "ROW[3]"  LOC = "p85"  ;

NET "LED[0]"  LOC = "p83"  ;
NET "LED[1]"  LOC = "p81"  ;
NET "LED[2]"  LOC = "p76"  ;
NET "LED[3]"  LOC = "p74"  ;
NET "LED[4]"  LOC = "p70"  ;
NET "LED[5]"  LOC = "p67"  ;
NET "LED[6]"  LOC = "p63"  ;
NET "LED[7]"  LOC = "p60"  ;

NET "DIGIT[0]"  LOC = "p82"  ;
NET "DIGIT[1]"  LOC = "p77"  ;
NET "DIGIT[0]"  LOC = "p75"  ;
NET "DIGIT[1]"  LOC = "p71"  ;

# PlanAhead Generated IO constraints 

NET "GCLKP1" IOSTANDARD = LVCMOS33;

NET "COL[0]"   PULLUP;
NET "COL[1]"   PULLUP;
NET "COL[2]"   PULLUP;
NET "COL[3]"   PULLUP;
NET "ROW[0]"   PULLUP;
NET "ROW[1]"   PULLUP;
NET "ROW[2]"   PULLUP;
NET "ROW[3]"   PULLUP;


2 comments: