Funktionsabbildung mit Altera Integer Arithmethic Megafunctions

Gast #2513409
Lesenswert?
• ▲
▼
Ich möchte in VHDL folgende Funktionsabbildung mit den Altera Integer 
Arithmethic Megafunctions realisieren:

f(x)= floor( 255*(x-50)/150 )
x ist eine unsigned 8bit Zahl mit 50 < x < 200
also bspw.
f(51) = floor(1.7) =1
f(199) = floor(253.3) = 253

f(x) soll auch wieder eine unsigned 8bit Zahl sein

Ich habe in der PDF( 
http://www.altera.com/literature/ug/ug_lpm_alt_mfug.pdf ) zu den Altera 
Integer Arithmethic Megafunctions keine größere Erklärung gesehen, also 
sehe zumindest nicht, wie ich die anders verwenden sollte... kriege aber 
immer 0 für f raus (wenn done flag gesetzt ist).

Hier der Code:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
LIBRARY lpm;
5
USE lpm.lpm_components.all;
6
 
7
ENTITY Func IS
8
PORT(
9
    x      : in std_logic_vector(7 downto 0);
10
    reset  : in std_logic;
11
    clk : in std_logic;
12
    f      : out std_logic_vector(7 downto 0);
13
    done   : out std_logic;
14
    );
15
END Func;
16
    
17
ARCHITECTURE rtl OF Func IS
18

19
--dividierer mit 16 bit zähler und 8bit nenner
20
component LPM_DIVIDE
21
    generic (LPM_WIDTHN : natural := 16;
22
         LPM_WIDTHD : natural := 8;
23
LPM_NREPRESENTATION : string := "UNSIGNED";
24
LPM_DREPRESENTATION : string := "UNSIGNED";
25
LPM_PIPELINE : natural := 0;
26
LPM_TYPE : string := L_DIVIDE;
27
LPM_HINT : string := "UNUSED");
28
port (NUMER : in std_logic_vector(LPM_WIDTHN-1 downto 0);
29
DENOM : in std_logic_vector(LPM_WIDTHD-1 downto 0);
30
ACLR : in std_logic := '0';
31
CLOCK : in std_logic := '0';
32
CLKEN : in std_logic := '1';
33
QUOTIENT : out std_logic_vector(LPM_WIDTHN-1 downto 0);
34
REMAIN : out std_logic_vector(LPM_WIDTHD-1 downto 0));
35
end component;
36
 
37
component LPM_MULT
38
    generic ( LPM_WIDTHA : natural := 8;
39
         LPM_WIDTHB : natural := 8;
40
         LPM_WIDTHS : natural := 16;
41
         LPM_WIDTHP : natural := 16;
42
LPM_REPRESENTATION : string := "UNSIGNED";
43
LPM_PIPELINE : natural := 0;
44
LPM_TYPE: string := L_MULT;
45
LPM_HINT : string := "UNUSED");
46
port ( DATAA : in std_logic_vector(LPM_WIDTHA-1 downto 0);
47
DATAB : in std_logic_vector(LPM_WIDTHB-1 downto 0);
48
ACLR : in std_logic := '0';
49
CLOCK : in std_logic := '0';
50
CLKEN : in std_logic := '1';
51
SUM : in std_logic_vector(LPM_WIDTHS-1 downto 0) := (OTHERS
52
=> '0');
53
RESULT : out std_logic_vector(LPM_WIDTHP-1 downto 0));
54
end component;
55
 
56
type state_t is (S_start, S_calc, S_done);
57
signal state, state_nxt : state_t;
58

59
signal cs_div_res  : std_logic_vector(15 downto 0);
60
signal cs_mult_res : std_logic_vector(15 downto 0);
61
signal cs_diff_res : std_logic_vector(7 downto 0);
62
signal counter : std_logic_vector(7 downto 0);
63
signal calc : std_logic;
64
 
65
 begin
66
 
67
  cs_mult: LPM_MULT
68
  port map (
69
     DATAA  => "11111111",
70
     DATAB  => cs_diff_res,
71
     RESULT => cs_mult_res);
72
 
73
  cs_div: LPM_DIVIDE
74
  port map (
75
     NUMER    => cs_mult_res,
76
     DENOM    => "10010110", --150 binär
77
     QUOTIENT => cs_div_res);
78
 
79
  process(x)
80
    begin
81
     cs_diff_res <= std_logic_vector(unsigned(x)-unsigned("110010")); --binär 50
82
     f <= cd_div_res (7 downto 0); --die ersten 8 least significant bit
83
  end process;
84

85
  process(clk)
86
  begin
87
    if clk_in'event and clk_in='1' then
88
      if reset = '1' then
89
        counter <= (others => '0');
90
        state <= S_start;
91
      end if;         
92
        state <= state_nxt;
93
      if calc = '1' then
94
        counter <= std_logic_vector(unsigned(counter) + 1);
95
      else
96
        counter <= (others => '0');
97
      end if;
98
    end if;
99
  end process;
100
 
101
  process(state, counter)
102
  begin
103
      --defaultwerte
104
  
105
      state_nxt <= state;
106
      calc <= '0';
107
      done <= '0';
108
 
109
      case state is
110
         when S_start =>
111
          state_nxt <= S_calc;
112
           
113
         when S_calc =>
114
          calc='1';
115
          if counter > 50 then --nach spätestens 50 takten sollte die berechnung fertig sein
116
            state_nxt <= S_done;
117
          end if;
118

119
         when S_done =>
120
          done <= '1';
121
          --idle
122
      end case;
123
  end process;
124
END rtl;
Moderator (Firma: Titel) Persönliche Seite #2513979
Lesenswert?
• ▲
▼
yunokwork schrieb:
> kriege aber immer 0 für f raus
Teil die Rechnung mal in kleiner Schritte auf.
Und: in welchem Rechenschritt klemmt es?

Dir ist schon klar, dass der Synthesizer bei deiner Schreibweise gerne 
auch so rechnen darf: f(x)= floor( 255*((x-50)/150) )
Und  (x-50)/150   ist fast immer kleiner als 1...  :-o


Überaus bedenklich ist übrigens die Division mit 150. Ich würde diesen 
Rechenschritt eher eine Multiplikation und anschliessendes Abschneiden 
von LSBs umwandeln.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.