Bresenham.vhd

Gast #1770198
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...
Gast #1770447
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;
Moderator (Firma: Titel) Persönliche Seite #1770462
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;
Gast #1770483
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
Gast #1770533
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren