readout_rm/readout_awg_rm.sv

743 lines
24 KiB
Systemverilog

//FILE_HEADER-------------------------------------------------------
//FILE_NAME : readout_awg_rm.sv
//DEPARTEMENT : QuantumCTek-ASIC
//AUTHOR : Yunzhuo Zhang
//TIME : 2025.4.10
//*******************************************************************
//DESCRIPTION : awg reference model define
//*******************************************************************
//END_HEADER*********************************************************
`ifndef READOUT_AWG_RM
`define READOUT_AWG_RM
`include "../testbench/refm/mcu_cw_item.sv"
`include "../testbench/refm/nco_dpi/codegen/dll/nco_model/nco_dpi_pkg.sv"
`include "../testbench/refm/hilbert_dpi/codegen/dll/hilbert_fir/hilbert_fir_dpi_pkg.sv"
import nco_dpi_pkg::*;
import hilbert_fir_dpi_pkg::*;
class readout_awg_rm extends uvm_component;
`uvm_component_utils(readout_awg_rm);
virtual rm_if rm_if; //sync
uvm_analysis_port #(EZQ_readout_dac_item) dac_rm2scb_port;
uvm_blocking_get_port #(mcu_cw_item) mcu_get_port;
bit [31:0] mcu_timer ;
bit [31:0] mcu_counter ;
bit [31:0] loc_state ;
bit [31:0] glb_state ;
bit [31:0] feed_data ;
bit [31:0] wave_ctrl ;
bit [31:0] amplitude ;
bit [31:0] frequency ;
bit [31:0] phase ;
bit [31:0] command ;
bit [31:0] func_ctrl ;
bit [31:0] pump_ctrl ;
bit [31:0] mark_ctrl ;
bit [31:0] cw_data ;
bit cw_valid ;
mcu_cw_item cw_queue[$] ;
bit [31:0] clock_cycle ;
bit [31:0] awg_clock_cycle ;
bit [15:0] env_len ;
bit [31:0] ram_data[bit[31:0]];
bit [31:0] wr_data ;
bit [31:0] wr_addr ;
bit [31:0] dac_send_cnt ;
bit [15:0]data_out_0[$];
bit [15:0]data_out_1[$];
bit [15:0]data_out_2[$];
bit [15:0]data_out_3[$];
bit [15:0]data_out_4[$];
bit [15:0]data_out_5[$];
bit [15:0]data_out_6[$];
bit [15:0]data_out_7[$];
bit [15:0]data_outb_0[$];
bit [15:0]data_outb_1[$];
bit [15:0]data_outb_2[$];
bit [15:0]data_outb_3[$];
bit [15:0]data_outb_4[$];
bit [15:0]data_outb_5[$];
bit [15:0]data_outb_6[$];
bit [15:0]data_outb_7[$];
extern function new(string name,uvm_component parent);
extern function void build_phase(uvm_phase phase);
extern virtual task run_phase(uvm_phase phase);
extern task get_mcu_cw_item();
extern task get_spi_item();
extern task get_config_data();
extern task send_dac_item();
extern task awg_exe();
extern task if_pump_mark();
extern task hilbert_fir(
input bit signed [15:0] hilbert_in[$],
input bit [15:0] data_size,
output bit signed [15:0] hilbert_out[$]
);
endclass
function readout_awg_rm::new(string name,uvm_component parent);
super.new(name,parent);
endfunction : new
function void readout_awg_rm::build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual rm_if)::get(this,"","rm_if",rm_if))
`uvm_fatal("CFGERR",{"virtual interface must be set for: ",get_full_name(),".vif"});
mcu_get_port = new("spi_get_port",this);
dac_rm2scb_port = new("dac_rm2scb_port",this);
endfunction
task readout_awg_rm::get_mcu_cw_item();
mcu_cw_item mcu_cw_item;
forever begin
mcu_get_port.get(mcu_cw_item);
cw_data = mcu_cw_item.cw_data;
cw_valid = mcu_cw_item.cw_valid;
`uvm_info(get_type_name(),$sformatf("awg_mcu_cw_data = %0h,awg_mcu_cycle = %0h,awg_cw_valid = %h",cw_data,mcu_cw_item.clock_cycle,cw_valid),UVM_LOW)
if(cw_valid)begin
clock_cycle = mcu_cw_item.clock_cycle;
cw_queue.push_back(mcu_cw_item);
`uvm_info(get_type_name(),$sformatf("cw_queue_size = %0h",cw_queue.size()),UVM_MEDIUM)
end
end
endtask
task readout_awg_rm::get_spi_item();
forever begin
@(wr_data or wr_addr)
ram_data[wr_addr] = wr_data;
`uvm_info(get_type_name(),$sformatf("wr_addr = %0h,wr_data = %0h",wr_addr,wr_data),UVM_LOW)
end
endtask
task readout_awg_rm::get_config_data();
forever begin
@(posedge `CLK);
if(ram_data.exists(`AWG_MCU_TIMER))begin
mcu_timer = ram_data[`AWG_MCU_TIMER];
end
if(ram_data.exists(`AWG_MCU_COUNTER))begin
mcu_counter = ram_data[`AWG_MCU_COUNTER];
end
if(ram_data.exists(`AWG_LOC_STATE))begin
loc_state = ram_data[`AWG_LOC_STATE];
end
if(ram_data.exists(`AWG_GLB_STATE))begin
glb_state = ram_data[`AWG_GLB_STATE];
end
/*
if(ram_data.exists(`AWG_FEED_DATA))begin
feed_data = ram_data[`AWG_FEED_DATA];
end
*/
if(ram_data.exists(`WAVE_CTRL))begin
wave_ctrl = ram_data[`WAVE_CTRL];
end
if(ram_data.exists(`AMPLITUDE))begin
amplitude = ram_data[`AMPLITUDE];
end
if(ram_data.exists(`FREQUENCY))begin
frequency = ram_data[`FREQUENCY];
end
if(ram_data.exists(`PHASE))begin
phase = ram_data[`PHASE];
end
if(ram_data.exists(`AWG_COMMAND))begin
command = ram_data[`AWG_COMMAND];
end
if(ram_data.exists(`AWG_FUNC_CTRL))begin
func_ctrl = ram_data[`AWG_FUNC_CTRL];
end
if(ram_data.exists(`PUMP_CTRL))begin
pump_ctrl = ram_data[`PUMP_CTRL];
end
else begin
pump_ctrl = 32'h10010;
end
if(ram_data.exists(`MARK_CTRL))begin
mark_ctrl = ram_data[`MARK_CTRL];
end
else begin
mark_ctrl = 32'h10010;
end
end
endtask
task readout_awg_rm::send_dac_item();
EZQ_readout_dac_item dac_item_pkt;
forever begin
if(data_out_0.size()>`DAC_MON_CYCLE)begin
dac_item_pkt = new();
dac_item_pkt.data_out0 = data_out_0[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_out1 = data_out_1[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_out2 = data_out_2[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_out3 = data_out_3[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_out4 = data_out_4[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_out5 = data_out_5[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_out6 = data_out_6[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_out7 = data_out_7[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_outb0 = data_outb_0[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_outb1 = data_outb_1[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_outb2 = data_outb_2[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_outb3 = data_outb_3[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_outb4 = data_outb_4[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_outb5 = data_outb_5[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_outb6 = data_outb_6[0+: `DAC_MON_CYCLE];
dac_item_pkt.data_outb7 = data_outb_7[0+: `DAC_MON_CYCLE];
// dac_item_pkt.delay_cycle = awg_clock_cycle;
dac_rm2scb_port.write(dac_item_pkt);
`uvm_info(get_type_name(),$sformatf("dac_send_cnt = %0h",dac_send_cnt),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_out_0[0+: `DAC_MON_CYCLE] = %0p",data_out_0[0+: `DAC_MON_CYCLE]),UVM_LOW)
/*
`uvm_info(get_type_name(),$sformatf("data_out_1 = %0p",data_out_1),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_out_2 = %0p",data_out_2),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_out_3 = %0p",data_out_3),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_out_4 = %0p",data_out_4),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_out_5 = %0p",data_out_5),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_out_6 = %0p",data_out_6),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_out_7 = %0p",data_out_7),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_outb_0 = %0p",data_outb_0),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_outb_1 = %0p",data_outb_1),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_outb_2 = %0p",data_outb_2),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_outb_3 = %0p",data_outb_3),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_outb_4 = %0p",data_outb_4),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_outb_5 = %0p",data_outb_5),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_outb_6 = %0p",data_outb_6),UVM_LOW
`uvm_info(get_type_name(),$sformatf("data_outb_7 = %0p",data_outb_7),UVM_LOW)
`uvm_info(get_type_name(),$sformatf("data_outb_7 = %0p",data_outb_7),UVM_LOW)
*/
data_out_0 = data_out_0[`DAC_MON_CYCLE : $];
data_out_1 = data_out_1[`DAC_MON_CYCLE : $];
data_out_2 = data_out_2[`DAC_MON_CYCLE : $];
data_out_3 = data_out_3[`DAC_MON_CYCLE : $];
data_out_4 = data_out_4[`DAC_MON_CYCLE : $];
data_out_5 = data_out_5[`DAC_MON_CYCLE : $];
data_out_6 = data_out_6[`DAC_MON_CYCLE : $];
data_out_7 = data_out_7[`DAC_MON_CYCLE : $];
data_outb_0 = data_outb_0[`DAC_MON_CYCLE : $];
data_outb_1 = data_outb_1[`DAC_MON_CYCLE : $];
data_outb_2 = data_outb_2[`DAC_MON_CYCLE : $];
data_outb_3 = data_outb_3[`DAC_MON_CYCLE : $];
data_outb_4 = data_outb_4[`DAC_MON_CYCLE : $];
data_outb_5 = data_outb_5[`DAC_MON_CYCLE : $];
data_outb_6 = data_outb_6[`DAC_MON_CYCLE : $];
data_outb_7 = data_outb_7[`DAC_MON_CYCLE : $];
dac_send_cnt++;
end
@(posedge `CLK);
end
endtask
task readout_awg_rm::awg_exe();
//fid
chandle objhandle = null ;
chandle OBJhandle = null ;
bit [31:0] zeros_len;
//get wave_idx & wave
bit [5 :0] wave_id ;
bit [24:0] env_map_addr ;
bit [31:0] env_idx ;
bit [24:0] env_addr ;
bit [24:0] env_addr_1 ;
bit [24:0] env_addr_2 ;
bit [24:0] env_addr_3 ;
bit [`NUM_WAY*`DATA_WIDTH-1 :0] wave_out ;
bit [31:0] wave_out_0 ;
bit [31:0] wave_out_1 ;
bit [31:0] wave_out_2 ;
bit [31:0] wave_out_3 ;
bit [127:0] wave_out_queue[$] ;
int k ;
//wave_mod output signal
bit [1 :0] mod_mode ;
bit loc_rst_n ;
bit hilbert_en ;
bit iq_mod_en ;
bit clr_en ;
bit mix_en ;
int j ;
bit [47:0] frequency_48;
real nco_acc_out ;
real nco_acc_in ;
bit signed[15:0] nco_cos[`NUM_WAY-1 :0] ;
bit signed[15:0] nco_sin[`NUM_WAY-1 :0] ;
bit signed[15:0] nco_cos_queue[$] ;
bit signed[15:0] nco_sin_queue[$] ;
bit signed[15:0] hilbert_in[$];
bit signed[15:0] hilbert_out[$];
bit signed[15:0] iq_mod_data_i_queue[$];
bit signed[15:0] iq_mod_data_q_queue[$];
bit signed[31:0] iq_mod_data_i_temp ;
bit signed[31:0] iq_mod_data_q_temp ;
bit signed[31:0] i_mult_cos;
bit signed[31:0] i_mult_sin;
bit signed[31:0] q_mult_cos;
bit signed[31:0] q_mult_sin;
bit signed[15:0] iq_mod_data_i[`NUM_WAY-1 :0] ;
bit signed[15:0] iq_mod_data_q[`NUM_WAY-1 :0] ;
bit signed[15:0] wave_mod_out[$] ;
//wave_amp output siganl
bit [31:0] wave_amp_out_temp;
bit [`DATA_WIDTH-1:0] wave_amp_out[`NUM_WAY-1 :0];
//wave_mix output siganl
bit [`DATA_WIDTH-1:0] wave_mix_out[`NUM_WAY-1:0];
bit [`DATA_WIDTH-1:0] wave_mix_outb[`NUM_WAY-1:0];
//Pump & Mark signal
//wait sync signal
`uvm_info(get_type_name(),"awg wait sync_in",UVM_LOW)
wait (`SYNC_IN);
`uvm_info(get_type_name(),"awg sync_in come",UVM_LOW)
forever begin
wait(cw_valid == 1);
`uvm_info(get_type_name(),$sformatf("awg_cw_data = %h,wave_ctrl = %h,func_ctrl = %h",cw_data,wave_ctrl,func_ctrl),UVM_LOW)
//config signals
mod_mode = func_ctrl[1:0];
clr_en = cw_data[6];
loc_rst_n = (mod_mode == 2'b01) | (mod_mode == 2'b11);
hilbert_en = (mod_mode == 2'b01) | (mod_mode == 2'b10);
iq_mod_en = (mod_mode == 2'b01);
mix_en = ~func_ctrl[2];
`uvm_info(get_type_name(),$sformatf("mod_mode = %h,clr_en = %h",mod_mode,clr_en),UVM_LOW);
`uvm_info(get_type_name(),$sformatf("loc_rst_n = %h,hilbert_en = %h,iq_mod_en = %h",loc_rst_n,hilbert_en,iq_mod_en),UVM_LOW);
////////////////////////////////////////
//delay calculator
///////////////////////////////////////
//wave_play : 3
//hilbert : 8
//nco : 11
//iq_mod+mux: 2 + 1
//amp : 1
//mix : 1
//awg_out to dac_if :3
awg_clock_cycle = clock_cycle + 3; //wave_play
case(mod_mode)
2'b00 : awg_clock_cycle = awg_clock_cycle + 2 + 3; //hilbert_in
2'b01 : awg_clock_cycle = awg_clock_cycle + 8 + 2 + 1 + 2 + 3; //iq_mod
2'b10 : awg_clock_cycle = awg_clock_cycle + 8 + 1 + 2 + 3; //hilbert_q
2'b11 : awg_clock_cycle = awg_clock_cycle + 8 + 1 + 2 + 3; //nco_cos
endcase
`uvm_info(get_type_name(),$sformatf("mod_mode = %0h,awg_clock_cycle = %0h",mod_mode,awg_clock_cycle),UVM_LOW);
zeros_len = awg_clock_cycle - data_out_0.size() - dac_send_cnt * `DAC_MON_CYCLE;
`uvm_info(get_type_name(),$sformatf("data_out_0.size() = %0h",data_out_0.size()),UVM_LOW);
for (int i = 0; i < zeros_len; i++)begin
data_out_0.push_back(16'h8000);
data_out_1.push_back(16'h8000);
data_out_2.push_back(16'h8000);
data_out_3.push_back(16'h8000);
data_out_4.push_back(16'h8000);
data_out_5.push_back(16'h8000);
data_out_6.push_back(16'h8000);
data_out_7.push_back(16'h8000);
data_outb_0.push_back(16'h8000);
data_outb_1.push_back(16'h8000);
data_outb_2.push_back(16'h8000);
data_outb_3.push_back(16'h8000);
data_outb_4.push_back(16'h8000);
data_outb_5.push_back(16'h8000);
data_outb_6.push_back(16'h8000);
data_outb_7.push_back(16'h8000);
end
`uvm_info(get_type_name(),$sformatf("dac_send_cnt = %0h,zeros_len = %0h,data_out_0.size() = %0h",dac_send_cnt,zeros_len,data_out_0.size()),UVM_LOW);
/////////////////////////////////////////////
//AWG functions
/////////////////////////////////////////////
//wave_play
wave_id = cw_data[5 :0];
env_map_addr= 25'hA00000 + {wave_id,2'b00};
env_idx = ram_data.exists(env_map_addr) ? ram_data[env_map_addr] : 0; //get env_idx
env_addr = 25'hB00000 + {env_idx[31:16],4'b0}; //start address
env_len = env_idx[15:0]; //128bit -- 4'b0
`uvm_info(get_type_name(),$sformatf("env_map_addr = %h,env_idx = %h",env_map_addr,env_idx),UVM_LOW);
`uvm_info(get_type_name(),$sformatf("env_addr = %h,env_len = %h",env_addr,env_len),UVM_LOW);
for(k =0; k<env_len; k++)begin
wave_out_0 = ram_data[env_addr];
env_addr_1 = env_addr + 4;
env_addr_2 = env_addr + 8;
env_addr_3 = env_addr + 12;
wave_out_1 = ram_data[env_addr_1];
wave_out_2 = ram_data[env_addr_2];
wave_out_3 = ram_data[env_addr_3];
wave_out = {wave_out_3,wave_out_2,wave_out_1,wave_out_0};
env_addr = env_addr + 16;
`uvm_info(get_type_name(),$sformatf("wave_out = %h,env_addr = %h",wave_out,env_addr),UVM_LOW);
//hilbert_fir
for(j = 0; j<`NUM_WAY; j++)begin
hilbert_in.push_back(wave_out[j*`DATA_WIDTH +:`DATA_WIDTH]) ;
`uvm_info(get_type_name(),$sformatf("hilbert_in[%0h] = %h",j,wave_out[j*`DATA_WIDTH +:`DATA_WIDTH]),UVM_LOW);
end
end
`uvm_info(get_type_name(),$sformatf("hilbert_in_queue = %p,hilbert_in_queue.size",hilbert_in,hilbert_in.size()),UVM_LOW);
hilbert_fir(hilbert_in,hilbert_in.size(),hilbert_out);
//wave_mode
for(k =0; k<env_len; k++)begin
frequency_48 = {1'b0,frequency,15'b0};
`uvm_info(get_type_name(),$sformatf("frequency = %h,frequency_48 = %h,phase[31:16] = %h",frequency,frequency_48,phase[31:16]),UVM_LOW);
`uvm_info(get_type_name(),$sformatf("clk_cycle = %h",k),UVM_LOW);
//nco dpi
//DPI_nco_terminate(objhandle);
objhandle=DPI_nco_initialize(objhandle);
for (j = 0; j<`NUM_WAY; j++)begin
DPI_nco(objhandle,real'(frequency_48),real'(phase[31:16]),real'(clr_en),real'(nco_acc_in + 2*(j+1)*frequency_48),nco_cos[j],nco_sin[j],nco_acc_out);
nco_cos_queue.push_back(nco_cos[j]);
nco_sin_queue.push_back(nco_sin[j]);
`uvm_info(get_type_name(),$sformatf("nco_acc_in + 2*%0h * frequency = %h",j,(nco_acc_in + 2*(j+1)*frequency_48)),UVM_LOW);
`uvm_info(get_type_name(),$sformatf("cos[%0h] = %h,sin[%0h] = %h,nco_acc_out =%h ",j,nco_cos[j],j,nco_sin[j],nco_acc_out),UVM_LOW);
end
nco_acc_in = nco_acc_in + 16 * frequency_48;
//mod_i
for(j = 0; j<`NUM_WAY; j++)begin
i_mult_cos = hilbert_in[j+k*`NUM_WAY]*nco_cos[j];
q_mult_sin = hilbert_out[j+k*`NUM_WAY]*nco_sin[j];
iq_mod_data_i_temp = i_mult_cos - q_mult_sin;
if(iq_mod_data_i_temp[31] == 1)begin
if(iq_mod_data_i_temp[15:0] == 0)begin
iq_mod_data_i[j] = $floor(iq_mod_data_i_temp/32768);
end else begin
iq_mod_data_i[j] = $floor(iq_mod_data_i_temp/32768)- 1;
end
end
else begin
iq_mod_data_i[j] = $floor(iq_mod_data_i_temp/32768);
end
iq_mod_data_i_queue.push_back(iq_mod_data_i[j]);
// `uvm_info(get_type_name(),$sformatf("hilbert_in[%0d+%0d*`NUM_WAY] = %h,nco_cos[%0d] = %h",j,k,hilbert_in[j+k*`NUM_WAY],j,nco_cos[j]),UVM_LOW);
// `uvm_info(get_type_name(),$sformatf("hilbert_out[%0d+%0d*`NUM_WAY] = %h,nco_sin[%0d] = %h",j,k,hilbert_out[j+k*`NUM_WAY],j,nco_sin[j]),UVM_LOW);
// `uvm_info(get_type_name(),$sformatf("i_mult_cos = %h,q_mult_sin = %h",i_mult_cos,q_mult_sin),UVM_LOW);
`uvm_info(get_type_name(),$sformatf("iq_mod_data_i_temp = %h,iq_mod_data_i[%0h] = %h",iq_mod_data_i_temp,j,iq_mod_data_i[j]),UVM_LOW);
end
//mod_q
for(j = 0; j<`NUM_WAY; j++)begin
i_mult_sin = hilbert_in[j+k*`NUM_WAY]*nco_sin[j];
q_mult_cos = hilbert_out[j+k*`NUM_WAY]*nco_cos[j];
iq_mod_data_q_temp = q_mult_cos + i_mult_sin;
if(iq_mod_data_q_temp[31] == 1)begin
if(iq_mod_data_q_temp[15:0] == 0)begin
iq_mod_data_q[j] = $floor(iq_mod_data_q_temp/32768);
end else begin
iq_mod_data_q[j] = $floor(iq_mod_data_q_temp/32768)- 1;
end
end
else begin
iq_mod_data_q[j] = $floor(iq_mod_data_q_temp/32768);
end
iq_mod_data_q_queue.push_back(iq_mod_data_q[j]);
// iq_mod_data_q[j] = {iq_mod_data_q_temp[31],iq_mod_data_q_temp[29:15]};
`uvm_info(get_type_name(),$sformatf("iq_mod_data_q_temp = %h,iq_mod_data_q[%0h] = %h",iq_mod_data_q_temp,j,iq_mod_data_q[j]),UVM_LOW);
end
end
//mux
case(mod_mode)
2'b00 : wave_mod_out = hilbert_in;
2'b01 : wave_mod_out = iq_mod_data_i_queue;
2'b10 : wave_mod_out = hilbert_out;
2'b11 : wave_mod_out = nco_cos_queue;
endcase
`uvm_info(get_type_name(),$sformatf("wave_mod_out = %p,wave_mod_out.size()=%0h",wave_mod_out,wave_mod_out.size()),UVM_LOW);
//wave_amp,mix
`uvm_info(get_type_name(),$sformatf("AMP = %0h",amplitude[31:16]),UVM_LOW);
for(k =0; k<env_len; k++)begin
for(j = 0; j<`NUM_WAY; j++)begin
wave_amp_out_temp = wave_mod_out[j+k*`NUM_WAY] * $signed(amplitude[31:16]);
wave_amp_out[j] = $rtoi(wave_amp_out_temp/16384);
`uvm_info(get_type_name(),$sformatf("wave_mod_out = %0h,wave_amp_out_temp=%0h,wave_amp_out[%0h] = %0h",wave_mod_out[j+k*`NUM_WAY],wave_amp_out_temp,j,wave_amp_out[j]),UVM_LOW);
wave_mix_out[j] = wave_amp_out[j]^{1'b1, {`DATA_WIDTH-1{1'b0}}};
if(mix_en)begin
wave_mix_outb[j] = ~wave_mix_out[j]+1'b1;
end else begin
wave_mix_outb[j] = wave_mix_out[j];
end
`uvm_info(get_type_name(),$sformatf("mix_en = %0h,wave_mix_out[%0h] = %0h,wave_mix_outb[%0h] = %0h",mix_en,j,wave_mix_out[j],j,wave_mix_outb[j]),UVM_LOW);
end
data_out_0.push_back(wave_mix_out[0]);
data_out_1.push_back(wave_mix_out[1]);
data_out_2.push_back(wave_mix_out[2]);
data_out_3.push_back(wave_mix_out[3]);
data_out_4.push_back(wave_mix_out[4]);
data_out_5.push_back(wave_mix_out[5]);
data_out_6.push_back(wave_mix_out[6]);
data_out_7.push_back(wave_mix_out[7]);
data_outb_0.push_back(wave_mix_outb[0]);
data_outb_1.push_back(wave_mix_outb[1]);
data_outb_2.push_back(wave_mix_outb[2]);
data_outb_3.push_back(wave_mix_outb[3]);
data_outb_4.push_back(wave_mix_outb[4]);
data_outb_5.push_back(wave_mix_outb[5]);
data_outb_6.push_back(wave_mix_outb[6]);
data_outb_7.push_back(wave_mix_outb[7]);
end
`uvm_info(get_type_name(),$sformatf("push_data_out_0.size() = %0h",data_out_0.size()),UVM_LOW);
cw_valid = 0;
nco_acc_out = 0;
nco_acc_in = 0;
hilbert_in.delete();
nco_cos_queue.delete();
nco_sin_queue.delete();
iq_mod_data_i_queue.delete();
iq_mod_data_q_queue.delete();
end
endtask
task readout_awg_rm::if_pump_mark();
//item
mcu_cw_item mcu_cw_item;
//pump and mark signal
bit [31:0] wait_cycle = 100;
bit [31:0] cnt;
bit pump_flag = 1'b1;
bit mark_flag = 1'b1;
bit [31:0] cw_data_if;
bit pump_trig ;
bit mark_trig ;
bit [3 :0] align_del;
bit [15:0] pump_delay;
bit [15:0] pump_width;
bit [15:0] mark_delay;
bit [15:0] mark_width;
wait(`SYNC_IN)
`uvm_info(get_type_name(),("if_pump_mark.sync_in "),UVM_LOW);
forever begin
//pump
@(posedge `CLK);
cnt++;
rm_if.cnt = cnt;
if(cw_queue.size()>0 && pump_flag == 1 && mark_flag == 1)begin
mcu_cw_item = cw_queue.pop_front();
wait_cycle = mcu_cw_item.clock_cycle;
cw_data_if = mcu_cw_item.cw_data;
pump_flag = 1'b0;
mark_flag = 1'b0;
pump_trig = cw_data_if[8];
mark_trig = cw_data_if[9];
`uvm_info(get_type_name(),$sformatf("pump_trig = %0h,mark_trig = %0h",pump_trig,mark_trig),UVM_LOW);
`uvm_info(get_type_name(),$sformatf("wait_cycle = %0h,cw_data_if= 0%h",wait_cycle,cw_data_if),UVM_LOW);
case (func_ctrl[1:0])
2'b00 : align_del = 4'h0;
2'b01 : align_del = 4'ha;
2'b10 : align_del = 4'h8;
2'b11 : align_del = 4'h8;
endcase
pump_delay = pump_ctrl[31:16] + align_del + 2; //compare to cw_valid
pump_width = pump_ctrl[15:0] + env_len;
`uvm_info(get_type_name(),$sformatf("pump_delay = %0h,pump_width = %0h,align_del = %0h",pump_delay,pump_width,align_del),UVM_LOW);
mark_delay = mark_ctrl[31:16] + 2; //compare to cw_valid
mark_width = mark_ctrl[15:0];
`uvm_info(get_type_name(),$sformatf("mark_delay = %0h,mark_width = %0h",mark_delay,mark_width),UVM_LOW);
end
fork
if(cnt == wait_cycle)begin
repeat(pump_delay)begin
rm_if.pump_rm = func_ctrl[4];
@(posedge `CLK);
end
repeat(pump_width)begin
if(pump_trig)begin
rm_if.pump_rm = ~func_ctrl[4];
@(posedge `CLK);
end
else begin
rm_if.pump_rm = func_ctrl[4];
@(posedge `CLK);
end
end
rm_if.pump_rm = 1'b0;
pump_flag = 1;
end
//mark
if(cnt == wait_cycle)begin
repeat(mark_delay)begin
rm_if.mark_rm = func_ctrl[5];
@(posedge `CLK);
end
repeat(mark_width)begin
if(mark_trig)begin
rm_if.mark_rm = ~func_ctrl[5];
@(posedge `CLK);
end
else begin
rm_if.mark_rm = func_ctrl[5];
@(posedge `CLK);
end
end
rm_if.mark_rm = 1'b0;
mark_flag = 1;
end
if(cnt == wait_cycle)begin
if(pump_delay + pump_width >= mark_delay + mark_width)begin
repeat(pump_delay + pump_width)begin
cnt++;
rm_if.cnt = cnt;
@(posedge `CLK);
end
end
else begin
repeat(mark_delay + mark_width)begin
cnt++;
rm_if.cnt = cnt;
@(posedge `CLK);
end
end
end
join
end
endtask
task readout_awg_rm::hilbert_fir(
input bit signed[15:0] hilbert_in[$],
input bit [15:0] data_size,
output bit signed[15:0] hilbert_out[$]
);
localparam COEFF_LEN = 33;
bit signed [15:0] coeff [0:COEFF_LEN-1] = {
16'd0, -16'd69, 16'd0, -16'd202, 16'd0, -16'd471,
16'd0, -16'd950, 16'd0, -16'd1766, 16'd0, -16'd3213,
16'd0, -16'd6337, 16'd0, -16'd20648, 16'd0, 16'd20648,
16'd0, 16'd6337, 16'd0, 16'd3213, 16'd0, 16'd1766,
16'd0, 16'd950, 16'd0, 16'd471, 16'd0, 16'd202,
16'd0, 16'd69, 16'd0
};
bit signed [31:0] acc ;
bit signed [31:0] mul;
//conv
`uvm_info(get_type_name(),$sformatf("hilbert_in_queue = %p",hilbert_in),UVM_LOW);
`uvm_info(get_type_name(),$sformatf("coeff = %p,data_size = %0d",coeff,data_size),UVM_LOW);
for (int i = 0; i < COEFF_LEN + data_size; i++) begin
for (int j = 0 ; j <= i; j++)begin
mul = coeff[i-j] * hilbert_in[j];
acc = acc + mul;
// `uvm_info(get_type_name(),$sformatf("coeff[%0d-%0d] = %0d ,hilbert_in[%0d] = %0d",i,j,coeff[i-j],j,hilbert_in[j]),UVM_LOW);
// `uvm_info(get_type_name(),$sformatf("mul = %0d, mul[31:16] = %0d,acc = %0d",mul,$signed(mul[31:16]),acc),UVM_LOW);
end
if(acc[31] == 1)begin
if(acc[15:0] == 0)begin
hilbert_out[i] = $floor(acc/32768);
end else begin
hilbert_out[i] = $floor(acc/32768)- 1;
end
end
else begin
hilbert_out[i] = $floor(acc/32768);
end
// hilbert_out[i] = $floor(acc/32768);
`uvm_info(get_type_name(),$sformatf("acc = %0d ,acc[31:16] = %0d,hilbert_out = %0d",acc,$floor(acc/32768),hilbert_out[i]),UVM_LOW);
acc = 32'b0;
end
`uvm_info(get_type_name(),$sformatf("hilbert_out = %p,hilbert_out.size() = %d",hilbert_out,hilbert_out.size()),UVM_LOW);
hilbert_out = hilbert_out[16:COEFF_LEN + data_size-18];
`uvm_info(get_type_name(),$sformatf("hilbert_out = %p,hilbert_out.size() = %d",hilbert_out,hilbert_out.size()),UVM_LOW);
endtask
task readout_awg_rm::run_phase(uvm_phase phase);
fork
get_mcu_cw_item();
get_spi_item();
get_config_data();
awg_exe();
if_pump_mark();
send_dac_item();
join
endtask
`endif