1

i am trying to do an algorithm that verify prime numbers. To do this i have to make a circuit using RTL Design method, i am using the algorithm below to get the prime number:

int prime (int x) {
int i, div;
div = 0;
    for (i = 1; i <= x; i++){
        if (mod(x, i) == 0)
        div++;
    }
if (div == 2)
return 1; // PRIME
else
return 0; // NPRIME
}

To implement this solution I created two blocks: Datapath and Control like the image below:

enter image description here

My datapath has 4 intern blocks:

for_reg --> register that control the loop for of the prime algorithm (have a flag to indicate when the loop ends)
buffer  --> Makes the output equal the input
modulo  --> Get the mod of the div from the two inputs
comp    --> Compare the output from modulo (if equal 0 the output of compare goes 1 else 0).

My control works comparing the input C (input C <= output_comp), if the comparison value is equal 1 I increment the signal div, after this i verify the value of the input flag, if is equal 1 i go to the finish state of the state machine that verify if the value of signal div is equal 2, if it is the output of control gets value 1, if not gets value 0 (1 - prime , 0 - not prime).

My problem is in the output of control block that stays always in 0. I've simulated all blocks separated and it seems to work correctly.

enter image description here

I believe the error is in the for_reg or in the control block, because the other blocks are simple and like I said before, its working correctly.

Below the simulation of the mod block:

enter image description here

PS.: I've used a state machine to create this block, when it gets on the final state automatically returns to the first state, so it's because of that the output stays always 0 and 3.

Below the codes from control and for_reg:

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

ENTITY verifica_primo_control IS
  PORT (
       i_CLK    : IN STD_ULOGIC;
       i_RST    : IN STD_LOGIC;
       i_C      : IN STD_LOGIC;
       i_FLAG   : IN STD_LOGIC;
       o_DOUT   : OUT STD_LOGIC
      );     
END verifica_primo_control;

ARCHITECTURE arch_1 OF verifica_primo_control IS
  TYPE state_type IS (s0, s1, s2, s3);
  SIGNAL stateT : state_type;
  SIGNAL w_AUX : integer;
BEGIN
  PROCESS(i_CLK)
  BEGIN
    IF rising_edge(i_CLK) THEN
      IF (i_RST = '1') THEN
        stateT <= s0;
        w_aux <= 0;
      ELSE
        CASE stateT IS
          when s0 => IF (i_C = '1') THEN
                        stateT <= s1;
                     ELSE
                        stateT <= s3;
                     END IF;
          when s1 => w_AUX <= w_AUX +1;
                     if (i_FLAG = '1') then 
                       stateT <= s2;
                     else 
                       stateT <= s0;
                     end if;
          when s2 => IF (w_AUX = 2) THEN
                        o_DOUT <= '1';
                     ELSE 
                        o_DOUT <= '0';
                     END IF;
          when s3 => 
                    if (i_FLAG = '1') then 
                       stateT <= s2;
                     else 
                       stateT <= s0;
                     end if;
        END CASE;
      END IF;
    END IF;
  END PROCESS;


END arch_1;

enter image description here


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

ENTITY for_reg IS
  PORT (
      i_CLR  : IN STD_LOGIC;         
      i_CLK  : IN STD_ULOGIC;        
      i_X    : IN UNSIGNED (7 downto 0); -- number input to verify if its prime
      i_I    : IN UNSIGNED (7 downto 0) ;        
      o_FLAG : OUT STD_LOGIC;
      o_II   : OUT UNSIGNED (7 downto 0)
      );     
END for_reg;

ARCHITECTURE arch_1 OF for_reg IS
signal w_AUX : unsigned (7 downto 0);
BEGIN
  PROCESS(i_CLK)
  BEGIN
    IF rising_edge(i_CLK) THEN
      IF (i_CLR = '1') THEN
        o_II <= "00000000";
        w_AUX <= "00000000";
        o_FLAG <='0';
      ELSIF (i_CLR ='0' AND i_I < i_X) THEN
        w_AUX <= i_I;
        o_II <= w_AUX + "00000001";
        o_FLAG <='0';
      ELSIF (i_CLR = '0' AND i_I = i_X) THEN
        o_II <= i_I;
        o_FLAG <= '1';
      END IF;
    END IF;
  END PROCESS;


END arch_1;

enter image description here

Like i said before, i believe the error is in one of this two blocks, i believe with that codes is possible verify where is the error. If this is not enough to have the MCVE warn me that i will update the post with the the other codes that is necessary to verify the error.

I am using the quartus II simulator, so I don't have a testbanch for this, I put all the test signals manually.

Mutante
  • 278
  • 5
  • 18
  • 1
    Start with a testbench. Translate that "algorithm" into a VHDL function - the last 4 lines turn into `return div = 2;` so it's not difficult. Now you have a golden model which the TB can compare the outputs from your RTL model against. Then proceed from there by stepwise refinement. –  Jun 29 '16 at 18:43
  • 1
    StateT, i_RST and w_AUX aren't shown in a waveform. Without an [MCVE](http://stackoverflow.com/help/mcve) a reader can't replicate the problem you don't fully instrument, asking for an educated guess. Here's one - you didn't initialize w_AUX with i_RST, it's initial value is INTEGER'LEFT (it's unconstrained), you didn't simulate long enough to reach w_AUX = 2. Supplying enough information in your question can also point you to the problem without anyone guessing. What VHDL simulator can't do a [testbench](http://vhdl.renerta.com/mobile/source/vhd00073.htm)? –  Jun 29 '16 at 21:05
  • @user1155120 I've updated the original post, sorry about the missing waveforms. Another doubt now, can i generate a testbanch automatically with quartus or i have to do this manually? I hope with this waveforms you can replicate my problem. – Mutante Jun 29 '16 at 23:09
  • In function prime `if (x % i == 0) // WAS if (mod(x, i) == 0)`. You count the number of times `x` modulus non-zero `i` equals 0 (a prime number divides only by 1 and itself with no remainder (== 0), it's how `div` ends up 2). Where does i_C come from? (And why is it high for all three times through the loop?) There's no for_reg dependency on stateT (or any outputs from verifica_primo_control). Your design specification fragments don't appear to implement the C `prime` [function](https://www.dropbox.com/s/r8yyt2ljem0iu5t/prime_test.c?dl=1). –  Jun 30 '16 at 01:05
  • 1) I dont understand what you said, you are saying that i am doing x mod 0? 2) The value of C i create in the simulation, like i said in the description this value comes from a comparator block ( The comparator block verify if the output of the mod block is equal 0, if it is equal 0 the i_C on the control gets the value 1, if the output of the mod block is different than 0 the i_C gets value 0. – Mutante Jun 30 '16 at 01:27

0 Answers0