searching in memory at verilog

H

Hana'a AL-Theiabat

Guest
I need to make a module which responsible to search overall memory to find a specific value and return the address location, but I have the following error after do Synthesize in Xilinx.

Loop count limit exceeded. Condition is never false.

the Search module: responsible to take the value input and do search on the RAM memory, and return address.

module Search(
clk,
rst,
SearchData,
FindAddress,
StopSearch
);
input clk;
input rst;
input[7:0] SearchData;
output reg [1:0] FindAddress;
output reg StopSearch;
integer i;

wire read_rq;
reg [1:0] nxt_address;

initial
begin nxt_address=0;i=0; end

wire[7:0] read_data_inx;

D0_RAM1 D0(
.clk(clk),
.rst(rst),
.read_rq(read_rq),
.write_rq(0),
.rw_address(nxt_address),
.write_data(0),
.read_data(read_data_inx)
);
always @(posedge clk )
begin
while (nxt_address <4) begin
if (read_data_inx == SearchData) begin //master i has priority
FindAddress <= nxt_address;
StopSearch=1;
end
else begin
StopSearch=0;
end

nxt_address <= nxt_address+1;
end
end
endmodule


and the RAM module:

module D0_RAM1(
clk,
rst,
read_rq,
write_rq,
rw_address,
write_data,
read_data
);
input clk;
input rst;
input read_rq;
input write_rq;
input[1:0] rw_address; //2 bit
input[7:0] write_data;
output[7:0] read_data;

reg[7:0] read_data;

integer out, i;

// Declare memory 2^2 x8 bits
// 2^2 = 4
reg [7:0] memory_ram_d [3:0];
reg [7:0] memory_ram_q [3:0];

// Use positive edge of clock to read the memory
// Implement cyclic shift right
always @(posedge clk or
negedge rst)
begin
if (!rst)
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= 0;
end
else
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= memory_ram_d;
end
end
//q=d

always @(*)
begin
for (i=0;i<3; i=i+1)
memory_ram_d = memory_ram_q;
if (write_rq && !read_rq)
memory_ram_d[rw_address] = write_data;
if (!write_rq && read_rq)
read_data = memory_ram_q[rw_address];
end

endmodule


the while statement which caused the previous error.
 
In article <cd1b5dd3-65d0-45ff-9c04-91304e60830b@googlegroups.com>,
Hana'a AL-Theiabat <hanatheabat@gmail.com> wrote:

Hana,

There's a lot going on in your code, so I'll just speak generally.

Loops in verilog (or VHDL) must be statically defined in order to be
synthesized. Meaning the limits (start/end point) must be
non-stateful. In software terms the compiler must be able
to "unroll" the loop.

Your loop isn't statically defined.

I suggest NOT using while loops - just to get you in the right
frame of mind. No one uses while loops in HW designs. Loops
in HW are rare, but are needed in certain cases. In cases
that they are used, it's always a for loop like:

for( i = 0; i < SOME_STATIC_VAL; i = i + 1 )

For reasons I mentioned above.

You actually don't need a loop at all. You need a state machine.
You're code has nxt_address stepping through all possible values (0-3)
within a single clock cycle. Pretty sure that's not what you intended.
Further, your loop termination condition will NEVER terminate as
the values 0-3 are ALWAYS less than 4. That specifically
is what's leading to your error message, but you've got
general algorithm problems too.

Regards,

Mark
 
On Friday, April 10, 2015 at 6:14:15 PM UTC+2, Mark Curry wrote:
In article <cd1b5dd3-65d0-45ff-9c04-91304e60830b@googlegroups.com>,
Hana'a AL-Theiabat <hanatheabat@gmail.com> wrote:

Hana,

There's a lot going on in your code, so I'll just speak generally.

Loops in verilog (or VHDL) must be statically defined in order to be
synthesized. Meaning the limits (start/end point) must be
non-stateful. In software terms the compiler must be able
to "unroll" the loop.

Your loop isn't statically defined.

I suggest NOT using while loops - just to get you in the right
frame of mind. No one uses while loops in HW designs. Loops
in HW are rare, but are needed in certain cases. In cases
that they are used, it's always a for loop like:

for( i = 0; i < SOME_STATIC_VAL; i = i + 1 )

For reasons I mentioned above.

You actually don't need a loop at all. You need a state machine.
You're code has nxt_address stepping through all possible values (0-3)
within a single clock cycle. Pretty sure that's not what you intended.
Further, your loop termination condition will NEVER terminate as
the values 0-3 are ALWAYS less than 4. That specifically
is what's leading to your error message, but you've got
general algorithm problems too.

