Search code examples
vhdlquartus

Two outputs values in a mod operation using vhdl


I am trying to do a circuit that get the MOD of two numbers, my problem is in the output of that circuit, the output shows 0 and then the correct value of MOD, i have to integrate this circuito to another circuit to do a circuito that shows if a number is prime or not. When i integrate the MOD circuit to the PRIME number circuit, the output of the PRIME circuit goes always wrong because the situation above, the output of the MOD circuit shows always two values. The output form below:

enter image description here

In this image the circuit get always 0 and 3 because my state machine stays in loop, this is not the problem, the problem is: i need that output stay always with the value of the MOD and no zeros. In this example should stay always 3.

My control code.

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;

ENTITY operacao_modulo_control IS
  PORT (
       i_CLK    : IN STD_ULOGIC;
       i_RST    : IN STD_LOGIC;
       i_S      : IN INTEGER;
       i_COMP   : IN STD_LOGIC;
       o_LD_CLR : OUT STD_LOGIC;
       o_LD_K   : OUT STD_LOGIC;
       o_DOUT   : OUT INTEGER
      );     
END operacao_modulo_control;

ARCHITECTURE arch_1 OF operacao_modulo_control IS
  TYPE state_type IS (s0, s1, s2,s3);
  SIGNAL stateT : state_type;
BEGIN
  PROCESS(i_CLK)
  BEGIN
    IF rising_edge(i_CLK) THEN
      IF (i_RST = '1') THEN
        stateT <= s0;
      ELSE
        CASE stateT IS
          when s0 => stateT <= s1;
          when s1 => if (i_COMP = '1') then 
                       stateT <= s2;
                     else 
                       stateT <= s3;
                     end if;
          when s2 => stateT <= s1;
          when s3 => stateT <= s0;
        END CASE;
      END IF;
    END IF;
  END PROCESS;

  o_LD_CLR <= '1' WHEN (stateT = s0) ELSE '0';
  o_LD_K <= '1' WHEN (stateT = s2) ELSE '0';
  o_DOUT <= i_S WHEN (stateT = s3) ELSE 0;

END arch_1;

How can i change this to make the output shows only the correct value of the MOD and no zeros?

If the other codes is necessary, they are below:

Datapath:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;

entity operacao_modulo_datapath is
port (
    i_RESET         : IN STD_LOGIC;                             -- Sinal para resetar a maquina de estados do contador
    i_CLOCK         : IN STD_ULOGIC;                            -- Clock
    i_LOAD_K        : IN STD_LOGIC;                             -- Sinal para carregar K
    i_LOAD_CLEAR    : IN STD_LOGIC;                             -- Sinal para limpar K
    i_A             : IN UNSIGNED (7 downto 0);                 -- Entrada A
    i_B             : IN UNSIGNED (7 downto 0);                 -- Entrada B
    o_OUTS          : OUT INTEGER;                              -- Saida da operação aritmética
    o_COMP          : OUT STD_LOGIC                             -- Saída do comparador
    );
end operacao_modulo_datapath;


architecture arch_1 of operacao_modulo_datapath is

component tot is
port    (
      i_RST  : IN STD_LOGIC;
      i_CLR  : IN STD_LOGIC;         -- Sinal vindo do controle para limpar o valor de K
      i_CLK  : IN STD_ULOGIC;        -- Sinal de clock para sincronizar com o controle
      i_DINL : IN STD_LOGIC ;        -- Sinal de load para carregar K
      i_DINK : IN INTEGER;           -- Valor antigo de K
      o_DOUTK : OUT INTEGER
      );  -- data output
end component;


component array_multiplier is 
port (
    i_MULTIPLICAND : in unsigned(7 downto 0); -- data input
    i_MULTIPLIER : in integer; -- data input
    o_DOUT : out std_logic_vector(15 downto 0)); -- data output
end component;  


component alu_mod is 
port (
    i_DINA  : IN UNSIGNED (7 downto 0);          -- Entrada A
    i_DINM  : IN STD_LOGIC_VECTOR(15 downto 0);  -- entrada do multiplicador
    o_DOUTS : OUT INTEGER                      -- saída S da operação de mod
    ); 
end component;  


component comparator is 
port (
    i_DINS : IN INTEGER;                         -- Entrada S (saída S da alu_mod)
    i_DINB : IN UNSIGNED (7 downto 0);           -- Entrada B (entrada do usuário)
    o_DOUT : OUT STD_LOGIC);                     -- Saída para informar o resultado da comparação
end component;  



