Forum: FPGA, VHDL & Co. Vector teilen und verzögert ausgeben


von Frank L. (franky83)


Lesenswert?

Hallo,
ich hänge gerade etwas und benötige eure Hilfe.

Einfache Situation:
data_in : std_logic_vector(7 downto 0);
data_out : std_logic_vector(7 downto 0);
clk : std_logic;
rst : std_logic;

Nun werden die Daten von data_in modifiziert und zu einem 16bit Vector 
kombiniert. Dieser soll nun aber wieder über den 8bit data_out Port 
geschickt werden. Ich komme hierbei nicht weiter. Habe es mit einem 
Shiftregister probiert, was jedoch zu einem multiple drivers führte.

Ich wäre euch sehr dankbar für einen neuen Ansatz.

Gruß

von Harry (Gast)


Lesenswert?

zeig doch mal deinen bisherigen ansatz

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


Lesenswert?

Frank L. schrieb:
> zu einem 16bit Vector kombiniert.
> Dieser soll nun aber wieder über den 8bit data_out Port geschickt werden.
Da wäre dann noch ein Signal nicht ohne, das anzeigt, ob da gerade das 
High- oder Low-Byte ausgegeben wird...

Alternativ kannst du ja auch 4 Nibbles ausgeben oder 3*6 Bit, und mit 
den restlichen Leitungen die Position im 16-Bit-Wort anzeigen...

von Frank L. (franky83)


Lesenswert?

Harry schrieb:
> zeig doch mal deinen bisherigen ansatz
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
6
entity rep_entity is
7
8
  generic (
9
        data_width : integer := 8
10
        );
11
12
    port (
13
        clk: in std_logic;
14
        rst: in std_logic;
15
        data_in  : in  std_logic_vector(data_width-1 downto 0);
16
        data_out : out std_logic_vector(data_width-1 downto 0)
17
        );
18
19
end rep_entity;
20
21
architecture Behavioral of rep_entity is
22
23
  component rep_comp
24
    port (  
25
        data_in  : in  std_logic_vector(data_width/2-1 downto 0);
26
        data_out : out std_logic_vector(data_width-1 downto 0)
27
        );
28
  end component;
29
30
  signal tmp_out  : std_logic_vector(data_width-1 downto 0);
31
  signal x_in_r   : std_logic_vector(data_width-1 downto 0);
32
  
33
  type myarray is array (0 to 5) of std_logic_vector((data_width/2)-1 downto 0);
34
  signal shifter : myarray;
35
  
36
begin
37
  
38
  rep1: rep_comp
39
  port map(
40
    data_in => shifter(5),
41
    data_out => tmp_out
42
  );
43
  
44
    rep:process(clk,rst)
45
    begin
46
47
      if rst = '0' then
48
49
          shifter <= (others =>(others => '0'));
50
          x_in_r <= (others => '0');
51
52
      elsif rising_edge(clk) then
53
54
          x_in_r <= data_in;
55
56
          shifter(0) <= x_in_r(data_width-1 downto data_width/2);
57
          shifter(5) <= x_in_r(data_width/2-1 downto 0);
58
59
          shifter(1) <= shifter(0);
60
          shifter(2) <= shifter(1);
61
          shifter(3) <= shifter(2);
62
          shifter(4) <= shifter(3);
63
          shifter(5) <= shifter(4);
64
65
      end if;
66
67
    end process;
68
69
    data_out <= tmp_out;
70
  
71
end Behavioral;

Es ist nicht so, dass ich nicht weiss warum mein Ansatz nicht 
funktioniert aber ich weiß leider auch nicht wie ich es machen könnte.

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


Lesenswert?

Frank L. schrieb:
1
     shifter(5) <= x_in_r(data_width/2-1 downto 0);
2
     :
3
     shifter(5) <= shifter(4);
Merk dir: die letzte Zuweisung in einem Prozess gewinnt.

Frank L. schrieb:
> was jedoch zu einem multiple drivers führte.
Ich kann hier keine multiplen Treiber sehen...
Was ist (abgesehen von der obern angesprochenen Ungereimtheit) das 
Problem bei diesem Code?

von Frank L. (franky83)


Lesenswert?

Lothar Miller schrieb:
> Ich kann hier keine multiplen Treiber sehen...

1
rep1: rep_comp
2
  port map(
3
    data_in => shifter(5), -- hier einmal
4
    data_out => tmp_out
5
  );
6
7
----------
8
9
shifter(5) <= x_in_r(data_width/2-1 downto 0); -- und hier

Ja ich weiß, Signale erhalten erst ihre Werte nach dem Prozess.
Wie kann ich nun am besten das zweite Byte erst im darauffolgenden Takt 
ausgeben? Tipp?

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


Lesenswert?

Frank L. schrieb:
> data_in => shifter(5), -- hier einmal
Ich würde fast behaupten, data_in wäre ein IN PORT...
Der treibt nichts.

Frank L. schrieb:
> Wie kann ich nun am besten das zweite Byte erst im darauffolgenden Takt
> ausgeben? Tipp?
Nimm einen Multiplexer:
1
  signal toggle : std_logic := '0';
2
3
4
    rep:process(clk,rst)
5
    begin
6
7
      if rst = '0' then   -- Naja. Wofür?
8
          shifter <= (others =>(others => '0'));
9
          x_in_r <= (others => '0');
10
      elsif rising_edge(clk) then
11
          if (toggle='1') then  -- high Byte
12
             data_out <= x_in_r(15 downto 8);
13
          else                  -- low Byte
14
             data_out <= x_in_r(7 downto 0);
15
             x_in_r <= data_in; -- und dann wieder ein neues Wort einlesen
16
          end if;
17
          toggle <= not toggle;
18
      end if;
19
    end process;
Aber wie gesagt: du siehst nicht, wo du gerade bist (High- oder 
Low-Byte)... :-/

Ach so, das mit dem "verzögert ausgeben"...
Um wieviel verzögert?
Kommen da zwischenzeitlich neue Daten?

von Frank L. (franky83)


Lesenswert?

Vielen Dank Lothar,

mit dem Treiber hast du natürlich recht. Mit irgendeiner Kombo hatte ich 
es aber. Nun aber egal. Dein Ansatz läuft. Vielen Vielen Dank

Nun ist es ja so, dass jeden Takt neue Daten rein kommen, verarbeitet 
werden und wieder byteweise ausgegeben werden müssen. Natürlich dauert 
die Verarbeitung länger als nur einen Takt und somit gehen Daten 
verloren.

von Frank L. (franky83)


Lesenswert?

Es soll eigentlich ein Wiederholungscode werden aber irgendwie lauf ich 
damit gegen den Baum gerade wenn ich eine ungerade Anzahl an 
Bit-Wiederholungen habe.

Weißt du vielleicht Rat? Ich würde mich sehr freuen über etwas 
Unterstützung.

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.