Forum: FPGA, VHDL & Co. Problem mit a^b mod m als Zustandsmaschine


von Hans-Werner (Gast)


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;

von Jan M. (mueschel)


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.

von TheMason (Gast)


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.

von Hans-Werner (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.