Forum: FPGA, VHDL & Co. Zuweisunf slv verschiedener Länge


von ope (Gast)


Lesenswert?

folgendes klappt nicht:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
use ieee.std_logic_unsigned.all;
5
use ieee.numeric_std.all;
6
7
foo : block
8
  signal   b  : std_logic_vector(7 downto 0);
9
  signal   m  : std_logic_vector(79 downto 0);
10
11
  begin 
12
    ...
13
14
  bar : process ....
15
16
    case lola
17
      ...
18
      b <= m(25 downto 24);      
19
      ...
20
      b <= m(23 downto 16);

Der erste Ausdruck ist 2 bit lang, gut; habe es schon versucht mit 6
Byte ZeroPad (als Konstante definiert) und "&" Operator. Der zweite
Ausdruck will auch nicht. Bzeichnender Weise ist der Fehler prinzipiell
gleich:

Index value 24 is out of range 7 downto 0.
Index value 25 is out of range 7 downto 0.
Index value 16 is out of range 7 downto 0.
Index value 23 is out of range 7 downto 0.

Wie ich inzwischen feststellen musste, ist ein der Slice (1 downto 0)
nicht unbedingt gleichbedeutend mit mit einem slv der Länge 2. Warum,
verschliesst sich mir (EVtl. hat ja jemand eine Begründung).

