Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Using CPLD and VHDL to write a code for a multifunction Calculator

  1. Feb 27, 2009 #1
    Hey Afternoon people,

    Alright, in need of your major help and hoping you allow yourselves to feel good enough to help me.Alright allow me to get to it.

    Writing a program code for a multifunction calculator system using a CPLD and VHDL.

    The calculator contains:

    1 2 3
    4 5 6
    7 8 9 0

    4 additional functions need to be added to the calculator by using '0' as a shift function.

    The function +, -, /, x.

    So far all the code written up is as follows.Feel good enough to check it and help me add to it, thank you very much.

    DEBOUNCING BEHAVIOR
    ----------------------------------------------------------------------------------
    -- Company:
    -- Engineer:
    --
    -- Create Date: 11:35:19 02/01/2009
    -- Design Name:
    -- Module Name: debounce - Behavioral
    -- Project Name:
    -- Target Devices:
    -- Tool versions:
    -- Description:
    --
    -- Dependencies:
    --
    -- Revision:
    -- Revision 0.01 - File Created
    -- Additional Comments:
    --
    ----------------------------------------------------------------------------------
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    ---- Uncomment the following library declaration if instantiating
    ---- any Xilinx primitives in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;

    entity debounce is
    Port ( clock : in std_logic;
    keyin : in STD_LOGIC_VECTOR (3 downto 0);
    keyout : out STD_LOGIC_VECTOR (3 downto 0));
    end debounce;

    architecture behaviour of debounce is
    signal clk: std_logic;

    begin

    milli_s_period: process(clock)
    variable cnt: std_logic_vector (14 downto 0);
    begin

    if rising_edge(clock) then

    cnt := cnt + '1';
    --if cnt = "000000000000011" then -- test
    if cnt = "110001001010111" then
    cnt := "000000000000000";
    clk <= '1';
    else
    clk <= '0';
    end if;

    end if;
    end process;

    debounce: process(clk)
    begin

    if rising_edge(clk) then
    keyout <= keyin;
    end if;
    end process;

    end behaviour;


    DISPLAYING TEXT

    ----------------------------------------------------------------------------------
    -- Company:
    -- Engineer:
    --
    -- Create Date: 11:23:33 02/01/2009
    -- Design Name:
    -- Module Name: display - Behavioral
    -- Project Name:
    -- Target Devices:
    -- Tool versions:
    -- Description:
    --
    -- Dependencies:
    --
    -- Revision:
    -- Revision 0.01 - File Created
    -- Additional Comments:
    --
    ----------------------------------------------------------------------------------
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    ---- Uncomment the following library declaration if instantiating
    ---- any Xilinx primitives in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;

    entity display is

    generic(width :positive := 5);

    Port (
    input : in STD_LOGIC_VECTOR (3 downto 0);
    output : out STD_LOGIC_VECTOR (6 downto 0));
    end display;

    architecture a of display is

    begin

    process(input)

    begin
    -- if rising_edge(clk) then
    case input is

    when "0000" =>
    output<="0000001";
    when "0001" =>
    output<="1001111";
    when "0010" =>
    output<="0010010";
    when "0011" =>
    output<="0000110";
    when "0100" =>
    output<="1001100";
    when "0101" =>
    output<="0100100";
    when "0110" =>
    output<="0100000";
    when "0111" =>
    output<="0001111";
    when "1000" =>
    output<="0000000";
    when "1001" =>
    output<="0000100";
    when "1010" =>
    output<="0001000";
    when "1011" =>
    output<="0000111";
    when "1100" =>
    output<="0110001";
    when "1101" =>
    output<="1101000";
    when "1110" =>
    output<="0110000";
    when "1111" =>
    output<="0111000";
    when others=>
    output<="0011111";

    end case;
    -- end if;
    end process;

    end a;

    DISPLAYING TB.VHDL[1]

    --------------------------------------------------------------------------------
    -- Company:
    -- Engineer:
    --
    -- Create Date: 14:38:01 02/09/2009
    -- Design Name:
    -- Module Name: L:/calcutator/keypad/display_tb.vhd
    -- Project Name: keypad
    -- Target Device:
    -- Tool versions:
    -- Description:
    --
    -- VHDL Test Bench Created by ISE for module: display
    --
    -- Dependencies:
    --
    -- Revision:
    -- Revision 0.01 - File Created
    -- Additional Comments:
    --
    -- Notes:
    -- This testbench has been automatically generated using types std_logic and
    -- std_logic_vector for the ports of the unit under test. Xilinx recommends
    -- that these types always be used for the top-level I/O of a design in order
    -- to guarantee that the testbench will bind correctly to the post-implementation
    -- simulation model.
    --------------------------------------------------------------------------------
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    USE ieee.std_logic_unsigned.all;
    USE ieee.numeric_std.ALL;

    ENTITY display_tb IS
    END display_tb;

    ARCHITECTURE behavior OF display_tb IS

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT display
    PORT(
    input : IN std_logic_vector(3 downto 0);
    output : OUT std_logic_vector(6 downto 0)
    );
    END COMPONENT;


    --Inputs
    signal input : std_logic_vector(3 downto 0) := (others => '0');

    --Outputs
    signal output : std_logic_vector(6 downto 0);

    BEGIN

    -- Instantiate the Unit Under Test (UUT)
    uut: display PORT MAP (
    input => input,
    output => output
    );

    -- No clocks detected in port list. Replace <clock> below with
    -- appropriate port name

    constant <clock>_period := 1ns;

    <clock>_process :process
    begin
    <clock> <= '0';
    wait for <clock>_period/2;
    <clock> <= '1';
    wait for <clock>_period/2;
    end process;


    -- Stimulus process
    stim_proc: process
    begin
    -- hold reset state for 100ms.
    wait for 100ms;

    wait for <clock>_period*10;

    -- insert stimulus here

    wait;
    end process;

    END;

    KEYPAD[1]

    ----------------------------------------------------------------------------------
    -- Company:
    -- Engineer:
    --
    -- Create Date: 08:36:44 02/01/2009
    -- Design Name:
    -- Module Name: keypad - Behavioral
    -- Project Name:
    -- Target Devices:
    -- Tool versions:
    -- Description:
    --
    -- Dependencies:
    --
    -- Revision:
    -- Revision 0.01 - File Created
    -- Additional Comments:
    --
    ----------------------------------------------------------------------------------
    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    USE ieee.std_logic_arith.all;
    USE ieee.std_logic_unsigned.all;


    ENTITY keypad IS
    PORT(
    clk : IN STD_LOGIC;
    resetn : IN STD_LOGIC;
    row : IN STD_LOGIC_VECTOR(3 downto 0);
    col : OUT STD_LOGIC_VECTOR(3 downto 0);
    keyvalue_registered : OUT STD_LOGIC_VECTOR(3 downto 0);
    keyvalid : OUT STD_LOGIC
    );
    END keypad;

    ARCHITECTURE mixed OF keypad IS
    TYPE STATE_TYPE IS ( Start_State, DriveAll, KeyDetect,
    Delay, Drive1, Detect1, Drive2, Detect2,
    Drive3, Detect3, Drive4, Detect4,
    Decode1, Decode2, Decode3, Decode4,
    Latch0, Latch1, Latch2, Latch3,
    Latch4, Latch5, Latch6, Latch7,
    Latch8, Latch9, Latch10, Latch11, Latch12,
    Latch13, Latch14, Latch15, PrepareDrive,
    Capture0, Capture1, Capture2, Capture3, Capture4,
    Capture5, Capture6, Capture7, Capture8,
    Capture9, Capture10, Capture11,
    Capture12, Capture13, Capture14, Capture15,
    KeyReleaseAssert, KeyReleaseDetect
    );
    SIGNAL state: STATE_TYPE;
    signal sense: std_logic;
    signal count_value: std_logic_vector(3 downto 0);
    signal count_resetn: std_logic;
    signal keyvalue: std_logic_vector(3 downto 0);
    signal register_load: std_logic;
    signal register_resetn: std_logic;

    BEGIN



    sense <= row(0) and row(1) and row(2) and row(3);

    -- Moore Machine Next state logic
    PROCESS (clk)
    BEGIN
    IF resetn = '0' THEN
    state <= Start_State;
    ELSIF clk'EVENT AND clk = '1' THEN
    CASE state IS
    WHEN Start_State =>
    state <= DriveAll;

    WHEN DriveAll => -- drive all cols
    IF count_value = "1111" THEN
    state <= KeyDetect;
    END IF;

    WHEN KeyDetect => -- determine if any key is pressed. If
    -- not, continue driving columns
    IF sense = '1' THEN
    state <= DriveAll;
    elsif sense = '0' then
    state <= Delay;
    END IF;

    WHEN Delay => -- key detected, delay
    IF count_value = "1111" THEN
    state <= PrepareDrive;
    END IF;

    when PrepareDrive => -- determine what key was pressed
    state <= Drive1;

    when Drive1 => -- Is key in column 1
    if count_value = "1111" THEN
    state <= Detect1;
    end if;

    when Detect1 =>
    if sense = '1' then
    state <= Drive2;
    elsif sense = '0' then
    state <= Decode1;
    end if;

    when Drive2 => -- Is key in column 2
    if count_value = "1111" then
    state <= Detect2;
    end if;

    when Detect2 =>
    if sense = '1' then
    state <= Drive3;
    elsif sense = '0' then
    state <= Decode2;
    end if;

    when Drive3 => -- Is key in column 3
    if count_value = "1111" then
    state <= Detect3;
    end if;

    when Detect3 =>
    if sense = '1' then
    state <= Drive4;
    elsif sense = '0' then
    state <= Decode3;
    end if;

    when Drive4 => -- Is key in column 4
    if count_value = "1111" then
    state <= Detect4;
    end if;

    when Detect4 =>
    if sense = '1' then
    state <= Drive1;
    elsif sense = '0' then
    state <= Decode4;
    end if;

    when Decode1 => -- Determine which key in column 1 is pressed
    if row(0) = '0' then
    state <= Latch0;
    elsif row(1) = '0' then
    state <= Latch4;
    elsif row(2) = '0' then
    state <= Latch8;
    else
    state <= Latch12;
    end if;

    when Decode2 => -- Determine which key in column 2 is pressed
    if row(0) = '0' then
    state <= Latch1;
    elsif row(1) = '0' then
    state <= Latch5;
    elsif row(2) = '0' then
    state <= Latch9;
    else
    state <= Latch13;
    end if;

    when Decode3 => -- Determine which key in column 3 is pressed
    if row(0) = '0' then
    state <= Latch2;
    elsif row(1) = '0' then
    state <= Latch6;
    elsif row(2) = '0' then
    state <= Latch10;
    else
    state <= Latch14;
    end if;

    when Decode4 => -- Determine which key in column 4 is pressed
    if row(0) = '0' then
    state <= Latch3;
    elsif row(1) = '0' then
    state <= Latch7;
    elsif row(2) = '0' then
    state <= Latch11;
    else
    state <= Latch15;
    end if;

    -- states to enable the output register to load the detected key on the
    -- next rising edge of the clock
    when Latch0 =>
    state <= Capture0;

    when Latch1 =>
    state <= Capture1;

    when Latch2 =>
    state <= Capture2;

    when Latch3 =>
    state <= Capture3;

    when Latch4 =>
    state <= Capture4;

    when Latch5 =>
    state <= Capture5;

    when Latch6 =>
    state <= Capture6;

    when Latch7 =>
    state <= Capture7;

    when Latch8 =>
    state <= Capture8;

    when Latch9 =>
    state <= Capture9;

    when Latch10 =>
    state <= Capture10;

    when Latch11 =>
    state <= Capture11;

    when Latch12 =>
    state <= Capture12;

    when Latch13 =>
    state <= Capture13;

    when Latch14 =>
    state <= Capture14;

    when Latch15 =>
    state <= Capture15;

    -- states when the detected key value is loaded into output register
    when Capture0 =>
    state <= KeyReleaseAssert;

    when Capture1 =>
    state <= KeyReleaseAssert;

    when Capture2 =>
    state <= KeyReleaseAssert;

    when Capture3 =>
    state <= KeyReleaseAssert;

    when Capture4 =>
    state <= KeyReleaseAssert;

    when Capture5 =>
    state <= KeyReleaseAssert;

    when Capture6 =>
    state <= KeyReleaseAssert;

    when Capture7 =>
    state <= KeyReleaseAssert;

    when Capture8 =>
    state <= KeyReleaseAssert;

    when Capture9 =>
    state <= KeyReleaseAssert;

    when Capture10 =>
    state <= KeyReleaseAssert;

    when Capture11 =>
    state <= KeyReleaseAssert;

    when Capture12 =>
    state <= KeyReleaseAssert;

    when Capture13 =>
    state <= KeyReleaseAssert;

    when Capture14 =>
    state <= KeyReleaseAssert;

    when Capture15 =>
    state <= KeyReleaseAssert;

    -- Wait for user to release the depressed key
    when KeyReleaseAssert =>
    if count_value = "1111" then
    state <= KeyReleaseDetect;
    end if;

    when KeyReleaseDetect =>
    if sense = '1' then
    state <= Start_State;
    elsif sense = '0' then
    state <= KeyReleaseAssert;
    end if;


    END CASE;
    END IF;
    END PROCESS;

    -- enable the counter reset in the state before the counter is to be used
    WITH state SELECT
    count_resetn <=
    '0' WHEN Start_State,
    '0' WHEN KeyDetect,
    '0' WHEN PrepareDrive,
    '0' when Detect1,
    '0' when Detect2,
    '0' when Detect3,
    '0' when Detect4,
    '0' when Capture0,
    '0' when Capture1,
    '0' when Capture2,
    '0' when Capture3,
    '0' when Capture4,
    '0' when Capture5,
    '0' when Capture6,
    '0' when Capture7,
    '0' when Capture8,
    '0' when Capture9,
    '0' when Capture10,
    '0' when Capture11,
    '0' when Capture12,
    '0' when Capture13,
    '0' when Capture14,
    '0' when Capture15,
    '0' when KeyReleaseDetect,
    '1' when others;

    -- assert the register load signal in the state before the keyvalue is to be
    -- latched into the output register
    with state select
    register_load <=
    '1' when latch0,
    '1' when latch1,
    '1' when latch2,
    '1' when latch3,
    '1' when latch4,
    '1' when latch5,
    '1' when latch6,
    '1' when latch7,
    '1' when latch8,
    '1' when latch9,
    '1' when latch10,
    '1' when latch11,
    '1' when latch12,
    '1' when latch13,
    '1' when latch14,
    '1' when latch15,
    '1' when capture0,
    '1' when capture1,
    '1' when capture2,
    '1' when capture3,
    '1' when capture4,
    '1' when capture5,
    '1' when capture6,
    '1' when capture7,
    '1' when capture8,
    '1' when capture9,
    '1' when capture10,
    '1' when capture11,
    '1' when capture12,
    '1' when capture13,
    '1' when capture14,
    '1' when capture15,
    '0' when others;

    -- outputs to determine which columns to drive during keyscanning phase
    with state select
    col <=
    "0111" when Drive1,
    "0111" when Detect1,
    "0111" when Decode1,
    "1011" when Drive2,
    "1011" when Detect2,
    "1011" when Decode2,
    "1101" when Drive3,
    "1101" when Detect3,
    "1101" when Decode3,
    "1110" when Drive4,
    "1110" when Detect4,
    "1110" when Decode4,
    "0000" when others; -- including DriveAll and KeyReleaseAssert

    -- the value of the detected key in binary
    with state select
    keyvalue <=
    "0000" when Latch0,
    "0000" when Capture0,
    "0001" when Latch1,
    "0001" when Capture1,
    "0010" when Latch2,
    "0010" when Capture2,
    "0011" when Latch3,
    "0011" when Capture3,
    "0100" when Latch4,
    "0100" when Capture4,
    "0101" when Latch5,
    "0101" when Capture5,
    "0110" when Latch6,
    "0110" when Capture6,
    "0111" when Latch7,
    "0111" when Capture7,
    "1000" when Latch8,
    "1000" when Capture8,
    "1001" when Latch9,
    "1001" when Capture9,
    "1010" when Latch10,
    "1010" when Capture10,
    "1011" when Latch11,
    "1011" when Capture11,
    "1100" when Latch12,
    "1100" when Capture12,
    "1101" when Latch13,
    "1101" when Capture13,
    "1110" when Latch14,
    "1110" when Capture14,
    "1111" when Latch15,
    "1111" when Capture15,
    "0000" when others;

    -- assert the keyvalid flag when a valid key is detected
    with state select
    keyvalid <=
    '1' when Capture0,
    '1' when Capture1,
    '1' when Capture2,
    '1' when Capture3,
    '1' when Capture4,
    '1' when Capture5,
    '1' when Capture6,
    '1' when Capture7,
    '1' when Capture8,
    '1' when Capture9,
    '1' when Capture10,
    '1' when Capture11,
    '1' when Capture12,
    '1' when Capture13,
    '1' when Capture14,
    '1' when Capture15,
    '0' when others;

    END mixed;

    KEYPAD TB.VHDL[1]

    --------------------------------------------------------------------------------
    -- Company:
    -- Engineer:
    --
    -- Create Date: 13:49:31 02/10/2009
    -- Design Name:
    -- Module Name: L:/calcutator/keypad/keypad_tb.vhd
    -- Project Name: keypad
    -- Target Device:
    -- Tool versions:
    -- Description:
    --
    -- VHDL Test Bench Created by ISE for module: keypad
    --
    -- Dependencies:
    --
    -- Revision:
    -- Revision 0.01 - File Created
    -- Additional Comments:
    --
    -- Notes:
    -- This testbench has been automatically generated using types std_logic and
    -- std_logic_vector for the ports of the unit under test. Xilinx recommends
    -- that these types always be used for the top-level I/O of a design in order
    -- to guarantee that the testbench will bind correctly to the post-implementation
    -- simulation model.
    --------------------------------------------------------------------------------
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    USE ieee.std_logic_unsigned.all;
    USE ieee.numeric_std.ALL;

    ENTITY keypad_tb IS
    END keypad_tb;

    ARCHITECTURE behavior OF keypad_tb IS

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT keypad
    PORT(
    clk : IN std_logic;
    resetn : IN std_logic;
    row : IN std_logic_vector(3 downto 0);
    col : OUT std_logic_vector(3 downto 0);
    keyvalue_registered : OUT std_logic_vector(3 downto 0);
    keyvalid : OUT std_logic
    );
    END COMPONENT;


    --Inputs
    signal clk : std_logic := '0';
    signal resetn : std_logic := '0';
    signal row : std_logic_vector(3 downto 0) := (others => '0');

    --Outputs
    signal col : std_logic_vector(3 downto 0);
    signal keyvalue_registered : std_logic_vector(3 downto 0);
    signal keyvalid : std_logic;

    -- Clock period definitions
    constant clk_period : time := 1us;

    BEGIN

    -- Instantiate the Unit Under Test (UUT)
    uut: keypad PORT MAP (
    clk => clk,
    resetn => resetn,
    row => row,
    col => col,
    keyvalue_registered => keyvalue_registered,
    keyvalid => keyvalid
    );

    -- Clock process definitions
    clk_process :process
    begin
    clk <= '0';
    wait for clk_period/2;
    clk <= '1';
    wait for clk_period/2;
    end process;


    -- Stimulus process
    stim_proc: process
    begin
    -- hold reset state for 100ms.
    wait for 100ms;

    wait for clk_period*10;

    -- insert stimulus here

    wait;
    end process;

    END;
     
  2. jcsd
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Can you offer guidance or do you also need help?
Draft saved Draft deleted



Similar Discussions: Using CPLD and VHDL to write a code for a multifunction Calculator
Loading...