I’m trying to make a single task for CRC generator for CRC_15, CRC_17 & CRC_21. Following is the code:
function crc_size crc_calc(crc_size crc ,bit data, int crc_bits, int crc_polynomial);
bit crc_nxt=0;
crc_calc = new [crc_bits+1];
crc_nxt = data ^ crc[crc_bits];
crc[crc_bits:1] = crc[crc_bits-1:0];
crc[0] = 0;
if(crc_nxt)begin
crc[crc_bits:0]=crc ^ crc_polynomial;
end
return crc;
endfunction
Where crc_size is defined as follows:
typedef bit crc_size[];
crc_bits & crc_polynomial are defined in a task as follows:
int crc_bits;
int crc_polynomial;
The values of crc_bits (i.e.,14,16,20) and crc_polynomial are assigned according to modes in the task and then is passed in the above function.
I’m getting the following error:
** Error: ** while parsing file included at : Range must be bounded by constant expressions.
Taking it as a parameter is fine but the value of crc_bits is dependent on the sequence_item. So if in a single testcase I want to send different data length formats which uses their respective CRCs then I won’t be able to change the crc_bits again and again.
crc_bits calculation is done something like this as follows:
I’m getting compilation error for the above codes. If talked about the biggest value then theoretically it’ll be CRC 21 generator. Following is it’s code:
CRC_RG = 0; // initialize shift register
REPEAT
CRCNXT = NXTBIT EXOR CRC_RG(20);
CRC_RG(20:1) = CRC_RG(19:0); // shift left by 1 position
CRC_RG(0) = 0;
IF CRCNXT THEN
CRC_RG(20:0) = CRC_RG(20:0) EXOR (302899hex); ENDIF
UNTIL (CRC SEQUENCE starts or there is an ERROR condition)
I first thought of using part-select but since width is variable, we can not use it. but since width is variable and only 3 possible combinations are there, why don’t you write case statement?
You can solve your problem by uasing a variable. But this variable nas to be initialized, best at declaration or using a default value in your task definition.
Afterwards you can update/modify this variable.
Please check the following code:
class driver extends uvm_driver #(sequence_item);
`uvm_component_utils_begin(driver)
`uvm_component_utils_end
uvm_analysis_port #(sequence_item)drv2scb_port;
sequence_item seq_item;
virtual interface interface vif;
agent agent_ptr;
int bit_q_size;
typedef bit crc_size[]; //Debug purpose for CRC
function new(string name,uvm_component parent);
super.new(name,parent);
endfunction
function void build();
super.build();
drv2scb_port=new("drv2scb_port",this);
endfunction
// START_ENCRYPTION
task run();
//body
endtask
rand bit eof_bit;
task frame(sequence_item obj);
byte crc_data;
int crc_bits = 14;
int crc_polynomial;
bit crc_reg[]; //Debug purpose for CRC
bit crc_reg_cur[]; //Debug purpose for CRC
obj.bit_q={};
//body to send different frames
crc_bits = 14; // Need to update condition for 3 different scenarios
crc_polynomial = 'h4599; // Need to update condition for 3 different scenarios
for(int i=0; i<obj.bit_q.size;i++) begin
for(int i=0;i<obj.bit_q.size;i++)begin
crc_reg = new[crc_bits+1];
crc_reg_cur = new[crc_bits+1];
crc_reg = crc_calc(crc_reg_cur , obj.bit_q[i],crc_bits,crc_polynomial);
crc_reg_cur = crc_reg;
end
endtask :create_frame
///////////////////////////////////////////////////////////////////////////////
// crc calculation using frames sof -> data(if present) (else) controlled field
///////////////////////////////////////////////////////////////////////////////
/* function bit [14:0] crc_calc(bit [14:0]crc ,bit data); //Initial CRC calculation
bit crc_nxt=0;
crc_nxt = data ^ crc[14];
crc[14:1] = crc[13:0];
crc[0] = 0;
if(crc_nxt)begin
crc[14:0]=crc ^ 'h4599;
end
return crc;
endfunction */
//CRC calculation function updated by me
function crc_size crc_calc(crc_size crc ,bit data, int crc_bits, int crc_polynomial);
bit crc_nxt=0;
crc_calc = new [crc_bits+1];
crc_nxt = data ^ crc[crc_bits];
crc[crc_bits:1] = crc[crc_bits-1:0];
crc[0] = 0;
if(crc_nxt)begin
crc[crc_bits:0]=crc ^ crc_polynomial;
end
return crc;
endfunction
endclass