So, wie bekomme ich es denn nun zum kompilieren? Habe auch schon
conv_std_log_vector(unsigned(m(25 downto 24)), b'length) ohne Erfolg
versucht.

Viele Grüße
Olaf

von FPGA-User (Gast)


Lesenswert?

folgender Code wird bei mir problemlos compiliert:
_________________________________________________

entity vector_test is
    Port
    (
      clk : in  std_logic;
      sel : in  integer range 0 to 5;
      res : out std_logic_vector(7 downto 0)

    );
end;

architecture Behavioral of vector_test is

   signal b : std_logic_vector(7 downto 0);
   signal m : std_logic_vector(79 downto 0);

begin

   process (clk)
   begin

      if rising_edge(clk) then

         case sel is

            when 0 =>
               b <= m(7 downto 0);

            when 1 =>
               b <= m(23 downto 16);

            when others =>
               b <= m(79 downto 72);

         end case;
      end if;
   end process;
   res <= b;

-> vielleicht musst Du doch mal den original-code posten ?
Was meinst Du mit Slice (1 downto 0) nicht gleich Vector 2 bit?
Ob Du von einem Zähler mit 4 bit Breite 2 bits abgreifst oder
einen entspr. 2 bit Zähler nimmst ist doch völlig wurscht.
Entscheidend ist nur der Typ: signed, unsigned oder std_logic_vector...

von ope (Gast)


Lesenswert?

Vielen Dank, anscheinend handelt sich auch noch um einen Seiten Effekt.
Mit slice meinte ich das "herausfischen" eines "Subvectors", eben
(1 downto 0) aus einem slv(7 downto 0).

Ich bin gerade dabei, eine 6te Version zur LA RAM Ansteuerung zu
basteln. Das Prinzip: 512x80 bit ist der Speicher org. (einfacher, als
tiefer und geringere Bitbreite), d.h. ich muss meine Samples(Timestamp
und aquired Samples) zusammenfassen (26bit). Somit passen 3 "Tupel"
in die 80 bit und ich habe noch 2 Status bits. Auslesen passiert über
8bits. Diese Version ersetzt die Multiplexed Version, mal sehen, wie es
aussschaut mit mehr States, die ja den Mux ersetzten müssen.

Hier aber erstmal der ungekürzte Source.

[vdhl]
library unisim;
use unisim.vcomponents.all;

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

entity sample_ram is

   generic (
      RESET_ACTIVE : std_logic := '1';
      TIMESTAMP_SZ : positive  := 10;
      SAMPLE_SZ    : positive  := 16);

   port (
      clk         : in    std_logic;
      reset       : in    std_logic;
      wr          : in    std_logic;
      rd          : in    std_logic;
      timestamp   : in    std_logic_vector(TIMESTAMP_SZ-1 downto 0);
      sample      : in    std_logic_vector(SAMPLE_SZ-1 downto 0);
      d8o         : out   std_logic_vector(7 downto 0);
      aquire      : in    std_logic;
      aquire_done : inout std_logic);

end sample_ram;


architecture default of sample_ram is

   type ram_ctrl_t is record
      en : std_logic;
      we : std_logic;
   end record;
   signal ram_ctrl : ram_ctrl_t;

   subtype addr_bus_t is std_logic_vector(8 downto 0);
   subtype wr_data_bus_t is std_logic_vector(79 downto 0);
   subtype rd_data_bus_t is std_logic_vector(7 downto 0);

   type ram_bus_t is record
      addr : addr_bus_t;
      di   : wr_data_bus_t;
      do   : rd_data_bus_t;
   end record;
   signal ram_bus : ram_bus_t;

   subtype addr_cnt_t is integer range 511 downto 0;
   subtype modulo_cnt_t is integer range 11 downto 0;

   type addr_cntr_t is record
      enable  : std_logic;
      modulo  : integer;
      load    : std_logic;
      ld_addr : addr_cnt_t;
   end record;
   signal addr_cntr : addr_cntr_t;
   signal mux_sel   : modulo_cnt_t;

begin


------------------------------------------------------------------------ 
-----
   -- fsm control read/write/aquire

------------------------------------------------------------------------ 
-----
   fsm : block

      -- one-hot state encoding
      subtype state_t is std_logic_vector(25 downto 0);

      constant reset_state           : state_t := (0  => '1', others
=> '0');
      constant idle_state            : state_t := (1  => '1', others
=> '0');
      constant write_s0_state        : state_t := (2  => '1', others
=> '0');
      constant write_s1_state        : state_t := (3  => '1', others
=> '0');
      constant write_s2_state        : state_t := (4  => '1', others
=> '0');
      constant write_state           : state_t := (5  => '1', others
=> '0');
      constant aquire_s0_state       : state_t := (6  => '1', others
=> '0');
      constant aquire_s1_state       : state_t := (7  => '1', others
=> '0');
      constant aquire_s2_state       : state_t := (8  => '1', others
=> '0');
      constant aquire_state          : state_t := (9  => '1', others
=> '0');
      constant aquire_done_state     : state_t := (10 => '1', others
=> '0');
      constant read_b0_state         : state_t := (11 => '1', others
=> '0');
      constant read_b1_state         : state_t := (12 => '1', others
=> '0');
      constant read_b2_state         : state_t := (13 => '1', others
=> '0');
      constant read_b3_state         : state_t := (14 => '1', others
=> '0');
      constant read_b4_state         : state_t := (15 => '1', others
=> '0');
      constant read_b5_state         : state_t := (16 => '1', others
=> '0');
      constant read_b6_state         : state_t := (17 => '1', others
=> '0');
      constant read_b7_state         : state_t := (18 => '1', others
=> '0');
      constant read_b8_state         : state_t := (19 => '1', others
=> '0');
      constant read_b9_state         : state_t := (20 => '1', others
=> '0');
      constant read_b10_state        : state_t := (21 => '1', others
=> '0');
      constant read_b11_state        : state_t := (22 => '1', others
=> '0');
      constant read_b12_state        : state_t := (23 => '1', others
=> '0');
      constant read_state            : state_t := (24 => '1', others
=> '0');
      --
      signal   m_state, m_next_state : state_t;
      --
      signal   m_data_tupel          : wr_data_bus_t;
      signal   m_data_temp           : wr_data_bus_t;
      signal   m_read_byte           : rd_data_bus_t;
      --
      signal   m_ram_ctrl            : ram_ctrl_t;
      signal   m_addr_cntr           : addr_cntr_t;
      signal   m_aquire_done         : std_logic;

   begin


------------------------------------------------------------------------ 
-

      sync_proc : process (clk, reset)

      begin

         if (reset = RESET_ACTIVE) then
            m_state <= reset_state;
         elsif rising_edge(clk) then
            m_state           <= m_next_state;
            ram_ctrl.en       <= m_ram_ctrl.en;
            ram_ctrl.we       <= m_ram_ctrl.we;
            aquire_done       <= m_aquire_done;
            addr_cntr.enable  <= m_addr_cntr.enable;
            addr_cntr.modulo  <= m_addr_cntr.modulo;
            addr_cntr.load    <= m_addr_cntr.load;
            addr_cntr.ld_addr <= m_addr_cntr.ld_addr;
            --
            ram_bus.di        <= m_data_tupel;
         end if;

      end process;


------------------------------------------------------------------------ 
-

      output_decode : process (m_data_temp, m_state, ram_bus, sample,
                               timestamp)
         constant TOP_ADDR   : integer                      := 512;
         constant ZERO_PAD   : std_logic_vector(5 downto 0) := (others
=> '0');
         variable m_addr_cnt : addr_cnt_t;
      begin

         case m_state is

            when reset_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               m_addr_cnt  := 0;


----------------------------------------------------------------
               -- IDLE STATE (process output_decode)

----------------------------------------------------------------
            when idle_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';


----------------------------------------------------------------
               -- WRITE STATES (process output_decode)

----------------------------------------------------------------
            when write_s0_state =>
               m_ram_ctrl.en            <= '0';
               m_ram_ctrl.we            <= '0';
               m_data_tupel             <= m_data_temp;
               m_addr_cnt               := (m_addr_cnt + 1) mod
TOP_ADDR;
               m_data_temp(25 downto 0) <= timestamp & sample;

            when write_s1_state =>
               m_ram_ctrl.en             <= '0';
               m_ram_ctrl.we             <= '0';
               m_data_temp(51 downto 26) <= timestamp & sample;

            when write_s2_state =>
               m_ram_ctrl.en             <= '0';
               m_ram_ctrl.we             <= '0';
               m_data_temp(77 downto 52) <= timestamp & sample;

            when write_state =>         -- unused
               m_ram_ctrl.en <= '1';
               m_ram_ctrl.we <= '1';


----------------------------------------------------------------
               -- READ STATES (process output_decode)

----------------------------------------------------------------
            when read_b0_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 0,  sample #0 ts msb
               m_read_byte    <=
std_logic_vector(resize(unsigned(ram_bus.do(25 downto 24)),
m_read_byte'length));

            when read_b1_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 1,  sample #0 ts lsb
               m_read_byte   <= ram_bus.do(23 downto 16);

            when read_b2_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 2,  sample #0 msb
               m_read_byte   <= ram_bus.do(15 downto 8);

            when read_b3_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 3,  sample #0 lsb
               m_read_byte   <= ram_bus.do(7 downto 0);


            when read_b4_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 4,  sample #1 ts msb
               m_read_byte   <= ZERO_PAD & ram_bus.do(51 downto 50);

            when read_b5_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 5,  sample #1 ts lsb
               m_read_byte   <= ram_bus.do(49 downto 42);

            when read_b6_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 6,  sample #1 msb
               m_read_byte   <= ram_bus.do(41 downto 34);

            when read_b7_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 7,  sample #1 lsb
               m_read_byte   <= ram_bus.do(33 downto 26);


            when read_b8_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 8, sample #2 ts msb
               m_read_byte   <= ZERO_PAD & ram_bus.do(77 downto 76);

            when read_b9_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 9, sample #2 ts lsb
               m_read_byte   <= ram_bus.do(75 downto 68);

            when read_b10_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 10,  sample #2 msb
               m_read_byte   <= ram_bus.do(67 downto 60);
            when read_b11_state =>
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';
               -- byte 11,  sample #2 lsb
               m_read_byte   <= ram_bus.do(59 downto 52);


            when read_state =>          -- unused
               m_ram_ctrl.en <= '0';
               m_ram_ctrl.we <= '0';

            when others => null;

         end case;

      end process;


------------------------------------------------------------------------ 
-

      next_state_decode : process (aquire, m_aquire_done, m_state, rd,
reset,
                                   wr)

         variable m_mode_bits : std_logic_vector(3 downto 0);

      begin

         m_next_state <= m_state;

         m_mode_bits := wr & aquire & m_aquire_done & rd;

         case m_state is

            when reset_state =>
               if (reset = RESET_ACTIVE) then
                  m_next_state <= reset_state;
               else
                  m_next_state <= idle_state;
               end if;


----------------------------------------------------------------
               -- IDLE STATE (process next_state_decode)

----------------------------------------------------------------
            when idle_state =>
               case m_mode_bits is
                  --   wr,aq,aqd,rd
                  when "0000" => m_next_state <= idle_state;
                  when "1000" => m_next_state <= write_s0_state;
                  when "0001" => m_next_state <= read_b0_state;
                  when others => null;
               end case;


----------------------------------------------------------------
               -- WRITE STATES (process next_state_decode)

----------------------------------------------------------------
            when write_s0_state =>
               case m_mode_bits is
                  --   wr,aq,aqd,rd
                  when "0000" => m_next_state <= idle_state;
                  when "1000" => m_next_state <= write_s1_state;
                  when others => null;
               end case;

            when write_s1_state =>
               case m_mode_bits is
                  --   wr,aq,aqd,rd
                  when "0000" => m_next_state <= idle_state;
                  when "1000" => m_next_state <= write_s2_state;
                  when others => null;
               end case;

            when write_s2_state =>
               case m_mode_bits is
                  --   wr,aq,aqd,rd
                  when "0000" => m_next_state <= idle_state;
                  when "1000" => m_next_state <= write_s0_state;
                  when others => null;
               end case;


------------------------------------------------------------------------ 
-------
               -- READ STATES (process next_state_decode)

------------------------------------------------------------------------ 
-------
            when read_state =>
               case m_mode_bits is
                  --   wr,aq,aqd,rd
                  when "0000" => m_next_state <= idle_state;
                  when "0001" => m_next_state <= read_state;
                  when others => null;
               end case;

            when others => null;

         end case;

      end process;


------------------------------------------------------------------------ 
-

   end block;




------------------------------------------------------------------------ 
----
-- ram 512x80 used
------------------------------------------------------------------------ 
----
   block_ram : block is

      signal m_reset : std_logic;

   begin

      -- RAMB4_Sxx; reset is active high, inferiored ram is handled
      -- by generic.
      m_reset <= '1' when (reset = RESET_ACTIVE) else '0';

      ram_512x80_i : entity work.ram_512x80
         generic map (
            RESET_ACTIVE => RESET_ACTIVE)
         port map (
            clk   => clk,
            reset => m_reset,
            en    => ram_ctrl.en,
            we    => ram_ctrl.we,
            AB    => ram_bus.addr,
            DB_I  => ram_bus.di,
            DB_O  => ram_bus.do);

   end block;

end default;

[/vhdl]

Die RAM instance unten speilt noch nciht die Rolle. Die Fehler sind:

** Error: ../source/vhdl/sample_ram.vhd(187): (vcom-1152) Index value
24 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(187): (vcom-1152) Index value
25 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(187): Unknown identifier
'resize'.
** Error: ../source/vhdl/sample_ram.vhd(193): (vcom-1152) Index value
16 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(193): (vcom-1152) Index value
23 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(199): (vcom-1152) Index value 8
is out o
f range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(199): (vcom-1152) Index value
15 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(212): (vcom-1152) Index value
50 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(212): (vcom-1152) Index value
51 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(218): (vcom-1152) Index value
42 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(218): (vcom-1152) Index value
49 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(224): (vcom-1152) Index value
34 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(224): (vcom-1152) Index value
41 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(230): (vcom-1152) Index value
26 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(230): (vcom-1152) Index value
33 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(237): (vcom-1152) Index value
76 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(237): (vcom-1152) Index value
77 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(243): (vcom-1152) Index value
68 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(243): (vcom-1152) Index value
75 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(249): (vcom-1152) Index value
60 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(249): (vcom-1152) Index value
67 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(254): (vcom-1152) Index value
52 is out
of range 7 downto 0.
** Error: ../source/vhdl/sample_ram.vhd(254): (vcom-1152) Index value
59 is out
of range 7 downto 0.
-- Loading package std_logic_unsigned
-- Loading entity ram_512x80
** Error: ../source/vhdl/sample_ram.vhd(375): Length of expected is 80;
length o
f actual is 8.
** Error: ../source/vhdl/sample_ram.vhd(381): VHDL Compiler exiting

von ope (Gast)


Lesenswert?

eine Edit function wäre echt toll hier :/

von ope (Gast)


Lesenswert?

Das Ganze soll einmal ein Ringbuffer werden. Bei Write active schreibt
er im Ring alles mit, was er bekommt, bei Aquire active wird die
aktuelle Adresse und Tupel/Byte Offset gespeichert und nach X %
aufgehört zu schreiben. Somit hat man nach Aquire auch die
Vorgeschichte des Ereignisses. Anschliessend kann man die Daten wieder
auslesen.

Viele Grüße
Olaf

von ope (Gast)


Lesenswert?

eine Kleinigkeit, es muss heissen:
1
   subtype rd_data_bus_t is std_logic_vector(79 downto 0);

von ope (Gast)


Lesenswert?

... entsprechend ändern sich auch die Fehlermeldungen:

** Error: ../source/vhdl/sample_ram.vhd(192): Unknown identifier
'resize'.

nun ja ...

** Error: ../source/vhdl/sample_ram.vhd(198): Length of expected is 80;
length of slice name is 8.

Die Zeilennummern stimmen nicht mit den obigen überein, der Fehler
betrifft aber noch immer Zuweisungen wie:

[/vhdl]
m_read_byte   <= ram_bus.do(23 downto 16);
[/vhdl]

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.