What is wrong with following Verilog code where I am trying to pass a one-dimensional array?
module stimulus;
wire [3:0] max,med,min;
reg[3:0] row_data[0:2];
reg cin;
sorting_three sr(max,med,min,row_data,cin); // line no.27
initial begin
row_data[0]=4'b0010;
row_data[1]=4'b1001;
row_data[2]=4'b1010;
cin=1'b0;
end
endmodule
It's giving an error like:
ERROR:HDLCompiler:251 – "stimulus.v" Line 27. Cannot access memory row_data directly
ERROR:HDLCompiler:598 – "stimulus.v" Line 21. Module stimulus ignored due to previous errors
Best Answer
There seems to be a problem in the port declaration for module
sorting_three
. You're trying to pass an argument that can't exist.Looks like module
stimulus
must be a test bench for modulesorting_three
, since modulestimulus
does not have any input or output ports.Test bench module
stimulus
declares memory row_data as a 1-dimensional array of 4-bit registers, first address 0 last address 2. So this memory must have two address bits and four data bits. Initial values are declared in theinitial
block. This seems to be used as read-only memory, there's nothing to indicate that the values would ever be changed from the initial values when the circuit is synthesized.But how does that row_data memory connect to module
sorting_three
?Verilog is a hardware synthesis language. The read-only memory row_data must connect to module
sorting_three
through its 2-bit address port and its 4-bit data port. There is no such thing as the address of the row_data array "in memory", there's only the RTL code that describes the hardware. If you've come from a software programming background, this is the trickiest thing about learning Verilog or VHDL: thinking about what hardware circit you want to synthesize instead of describing its runtime behavior.The test bench has to declare not only that the row_data memory array exists somewhere in the hardware, but also declare the wires that connect to the memory's address and data ports:
The declaration for sorting_three should look like this (note I'm using Verilog 2001 style port declarations for readability):
Inside module
sorting_three
, the output portrow_data_address
must be driven to2'b00
,2'b01
, or2'b10
to select one element of row_data on each clock cycle. Then, on the next clock cycle, valid data from row_data should be available fromrow_data_dout
.If the module needed to be able to write into the memory as well as read, then the memory needs to use additional ports for data_in and write_enable.
If the module was accessing off-chip memory, then additional clock cycles (known as "wait states") might be needed before valid data became available. But for on-chip memory inside an FPGA, usually single cycle access.
Alternative without synchronous memory access
Since there are only three addresses, and they seem to be read-only, you could pass them all individually instead of packing them into row_data memory:
However Verilog doesn't support a port declaration like input wire [3:0] row_data_array [0:2], that's not something that could be synthesized in hardware.
No clock in testbench
A second problem is this test bench doesn't seem to be driving a clock. I usually use something like this to generate a testbench clock for simulation: