Wednesday, June 22, 2011

Declaring 2D Array I/O Ports in Verilog

2D arrays in verilog can be declared as :-
wire/reg [column_limit : 0] [0 : row_limit] ;

Eg:-
wire [7:0] byteMem [0:31]; => this creates a wire array of 8 bits * 32.

Using 2D arrays in verilog is a very tricky thing. System verilog supports 2D arrays but verilog seems to treat it as an estranged friend. Flexibility in assigning and accessing the 2D arrays are very hard. But as always, there are work arounds.

Verilog doesn't support 2D arrays as I/O ports. But there are cases when using and accessing 2D arrays are more efficient in reducing the code lines as well as improves the readability of the code. The work around for this is to declare the I/O ports as 1D array and use 2D wire internally which is then assigned the value as in the I/Os.

Suppose you need an output of 8bytes * 4 locations.
1) Assign the output as array of (8*4) width, i.e. [8*4-1:0]
2) Use an internal wire/reg array of 8bytes * 4 locations :-
wire [7:0] temp [0:3];
3) Using generate statement, assign the temp 2D array to store the values of the output array.
*Note :- A simple define could be used to assign the values. Refer to Comment #7 on the link below for more. Comment #7.

Simply use the macros defined in the link to implement virtual 2D array output/input ports.

Monday, June 13, 2011

Cygwin : "bash: $'\r': command not found"

When we copy bash scripts, edit them and then try to run these on the Cygwin, many a times we get the error :-
"bash: $'\r': command not found".

I don't know the exact reason for this, but it seems the bash can't read the file properly, so we need to use the dos2unix.exe command in the cygwin to convert the script to readable format. This solves the problem.

Syntax :- dos2unix.exe scriptname .

Then run the script. It should run fine.

Sunday, June 12, 2011

Declaring Ports in Verilog

Declaring ports in Verilog can be a tricky issue for beginners. Here is a brief of how and what to declare a port in Verilog HDL.

We will start dividing the ports on the basis of their location, i.e. input/output and on the basis of their behavior, i.e. registered data or simple wires.

On the basis of Location:-
We can group the ports into three on the basis of their locations :-
1) Input ports,
2) Output ports, and
3) Inout ports.

The input ports are basically the pins from where the data and signals reach the block. The output ports are the pins from where the data and signals leave the block. And the inouts are ports which can act as input and output during the run time.

On the basis of Behavior:-
We can group the ports into two on the basis of their behavior:-
1) Reg
2) Wire

If you want the data to be registered, then declare the port as reg. This will store the data/signal, which can be used later in the design. On the other hand, if you just want a signal to propagate from one point to another without any delay or storage, then declare it as the wire.

Even the inputs/outputs/inouts need to be declared on the basis of their behavior. Inputs are always wires, inouts are also always wire but outputs can be declared as wires or regs based on their behavior.

Refer to following diagram :-



Diagram Reference :- www.asic-world.com