Regards,

Mark

Thanks Mark for your reply.
I am beginner at verilog, is it good to make state machine instead of loop?
So it could search all memory within one cycle?
if so how to do it with state machine?

Thanks
 
In article <0048234f-c3c8-4a2d-9994-b7abfb0ad736@googlegroups.com>,
Hana'a AL-Theiabat <hanatheabat@gmail.com> wrote:
On Friday, April 10, 2015 at 6:14:15 PM UTC+2, Mark Curry wrote:
In article <cd1b5dd3-65d0-45ff-9c04-91304e60830b@googlegroups.com>,
Hana'a AL-Theiabat <hanatheabat@gmail.com> wrote:

Hana,

There's a lot going on in your code, so I'll just speak generally.

Loops in verilog (or VHDL) must be statically defined in order to be
synthesized. Meaning the limits (start/end point) must be
non-stateful. In software terms the compiler must be able
to "unroll" the loop.

Your loop isn't statically defined.

I suggest NOT using while loops - just to get you in the right
frame of mind. No one uses while loops in HW designs. Loops
in HW are rare, but are needed in certain cases. In cases
that they are used, it's always a for loop like:

for( i = 0; i < SOME_STATIC_VAL; i = i + 1 )

For reasons I mentioned above.

You actually don't need a loop at all. You need a state machine.
You're code has nxt_address stepping through all possible values (0-3)
within a single clock cycle. Pretty sure that's not what you intended.
Further, your loop termination condition will NEVER terminate as
the values 0-3 are ALWAYS less than 4. That specifically
is what's leading to your error message, but you've got
general algorithm problems too.

Regards,

Mark


Thanks Mark for your reply.
I am beginner at verilog, is it good to make state machine instead of loop?
So it could search all memory within one cycle?

Most memories only allow you to read one value on every clock. So no,
you can't search all memory within one cycle. You need a state-machine
of some sort.

>if so how to do it with state machine?

Sorry, that's outside the scope of what can be taught in a newsgroup.
State-machine design is Hardware 101 - i.e. one of the first
things you learn.

Regards,

Mark
 
On Friday, April 10, 2015 at 4:40:14 PM UTC+2, Hana'a AL-Theiabat wrote:
I need to make a module which responsible to search overall memory to find a specific value and return the address location, but I have the following error after do Synthesize in Xilinx.

Loop count limit exceeded. Condition is never false.

the Search module: responsible to take the value input and do search on the RAM memory, and return address.

module Search(
clk,
rst,
SearchData,
FindAddress,
StopSearch
);
input clk;
input rst;
input[7:0] SearchData;
output reg [1:0] FindAddress;
output reg StopSearch;
integer i;

wire read_rq;
reg [1:0] nxt_address;

initial
begin nxt_address=0;i=0; end

wire[7:0] read_data_inx;

D0_RAM1 D0(
.clk(clk),
.rst(rst),
.read_rq(read_rq),
.write_rq(0),
.rw_address(nxt_address),
.write_data(0),
.read_data(read_data_inx)
);
always @(posedge clk )
begin
while (nxt_address <4) begin
if (read_data_inx == SearchData) begin //master i has priority
FindAddress <= nxt_address;
StopSearch=1;
end
else begin
StopSearch=0;
end

nxt_address <= nxt_address+1;
end
end
endmodule


and the RAM module:

module D0_RAM1(
clk,
rst,
read_rq,
write_rq,
rw_address,
write_data,
read_data
);
input clk;
input rst;
input read_rq;
input write_rq;
input[1:0] rw_address; //2 bit
input[7:0] write_data;
output[7:0] read_data;

reg[7:0] read_data;

integer out, i;

// Declare memory 2^2 x8 bits
// 2^2 = 4
reg [7:0] memory_ram_d [3:0];
reg [7:0] memory_ram_q [3:0];

// Use positive edge of clock to read the memory
// Implement cyclic shift right
always @(posedge clk or
negedge rst)
begin
if (!rst)
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= 0;
end
else
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= memory_ram_d;
end
end
//q=d

always @(*)
begin
for (i=0;i<3; i=i+1)
memory_ram_d = memory_ram_q;
if (write_rq && !read_rq)
memory_ram_d[rw_address] = write_data;
if (!write_rq && read_rq)
read_data = memory_ram_q[rw_address];
end

endmodule


the while statement which caused the previous error.


what about using Content-addressable memory (CAM)?
is it a good idea? what do you think?
 
On Friday, April 10, 2015 at 4:40:14 PM UTC+2, Hana'a AL-Theiabat wrote:
I need to make a module which responsible to search overall memory to find a specific value and return the address location, but I have the following error after do Synthesize in Xilinx.

