743 lines
24 KiB
Systemverilog
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
|