Problem mit a^b mod m als Zustandsmaschine

Gast #909701
Lesenswert?

Hier mein Versuch a^b mod m als Zustandsmaschine zu modellieren 
inklusive Testbench. Den Modulus habe ich momentan ausgeklammert. Es 
soll also a^b berechnet werden. In der Testbench sind a und b momentan 
auf 3 gesetzt. Die Bitbreite liegt bei 4. Es sollte also 27 berechnet 
werden. erg erhält auch den Wert 27. Bei der Zuweisung zu 
std_logic_vector wird daraus jedoch 11. Welche Bitbreite muß ich für das 
Ergebnis wählen ? Die Synthese liefert leider einige Warnungen.  Bastel 
schon lange daran herum und finde den Fehler nicht.
1
library IEEE;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
use ieee.math_real.all;
5

6
entity eight_bit_multiplier is
7
  generic
8
  (
9
    size : integer := 4;
10
    m : integer := 2 ** 8
11
  );
12
  port
13
  (
14
    clock              : in   std_logic;
15
    a                : in   std_logic_vector(size-1 downto 0);
16
    b                       : in   std_logic_vector(size-1 downto 0);
17
    c                       : out std_logic_vector(size-1 downto 0)
18
  );  
19
  
20
end eight_bit_multiplier;
21

22
-- c = (a ^ b) mod m
23
architecture eight_bit_multiplier_rtl of eight_bit_multiplier is
24
  type states is (first, second, third, forth);
25
  signal state : states := first;
26
  signal next_state : states;
27
  subtype long is integer range 0 to 2 ** size - 1;
28

29
  signal exp   : long;
30
  signal erg   : long;
31
  signal erg_temp, exp_temp : long;
32
  subtype index is integer range size-1 downto 0;
33
  signal i : index;
34
begin  
35
  
36
  clocking : process (clock)
37
  begin
38
    if rising_edge(clock)
39
    then
40
      state <= next_state;
41
    end if;
42
  end process;
43
  
44
   -- generate_key : process (clock)
45
  -- begin
46
    -- if rising_edge(clock)
47
    -- then
48
      -- erg <= 1;
49
      -- exp <=  to_integer(unsigned(a));    
50
      -- for i in b'range loop
51
        -- if b(i) = '1'
52
        -- then  
53
          -- erg <= erg * exp;
54
        -- else
55
          -- null;
56
        -- end if;
57
        -- exp <= exp * exp;
58
      -- end loop;
59
      --c <= std_logic_vector(to_unsigned(erg,size*size));
60
    --end if;
61
    --end process;
62
    
63
    
64
  state_machine : process (clock)
65
  begin
66
     if rising_edge(clock)
67
    then
68
    case state is
69
      when first => erg <= 1;
70
                exp <= to_integer(unsigned(a));
71
                i <= b'high;
72
                next_state <= second;
73
      when second => if i > b'low
74
                then
75
                  if b(i) = '1'
76
                  then
77
                    -- erg_temp <= (erg * exp) mod m;
78
                    erg_temp <= (erg * exp);
79
                  else
80
                    erg_temp <= exp;
81
                  end if;
82
                  -- exp_temp <= (exp * exp) mod m;
83
                  exp_temp <= exp * exp;
84
                end if;
85
                 next_state <= third;
86
      when third => erg <= erg_temp;
87
                exp <= exp_temp;  
88
                if i > b'low
89
                then                                
90
                  i <= i - 1;                
91
                  next_state <= second;
92
                else
93
                  next_state <= forth;
94
                end if;
95
    
96
      when forth => c <= std_logic_vector(to_unsigned(erg,size));
97
    end case;  
98
    end if; -- rising_edge
99
  end process;
100
  
101
  
102
end architecture eight_bit_multiplier_rtl;
1
 LIBRARY ieee;
2
  USE ieee.std_logic_1164.ALL;
3
  USE ieee.numeric_std.ALL;
4

5
  ENTITY testbench IS
6
  END testbench;
7

8
  ARCHITECTURE behavior OF testbench IS 
9

10
  -- Component Declaration
11
          COMPONENT eight_bit_multiplier
12
       PORT(
13
                  clock : IN std_logic;
14
                  a, b : IN std_logic_vector(0 to 3);       
15
                  -- c : OUT std_logic_vector(0 to 3)
16
            c : out std_logic_vector(0 to 3)
17
                  );
18
          END COMPONENT;
19

20
          signal signal_a : std_logic_vector(0 to 3);
21
         signal signal_b : std_logic_vector(0 to 3);
22
      -- signal signal_c : std_logic_vector(0 to 7);
23
      signal signal_c : std_logic_vector(0 to 3);
24
      signal clock_internal : std_logic;
25
      
26
        -- Clock period definitions
27
   constant clock_period_testbench    : time := 10ns;
28
  signal stop_the_clock: boolean;
29
  BEGIN
30

31
  -- Component Instantiation
32
          uut: eight_bit_multiplier PORT MAP(
33
                  a => signal_a,
34
                  b => signal_b,
35
            c => signal_c,
36
            clock => clock_internal
37
          );
38

39
  clocking : process
40
  begin
41
    while not stop_the_clock loop
42
      clock_internal <= '1', '0' after clock_period_testbench / 2;
43
     wait for clock_period_testbench;
44
    end loop;
45
    wait;
46
  end process;
47

48
  
49
  --  Test Bench Statements
50
     tb : PROCESS
51
     BEGIN
52
      
53
        wait for 10 ns; -- wait until global set/reset completes
54

55
        -- Add user defined stimulus here
56
      
57
      signal_a <= "0011";
58
      signal_b <= "0011";
59
        wait; -- will wait forever
60
     END PROCESS tb;
61
  --  End Test Bench 
62

63
  END;
#909989
Lesenswert?

>Den Modulus habe ich momentan ausgeklammert.
Nein, den hast du mit drin, da c die gleiche Breite hat wie a und b:
11 = 27 mod 2^size

Die nötige Breite für das komplette Ergebnis hattest du doch schon im 
anderen Thread geschrieben (warum eigentlich der neue?): (size*size-1 
downto 0)

Die Warnungen dürften sich auf die abgeschnittenen Bits beziehen.
Gast #910003
Lesenswert?

kruzen blick drübergeworfen. wie jan schon sagte fehlen dir im ergebnis 
bits.
als ergebnis hast du 11. rechne spaßeshalber ein mglweise auf 1 
gesetztes 4. bit [16]. dann kommst du auf deine 27.
würde also bis auf die länge deines ergebnisses passen.
Gast #910233
Lesenswert?

Typischer Fall von Selbstüberlistung.
Dezimal 27 auf 4 Bit beschränkt, bzw. modulo 16 ist natürlich dezimal 
11.
Musste noch eine If-Abfrage einfügen, aber funktioniert.
-- Getested mit 3^4 mod 16, 3^4 mod 15, 1^4 mod 15
-- Getested mit 15^3 mod 15, 7^3 mod 15

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren