mikrocontroller.net

Forum: FPGA, VHDL & Co. Bresenham.vhd


Autor: yosra (Gast) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

ich habe einen Bresenham in VHDL geschrieben.
-- Bresenham.vhd
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

ENTITY Bresenham IS
   generic
  (
    SHIFT_WIDTH       : natural := 1  
  );
  PORT
  (
    clk       : in std_logic;
    reset_n   : in std_logic;
    fval_in   : in std_logic;
    lval_in   : in std_logic;
    pval_in   : in std_logic;
    ref_in    : in std_logic_vector(15 downto 0);
        
    ref_out   : out std_logic_vector(15 downto 0);
    fval_out  : out std_logic;
    lval_out  : out std_logic;
    pval_out  : out std_logic;
    rdref     : out std_logic

  );
END Bresenham;

ARCHITECTURE behavior OF Bresenham IS

   signal r_fval          : std_logic_vector(SHIFT_WIDTH-1 downto 0); 
   signal r_lval          : std_logic_vector(SHIFT_WIDTH-1 downto 0);
   signal r_pval          : std_logic_vector(SHIFT_WIDTH-1 downto 0);
   
   signal r_ref           : std_logic_vector(11 downto 0);
   signal r_ref_in        : unsigned(15 downto 0):=(others => '0');
   signal r2_ref_in       : integer := 0;
   signal r3_ref_in       : integer := 0;
   signal ref_result      : std_logic_vector(15 downto 0):=(others => '0');
   
   signal state           : std_logic:='0';
   