signal w_OUT   : STD_LOGIC;
signal w_Ko    : INTEGER;
signal w_Ki    : INTEGER;
signal w_OUT0  : INTEGER;
signal w_OUT1  : std_logic_vector(15 downto 0);

begin 

u_0: tot port map (
                  i_RST   => i_RESET,
                  i_CLR   => i_LOAD_CLEAR,
                  i_CLK   => i_CLOCK,
                  i_DINL  => i_LOAD_K,
                  i_DINK  => w_Ko,
                  o_DOUTK => w_Ko
                  );

u_1: array_multiplier port map (
                  i_MULTIPLICAND => i_B,
                  i_MULTIPLIER   => w_Ko,
                  o_DOUT         => w_OUT1
                  );


u_2: alu_mod port map (
                 i_DINA   => i_A,
                 i_DINM   => w_OUT1,
                 o_DOUTS  => w_OUT0
                 );

u_3: comparator port map (
                i_DINS   => w_OUT0,                    
                i_DINB   => i_B,           
                o_DOUT   => w_OUT                  
                 );


o_OUTS <= w_OUT0;
o_COMP <= w_OUT;                


end arch_1;

Top level entity:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;

entity operacao_modulo_top is
port (
    i_RESETAR         : IN STD_LOGIC;                             -- Sinal para resetar a maquina de estados do contador
    i_CLCK            : IN STD_ULOGIC;                            -- Clock
    i_INA             : IN UNSIGNED (7 downto 0);                 -- Entrada A
    i_INB             : IN UNSIGNED (7 downto 0);                 -- Entrada B
    o_SOMA            : OUT INTEGER                              -- Saida da operação aritmética
    );
end operacao_modulo_top;


architecture arch_1 of operacao_modulo_top is

component operacao_modulo_datapath is
port(
        i_RESET         : IN STD_LOGIC;                             -- Sinal para resetar a maquina de estados do contador
        i_CLOCK         : IN STD_ULOGIC;                            -- Clock
        i_LOAD_K        : IN STD_LOGIC;                             -- Sinal para carregar K
        i_LOAD_CLEAR    : IN STD_LOGIC;                             -- Sinal para limpar K
        i_A             : IN UNSIGNED (7 downto 0);                 -- Entrada A
        i_B             : IN UNSIGNED (7 downto 0);                 -- Entrada B
        o_OUTS          : OUT INTEGER;                              -- Saida da operação aritmética
        o_COMP          : OUT STD_LOGIC                             -- Saída do comparador
     );  
end component;


component operacao_modulo_control is 
port (
       i_CLK    : IN STD_ULOGIC;
       i_RST    : IN STD_LOGIC;
       i_S      : IN INTEGER;
       i_COMP   : IN STD_LOGIC;
       o_LD_CLR : OUT STD_LOGIC;
       o_LD_K   : OUT STD_LOGIC;
       o_DOUT   : OUT INTEGER
      ); 
end component;  


signal w_OUT0  : INTEGER;
signal w_OUT3  : INTEGER;
signal w_OUT1  : STD_LOGIC;
signal w_OUT2  : STD_LOGIC;
signal w_OUT   : STD_LOGIC;




begin 

u_0: operacao_modulo_datapath port map (
                                          i_RESET          => i_RESETAR,        
                                          i_CLOCK          => i_CLCK,        
                                          i_LOAD_K         => w_OUT2,
                                          i_LOAD_CLEAR     => w_OUT1,
                                          i_A              => i_INA,
                                          i_B              => i_INB,
                                          o_OUTS           => w_OUT0,
                                          o_COMP           => w_OUT           
                                        );

u_1: operacao_modulo_control port map (
                                        i_CLK    => i_CLCK,
                                        i_RST    => i_RESETAR,
                                        i_S      => w_OUT0,
                                        i_COMP   => w_OUT,
                                        o_LD_CLR => w_OUT1,
                                        o_LD_K   => w_OUT2,
                                        o_DOUT   => w_OUT3
                                      );


o_SOMA <= w_OUT3;            


end arch_1;

Solution

  • Your problem is this line:

    o_DOUT <= i_S WHEN (stateT = s3) ELSE 0;
    

    stateT only equals s3 one clock in three, hence you output. If you don't want the zeros, you need to store the value of i_S in some flip-flops, which are updated when stateT = s3:

    PROCESS(i_CLK)
    BEGIN
      IF rising_edge(i_CLK) THEN
        IF i_RST = '1' THEN
          o_DOUT <= 0;
        ELSIF stateT = s3 THEN
          o_DOUT <= i_S;
        END IF;
      END IF;
    END PROCESS;
    

    http://www.edaplayground.com/x/25QN