Loop count limit exceeded. Condition is never false.

the Search module: responsible to take the value input and do search on the RAM memory, and return address.

module Search(
clk,
rst,
SearchData,
FindAddress,
StopSearch
);
input clk;
input rst;
input[7:0] SearchData;
output reg [1:0] FindAddress;
output reg StopSearch;
integer i;

wire read_rq;
reg [1:0] nxt_address;

initial
begin nxt_address=0;i=0; end

wire[7:0] read_data_inx;

D0_RAM1 D0(
.clk(clk),
.rst(rst),
.read_rq(read_rq),
.write_rq(0),
.rw_address(nxt_address),
.write_data(0),
.read_data(read_data_inx)
);
always @(posedge clk )
begin
while (nxt_address <4) begin
if (read_data_inx == SearchData) begin //master i has priority
FindAddress <= nxt_address;
StopSearch=1;
end
else begin
StopSearch=0;
end

nxt_address <= nxt_address+1;
end
end
endmodule


and the RAM module:

module D0_RAM1(
clk,
rst,
read_rq,
write_rq,
rw_address,
write_data,
read_data
);
input clk;
input rst;
input read_rq;
input write_rq;
input[1:0] rw_address; //2 bit
input[7:0] write_data;
output[7:0] read_data;

reg[7:0] read_data;

integer out, i;

// Declare memory 2^2 x8 bits
// 2^2 = 4
reg [7:0] memory_ram_d [3:0];
reg [7:0] memory_ram_q [3:0];

// Use positive edge of clock to read the memory
// Implement cyclic shift right
always @(posedge clk or
negedge rst)
begin
if (!rst)
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= 0;
end
else
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= memory_ram_d;
end
end
//q=d

always @(*)
begin
for (i=0;i<3; i=i+1)
memory_ram_d = memory_ram_q;
if (write_rq && !read_rq)
memory_ram_d[rw_address] = write_data;
if (!write_rq && read_rq)
read_data = memory_ram_q[rw_address];
end

endmodule


the while statement which caused the previous error.


Thanks Rick.
I have solved the error which i have been faced. So I have the updated versions, but when I wrote a test bench, I see that the module didn't work correctly! always the output value is "don't care". Although I have initialized the memory.


Search module>>>
----------------------------

module Search (
clk,
rst,
SearchData,
FindAddress,
StopSearch
);
input clk;
input rst;
input[7:0] SearchData;
output reg [1:0] FindAddress;
output reg StopSearch;
integer i,x;

wire read_rq;
reg [1:0] nxt_address;
reg [2:0] ii;
initial
begin nxt_address=0;i=0; ii=0; end

wire[7:0] read_data_inx;

D0_RAM1 D0(
.clk(clk),
.rst(rst),
.read_rq(read_rq),
.write_rq(0),
.rw_address(nxt_address),
.write_data(0),
.read_data(read_data_inx)
);
always @(posedge clk )
begin
for ( x =0 ;x <4;x=x+1) begin
if (read_data_inx == SearchData) begin //master i has priority
FindAddress <= nxt_address;
StopSearch <=1;
end

nxt_address <= nxt_address+1;
end

end


the RAM module:
--------------------------------------------------

module D0_RAM1(
clk,
rst,
read_rq,
write_rq,
rw_address,
write_data,
read_data
);
input clk;
input rst;
input read_rq;
input write_rq;
input[1:0] rw_address; //2 bit
input[7:0] write_data;
output[7:0] read_data;

reg[7:0] read_data;
reg[3:0] count_;
integer out, i;

// Declare memory 2^2 x8 bits
// 2^2 = 4
reg [7:0] memory_ram_d [3:0];
reg [7:0] memory_ram_q [3:0];
initial
begin
count_=0;
for (i=0;i<4; i=i+1) begin
memory_ram_q <= i;
memory_ram_d <=i;
count_=count_+1;
end
end

// Use positive edge of clock to read the memory
// Implement cyclic shift right
always @(posedge clk or
negedge rst)
begin
if (!rst)
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= 0;
end
else
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= memory_ram_d;
end
end
//q=d

always @(*)
begin
for (i=0;i<3; i=i+1)
memory_ram_d = memory_ram_q;
if (write_rq && !read_rq)
memory_ram_d[rw_address] = write_data;
if (!write_rq && read_rq)
read_data = memory_ram_q[rw_address];
end

endmodule


---> Any ideas?

Thanks.
 
