Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to declare two dimensional input ports in Verilog?

Status
Not open for further replies.

barkha

Advanced Member level 4
Full Member level 1
Joined
Aug 8, 2005
Messages
114
Helped
21
Reputation
42
Reaction score
10
Trophy points
1,298
Location
India
Activity points
2,576
Hi,

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

verilog 2d array

do u mean like this ?

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

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?
 
  • Like
Reactions: Kaustav

    barkha

    Points: 2
    Helpful Answer Positive Rating
    V

    Points: 2
    Helpful Answer Positive Rating

    Kaustav

    Points: 2
    Helpful Answer Positive Rating
verilog input array

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

two dimensional input port in verilog

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

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.
 
Re: two dimensional input port in verilog

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

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.


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.
 

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.

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?
 
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.
 

Re: two dimensional input port in verilog

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.
 
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top