mikrocontroller.net

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


Autor: Hans-Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;

entity eight_bit_multiplier is
  generic
  (
    size : integer := 4;
    m : integer := 2 ** 8
  );
  port
  (
    clock              : in   std_logic;
    a                : in   std_logic_vector(size-1 downto 0);
    b                       : in   std_logic_vector(size-1 downto 0);
    c                       : out std_logic_vector(size-1 downto 0)
  );  
  
end eight_bit_multiplier;

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

  signal exp   : long;
  signal erg   : long;
  signal erg_temp, exp_temp : long;
  subtype index is integer range size-1 downto 0;
  signal i : index;
begin  
  
  clocking : process (clock)
  begin
    if rising_edge(clock)
    then
      state <= next_state;
    end if;
  end process;
  
   -- generate_key : process (clock)
  -- begin
    -- if rising_edge(clock)
    -- then
      -- erg <= 1;
      -- exp <=  to_integer(unsigned(a));    
      -- for i in b'range loop
        -- if b(i) = '1'
        -- then  
          -- erg <= erg * exp;
        -- else
          -- null;
        -- end if;
        -- exp <= exp * exp;
      -- end loop;
      --c <= std_logic_vector(to_unsigned(erg,size*size));
    --end if;
    --end process;
    
    
  state_machine : process (clock)
  begin
     if rising_edge(clock)
    then
    case state is
      when first => erg <= 1;
                exp <= to_integer(unsigned(a));
                i <= b'high;
                next_state <= second;
      when second => if i > b'low
                then
                  if b(i) = '1'
                  then
                    -- erg_temp <= (erg * exp) mod m;
                    erg_temp <= (erg * exp);
                  else
                    erg_temp <= exp;
                  end if;
                  -- exp_temp <= (exp * exp) mod m;
                  exp_temp <= exp * exp;
                end if;
                 next_state <= third;
      when third => erg <= erg_temp;
                exp <= exp_temp;  
                if i > b'low
                then                                
                  i <= i - 1;                
                  next_state <= second;
                else
                  next_state <= forth;
                end if;
    
      when forth => c <= std_logic_vector(to_unsigned(erg,size));
    end case;  
    end if; -- rising_edge
  end process;
  
  
end architecture eight_bit_multiplier_rtl;
 LIBRARY ieee;
  USE ieee.std_logic_1164.ALL;
  USE ieee.numeric_std.ALL;

  ENTITY testbench IS
  END testbench;

  ARCHITECTURE behavior OF testbench IS 

  -- Component Declaration
          COMPONENT eight_bit_multiplier
       PORT(
                  clock : IN std_logic;
                  a, b : IN std_logic_vector(0 to 3);       
                  -- c : OUT std_logic_vector(0 to 3)
            c : out std_logic_vector(0 to 3)
                  );
          END COMPONENT;

          signal signal_a : std_logic_vector(0 to 3);
         signal signal_b : std_logic_vector(0 to 3);
      -- signal signal_c : std_logic_vector(0 to 7);
      signal signal_c : std_logic_vector(0 to 3);
      signal clock_internal : std_logic;
      
        -- Clock period definitions
   constant clock_period_testbench    : time := 10ns;
  signal stop_the_clock: boolean;
  BEGIN

  -- Component Instantiation
          uut: eight_bit_multiplier PORT MAP(
                  a => signal_a,
                  b => signal_b,
            c => signal_c,
            clock => clock_internal
          );

  clocking : process
  begin
    while not stop_the_clock loop
      clock_internal <= '1', '0' after clock_period_testbench / 2;
     wait for clock_period_testbench;
    end loop;
    wait;
  end process;

  
  --  Test Bench Statements
     tb : PROCESS
     BEGIN
      
        wait for 10 ns; -- wait until global set/reset completes

        -- Add user defined stimulus here
      
      signal_a <= "0011";
      signal_b <= "0011";
        wait; -- will wait forever
     END PROCESS tb;
  --  End Test Bench 

  END;

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hans-Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.