On 4/10/2015 1:46 PM, Hana'a AL-Theiabat wrote:
On Friday, April 10, 2015 at 4:40:14 PM UTC+2, Hana'a AL-Theiabat wrote:
I need to make a module which responsible to search overall memory to find a specific value and return the address location, but I have the following error after do Synthesize in Xilinx.

Loop count limit exceeded. Condition is never false.

the Search module: responsible to take the value input and do search on the RAM memory, and return address.

module Search(
clk,
rst,
SearchData,
FindAddress,
StopSearch
);
input clk;
input rst;
input[7:0] SearchData;
output reg [1:0] FindAddress;
output reg StopSearch;
integer i;

wire read_rq;
reg [1:0] nxt_address;

initial
begin nxt_address=0;i=0; end

wire[7:0] read_data_inx;

D0_RAM1 D0(
.clk(clk),
.rst(rst),
.read_rq(read_rq),
.write_rq(0),
.rw_address(nxt_address),
.write_data(0),
.read_data(read_data_inx)
);
always @(posedge clk )
begin
while (nxt_address <4) begin
if (read_data_inx == SearchData) begin //master i has priority
FindAddress <= nxt_address;
StopSearch=1;
end
else begin
StopSearch=0;
end

nxt_address <= nxt_address+1;
end
end
endmodule


and the RAM module:

module D0_RAM1(
clk,
rst,
read_rq,
write_rq,
rw_address,
write_data,
read_data
);
input clk;
input rst;
input read_rq;
input write_rq;
input[1:0] rw_address; //2 bit
input[7:0] write_data;
output[7:0] read_data;

reg[7:0] read_data;

integer out, i;

// Declare memory 2^2 x8 bits
// 2^2 = 4
reg [7:0] memory_ram_d [3:0];
reg [7:0] memory_ram_q [3:0];

// Use positive edge of clock to read the memory
// Implement cyclic shift right
always @(posedge clk or
negedge rst)
begin
if (!rst)
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= 0;
end
else
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= memory_ram_d;
end
end
//q=d

always @(*)
begin
for (i=0;i<3; i=i+1)
memory_ram_d = memory_ram_q;
if (write_rq && !read_rq)
memory_ram_d[rw_address] = write_data;
if (!write_rq && read_rq)
read_data = memory_ram_q[rw_address];
end

endmodule


the while statement which caused the previous error.

what about using Content-addressable memory (CAM)?
is it a good idea? what do you think?


What is your target device? If you plan to actually build this circuit
in an FPGA you will find that FPGAs don't have content addressable
memory. They were available as chips at one point, being used in
mini-computer cache memories. I doubt they exist any longer.

A CAM consists of a RAM with a comparator at every memory word. When a
pattern is input every comparator checks to see if that value is stored
there and the address of a match is returned. The only way to build
this in an FPGA and likely an ASIC is to construct the memory out of FFs
and add the comparator to each one. Your while loop was trying to do
that, but you didn't update the loop variable correctly. You need to
learn about blocking vs. non-blocking assignments. I would explain them
to you, but I don't remember which name is which, lol. The assignment
with the <= doesn't take effect until the process exits so your loop
variable never updated and the loop never exited. Change the assignment
type and the loop will work and the tools will give you a CAM using FFs.

I guess the thing you aren't grasping about your loop is that this loop
is not in time. It is a loop in hardware. It will create N instances
of the logic described within the loop.

--

Rick
 
On 4/10/2015 3:52 PM, Hana'a AL-Theiabat wrote:
On Friday, April 10, 2015 at 4:40:14 PM UTC+2, Hana'a AL-Theiabat wrote:
I need to make a module which responsible to search overall memory to find a specific value and return the address location, but I have the following error after do Synthesize in Xilinx.

Loop count limit exceeded. Condition is never false.

the Search module: responsible to take the value input and do search on the RAM memory, and return address.

module Search(
clk,
rst,
SearchData,
FindAddress,
StopSearch
);
input clk;
input rst;
input[7:0] SearchData;
output reg [1:0] FindAddress;
output reg StopSearch;
integer i;

wire read_rq;
reg [1:0] nxt_address;

initial
begin nxt_address=0;i=0; end

wire[7:0] read_data_inx;

D0_RAM1 D0(
.clk(clk),
.rst(rst),
.read_rq(read_rq),
.write_rq(0),
.rw_address(nxt_address),
.write_data(0),
.read_data(read_data_inx)
);
always @(posedge clk )
begin
while (nxt_address <4) begin
if (read_data_inx == SearchData) begin //master i has priority
FindAddress <= nxt_address;
StopSearch=1;
end
else begin
StopSearch=0;
end

