Request Help - Cannot update array location

D

Daku

Guest
Could some Verilog guru please help a bit ? I am trying very hard to
update an array location, and failing. The source file and the
stimulus files are as below:

SOURCE FILE:

`timescale 10ns/1ns

module cam(clk,
read_en,
write_en,
search_item,
add_location,
add_data,
curr_pri,
curr_sec,
del_location);

parameter DATA_WIDTH=16;
parameter DEPTH=16;

input clk;
input read_en;
input write_en;
input [15:0] search_item;
input [7:0] add_location;
input [15:0] add_data;
output [7:0] curr_pri;
output [7:0] curr_sec;
output [7:0] del_location;

reg [7:0] curr_pri;
reg [7:0] curr_sec;
reg [7:0] del_location;
reg [15:0] currdata;
reg [DATA_WIDTH-1:0] CAMArray[DEPTH-1:0];
integer i;
integer pos;
integer lastpos;

initial
begin
for(i = 0; i < DEPTH; i=i+1) CAMArray=16'b0000000000000000;
i = 0;
pos = -1;
lastpos = -1;
curr_pri = 8'b00000000;
curr_sec = 8'b00000000;
del_location = 8'b00000000;
end

always @ (posedge read_en)
begin
if(!write_en)
begin
fork
checkmatch(0,CAMArray[0],search_item);
checkmatch(1,CAMArray[1],search_item);
checkmatch(2,CAMArray[2],search_item);
checkmatch(3,CAMArray[3],search_item);
checkmatch(4,CAMArray[4],search_item);
checkmatch(5,CAMArray[5],search_item);
checkmatch(6,CAMArray[6],search_item);
checkmatch(7,CAMArray[7],search_item);
checkmatch(8,CAMArray[8],search_item);
checkmatch(9,CAMArray[9],search_item);
checkmatch(10,CAMArray[10],search_item);
checkmatch(11,CAMArray[11],search_item);
checkmatch(12,CAMArray[12],search_item);
checkmatch(13,CAMArray[13],search_item);
checkmatch(14,CAMArray[14],search_item);
checkmatch(15,CAMArray[15],search_item);
join
if(pos != lastpos)
begin
lastpos = pos;
del_location = pos;
$display("Match pri %g sec %g at %g",
search_item[15:8], search_item[7:0], pos);
end
else
begin
$display("No match pri %g sec %g",
search_item[15:8], search_item[7:0]);
end
end
else
begin
$display("No read while write");
end
end

always @ (posedge write_en)
begin
if(!read_en)
begin
if(add_location < DEPTH && add_location >= 0)
begin
CAMArray[add_location]=add_data;
/*
$display("Add pri %g sec %g at %g",
CAMArray[15:8], CAMArray[7:0], add_location);
*/
end
end
end

always @ (posedge clk)
begin
if(!read_en && !write_en)
begin
findmaxprisec;
end
end

task checkmatch;
input integer ii;
input [15:0]a;
input [15:0]b;

begin
if(a[15:8]==b[15:8])
begin
if(a[7:0]==b[7:0])
begin
/*
$display("ii=%g a[15:8]=%g b[15:8]=%g a[7:0]=%g b[7:0]=%g",
ii, a[15:8], b[15:8], a[7:0], b[7:0]);
*/
pos = ii;
end
end
end
endtask


task findmaxprisec;
integer i1;

begin
currdata= CAMArray[0];
curr_pri = currdata[15:8];
curr_sec = currdata[7:0];

for(i1 = 1; i1 < DEPTH; i1=i1+1)
begin
currdata = CAMArray[i1];
if(currdata[15:8] > curr_pri)
begin
curr_pri = currdata[15:8];
end
if(currdata[7:0] > curr_sec)
begin
curr_sec = currdata[7:0];
end
end
/*
$display("curr_pri = %g curr_sec = %g", curr_pri, curr_sec);
*/
end
endtask


endmodule

STIMULUS:
`timescale 10ns/1ns

module camtb;

parameter HALF_MAX = 8;
parameter MAX = 16;
parameter clk_period = 10;


reg clock;
reg rd_en;
reg wt_en;
reg [MAX-1:0] data_to_search;
reg [HALF_MAX-1:0] data_to_add_loc;
reg [MAX-1:0] data_to_add;
wire [HALF_MAX-1:0] curr_pri;
wire [HALF_MAX-1:0] curr_sec;
wire [HALF_MAX-1:0] del_location;

reg [MAX-1:0] indexArray;
reg [HALF_MAX-1:0] pri;
reg [HALF_MAX-1:0] sec;
reg [HALF_MAX-1:0] currpri;
reg [HALF_MAX-1:0] currsec;
reg [HALF_MAX-1:0] dellocation;
integer currpos;


