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 module sorting_three
, since module stimulus
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 the initial
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:
reg [3:0] row_data[0:2]; // read-only memory, 4-bit data x 2-bit address
wire [1:0] row_data_address; // driven by module sorting_three
wire [3:0] row_data_dout; // driven by row_data[row_data_address]
assign row_data_dout = row_data[row_data_address];
The declaration for sorting_three should look like this (note I'm using Verilog 2001 style port declarations for readability):
module sorting_three_Memory (
output reg [3:0] max,
output reg [3:0] med,
output reg [3:0] min,
output reg [1:0] row_data_address, // drives row_data address
input wire [3:0] row_data_dout, // driven by row_data data out
input wire cin // clock
);
Inside module sorting_three
, the output port row_data_address
must be driven to 2'b00
, 2'b01
, or 2'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 from row_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:
module sorting_three_noMemory (
output reg [3:0] max,
output reg [3:0] med,
output reg [3:0] min,
input wire [3:0] row_data_0, // example 4'b0010
input wire [3:0] row_data_1, // example 4'b1001
input wire [3:0] row_data_2, // example 4'b1010
input wire cin
);
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:
localparam CLK_FREQ_HZ = 50_000_000;
localparam CLK_PERIOD_NS = 1_000_000_000 / CLK_FREQ_HZ;
always begin
#(CLK_PERIOD_NS/2.0);
clk=1;
#(CLK_PERIOD_NS/2.0);
clk=0;
end