nxt_address <= nxt_address+1;
end
end
endmodule


and the RAM module:

module D0_RAM1(
clk,
rst,
read_rq,
write_rq,
rw_address,
write_data,
read_data
);
input clk;
input rst;
input read_rq;
input write_rq;
input[1:0] rw_address; //2 bit
input[7:0] write_data;
output[7:0] read_data;

reg[7:0] read_data;

integer out, i;

// Declare memory 2^2 x8 bits
// 2^2 = 4
reg [7:0] memory_ram_d [3:0];
reg [7:0] memory_ram_q [3:0];

// Use positive edge of clock to read the memory
// Implement cyclic shift right
always @(posedge clk or
negedge rst)
begin
if (!rst)
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= 0;
end
else
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= memory_ram_d;
end
end
//q=d

always @(*)
begin
for (i=0;i<3; i=i+1)
memory_ram_d = memory_ram_q;
if (write_rq && !read_rq)
memory_ram_d[rw_address] = write_data;
if (!write_rq && read_rq)
read_data = memory_ram_q[rw_address];
end

endmodule


the while statement which caused the previous error.

Thanks Rick.
I have solved the error which i have been faced. So I have the updated versions, but when I wrote a test bench, I see that the module didn't work correctly! always the output value is "don't care". Although I have initialized the memory.


Search module
----------------------------

module Search (
clk,
rst,
SearchData,
FindAddress,
StopSearch
);
input clk;
input rst;
input[7:0] SearchData;
output reg [1:0] FindAddress;
output reg StopSearch;
integer i,x;

wire read_rq;
reg [1:0] nxt_address;
reg [2:0] ii;
initial
begin nxt_address=0;i=0; ii=0; end

wire[7:0] read_data_inx;

D0_RAM1 D0(
.clk(clk),
.rst(rst),
.read_rq(read_rq),
.write_rq(0),
.rw_address(nxt_address),
.write_data(0),
.read_data(read_data_inx)
);
always @(posedge clk )
begin
for ( x =0 ;x <4;x=x+1) begin
if (read_data_inx == SearchData) begin //master i has priority
FindAddress <= nxt_address;
StopSearch <=1;
end

nxt_address <= nxt_address+1;
end

end


the RAM module:
--------------------------------------------------

module D0_RAM1(
clk,
rst,
read_rq,
write_rq,
rw_address,
write_data,
read_data
);
input clk;
input rst;
input read_rq;
input write_rq;
input[1:0] rw_address; //2 bit
input[7:0] write_data;
output[7:0] read_data;

reg[7:0] read_data;
reg[3:0] count_;
integer out, i;

// Declare memory 2^2 x8 bits
// 2^2 = 4
reg [7:0] memory_ram_d [3:0];
reg [7:0] memory_ram_q [3:0];
initial
begin
count_=0;
for (i=0;i<4; i=i+1) begin
memory_ram_q <= i;
memory_ram_d <=i;
count_=count_+1;
end
end

// Use positive edge of clock to read the memory
// Implement cyclic shift right
always @(posedge clk or
negedge rst)
begin
if (!rst)
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= 0;
end
else
begin
for (i=0;i<3; i=i+1)
memory_ram_q <= memory_ram_d;
end
end
//q=d

always @(*)
begin
for (i=0;i<3; i=i+1)
memory_ram_d = memory_ram_q;
if (write_rq && !read_rq)
memory_ram_d[rw_address] = write_data;
if (!write_rq && read_rq)
read_data = memory_ram_q[rw_address];
end

endmodule


---> Any ideas?


No, I can't figure out what you are trying to do. To read the memory
you just assign the value of the memory array of the specified location
to the output. I don't understand why you are indexing through the
memory copying it from one memory to another. Why do you have
memory_ram_d and memory_ram_q? You only need one, pick one and use it
everywhere.

--

Rick
 
On 4/10/15 1:14 PM, Hana'a AL-Theiabat wrote:
Thanks Mark for your reply.
I am beginner at verilog, is it good to make state machine instead of loop?
So it could search all memory within one cycle?
if so how to do it with state machine?

Thanks

There are specialized ram called "Content Addressable Memories" that are
designed for such things. (a common use is in a cache controller to see
if a given chunk of memory is in the cache).

Standard memories do not work this way, and especially, the standard
memory block inside most programmable logic are not set up for this.

I suspect that, now that you have the name of the thing, a web search
for it might yield some discussion of how to efficiently implement one
in a typical FPGA. I am not sure this would be considered a "beginner"
topic, so be prepared to be overwhelmed.
 

Welcome to EDABoard.com

Sponsor

Back
Top