jlgazo
jlgazo

Reputation: 11

Trying to make a 4-bit multiplier in VHDL with 3x4 keypad input and 2x16 LCD to be implemented on a Spartan 3E board

everyone. I'm trying to make a 4-bit multiplier in VHDL. It is to be implemented on a Spartan 3E board using the built-in 2x16 LCD and a 3x4 keypad through a C922 IC.

Using it goes like this: user inputs a number through the keypad, presses a button for confirmation, enters a second number, presses the confirmation button again, and the product shows up on the LCD.

So far, the codes for the keypad+c922 and the LCD are okay. The code for the multiplier is almost okay. The problem is that the confirmation button only works when another number (which is not ultimately used) is pressed.

Here is my code. Following at are screenshots of the Xilinx simulation

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity multi_4bit is
    Port ( CLK : in  STD_LOGIC;
        RESET : in  STD_LOGIC;
        Input : in  STD_LOGIC_VECTOR (3 downto 0);
        DAVBL : in  STD_LOGIC;
        Confirm : in STD_LOGIC;
        Output : out  STD_LOGIC_VECTOR (7 downto 0));
end multi_4bit;

architecture Behavioral of multi_4bit is

type state is (R,S0,S1,S2,S3,S4);
signal pstate, nstate: state;
signal A_sig, B_sig: STD_LOGIC_VECTOR(3 downto 0);

begin

state_transition: process(CLK,RESET)
begin
    if RESET = '1' then
        pstate <= R;
    elsif rising_edge(CLK) then
        pstate <= nstate;
    end if;
end process;

nstate_output: process(pstate,DAVBL,Input)
variable temp_var: STD_LOGIC_VECTOR(3 downto 0);
variable tempMult_var,tempProd_var: STD_LOGIC_VECTOR(7 downto 0);
begin
    case pstate is
        when R =>
            nstate <= S0;
            tempMult_var := (others => '0');
            tempProd_var := (others => '0');

            A_sig <= (others => '0');
            B_sig <= (others => '0');

            Output <= (others => '0');
        when S0 =>
            nstate <= S0;         

            if (DAVBL = '1') then
                A_sig <= Input;
                nstate <= S1;
            end if;
        when S1 =>
            nstate <= S1;

            if (Confirm = '1') then
                nstate <= S2;
            end if;
        when S2 =>
            nstate <= S2;

            if (DAVBL = '1') then
                B_sig <= Input;
                nstate <= S3;
            end if;
        when S3 =>
            nstate <= S3;

            if (Confirm = '1') then
                nstate <= S4;
            end if;

        when S4 =>
            nstate <= S0;

            for x in 0 to 3 loop
                temp_var := (A_sig AND (B_sig(x)&B_sig(x)&B_sig(x)&B_sig(x) ) );
                tempMult_var := "0000" & temp_var;
                if (x=0) then tempMult_var := tempMult_var;
                elsif (x=1) then tempMult_var := tempMult_var(6 downto 0)&"0";
                elsif (x=2) then tempMult_var := tempMult_var(5 downto 0)&"00";
                elsif (x=3) then tempMult_var := tempMult_var(4 downto 0)&"000";        
                end if;
                tempProd_var := tempProd_var + tempMult_var;
            end loop;

            Output <= tempProd_var;
            tempProd_var := (others => '0');
    end case;
end process;

end Behavioral;

The simulation when no number is pressed with the confirmation button: enter image description here

The simulation when a number is pressed with the confirmation button: enter image description here

I've been going through my code for an hour now but still can't see what's wrong. Thanks in advance to anyone who can help.

Upvotes: 1

Views: 1214

Answers (1)

Josh
Josh

Reputation: 3655

As mentioned by fru1tbat, Brian, and David, you have a problem with the sensitivity list in the combinatorial portion of your state machine. Specifically, you are missing the Confirm input. Since the Confirm input is not in the sensitivity list, the state machine will not "wake up" to evaluate new outputs/state transitions when confirm changes state. You need to wait for another condition (a different button press) in order to evaluate properly and update the output.

There are multiple ways that this can be resolved.

  • You can make sure you have a complete sensitivity list for your state machine logic
  • With VHDL-2008, you can use process(all) to automatically list all necessary inputs in the sensitivity list (your compiler support may vary).
  • You can choose to use a "single process state machine" style, which avoids this issue. However, different styles of state machines have their strengths and pitfalls that need to be considered.

Upvotes: 0

Related Questions