+ Post New Thread
Results 1 to 12 of 12
  1. #1
    Full Member level 1
    Points: 2,275, Level: 11

    Join Date
    Aug 2005
    Location
    India
    Posts
    113
    Helped
    20 / 20
    Points
    2,275
    Level
    11

    How to declare two dimensional input ports in Verilog?

    Hi,

    Can anybody send any doc which explains how to declare two dimensional input ports in Verilog ?

    •   Alt21st November 2006, 06:23

      advertising

        
       

  2. #2
    Advanced Member level 1
    Points: 4,577, Level: 16
    sree205's Avatar
    Join Date
    Mar 2006
    Posts
    454
    Helped
    53 / 53
    Points
    4,577
    Level
    16

    verilog 2d array

    do u mean like this ?

    reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];



  3. #3
    Advanced Member level 5
    Points: 40,208, Level: 49

    Join Date
    Apr 2002
    Location
    USA
    Posts
    3,944
    Helped
    649 / 649
    Points
    40,208
    Level
    49

    verilog port array

    Verilog doesn't allow an I/O port to be a 2-D array.

    In Verilog 2001 you could flatten your array into a vector and pass that through the port, but that's somewhat awkward. Here is one way to do it:
    Code:
    module top (in, out);
      input   [31:0] in;
      wire     [7:0] array [0:3];
      output  [31:0] out;
    
      assign {array[3],array[2],array[1],array[0]} = in;
      assign out = {array[3],array[2],array[1],array[0]};
    endmodule
    Does anyone know a more compact syntax?


    3 members found this post helpful.

    •   Alt21st November 2006, 07:50

      advertising

        
       

  4. #4
    Advanced Member level 2
    Points: 4,734, Level: 16

    Join Date
    Sep 2004
    Location
    Bangalore, India
    Posts
    646
    Helped
    82 / 82
    Points
    4,734
    Level
    16

    verilog array port

    Quote Originally Posted by echo47
    Verilog doesn't allow an I/O port to be a 2-D array.
    FWIW, this is allowed in SystemVerilog, check with your simulator if it supports it.

    Regards
    Ajeetha, CVC
    www.noveldv.com



    •   Alt21st November 2006, 08:09

      advertising

        
       

  5. #5
    Newbie level 6
    Points: 1,466, Level: 8
    Achievements:
    7 years registered

    Join Date
    Aug 2006
    Posts
    10
    Helped
    1 / 1
    Points
    1,466
    Level
    8

    verilog input array

    verilog module I/O ports can't be declared 2-D arrry, illegal expresstion.



  6. #6
    Full Member level 4
    Points: 2,924, Level: 12

    Join Date
    Oct 2005
    Posts
    226
    Helped
    6 / 6
    Points
    2,924
    Level
    12

    two dimensional input port in verilog

    why it is not legal
    i think it can be synthesized
    !!!!!!!!!!!!!!!!!!!!!



  7. #7
    Advanced Member level 5
    Points: 12,897, Level: 27
    mrflibble's Avatar
    Join Date
    Apr 2010
    Posts
    2,356
    Helped
    590 / 586
    Points
    12,897
    Level
    27

    Re: two dimensional input port in verilog

    Grrrrr, it's 2011 and you still can't pass a simple 2-dimensional input or output to a module in verilog...

    Googling didn't really turn up anything , so I put together these quick macros. So far seems to do the trick.

    Code:
    `define PACK_ARRAY(PK_WIDTH,PK_LEN,PK_SRC,PK_DEST)    genvar pk_idx; generate for (pk_idx=0; pk_idx<(PK_LEN); pk_idx=pk_idx+1) begin; assign PK_DEST[((PK_WIDTH)*pk_idx+((PK_WIDTH)-1)):((PK_WIDTH)*pk_idx)] = PK_SRC[pk_idx][((PK_WIDTH)-1):0]; end; endgenerate
    
    `define UNPACK_ARRAY(PK_WIDTH,PK_LEN,PK_DEST,PK_SRC)  genvar unpk_idx; generate for (unpk_idx=0; unpk_idx<(PK_LEN); unpk_idx=unpk_idx+1) begin; assign PK_DEST[unpk_idx][((PK_WIDTH)-1):0] = PK_SRC[((PK_WIDTH)*unpk_idx+(PK_WIDTH-1)):((PK_WIDTH)*unpk_idx)]; end; endgenerate
    
    
    module example (
        input  [63:0] pack_4_16_in,
        output [31:0] pack_16_2_out
        );
    
    wire [3:0] in [0:15];
    `UNPACK_ARRAY(4,16,in,pack_4_16_in)
    
    wire [15:0] out [0:1];
    `PACK_ARRAY(16,2,in,pack_16_2_out)
    
    
    // useful code goes here
    
    endmodule // example

    In a real module of course I put the macro's in a seperate .v file and just `include it.

    As a matter of naming convention I use "pack_WIDTH_LEN_original_name" so I can keep track of what the hell it is I packed in there.

    Anyways, hope it is of some use to a future verilog victim.


    3 members found this post helpful.

  8. #8
    Member level 3
    Points: 994, Level: 7

    Join Date
    Mar 2009
    Location
    Manchester, UK
    Posts
    59
    Helped
    22 / 22
    Points
    994
    Level
    7

    Re: two dimensional input port in verilog

    use SystemVerilog. DC and synplify supports it. 2D or 3D ports are naturally supported.



  9. #9
    Newbie level 1
    Points: 352, Level: 4

    Join Date
    Jan 2011
    Posts
    1
    Helped
    0 / 0
    Points
    352
    Level
    4

    Re: two dimensional input port in verilog

    Thanks :)
    Didnt use the Macro as got afraid it might be used somewhere else in the design but the idea is nice and i just packed and unpacked each array manually.


    Quote Originally Posted by mrflibble View Post
    Grrrrr, it's 2011 and you still can't pass a simple 2-dimensional input or output to a module in verilog...

    Googling didn't really turn up anything , so I put together these quick macros. So far seems to do the trick.

    Code:
    `define PACK_ARRAY(PK_WIDTH,PK_LEN,PK_SRC,PK_DEST)    genvar pk_idx; generate for (pk_idx=0; pk_idx<(PK_LEN); pk_idx=pk_idx+1) begin; assign PK_DEST[((PK_WIDTH)*pk_idx+((PK_WIDTH)-1)):((PK_WIDTH)*pk_idx)] = PK_SRC[pk_idx][((PK_WIDTH)-1):0]; end; endgenerate
    
    `define UNPACK_ARRAY(PK_WIDTH,PK_LEN,PK_DEST,PK_SRC)  genvar unpk_idx; generate for (unpk_idx=0; unpk_idx<(PK_LEN); unpk_idx=unpk_idx+1) begin; assign PK_DEST[unpk_idx][((PK_WIDTH)-1):0] = PK_SRC[((PK_WIDTH)*unpk_idx+(PK_WIDTH-1)):((PK_WIDTH)*unpk_idx)]; end; endgenerate
    
    
    module example (
        input  [63:0] pack_4_16_in,
        output [31:0] pack_16_2_out
        );
    
    wire [3:0] in [0:15];
    `UNPACK_ARRAY(4,16,in,pack_4_16_in)
    
    wire [15:0] out [0:1];
    `PACK_ARRAY(16,2,in,pack_16_2_out)
    
    
    // useful code goes here
    
    endmodule // example

    In a real module of course I put the macro's in a seperate .v file and just `include it.

    As a matter of naming convention I use "pack_WIDTH_LEN_original_name" so I can keep track of what the hell it is I packed in there.

    Anyways, hope it is of some use to a future verilog victim.



  10. #10
    Advanced Member level 5
    Points: 12,897, Level: 27
    mrflibble's Avatar
    Join Date
    Apr 2010
    Posts
    2,356
    Helped
    590 / 586
    Points
    12,897
    Level
    27

    Re: two dimensional input port in verilog

    Quote Originally Posted by misplacer View Post
    Thanks :)
    Didnt use the Macro as got afraid it might be used somewhere else in the design but the idea is nice and i just packed and unpacked each array manually.
    Glad it was of some use. :)

    You say you got afraid it might be used somewhere else.. What "it"? The macro names PACK_ARRAY and UNPACK_ARRAY?

    If so, that's a valid concern since the names I chose are not super unique. I chose them to be somewhat intuitive. :P There is something that you can do to at least make sure that your part of the project is clean.

    file "util/array_pack_unpack.v":
    `ifndef ARRAY_PACK_UNPACK_V
    `ifdef PACK_ARRAY
    $finish; // macro PACK_ARRAY already exists. refusing to redefine.
    `endif
    `ifdef UNPACK_ARRAY
    $finish; // macro UNPACK_ARRAY already exists. refusing to redefine.
    `endif

    `define ARRAY_PACK_UNPACK_V 1
    `define PACK_ARRAY(PK_WIDTH,PK_LEN,PK_SRC,PK_DEST) genvar pk_idx; generate for (pk_idx=0; pk_idx<(PK_LEN); pk_idx=pk_idx+1) begin; assign PK_DEST[((PK_WIDTH)*pk_idx+((PK_WIDTH)-1)):((PK_WIDTH)*pk_idx)] = PK_SRC[pk_idx][((PK_WIDTH)-1):0]; end; endgenerate
    `define UNPACK_ARRAY(PK_WIDTH,PK_LEN,PK_DEST,PK_SRC) genvar unpk_idx; generate for (unpk_idx=0; unpk_idx<(PK_LEN); unpk_idx=unpk_idx+1) begin; assign PK_DEST[unpk_idx][((PK_WIDTH)-1):0] = PK_SRC[((PK_WIDTH)*unpk_idx+(PK_WIDTH-1)):((PK_WIDTH)*unpk_idx)]; end; endgenerate

    `endif

    Then in your code:
    Code:
    `include "util/array_pack_unpack.v"
    Incidentally I've been using this for some time now and no problems so far. :) It's a bit verbose due to all the sanity checks, but at least now your code will play nice with other stuff.

    Note that I said your part of the project is clean. If your project also contains Other Peoples Code [tm], then you can only do so much. Suppose your includes come first, and then some infidel's code that is parsed later overwrites your macro ... The infidel's macro will redefine your macro. His stuff will work, and yours will not.

    But that sort of thing is no reason to not use macro's. Why? Because if you want to take that line of reasoning you can never do anything when you don't know 100% of the entire project. What you can do is a few simple checks to make sure the macros you want to use are not already taken by someone else.

    Simply do:
    Code:
    grep -r '.*define.*PACK_ARRAY' your_source_dir
    or the windoze Find equivalent. Then you know if anywhere in the project-you-dont-quite-know it's used.

    So far I have not had any name collisions, so this method is anecdotally safe to use. ;)

    And before some clever soul points it out ... the use of $finish up there is not 100% pedantic person proof. By the language standard you are not allowed to use a $finish there.

    However, the sole purpose of that line is to 1) throw an error, and 2) throw an error that you can easily translate to "what the hell is happening?". And it does just that. For example from ISE if I do synthesize, when the "PACK_ARRAY" macro already exists (because I already defined it on purpose to test if my macro handles this cleanly) I get an error on that $finish line. This gives me enough info to know what's going on. I even added some comments. :P

    On a related note I've just played around a little with systemverilog for synthesis. Precisely because of plain verilog deficiencies like this. In verilog you have to resort to hacky macros like this, and in systemverilog things are a whole lot cleaner. Too bad xilinx ISE does not support systemverilog, despite their periodic claim of "we will support it Real-Soon-Now". :(

    Does anyone familiar with the Altera tools know if they support systemverilog for synthesis + simulation? If so, is it any good?


    2 members found this post helpful.

  11. #11
    Newbie level 1
    Points: 13, Level: 1

    Join Date
    Aug 2013
    Posts
    1
    Helped
    0 / 0
    Points
    13
    Level
    1

    Re: two dimensional input port in verilog

    Thanks very much for the above macro and explanations mrflibble!
    I had an issue with the Lattice Reveal debugger plainly refusing to start if anything in the project had array ports, so I used your pack macros--and it works mighty well.
    Wholeheartedly agree with the remarks on Verilog. How it's possible to this day we have to jump through such hoops just to make the compiler happy, I don't understand.



  12. #12
    Advanced Member level 2
    Points: 3,766, Level: 14

    Join Date
    Dec 2011
    Location
    Fremont, CA, USA
    Posts
    530
    Helped
    225 / 225
    Points
    3,766
    Level
    14
    Blog Entries
    4

    Re: two dimensional input port in verilog

    Quote Originally Posted by mrflibble View Post
    Does anyone familiar with the Altera tools know if they support systemverilog for synthesis + simulation? If so, is it any good?
    Altera uses ModelSim for Simulation and Quartus for synthesis and both have supported SystemVerilog for many years.
    Dave Rich
    Verification Technologist
    Mentor Graphics Corporation



+ Post New Thread
Please login

LinkBacks (?)

  1. 24th September 2013, 14:04
  2. 22nd August 2013, 06:06
  3. 18th June 2013, 10:51
  4. 19th May 2013, 01:31
  5. 14th May 2013, 09:04
  6. 22nd March 2013, 09:39
  7. 6th March 2013, 16:04
  8. 15th February 2013, 16:16
  9. 1st December 2012, 17:27
  10. 6th November 2012, 08:31
  11. 9th October 2012, 19:05
  12. 9th October 2012, 09:39
  13. 13th September 2012, 07:58
  14. 4th July 2012, 12:09
  15. 14th May 2012, 16:46
  16. 22nd April 2012, 19:01
  17. 28th March 2012, 13:54
  18. 9th August 2011, 13:48
  19. 18th July 2011, 20:07