Electronic – the difference between an array and a bus in Verilog

fpgaverilogvivado

I have been learning Verilog and Vivado at school, and I am now very confused by the usage of busses and arrays. Can anyone clarify the following?

  • What is the difference between an array and a bus?
    • During declaration, a bus would look something like reg [9:0]data while an array would be reg data[9:0]. Is there a subtle (or not-so-subtle) difference in how the language handles these cases?
    • Why are is a bus declared with and index in front of the variable name, but referenced with an index behind? For instance, data[3] would work regardless of whether data is declared as an array or bus.
  • I have found it is possible (although confusing) to create declarations such as reg [4:0]busArray[3:0], which would create 4x 5-bit registers.
    • Is this bad practice?
    • How is this different from 2d array declared reg arrayArray[4:0][3:0]?
  • When should I use a bus and when should I use an array?

I have a few other related questions as well…

  • When you have a declaration like reg [7:0]data[1023:0], is is possible to access individual bits and ranges?
    • I have had trouble accessing ranges of bits. For instance, data[7:0][4] seems to work, but data[0][255:0] or data[3:1][512:64] results in a syntax error. Are there rules about how you can access elements in busses and arrays?
  • Is is possible to declare a multi-dimensional bus? (something like reg [15:0][8:0]data)
  • Is there a way to type cast an array so that it is treated like a bus? This could be useful in order to pass an array into a module designed to accept a bus.

Best Answer

A bus enables you to define values that are wider than one bit. If you want to store or transmit (in parallel) a value between 0 and 15, you need a 4-bit bus. An array lets you store multiple values under a single name.

The difference between "[7:0] data" and "data[7:0]" is that the first is a single 8-bit-wide value while the second is eight single-bit values.

It's totally normal and useful to create an array of busses. They're sometimes called memories, because you can use them to model ROM or RAM. Your synthesis software can usually recognize when you've defined something that looks like ROM or RAM (for example, reg [7:0] data[1023:0] is basically 1K by 8-bit RAM) and synthesize it as actual physical ROM or RAM on the chip.

To understand which construct to use, just ask yourself what you have. Do you have a single multi-bit value? That's a bus. Do you have a bunch of single-bit values that you want to reference using a single name? Then use an array. Do you have a bunch of multi-bit values? Then use a memory.