Forum: FPGA, VHDL & Co. Bresenham.vhd


von yosra (Gast) (Gast)


Lesenswert?

Hi Leute,

ich habe einen Bresenham in VHDL geschrieben.
1
-- Bresenham.vhd
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
use ieee.std_logic_unsigned.all;
5
6
ENTITY Bresenham IS
7
   generic
8
  (
9
    SHIFT_WIDTH       : natural := 1  
10
  );
11
  PORT
12
  (
13
    clk       : in std_logic;
14
    reset_n   : in std_logic;
15
    fval_in   : in std_logic;
16
    lval_in   : in std_logic;
17
    pval_in   : in std_logic;
18
    ref_in    : in std_logic_vector(15 downto 0);
19
        
20
    ref_out   : out std_logic_vector(15 downto 0);
21
    fval_out  : out std_logic;
22
    lval_out  : out std_logic;
23
    pval_out  : out std_logic;
24
    rdref     : out std_logic
25
26
  );
27
END Bresenham;
28
29
ARCHITECTURE behavior OF Bresenham IS
30
31
   signal r_fval          : std_logic_vector(SHIFT_WIDTH-1 downto 0); 
32
   signal r_lval          : std_logic_vector(SHIFT_WIDTH-1 downto 0);
33
   signal r_pval          : std_logic_vector(SHIFT_WIDTH-1 downto 0);
34
   
35
   signal r_ref           : std_logic_vector(11 downto 0);
36
   signal r_ref_in        : unsigned(15 downto 0):=(others => '0');
37
   signal r2_ref_in       : integer := 0;
38
   signal r3_ref_in       : integer := 0;
39
   signal ref_result      : std_logic_vector(15 downto 0):=(others => '0');
40
   
41
   signal state           : std_logic:='0';
42
   
43
BEGIN
44
    
45
    ref_out  <= ref_result;
46
    fval_out <= r_fval (SHIFT_WIDTH-1);
47
    lval_out <= r_lval (SHIFT_WIDTH-1);
48
    pval_out <= r_pval (SHIFT_WIDTH-1);
49
    rdref   <= state;
50
51
   
52
  process(reset_n, clk)
53
  variable x1       : unsigned(7 downto 0):=(others => '0');
54
  variable y1       : unsigned(7 downto 0):=(others => '0');
55
  variable ex       : integer := 0;
56
  variable ex1      : integer := 0;
57
  variable x        : integer := 0;
58
  variable y        : integer := 0;
59
  begin
60
61
  if(reset_n = '0') then
62
    r_fval      <= conv_std_logic_vector('0', SHIFT_WIDTH);
63
    r_lval      <= conv_std_logic_vector('0', SHIFT_WIDTH);
64
    r_pval      <= conv_std_logic_vector('0', SHIFT_WIDTH);
65
    r_ref       <= (others => '0');
66
    r2_ref_in   <= 0;
67
    r3_ref_in   <= 0;
68
    r_ref       <= (others => '0');
69
    r_offset    <= (others => '0');
70
    ref_result  <= (others => '0');
71
      
72
  elsif(clk'event and clk = '1') then
73
    r_fval      <= r_fval (SHIFT_WIDTH-2 downto 0) & fval_in;
74
    r_lval      <= r_lval (SHIFT_WIDTH-2 downto 0) & lval_in;
75
    r_pval      <= r_pval (SHIFT_WIDTH-2 downto 0) & pval_in;
76
    ref_result1 <= ref_result;
77
      
78
    if (fval_in = '1' and lval_in ='0') then
79
       r_ref_in <= unsigned (ref_in);
80
       r2_ref_in<= conv_integer (r_ref_in (7 downto 0));
81
       r3_ref_in<= conv_integer (r_ref_in (15 downto 8));
82
       ex       := r2_ref_in/2;      
83
       state    <= '0';
84
    end if;
85
    if (lval_in ='1') then
86
       if (state = '0') then
87
    if (x <= r2_ref_in) then 
88
       if (ex < 0) then
89
          y  := y + 1;  
90
          ex := ex + r2_ref_in - r3_ref_in;
91
          x1 := conv_unsigned(x,8);
92
          y1 := conv_unsigned(y,8);
93
                      ref_result ( 7 downto 0) <= std_logic_vector(x1);  
94
          ref_result (15 downto 8) <= std_logic_vector(y1);
95
          x  := x + 1;
96
          if (x > r2_ref_in) then
97
            state <= '1';
98
          else 
99
            state <= '0';
100
          end if;
101
      else
102
         ex := ex - r3_ref_in;
103
         x1 := conv_unsigned(x,8);
104
         y1 := conv_unsigned(y,8);
105
                     ref_result ( 7 downto 0) <= std_logic_vector(x1);
106
                     ref_result (15 downto 8) <= std_logic_vector(y1);
107
         x  := x + 1; 
108
         if (x > r2_ref_in) then
109
      state <= '1';
110
         else 
111
      state <= '0';
112
         end if;
113
      end if;
114
    elsif(x > r2_ref_in) then
115
      state <= '1';
116
    else
117
      ref_result ( 7 downto 0) <= x"00";
118
      ref_result (15 downto 8) <= x"00";  
119
    end if;
120
       end if;
121
       if (state = '1') then        
122
    ref_result ( 7 downto 0) <= std_logic_vector(x1);
123
                ref_result (15 downto 8) <= std_logic_vector(y1);
124
       end if;
125
    else
126
       x     := 0;
127
       y     := 0;
128
       state <= '0';
129
    end if;
130
        end if;
131
     end process;  
132
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...

von Duke Scarring (Gast)


Lesenswert?

yosra (Gast) schrieb:
> Gibt´s gute Ratschläge oder
> Verbesserungen?
1
-- keine gute Idee
2
use ieee.std_logic_arith.all;
3
use ieee.std_logic_unsigned.all;

Besser mit
1
use ieee.numeric_std.all;
rechnen.

Duke

P.S.: Hast noch eine Testbench dazu?

von yosra (Gast) (Gast)


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;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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?
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
use ieee.std_logic_signed.all;

von yosra (Gast) (Gast)


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

von yosra (Gast) (Gast)


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..

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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.

von yosra (Gast) (Gast)


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;

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.