2
votes

I have made two verilog modules. The first one takes a nine-bit number and returns the position of first occurrence of 1 in it.

module findPositionOf_1(
  input [8:0] data,
  output reg [3:0] position
  );


  always @(data)
  begin
    if(data==9'b0000_00000)
      position=4'b0000;
    else if(data[0]==1)
      position=4'b0000;
    else if(data[1]==1)
      position=4'b0001;
    else if(data[2]==1)
      position=4'b0010;
    else if(data[3]==1)
      position=4'b0011;
    else if(data[4]==1)
      position=4'b0100;
    else if(data[5]==1)
      position=4'b0101;
    else if(data[6]==1)
      position=4'b0110;
    else if(data[7]==1)
      position=4'b0111;
    else if(data[8]==1)
      position=4'b1000;
  end    

endmodule

The second module is returning the second occurrence of 1. It is calling the first module first changing that bit to zero and again finding the occurrence of 1.

module findPositionOf_2nd_1(
  input [8:0] r1_data, 
  output [3:0] position1 
);

reg [3:0] pos,pos2; 
reg [8:0] temp;

integer i;
always @(r1_data)
begin
  findPositionOf_1 f1(.data(r1_data), .position(pos));


  i=pos;
  temp=r1_data;
  temp[i]=0;
  findPositionOf_1 f2(temp,pos2);
  if(pos2==4'b0000)
    position1=0;
  else
    position1=pos2;

end

endmodule

I am getting the following errors during compilation. Please help.

Checker 'findPositionOf_1' not found. Instantiation 'f1' must be of a visible checker. A begin/end block was found with an empty body. This is permitted in SystemVerilog, but not permitted in Verilog. Please look for any stray semicolons.

2

2 Answers

5
votes

By the way you write code it seems like you've not completely grasped how verilog(and other HDL languages) is different from "normal", procedural, coding.

You seem to assume that everything inside your always@ block will execute from top to bottom, and that modules are similar to functions. This is not the case. You need to think about how you expect the hardware to look when you've designed your module.

In this case you know that you want two findPositionOf_1 modules. You know that you want the result from the first (u_f1) to affect the input of the second (u_f2). To do this, instantiate the two modules and then determine the interconnect between them.

We can create a vector with a 1 in position pos by left-shifting '1 pos number of times (1<<pos). By xor-ing the bits together, the statement r1_data ^ 1<<pos will remove the unwanted 1.

module findPositionOf_2nd_1(input [8:0] r1_data, output [3:0] position1 );
wire [3:0] pos,pos2; 
wire [8:0] temp;

  findPositionOf_1 u_f1(.data(r1_data), .position(pos));
  findPositionOf_1 u_f2(.data(temp), .position(pos2));

  assign temp = r1_data ^ (1<<pos);
  assign position1 = pos2;

endmodule
1
votes

You have instantiated your module inside an always block which is a procedural block, which is syntactically incorrect. Secondly, you have used your first module as a function call, which is not permitted. As said, you need to have a separate testbench, where you can connect your both modules and check. Make the position of occurance of 1st one as input to the findPositionOf_2nd_1 module. For your question, perhaps this should help

Why can't I instantiate inside the procedural block in Verilog