first
This commit is contained in:
commit
652b4c1d1a
|
@ -0,0 +1,446 @@
|
|||
//FILE_HEADER-------------------------------------------------------
|
||||
//FILE_NAME : readout_awg_rm.sv
|
||||
//DEPARTEMENT : QuantumCTek-ASIC
|
||||
//AUTHOR : Yunzhuo Zhang
|
||||
//TIME : 2024.10.21
|
||||
//*******************************************************************
|
||||
//DESCRIPTION : awg reference model define
|
||||
//*******************************************************************
|
||||
//END_HEADER*********************************************************
|
||||
|
||||
//问题待解决:数据类型定义
|
||||
//pulsewidth信号定义在mcu_reg中
|
||||
|
||||
|
||||
`ifdef READOUT_AWG_RM
|
||||
`define READOUT_AWG_RM
|
||||
|
||||
//import uvm_pkg::*;
|
||||
import nco_dpi_pkg::*;
|
||||
import hilbert_fir_dpi_pkg::*;
|
||||
|
||||
class readout_awg_rm extends uvm_component;
|
||||
virtual rm_if rm_if; //clk和sync
|
||||
|
||||
uvm_blocking_get_export #(EZQ_readout_dac_item) dac_rm2scb_port; //wave输出给scoreboard
|
||||
uvm_blocking_get_port #(mcu_item) mcu_get_port; //从mcu获取带时间戳的包,包含cw,time
|
||||
|
||||
EZQ_readout_dac_item dac_item_pkt;
|
||||
mcu_item mcu_item_pkt;
|
||||
|
||||
`uvm_component_utils(readout_awg_rm);
|
||||
|
||||
static int NUM_WAY = 8;
|
||||
static int DATA_WIDTH = 16;
|
||||
|
||||
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 wave_play( //根据cw获取波形数据
|
||||
logic [5:0] wave_id,
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_mem_out[$],
|
||||
logic [15:0] wave_len;
|
||||
|
||||
logic [15:0]time_in,
|
||||
logic [15:0]time_out
|
||||
);
|
||||
|
||||
extern task wave_mode( //awg算法
|
||||
logic clr_valid, //sync
|
||||
logic clr_en, //cw_data[6]
|
||||
logic [1 :0] mod_mode, //func_ctrl[1:0]
|
||||
logic [31:0] fcw,
|
||||
logic [15:0] phase, //phase[31:16]
|
||||
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_in,
|
||||
logic [DATA_WIDTH-1:0] wave_mod_out[NUM_WAY],
|
||||
|
||||
logic [15:0]time_in,
|
||||
logic [15:0]time_out
|
||||
);
|
||||
|
||||
extern task wave_amp(
|
||||
logic [15:0] amplitude, //amp[31:16]
|
||||
logic [DATA_WIDTH-1:0] wave_amp_in[NUM_WAY],
|
||||
logic [DATA_WIDTH-1:0] wave_amp_out[NUM_WAY],
|
||||
logic [15:0]time_in,
|
||||
logic [15:0]time_out
|
||||
);
|
||||
|
||||
extern task wave_mix(
|
||||
logic mix_en , //~func_ctrl[2]
|
||||
logic [DATA_WIDTH-1:0] wave_in[NUM_WAY],
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_mix_out,
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_mix_outb,
|
||||
logic [15:0]time_in,
|
||||
logic [15:0]time_out
|
||||
);
|
||||
/*
|
||||
extern task pulse_generator_pump(
|
||||
logic pulse_en ,
|
||||
logic [15:0] delay,
|
||||
logic [31:0] width,
|
||||
logic inv_en ,
|
||||
logic [15:0] pulse
|
||||
);
|
||||
*/
|
||||
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::run_phase(uvm_phase phase);//main task
|
||||
//cw
|
||||
logic clk;
|
||||
logic [31:0] cw_data;
|
||||
logic sync;
|
||||
//awg config signal
|
||||
logic [31:0] mcu_timer,
|
||||
logic [31:0] mcu_counter,
|
||||
logic [31:0] pulse_width,
|
||||
|
||||
logic [31:0] amplitude,
|
||||
logic [31:0] frequency,
|
||||
logic [31:0] phase,
|
||||
|
||||
logic [31:0] loc_state,
|
||||
logic [31:0] glb_state,
|
||||
logic [31:0] feed_data,
|
||||
//control signal
|
||||
logic [31:0] command;
|
||||
logic [31:0] func_ctrl;
|
||||
logic [31:0] pump_ctrl;
|
||||
logic [31:0] mark_ctrl;
|
||||
//get wave_idx & wave
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_mem_out[$];
|
||||
//wave_mod output signal
|
||||
logic [DATA_WIDTH-1:0] wave_mod_out[NUM_WAY];
|
||||
//wave_amp output siganl
|
||||
logic [DATA_WIDTH-1:0] wave_amp_out[NUM_WAY];
|
||||
//wave_mix output siganl
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_mix_out;
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_mix_outb;
|
||||
//wave_out queue
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_out_list[$];
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_outb_list[$];
|
||||
//Pump & Mark signal
|
||||
logic pump_trig;
|
||||
logic mark_trig;
|
||||
logic pump_delay;
|
||||
logic mark_delay;
|
||||
logic [15:0] pump_width;
|
||||
logic [15:0] mark_width;
|
||||
//时间戳,mcu_item_pkt到来时,继承pkt中的时间
|
||||
logic [15:0] time_cw;
|
||||
logic [15:0] time_play;
|
||||
logic [15:0] time_mode;
|
||||
logic [15:0] time_amp;
|
||||
logic [15:0] time_mix;
|
||||
|
||||
// sync signal
|
||||
sync = rm_if.sync;
|
||||
|
||||
//MCU packet
|
||||
mcu_get_port.get(mcu_item_pkt);
|
||||
time_cw = mcu_item_pkt.clock_cycle;
|
||||
cw_data = mcu_item_pkt.cw_data;
|
||||
pulse_width = mcu_item_pkt.pulse_width;//该信号通过MCU的packet传送
|
||||
|
||||
//AWG reg
|
||||
frequency = reg_mems::awg_regfile.get("Frequency");
|
||||
phase = reg_mems::awg_regfile.get("Phase");
|
||||
amplitude = reg_mems::awg_regfile.get("Amplitude");
|
||||
|
||||
mcu_timer = reg_mems::awg_regfile.get("Timer");
|
||||
mcu_counter = reg_mems::awg_regfile.get("Counter");
|
||||
|
||||
loc_state = reg_mems::awg_regfile.get("LOC_State");
|
||||
glb_state = reg_mems::awg_regfile.get("GLB_State");
|
||||
feed_data = reg_mems::awg_regfile.get("FEED_Data");
|
||||
|
||||
func_ctrl = reg_mems::awg_regfile.get("Function");
|
||||
command = reg_mems::awg_regfile.get("Command");
|
||||
pump_ctrl = reg_mems::awg_regfile.get("pump_ctrl");
|
||||
mark_ctrl = reg_mems::awg_regfile.get("maker_ctrl");
|
||||
|
||||
//AWG functions
|
||||
wave_play(
|
||||
.wave_id(cw_data[5:0]),
|
||||
.wave_mem_out(wave_mem_out),
|
||||
.wave_len(wave_len)
|
||||
.time_in(time_cw),
|
||||
.time_out(time_play)
|
||||
);
|
||||
|
||||
for(k=0;k<wave_len;k++)begin
|
||||
wave_mode(
|
||||
.clr_valid(sync),
|
||||
.clr_en(cw_data[6]),
|
||||
.mod_mode(func_ctrl[1:0]),
|
||||
.fcw(frequency),
|
||||
.phase(phase[31:16]),
|
||||
.wave_in(wave_mem_out[k]),
|
||||
.wave_mod_out(wave_mod_out)
|
||||
.time_in(time_play),
|
||||
.time_out(time_mode)
|
||||
);
|
||||
|
||||
wave_amp(
|
||||
.amplitude(amplitude[31:16]), //amp[31:16]
|
||||
.wave_amp_in(wave_mod_out),
|
||||
.wave_amp_out(wave_amp_out),
|
||||
.time_in(time_mode),
|
||||
.time_out(time_amp)
|
||||
);
|
||||
|
||||
wave_mix(
|
||||
.mix_en(~func_ctrl[2]) , //~func_ctrl[2]
|
||||
.wave_in(wave_amp_out),
|
||||
.wave_mix_out(wave_mix_out),
|
||||
.wave_mix_outb(wave_mix_outb),
|
||||
.time_in(time_amp),
|
||||
.time_out(time_mix)
|
||||
);
|
||||
wave_out_list.push_back (wave_mix_out);
|
||||
wave_outb_list.push_back(wave_mix_outb);
|
||||
end
|
||||
//send to scoreboard
|
||||
dac_item_pkt.cycle = time_mix;
|
||||
|
||||
for (k=0;k<wave_len;k++)begin
|
||||
dac_item_pkt.data_out0[k] = wave_out_list[k][0*DATA_WIDTH:1*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_out1[k] = wave_out_list[k][1*DATA_WIDTH:2*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_out2[k] = wave_out_list[k][2*DATA_WIDTH:3*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_out3[k] = wave_out_list[k][3*DATA_WIDTH:4*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_out4[k] = wave_out_list[k][4*DATA_WIDTH:5*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_out5[k] = wave_out_list[k][5*DATA_WIDTH:6*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_out6[k] = wave_out_list[k][6*DATA_WIDTH:7*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_out7[k] = wave_out_list[k][7*DATA_WIDTH:8*DATA_WIDTH-1];
|
||||
|
||||
dac_item_pkt.data_outb0[k]= wave_outb_list[k][0*DATA_WIDTH:1*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_outb1[k]= wave_outb_list[k][1*DATA_WIDTH:2*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_outb2[k]= wave_outb_list[k][2*DATA_WIDTH:3*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_outb3[k]= wave_outb_list[k][3*DATA_WIDTH:4*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_outb4[k]= wave_outb_list[k][4*DATA_WIDTH:5*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_outb5[k]= wave_outb_list[k][5*DATA_WIDTH:6*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_outb6[k]= wave_outb_list[k][6*DATA_WIDTH:7*DATA_WIDTH-1];
|
||||
dac_item_pkt.data_outb7[k]= wave_outb_list[k][7*DATA_WIDTH:8*DATA_WIDTH-1];
|
||||
end
|
||||
|
||||
//pump and mark signal
|
||||
pump_trig = cw_data[8];
|
||||
mark_trig = cw_data[9];
|
||||
pump_delay = pump_ctrl[31:16];
|
||||
mark_delay = mark_ctrl[31:16];
|
||||
pump_width = func_ctrl[6] ? pulse_width[15:0] : pump_ctrl[15:0];
|
||||
mark_width = func_ctrl[7] ? pulse_width[31:16] : mark_ctrl[15:0];
|
||||
|
||||
//pump和mark信号的输出时间、输出宽度和输出极性
|
||||
if(pump_trig)begin
|
||||
rm_if.pump_width = pump_width;
|
||||
rm_if.pump_rm = ~func_ctrl[4];
|
||||
rm_if.pump_time = time_cw + pump_delay;
|
||||
end else begin
|
||||
rm_if.pump_width = 0;
|
||||
rm_if.pump_rm = func_ctrl[4];
|
||||
rm_if.pump_time = 0;
|
||||
end
|
||||
if(mark_trig)begin
|
||||
rm_if.mark_width = mark_width;
|
||||
rm_if.mark_rm = ~func_ctrl[5];
|
||||
rm_if.mark_time = time_cw + mark_delay;
|
||||
end else begin
|
||||
rm_if.mark_width = 0;
|
||||
rm_if.mark_rm = func_ctrl[5];
|
||||
rm_if.mark_time = 0;
|
||||
end
|
||||
endtask
|
||||
|
||||
task readout_awg_rm::wave_play(
|
||||
logic [5:0] wave_id,
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_mem_out[$],
|
||||
logic [15:0] wave_len;
|
||||
|
||||
logic [15:0]time_in,
|
||||
logic [15:0]time_out
|
||||
);
|
||||
logic [31:0] get_wave_idx_len;
|
||||
logic [15:0] wave_addr;
|
||||
logic [15:0] wave_len;
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0]wave_out[wave_len]; //wave_len个8*16bit数据
|
||||
|
||||
time_out = time_in + 16'd4;
|
||||
|
||||
reg_mems::env_indx_ram.get32bit({wave_id[5:0],2'b00},get_wave_idx_len); //获取wave地址和长度
|
||||
wave_addr = {get_wave_idx_len[31:16],4'b0};
|
||||
wave_len = get_wave_idx_len[15: 0];
|
||||
$display("wave_addr and wave_len is %b %d",wave_addr,wave_len);
|
||||
|
||||
reg_mems::env_data_ram.get32bit(wave_addr,wave_out); //获取wave波形数据
|
||||
|
||||
foreach (wave_out[i])begin
|
||||
wave_mem_out.push_back(wave_out[i]);
|
||||
$display("wave %d is %b ",i,wave_out[i]);
|
||||
end
|
||||
endtask
|
||||
|
||||
task readout_awg_rm::wave_mode(
|
||||
logic clr_valid, //sync
|
||||
logic clr_en, //cw_data[6]
|
||||
logic [1 :0] mod_mode, //func_ctrl[1:0]
|
||||
logic [31:0] fcw,
|
||||
logic [15:0] phase, //phase[31:16]
|
||||
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_in,
|
||||
logic [DATA_WIDTH-1:0] wave_mod_out[NUM_WAY],
|
||||
|
||||
logic [15:0]time_in,
|
||||
logic [15:0]time_out
|
||||
);
|
||||
//hilbert signal
|
||||
logic hilbert_en;
|
||||
logic [DATA_WIDTH-1:0] hilbert_in[NUM_WAY];
|
||||
real dpi_hilbert_out_i[NUM_WAY];
|
||||
real dpi_hilbert_out_q[NUM_WAY];
|
||||
logic [DATA_WIDTH-1:0] hilbert_out_i[NUM_WAY];
|
||||
logic [DATA_WIDTH-1:0] hilbert_out_q[NUM_WAY];
|
||||
//nco signal
|
||||
logic loc_rst_n;
|
||||
logic clr_en;
|
||||
logic [63:0] result_cos;
|
||||
logic [63:0] result_sin;
|
||||
logic [63:0] result_acc;
|
||||
logic [15:0] cos_list[$];
|
||||
logic [15:0] sin_list[$];
|
||||
//mod signal
|
||||
logic iq_mod_en;
|
||||
logic [DATA_WIDTH*2-1:0] iq_mod_data_i_temp;
|
||||
logic [DATA_WIDTH-1:0] iq_mod_data_i[NUM_WAY];
|
||||
// logic [DATA_WIDTH-1:0] iq_mod_data_q[NUM_WAY];
|
||||
|
||||
//inter signal
|
||||
loc_rst_n = ((mod_mode[1:0] == 2'b01) | (mod_mode[1:0] == 2'b11));
|
||||
hilbert_en = (mod_mode[1:0] == 2'b01) | (mod_mode[1:0] == 2'b10);
|
||||
iq_mod_en = (mod_mode[1:0] == 2'b01);
|
||||
|
||||
//time_delay
|
||||
if (mod_mode[1:0] == 2'b11) //nco out
|
||||
time_out = time_in + 16'd8 + 16'd1;
|
||||
else begin
|
||||
if(hilbert_en & iq_mod_en) //iq_mod out
|
||||
time_out = time_in + 16'd8 + 16'd2 + 16'd1;
|
||||
else if(hilbert_en & !iq_mod_en) //hilbert out
|
||||
time_out = time_in + 16'd8 + 16'd1;
|
||||
else (!hilbert_en)//wave_mem out
|
||||
time_out = time_in + 16'd1;
|
||||
end
|
||||
//NCO dpi
|
||||
objhandle=DPI_nco_initialize(objhandle);
|
||||
for (k=0;k<NUM_WAY-1;k++)begin
|
||||
//DPI_nco_terminate(objhandle);
|
||||
DPI_nco(objhandle,real(fcw),real(phase),real(clr_en),real(k*fcw),result_cos,result_sin,result_acc);
|
||||
cos_list.push_back(shortint(result_cos));
|
||||
sin_list.push_back(shortint(result_sin));
|
||||
end
|
||||
|
||||
//hilbert dpi
|
||||
for(k=0;k<NUM_WAY;k++)begin
|
||||
hilbert_in[k] = wave_in[k*DATA_WIDTH:(k+1)*DATA_WIDTH-1]; //将128bit数据拆分为16bit*8
|
||||
end
|
||||
OBJhandle=DPI_hilbert_fir_initialize(OBJhandle);
|
||||
//DPI_hilbert_fir_terminate(OBJhandle);
|
||||
DPI_hilbert_fir(OBJhandle,real(hilbert_in),dpi_hilbert_out_i,dpi_hilbert_out_q);//输入输出均为数组
|
||||
hilbert_out_i = shortint(dpi_hilbert_out_i);
|
||||
hilbert_out_q = shortint(dpi_hilbert_out_q);
|
||||
|
||||
foreach (hilbert_out_i[index])
|
||||
$display("hilbert_out_i is :%b",hilbert_out_i[index]);
|
||||
foreach (hilbert_out_q[index])
|
||||
$display("hilbert_out_q is :%b",hilbert_out_q[index]);
|
||||
//mod
|
||||
for(k=0;k<NUM_WAY;k++)begin
|
||||
iq_mod_data_i_temp = hilbert_out_i[k]*cos_list[k]-hilbert_out_q[k]*sin_list[k];
|
||||
iq_mod_data_i[k] = {iq_mod_data_i_temp[31],iq_mod_data_i_temp[29:15]};
|
||||
if(iq_mod_data_i[k]>32767) iq_mod_data_i[k] = 32767;
|
||||
if(iq_mod_data_i[k]<-32767) iq_mod_data_i[k] = -32767;
|
||||
end
|
||||
|
||||
for(k=0;k<NUM_WAY;k++)begin
|
||||
iq_mod_data_q_temp = hilbert_out_q[k]*cos_list[k]+hilbert_out_i[k]*sin_list[k];
|
||||
iq_mod_data_q[k] = {iq_mod_data_q_temp[31],iq_mod_data_q_temp[29:15]};
|
||||
if(iq_mod_data_q[k]>32767) iq_mod_data_q[k] = 32767;
|
||||
if(iq_mod_data_q[k]<-32767) iq_mod_data_q[k] = -32767;
|
||||
end
|
||||
|
||||
foreach (iq_mod_data_i[index])
|
||||
$display("iq_mod_data_i is :%b",iq_mod_data_i[index]);
|
||||
//mux
|
||||
case(mod_mode)
|
||||
2'b00 : wave_mod_out = hilbert_in;
|
||||
2'b01 : wave_mod_out = iq_mod_data_i;
|
||||
2'b10 : wave_mod_out = hilbert_out_q;
|
||||
2'b11 : wave_mod_out = cos_list;
|
||||
endcase
|
||||
|
||||
task readout_awg_rm::wave_amp(
|
||||
logic [15:0] amplitude, //amp[31:16]
|
||||
logic [DATA_WIDTH-1:0] wave_amp_in[NUM_WAY],
|
||||
logic [DATA_WIDTH-1:0] wave_amp_out[NUM_WAY],
|
||||
logic [15:0]time_in,
|
||||
logic [15:0]time_out
|
||||
);
|
||||
time_out = time_in +16'd1;
|
||||
|
||||
logic [DATA_WIDTH*2-1:0]wave_amp_out_temp;
|
||||
for(k=0;k<NUM_WAY-1;k++)begin
|
||||
wave_amp_out_temp = wave_amp_in[k] * amplitude;
|
||||
wave_amp_out[k] = {wave_amp_out_temp[31],wave_amp_out_temp[29:15]};
|
||||
if(wave_amp_out[k]>32767) wave_amp_out[k] = 32767;
|
||||
if(wave_amp_out[k]<-32767) wave_amp_out[k] = -32767;
|
||||
end
|
||||
endtask
|
||||
|
||||
task wave_mix(
|
||||
logic mix_en , //~func_ctrl[2]
|
||||
logic [DATA_WIDTH-1:0] wave_in[NUM_WAY],
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_mix_out,
|
||||
logic [DATA_WIDTH*NUM_WAY-1:0] wave_mix_outb,
|
||||
logic [15:0]time_in,
|
||||
logic [15:0]time_out
|
||||
);
|
||||
if(mix_en)
|
||||
time_out = time_in +16'd1;
|
||||
else
|
||||
time_out = time_in;
|
||||
|
||||
for(k=0;k<NUM_WAY;k++)begin
|
||||
wave_mix_out[k*DATA_WIDTH:(k+1)*DATA_WIDTH-1] = wave_in[k]^{1'b1, {DATA_WIDTH-1{1'b0}}};//unsign to sign
|
||||
end
|
||||
|
||||
if(mix_en)
|
||||
for(k=0;k<NUM_WAY;k++)begin
|
||||
wave_mix_outb[k*DATA_WIDTH:(k+1)*DATA_WIDTH-1] = ~wave_mix_out[k*DATA_WIDTH:(k+1)*DATA_WIDTH-1]+1'b1;//unsign to sign
|
||||
end else
|
||||
for(k=0;k<NUM_WAY;k++)begin
|
||||
wave_mix_outb[k*DATA_WIDTH:(k+1)*DATA_WIDTH-1] = wave_mix_out[k*DATA_WIDTH:(k+1)*DATA_WIDTH-1];
|
||||
end
|
||||
|
||||
foreach (wave_mix_out[index])
|
||||
$display("wave_mix_out is :%b",wave_mix_out[index]);
|
||||
foreach (wave_mix_outb[index])
|
||||
$display("wave_mix_outb is :%b",wave_mix_outb[index]);
|
||||
|
||||
endtask
|
||||
|
||||
`endif
|
Loading…
Reference in New Issue