BEGIN
    
    ref_out  <= ref_result;
    fval_out <= r_fval (SHIFT_WIDTH-1);
    lval_out <= r_lval (SHIFT_WIDTH-1);
    pval_out <= r_pval (SHIFT_WIDTH-1);
    rdref   <= state;

   
  process(reset_n, clk)
  variable x1       : unsigned(7 downto 0):=(others => '0');
  variable y1       : unsigned(7 downto 0):=(others => '0');
  variable ex       : integer := 0;
  variable ex1      : integer := 0;
  variable x        : integer := 0;
  variable y        : integer := 0;
  begin

  if(reset_n = '0') then
    r_fval      <= conv_std_logic_vector('0', SHIFT_WIDTH);
    r_lval      <= conv_std_logic_vector('0', SHIFT_WIDTH);
    r_pval      <= conv_std_logic_vector('0', SHIFT_WIDTH);
    r_ref       <= (others => '0');
    r2_ref_in   <= 0;
    r3_ref_in   <= 0;
    r_ref       <= (others => '0');
    r_offset    <= (others => '0');
    ref_result  <= (others => '0');
      
  elsif(clk'event and clk = '1') then
    r_fval      <= r_fval (SHIFT_WIDTH-2 downto 0) & fval_in;
    r_lval      <= r_lval (SHIFT_WIDTH-2 downto 0) & lval_in;
    r_pval      <= r_pval (SHIFT_WIDTH-2 downto 0) & pval_in;
    ref_result1 <= ref_result;
      
    if (fval_in = '1' and lval_in ='0') then
       r_ref_in <= unsigned (ref_in);
       r2_ref_in<= conv_integer (r_ref_in (7 downto 0));
       r3_ref_in<= conv_integer (r_ref_in (15 downto 8));
       ex       := r2_ref_in/2;      
       state    <= '0';
    end if;
    if (lval_in ='1') then
       if (state = '0') then
    if (x <= r2_ref_in) then 
       if (ex < 0) then
          y  := y + 1;  
          ex := ex + r2_ref_in - r3_ref_in;
          x1 := conv_unsigned(x,8);
          y1 := conv_unsigned(y,8);
                      ref_result ( 7 downto 0) <= std_logic_vector(x1);  
          ref_result (15 downto 8) <= std_logic_vector(y1);
          x  := x + 1;
          if (x > r2_ref_in) then
            state <= '1';
          else 
            state <= '0';
          end if;
      else
         ex := ex - r3_ref_in;
         x1 := conv_unsigned(x,8);
         y1 := conv_unsigned(y,8);
                     ref_result ( 7 downto 0) <= std_logic_vector(x1);
                     ref_result (15 downto 8) <= std_logic_vector(y1);
         x  := x + 1; 
         if (x > r2_ref_in) then
      state <= '1';
         else 
      state <= '0';
         end if;
      end if;
    elsif(x > r2_ref_in) then
      state <= '1';
    else
      ref_result ( 7 downto 0) <= x"00";
      ref_result (15 downto 8) <= x"00";  
    end if;
       end if;
       if (state = '1') then        
    ref_result ( 7 downto 0) <= std_logic_vector(x1);
                ref_result (15 downto 8) <= std_logic_vector(y1);
       end if;
    else
       x     := 0;
       y     := 0;
       state <= '0';
    end if;
        end if;
     end process;  
END behavior;


Ich hab´s getestet. Es funktioniert gut. Gibt´s gute Ratschläge oder 
Verbesserungen?
Ich will vor diesem Block einen FIFO ( für SDRAM bei Altera) bauen. Kann 
jemand mir helfen, wie der FIFO-Block aussieht?

danke...

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
yosra (Gast) schrieb:
> Gibt´s gute Ratschläge oder
> Verbesserungen?
-- keine gute Idee
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

Besser mit
use ieee.numeric_std.all;
rechnen.

Duke

P.S.: Hast noch eine Testbench dazu?

Autor: yosra (Gast) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besser mit

use ieee.numeric_std.all;

Warum? ich bin nicht sicher wegen negativen Zahlen. Deshalb habe ich mit 
use ieee.std_logic_unsigned.all gearbeitet.

Ja, Ich hab´s:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

------------------------------------------------------------------------ 
------------
entity Bresenham_TB is
end Bresenham_TB;
------------------------------------------------------------------------ 
------------
architecture behavior of Bresenham_TB is

    signal clk1          : std_logic;
    signal reset_n1   : std_logic;
    signal fval_in1  : std_logic;
    signal lval_in1  : std_logic;
    signal pval_in1  : std_logic;
    signal ref_in1  : std_logic_vector(15 downto 0);
    signal ref_out1  : std_logic_vector(15 downto 0);
    signal fval_out1  : std_logic;
    signal lval_out1  : std_logic;
    signal pval_out1  : std_logic;
    signal rdref1  : std_logic;
------------------------------------------------------------------------ 
------------
Component Bresenham
   port
    (
  clk          : in std_logic;
  reset_n   : in std_logic;
  fval_in    : in std_logic;
  lval_in          : in std_logic;
  pval_in    : in std_logic;
  ref_in    : in  std_logic_vector(15 downto 0);

  ref_out         : out std_logic_vector(15 downto 0);
  fval_out  : out std_logic;
  lval_out  : out std_logic;
  pval_out  : out std_logic;
  rdref    : out std_logic
  );
end component;

------------------------------------------------------------------------ 
------------
for all:Bresenham use entity work.Bresenham(behavior);
------------------------------------------------------------------------ 
------------
begin

PR_clk: process
begin
   clk1   <= '0';
   wait for 10 ns;
   clk1   <= '1';
   wait for 10 ns;

end process PR_clk;

reset_n1      <= '0', '1' after 100 ns;
fval_in1      <= '1';
pval_in1      <= '1';
lval_in1      <= '0', '1' after 200 ns, '0' after 5500 ns, '1' after 6 
us;
ref_in1       <= x"1234", x"5678" after 3 us;


------------------------------------------------------------------------ 
-----------------------------------
c1: Bresenham port map (clk1, reset_n1, fval_in1, lval_in1, pval_in1, 
ref_in1, ref_out1, fval_out1, lval_out1, pval_out1, rdref1);
------------------------------------------------------------------------ 
-----------------------------------
end behavior;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Warum? ich bin nicht sicher wegen negativen Zahlen.
Dafür gibt es in der numeric_std den expliziten Datentyp unsigned.

Bei deiner Beschreibung passiert das implizit über die Lib.
Was passiert, wenn einer zufällig die Lib austauscht?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;

Autor: yosra (Gast) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut..
es gibt kein Unterschied. Aber ich habe noch ein Multiplkator mit 
Überlauf nach der Bresenham-Block. und als ich es geändert habe, bekomme 
ich andere Ergebnisse als ich erwarte. Deshalb brauche ich unsigned.
Ich benutze numeric_std, aber du muss anstatt conv_unsigned bzw 
conv_integer to_unsigned und to_integer schreiben

Autor: yosra (Gast) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mein Programm mit Multiplikation erweitert. Für die 
Multiplikation lässt sich das VHDL-Quelltext mit
use ieee.numeric_std.all;
nicht kompilieren.
Sonst danke..

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Für die Multiplikation lässt sich das VHDL-Quelltext mit
> use ieee.numeric_std.all; nicht kompilieren.
Dann hast du irgendwas falsch gemacht. Die Multiplikation ist in der Lib 
(genauso wie die Division) für die Datentypen signed und unsigned 
überladen und funktioniert.

Autor: yosra (Gast) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kannst du mir zeigen wo der Fehler ist?

Übrigens brauche ich die division (durch $100), da ich die Daten im 
Eingang mit $100 multipliziert.


vid_in  : in  std_logic_vector(11 downto 0);
vid_out  : in  std_logic_vector(11 downto 0);
.
.
signal r_mul : std_logic_vector(VID_WIDTH + 8 downto 0);
.
.
.

r_mul <= vid_in * ('1' & ref_result(15 downto 8));
  if(r_mul(VID_WIDTH + 8) = '1') then  -- testen auf größer 256
        vid_out <= (others => '1');
  else
        vid_out <= r_mul((VID_WIDTH + 8 - 1) downto 8);
  end if;

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.