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 ?
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 ?