Search code examples
vhdlverilog

How does vhdl's concatenation operator work and how is it different from verilog


I solved this problem using Verilog in this websitehttps://hdlbits.01xz.net/wiki/Vector3.

module top_module (
  input [4:0] a, b, c, d, e, f,
  output [7:0] w, x, y, z );//
  assign {w,x,y,z} = { a, b, c, d, e, f,2'b11};
endmodule

So I tried to convert it to vhdl. Here is the code I wrote.

LIBRARY ieee;
   USE ieee.std_logic_1164.all;
ENTITY top_module IS
   PORT (
      a  : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
      b  : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
      c  : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
      d  : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
      e  : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
      f  : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
      w  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
      x  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
      y  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
      z  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
   );
END top_module;
ARCHITECTURE trans OF top_module IS
BEGIN
   (w, x, y, z) <= (a & b & c & d & e & f & "11");
END trans;

But Modelsim doesn't compile successfully, how can I modify it? How to use vhdl's concatenation operator correctly?


Solution

  • The OP's VHDL code is valid using tools supporting IEEE Std 1076-2008 (or later) as is. The parentheses on the waveform element expression are not required, and the port declarations can be compacted a bit:

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity top_module is
       port (
          a, b, c, d, e, f: in  std_logic_vector(4 downto 0);
          w, x, y, z:       out std_logic_vector(7 downto 0)
       );
    end entity top_module;
    
    architecture trans of top_module is
    begin
       (w, x, y, z) <= a & b & c & d & e & f & "11"; -- NO parentheses required
    end architecture trans;
    

    For those with an archeological bent you could explore the differences in aggregates for the assignment target between -2008 and earlier revisions.

    An aggregate assignment can be used in earlier revisions by creating a value of an array type whose elements are compatible with the subtype of w, x, y, and z:

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity top_module is
       port (
          a, b, c, d, e, f: in  std_logic_vector(4 downto 0);
          w, x, y, z:       out std_logic_vector(7 downto 0)
       );
    end entity top_module;
    
    architecture earlier_than_2008 of top_module is
        type some_arry is array (0 to 3) of std_logic_vector (7 downto 0);
    begin
        (w, x, y, z) <=
            some_arry'( a & b (4 downto 2), b (1 downto 0) & c & d(4),
                        d (3 downto 0) & e(4 downto 1), e (0) & f & "11" );
    end architecture;
    

    In this case the association between actual values and formal values of the unnamed object of type some_arry is positional, and implicit subtype conversion occurs in the association list. A qualified expression is used to specify the type of that unnamed object and the type of the object on the left hand side of the assignment is taken from context (the right hand side of the assignment statement).

    The type of the unnamed object can be a record type if the subtypes of w, x, y and z are not compatible (different lengths or different types).

    For IEEE std 1076-2008 see 9.3.3.3 Array aggregates, paragraph 4:

    ... For a positional association with an expression of the type of the aggregate, the expression specifies a number of matching elements (see 9.2.3) of the aggregate value given by the length of the value of the expression.

    This gives permission to have choices that are of the type of the aggregate and not just it's elements. The type of the aggregate would be taken from context, here the signal assignment waveform element, which is a std_logic_vector determined by operands of the concatenation operator (See 9.2.5 Adding operators, the concatenation result type is the same type as the array type of an operand). This permission eliminates the need for using a qualified expression and type declaration required in an earlier revision of the standard.

    Targets of a signal assignment statement that are in the form of an aggregate are described in 10.5.2 Simple signal assignments, 10.5.2.1 General paragraph 3, with only minor variations from earlier revisions of the standard.

    You'd also find that the VHDL code for earlier revisions of the standard are compatible with the -2008 standard leaving the earlier method useful for completely describing such a 'break out' or 'unpacking' for code documentation without explaining how to interpret what happens.