crc__bits is a variable… therefore its value is not known till runtime.
However for the part select operation in Verilog the ranges should be
statically determinable at compile time. Hence crc[crc_bits:1] is not
legal.
crc__bits is a variable… therefore its value is not known till runtime.
However for the part select operation in Verilog the ranges should be
statically determinable at compile time. Hence crc[crc_bits:1] is not
legal.
In reply to chr_sue:
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:
crc_bits = (req.mode==1) ? ((req.data_length <= 16) ? 17 : 21):15;
And CRC polynomial is based on the crc_bits. After this assignment I’m passing these two values as argument to the CRC generator function
In reply to chr_sue:
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?
In reply to chr_sue:
I’ve mentioned it previously. Posting the same for your reference again:
** Error: ** while parsing file included at : Range must be bounded by constant expressions.
In reply to juhi_p:
Thanks Juhi for your reply. But as my present method isn’t working properly I’ve implemented the same concept using case statement itself.
I just want to optimize my code as case statement would just lengthen it more and I’ll have to make three functions for the same functionality.
Please do help in implementing this concept of using the same function for three different scenarios.
In reply to dpanda:
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.
In reply to dpanda:
What did you really do? Did you set a default value on the corresponding task input?
In reply to chr_sue:
I’ve assigned a default value to the variable while declaring it. And still giving the crc_bits as input to it.
In reply to dpanda:
Looks like you are doing something wrong.
Please see my example here:
//=============================================================================
// Sequence : example_top_default_seq
// Author : <author> Tel: <phone> Email: <email>
// Using : <list of sub-sequences used by this sequences>
// Description : Sequence generating 1 item;
//=============================================================================
class example_top_default_seq extends example_top_base_seq;
`uvm_object_utils(example_top_default_seq)
// UVC sequences
apb_default_seq apb_seq;
spi_default_seq spi_seq;
int loop_no = 10;
extern function new(string name = "example_top_default_seq");
extern task body();
extern task run_seq(input int noofloops = loop_no);
endclass : example_top_default_seq
//-----------------------------------------------------------------------------
// example_top_default_seq implementation
//-----------------------------------------------------------------------------
function example_top_default_seq::new(string name = "example_top_default_seq");
super.new(name);
endfunction : new
task example_top_default_seq::run_seq(input int noofloops = loop_no);
repeat(noofloops) begin
`uvm_info(get_type_name(),"apb sequence starting", UVM_MEDIUM)
`uvm_info(get_type_name(),$sformatf("loop_no = %0d", loop_no), UVM_MEDIUM)
void'(apb_seq.randomize());
apb_seq.start(apb_sequencer_i);
`uvm_info(get_type_name(),"spi sequence starting", UVM_MEDIUM)
void'(spi_seq.randomize());
spi_seq.start(spi_sequencer_i);
end
`uvm_info(get_type_name(),"setting new loop_no", UVM_MEDIUM)
endtask
task example_top_default_seq::body();
super.body();
apb_seq = apb_default_seq::type_id::create("apb_seq");
spi_seq = spi_default_seq::type_id::create("spi_seq");
`uvm_info(get_type_name(),"default sequence starting", UVM_MEDIUM)
run_seq(loop_no);
loop_no = 5;
run_seq(loop_no);
`uvm_info(get_type_name(),"default sequence completed",UVM_MEDIUM)
endtask : body
In reply to chr_sue:
What is the intention of this typedef:
typedef bit crc_size;
We no 2 different typedefs.
The forward typedef for classes, like this typedef class C;
and the typedef to define a user-defined type like this
typedef logic [7:0] [3:0] T;
Here T is like an abbreviation with the following decalartion
T var;
mean this is a 2-dim variable var.
In reply to chr_sue:
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
In reply to dpanda:
You did not set a default value for crc_bits.
It has to be
function crc_size crc_calc(crc_size crc ,bit data, int crc_bits = 7, int crc_polynomial);
Now crc_bits has a fixed value at elaboration, but it can be overridden by any other value later on. The default value can be any other number.
In reply to dpanda:
Could you share your code with me privately?
If yes respond on my email:
christoph@christoph-suehnel.de