initial begin : camtb
$dumpfile ("/root/verilog/camtb.vcd");
$dumpvars (1, camtb);
data_to_add = {pri, sec};
clock = 1'b0;
rd_en = 1'b0;
wt_en = 1'b0;
data_to_search = 16'b0000000000000000;
data_to_add_loc= 8'b00000000;
indexArray = 16'b0000000000000000;
pri = 8'b00000000;
sec = 8'b00000000;
currpri = 8'b00000000;
currsec = 8'b00000000;
dellocation = 8'b00000000;
currpos = 0;

#5
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 2;
sec = 1;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en = 1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#10
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 3;
sec = 2;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en = 1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#10
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 3;
sec = 3;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en = 1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#10
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 3;
sec = 1;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en=1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#10
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 2;
sec = 2;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en = 1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#10
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 2;
sec = 3;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en = 1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#10
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 3;
sec = 4;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en=1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#10
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 4;
sec = 1;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en = 1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#10
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 4;
sec = 2;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en = 1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#10
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 4;
sec = 3;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en = 1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#10
findemptylocation(indexArray);
if(currpos < MAX)
begin
indexArray[currpos]=1'b1;
data_to_add_loc=currpos;
pri = 4;
sec = 4;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en = 1'b1;
#2
wt_en=1'b0;
if(pri > currpri)
begin
currpri = pri;
end
if(sec > currsec)
begin
currsec = sec;
end
end
else
begin
$display("Data not added");
end
#40
/*
pri = currpri;
sec = currsec;
*/
data_to_search[15:8] = currpri;
data_to_search[7:0] = currsec;
rd_en = 1'b1;
#2
rd_en = 1'b0;
dellocation = del_location;
indexArray[dellocation] = 1'b0;
findemptylocation(indexArray);
$display("deleted from %g", currpos);
data_to_add_loc=10;
pri = 0;
sec = 0;
data_to_add[15:8] = pri;
data_to_add[7:0] = sec;
wt_en = 1'b1;
#2
wt_en=1'b0;
#40
/*
pri = currpri;
sec = currsec;
*/
data_to_search[15:8] = currpri;
data_to_search[7:0] = currsec;
rd_en = 1'b1;
#2
rd_en = 1'b0;
dellocation = del_location;
indexArray[dellocation] = 1'b0;
#10
/* $display("deleted from %g", dellocation); */
#350 $finish;
end

always
begin
#(clk_period) clock = !clock;
/* $display("%g %g", curr_pri, curr_sec); */
currpri = curr_pri;
currsec = curr_sec;
end

task findemptylocation;
input [MAX-1:0] a;
integer ind;

begin
for(ind = 0; ind < MAX; ind=ind+1)
begin
if(a[ind] == 1'b0)
begin
currpos=ind;
disable findemptylocation;
end
end
end
endtask

cam c_a_m(
..clk (clock),
..read_en(rd_en),
..write_en(wt_en),
..search_item(data_to_search),
..add_location(data_to_add_loc),
..add_data(data_to_add),
..curr_pri(curr_pri),
..curr_sec(curr_sec),
..del_location(del_location)
);

endmodule

The output looks like:
Match pri 4 sec 4 at 10
deleted from 10
No match pri 4 sec 4

The output should rather look like:
Match pri 4 sec 4 at 10
deleted from 10
Match pri 4 sec 3 at 9

Could someone please kindly provide pointers as to what might be the
problem ?
 
Daku wrote:
Could some Verilog guru please help a bit ? I am trying very hard to
update an array location, and failing. The source file and the
stimulus files are as below:
....

Could someone please kindly provide pointers as to what might be the
problem ?
If you are going to post that much code a little explanation of how you
expect the various pieces to work would help. Commenting your code is
also helpful and a good habit to develop. Even better would be to first
verify which signals are being updated correctly and which are not to
give us an idea where to look. I'm guessing this is not a problem in the
array accesses and more likely a defect in the controlling logic.
Depending on the simulator there are ways to dump the array words so you
can monitor them, but a method that works for any simulator is to assign
each word to a monitor vector.

wire [DATA_WIDTH-1:0] CAMArray_0 = CAMArray[0];
wire [DATA_WIDTH-1:0] CAMArray_1 = CAMArray[1];

Since you array is small this should be fairly easy to do. You'll need
to change the depth of dumping and to be honest I'm not sure why you are
limiting this to only one level? This is simple RTL code and for debug
you want to look at every signal (level 0). Load everything into the
viewer and start looking for signals that are not changing as/when you
expect.

I hope this helps,

Cary
 

Welcome to EDABoard.com

Sponsor

Back
Top