//FILE_HEADER-------------------------------------------------------
//FILE_NAME       : readout_daq_rm.sv
//DEPARTEMENT     : QuantumCTek-ASIC
//AUTHOR          : Yunzhuo Zhang
//TIME            : 2025.3.10
//*******************************************************************
//DESCRIPTION     : daq reference model define
//*******************************************************************
//END_HEADER*********************************************************



`ifdef  READOUT_DAQ_RM
`define READOUT_DAQ_RM

//import uvm_pkg::*;

class readout_daq_rm extends uvm_component;
	`uvm_component_utils(readout_daq_rm);
	virtual rm_if rm_if; 	//sync

	uvm_blocking_get_port 	#(EZQ_readout_adc_item)  adc_get_port;		//get adc wave
	uvm_blocking_get_port   #(mcu_cw_item)  mcu_get_port; 					 //从mcu获取带时间戳的包，包含cw，time

    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 daq_block(
		ref logic [31:0]i,
		ref logic [31:0]cw_data		    ,
		ref logic [31:0]func_ctrl		,
		ref logic [31:0]demod_freq		,
		ref logic [31:0]demod_width	    ,
		ref logic [31:0]para_ab0		,
		ref logic [31:0]para_ab1		,
		ref logic [31:0]para_ab2		,
		ref logic [31:0]para_c0		    ,
		ref logic [31:0]para_c0		    ,
		ref logic [31:0]para_c1		    ,
		ref logic [31:0]para_c2		    ,
		ref logic [1 :0]state_data		,
		ref logic [31:0]iq_save_en		,
		ref logic [31:0]i_sum			,
		ref logic [31:0]q_sum			,
		ref logic [31:0]count_save_en   ,
		ref logic [31:0]count_state_0   ,
		ref logic [31:0]count_state_1   ,
		ref logic [31:0]count_state_2   ,
		ref logic [31:0]count_state_3   						
	);
	extern task dds(
		ref	logic [9 :0]	address,
		ref	logic [7 :0]	dds_cos[NUM_WAY-1:0],
		ref	logic [7 :0]	dds_sin[NUM_WAY-1:0],		
	);
	
	extern task data2sram(
		ref logic [31:0] qubit_state	,			
		ref logic [31:0] state0_count	[15:0],
		ref logic [31:0] state1_count	[15:0],
		ref logic [31:0] state2_count	[15:0],
		ref logic [31:0] state3_count	[15:0],
		ref logic [31:0] i_sum			[15:0],
		ref logic [31:0] q_sum			[15:0]
	);
	
	static logic NUM_WAY 	= 8;
	static logic NUM_QUBIT 	= 16;	
endclass

function readout_daq_rm::new(string name,uvm_component parent);
	super.new(name,parent);
endfunction : new

function void readout_daq_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"});
	//create port
    mcu_get_port = new("mcu_get_port",this);
    adc_get_port = new("adc_get_port",this);
endfunction

task readout_daq_rm::run_phase(uvm_phase phase);//main task
//cw
	logic	     clk;
	logic [31:0] clock_cycle;//width?
	logic [31:0] cw_data;
	logic		 sync;
//DAQ reg
	logic [31:0] mcu_timer;
	logic [31:0] mcu_counter;
	logic [31:0] loc_state;
	logic [31:0] glb_state;
	logic [31:0] feed_data;	
	logic [31:0] send_data;	
	logic [31:0] sram_count;
	logic [31:0] push_count;
    logic [31:0] command;
    logic [31:0] func_ctrl;
	logic [31:0] sample_depth;
    logic [31:0] int_threshold,
    logic [31:0] qubit_state,
    logic [31:0] read_req_ctrl,

	logic [31:0] demod_width	[15:0];
	logic [31:0] demod_freq		[15:0];	
	logic [31:0] count_state_0	[15:0],
    logic [31:0] count_state_1	[15:0],
    logic [31:0] count_state_2	[15:0],
    logic [31:0] count_state_3	[15:0],
    logic [31:0] i_sum			[15:0],
    logic [31:0] q_sum			[15:0],
    logic [31:0] para_ab0		[15:0],
    logic [31:0] para_ab1		[15:0],
    logic [31:0] para_ab2		[15:0],
    logic [31:0] para_c0		[15:0],
    logic [31:0] para_c1		[15:0],
    logic [31:0] para_c2		[15:0],    
	
// sync signal
    wait (`SYNC_IN);
    `uvm_info(get_type_name(),"wait sync_in",UVM_LOW)
	sync		 = rm_if.sync;
//MCU packet : get cw_data & cycle
	mcu_get_port.get(mcu_cw_item);
	clock_cycle  = mcu_cw_item.clock_cycle;
	cw_data		 = mcu_cw_item.cw_data;

//get DAQ reg 
	mcu_timer    = reg_mems::daq_regfile.get("timer");
	mcu_counter  = reg_mems::daq_regfile.get("counter");
	loc_state    = reg_mems::daq_regfile.get("loc_state");
	glb_state    = reg_mems::daq_regfile.get("glb_state");
	feed_data    = reg_mems::daq_regfile.get("feed_data");
	send_data    = reg_mems::daq_regfile.get("send_data");	
	sram_count   = reg_mems::daq_regfile.get("sram_count");
	push_count   = reg_mems::daq_regfile.get("push_count");
	command		 = reg_mems::daq_regfile.get("Command");
	func_ctrl    = reg_mems::daq_regfile.get("function");
	sample_depth   	= reg_mems::daq_regfile.get("sample_depth");
	int_threshold  	= reg_mems::daq_regfile.get("int_threshold");
//	qubit_state	   	= reg_mems::daq_regfile.get("qubit_state");
	read_req_ctrl   = reg_mems::daq_regfile.get("read_req_ctrl");

    demod_freq[ 0]    = reg_mems::daq_regfile.get("demod_freq_0");
    demod_freq[ 1]    = reg_mems::daq_regfile.get("demod_freq_1");	
    demod_freq[ 2]    = reg_mems::daq_regfile.get("demod_freq_2");
    demod_freq[ 3]    = reg_mems::daq_regfile.get("demod_freq_3");	
    demod_freq[ 4]    = reg_mems::daq_regfile.get("demod_freq_4");
    demod_freq[ 5]    = reg_mems::daq_regfile.get("demod_freq_5");	
    demod_freq[ 6]    = reg_mems::daq_regfile.get("demod_freq_6");
    demod_freq[ 7]    = reg_mems::daq_regfile.get("demod_freq_7");	
    demod_freq[ 8]    = reg_mems::daq_regfile.get("demod_freq_8");
    demod_freq[ 9]    = reg_mems::daq_regfile.get("demod_freq_9");	
    demod_freq[10]    = reg_mems::daq_regfile.get("demod_freq_10");
    demod_freq[11]    = reg_mems::daq_regfile.get("demod_freq_11");	
    demod_freq[12]    = reg_mems::daq_regfile.get("demod_freq_12");
    demod_freq[13]    = reg_mems::daq_regfile.get("demod_freq_13");	
    demod_freq[14]    = reg_mems::daq_regfile.get("demod_freq_14");
    demod_freq[15]    = reg_mems::daq_regfile.get("demod_freq_15");		
	
	demod_width[ 0]    = reg_mems::daq_regfile.get("demod_width_0");
    demod_width[ 1]    = reg_mems::daq_regfile.get("demod_width_1");	
    demod_width[ 2]    = reg_mems::daq_regfile.get("demod_width_2");
    demod_width[ 3]    = reg_mems::daq_regfile.get("demod_width_3");	
    demod_width[ 4]    = reg_mems::daq_regfile.get("demod_width_4");
    demod_width[ 5]    = reg_mems::daq_regfile.get("demod_width_5");	
    demod_width[ 6]    = reg_mems::daq_regfile.get("demod_width_6");
    demod_width[ 7]    = reg_mems::daq_regfile.get("demod_width_7");	
    demod_width[ 8]    = reg_mems::daq_regfile.get("demod_width_8");
    demod_width[ 9]    = reg_mems::daq_regfile.get("demod_width_9");	
    demod_width[10]    = reg_mems::daq_regfile.get("demod_width_10");
    demod_width[11]    = reg_mems::daq_regfile.get("demod_width_11");	
    demod_width[12]    = reg_mems::daq_regfile.get("demod_width_12");
    demod_width[13]    = reg_mems::daq_regfile.get("demod_width_13");	
    demod_width[14]    = reg_mems::daq_regfile.get("demod_width_14");
    demod_width[15]    = reg_mems::daq_regfile.get("demod_width_15");		
	
	para_ab0[ 0]    = reg_mems::daq_regfile.get("Q0_state_est_ab_0");
    para_ab0[ 1]    = reg_mems::daq_regfile.get("Q0_state_est_ab_1");	
    para_ab0[ 2]    = reg_mems::daq_regfile.get("Q0_state_est_ab_2");
    para_ab0[ 3]    = reg_mems::daq_regfile.get("Q0_state_est_ab_3");	
    para_ab0[ 4]    = reg_mems::daq_regfile.get("Q0_state_est_ab_4");
    para_ab0[ 5]    = reg_mems::daq_regfile.get("Q0_state_est_ab_5");	
    para_ab0[ 6]    = reg_mems::daq_regfile.get("Q0_state_est_ab_6");
    para_ab0[ 7]    = reg_mems::daq_regfile.get("Q0_state_est_ab_7");	
    para_ab0[ 8]    = reg_mems::daq_regfile.get("Q0_state_est_ab_8");
    para_ab0[ 9]    = reg_mems::daq_regfile.get("Q0_state_est_ab_9");	
    para_ab0[10]    = reg_mems::daq_regfile.get("Q0_state_est_ab_10");
    para_ab0[11]    = reg_mems::daq_regfile.get("Q0_state_est_ab_11");	
    para_ab0[12]    = reg_mems::daq_regfile.get("Q0_state_est_ab_12");
    para_ab0[13]    = reg_mems::daq_regfile.get("Q0_state_est_ab_13");	
    para_ab0[14]    = reg_mems::daq_regfile.get("Q0_state_est_ab_14");
    para_ab0[15]    = reg_mems::daq_regfile.get("Q0_state_est_ab_15");
	
	para_ab1[ 0]    = reg_mems::daq_regfile.get("Q1_state_est_ab_0");
    para_ab1[ 1]    = reg_mems::daq_regfile.get("Q1_state_est_ab_1");	
    para_ab1[ 2]    = reg_mems::daq_regfile.get("Q1_state_est_ab_2");
    para_ab1[ 3]    = reg_mems::daq_regfile.get("Q1_state_est_ab_3");	
    para_ab1[ 4]    = reg_mems::daq_regfile.get("Q1_state_est_ab_4");
    para_ab1[ 5]    = reg_mems::daq_regfile.get("Q1_state_est_ab_5");	
    para_ab1[ 6]    = reg_mems::daq_regfile.get("Q1_state_est_ab_6");
    para_ab1[ 7]    = reg_mems::daq_regfile.get("Q1_state_est_ab_7");	
    para_ab1[ 8]    = reg_mems::daq_regfile.get("Q1_state_est_ab_8");
    para_ab1[ 9]    = reg_mems::daq_regfile.get("Q1_state_est_ab_9");	
    para_ab1[10]    = reg_mems::daq_regfile.get("Q1_state_est_ab_10");
    para_ab1[11]    = reg_mems::daq_regfile.get("Q1_state_est_ab_11");	
    para_ab1[12]    = reg_mems::daq_regfile.get("Q1_state_est_ab_12");
    para_ab1[13]    = reg_mems::daq_regfile.get("Q1_state_est_ab_13");	
    para_ab1[14]    = reg_mems::daq_regfile.get("Q1_state_est_ab_14");
    para_ab1[15]    = reg_mems::daq_regfile.get("Q1_state_est_ab_15");	

	para_ab2[ 0]    = reg_mems::daq_regfile.get("Q2_state_est_ab_0");
    para_ab2[ 1]    = reg_mems::daq_regfile.get("Q2_state_est_ab_1");	
    para_ab2[ 2]    = reg_mems::daq_regfile.get("Q2_state_est_ab_2");
    para_ab2[ 3]    = reg_mems::daq_regfile.get("Q2_state_est_ab_3");	
    para_ab2[ 4]    = reg_mems::daq_regfile.get("Q2_state_est_ab_4");
    para_ab2[ 5]    = reg_mems::daq_regfile.get("Q2_state_est_ab_5");	
    para_ab2[ 6]    = reg_mems::daq_regfile.get("Q2_state_est_ab_6");
    para_ab2[ 7]    = reg_mems::daq_regfile.get("Q2_state_est_ab_7");	
    para_ab2[ 8]    = reg_mems::daq_regfile.get("Q2_state_est_ab_8");
    para_ab2[ 9]    = reg_mems::daq_regfile.get("Q2_state_est_ab_9");	
    para_ab2[10]    = reg_mems::daq_regfile.get("Q2_state_est_ab_10");
    para_ab2[11]    = reg_mems::daq_regfile.get("Q2_state_est_ab_11");	
    para_ab2[12]    = reg_mems::daq_regfile.get("Q2_state_est_ab_12");
    para_ab2[13]    = reg_mems::daq_regfile.get("Q2_state_est_ab_13");	
    para_ab2[14]    = reg_mems::daq_regfile.get("Q2_state_est_ab_14");
    para_ab2[15]    = reg_mems::daq_regfile.get("Q2_state_est_ab_15");	
	
	para_c0[ 0]    = reg_mems::daq_regfile.get("Q0_state_est_c_0");
    para_c0[ 1]    = reg_mems::daq_regfile.get("Q0_state_est_c_1");	
    para_c0[ 2]    = reg_mems::daq_regfile.get("Q0_state_est_c_2");
    para_c0[ 3]    = reg_mems::daq_regfile.get("Q0_state_est_c_3");	
    para_c0[ 4]    = reg_mems::daq_regfile.get("Q0_state_est_c_4");
    para_c0[ 5]    = reg_mems::daq_regfile.get("Q0_state_est_c_5");	
    para_c0[ 6]    = reg_mems::daq_regfile.get("Q0_state_est_c_6");
    para_c0[ 7]    = reg_mems::daq_regfile.get("Q0_state_est_c_7");	
    para_c0[ 8]    = reg_mems::daq_regfile.get("Q0_state_est_c_8");
    para_c0[ 9]    = reg_mems::daq_regfile.get("Q0_state_est_c_9");	
    para_c0[10]    = reg_mems::daq_regfile.get("Q0_state_est_c_10");
    para_c0[11]    = reg_mems::daq_regfile.get("Q0_state_est_c_11");	
    para_c0[12]    = reg_mems::daq_regfile.get("Q0_state_est_c_12");
    para_c0[13]    = reg_mems::daq_regfile.get("Q0_state_est_c_13");	
    para_c0[14]    = reg_mems::daq_regfile.get("Q0_state_est_c_14");
    para_c0[15]    = reg_mems::daq_regfile.get("Q0_state_est_c_15");
	
	para_c1[ 0]    = reg_mems::daq_regfile.get("Q1_state_est_c_0");
    para_c1[ 1]    = reg_mems::daq_regfile.get("Q1_state_est_c_1");	
    para_c1[ 2]    = reg_mems::daq_regfile.get("Q1_state_est_c_2");
    para_c1[ 3]    = reg_mems::daq_regfile.get("Q1_state_est_c_3");	
    para_c1[ 4]    = reg_mems::daq_regfile.get("Q1_state_est_c_4");
    para_c1[ 5]    = reg_mems::daq_regfile.get("Q1_state_est_c_5");	
    para_c1[ 6]    = reg_mems::daq_regfile.get("Q1_state_est_c_6");
    para_c1[ 7]    = reg_mems::daq_regfile.get("Q1_state_est_c_7");	
    para_c1[ 8]    = reg_mems::daq_regfile.get("Q1_state_est_c_8");
    para_c1[ 9]    = reg_mems::daq_regfile.get("Q1_state_est_c_9");	
    para_c1[10]    = reg_mems::daq_regfile.get("Q1_state_est_c_10");
    para_c1[11]    = reg_mems::daq_regfile.get("Q1_state_est_c_11");	
    para_c1[12]    = reg_mems::daq_regfile.get("Q1_state_est_c_12");
    para_c1[13]    = reg_mems::daq_regfile.get("Q1_state_est_c_13");	
    para_c1[14]    = reg_mems::daq_regfile.get("Q1_state_est_c_14");
    para_c1[15]    = reg_mems::daq_regfile.get("Q1_state_est_c_15");	

	para_c2[ 0]    = reg_mems::daq_regfile.get("Q2_state_est_c_0");
    para_c2[ 1]    = reg_mems::daq_regfile.get("Q2_state_est_c_1");	
    para_c2[ 2]    = reg_mems::daq_regfile.get("Q2_state_est_c_2");
    para_c2[ 3]    = reg_mems::daq_regfile.get("Q2_state_est_c_3");	
    para_c2[ 4]    = reg_mems::daq_regfile.get("Q2_state_est_c_4");
    para_c2[ 5]    = reg_mems::daq_regfile.get("Q2_state_est_c_5");	
    para_c2[ 6]    = reg_mems::daq_regfile.get("Q2_state_est_c_6");
    para_c2[ 7]    = reg_mems::daq_regfile.get("Q2_state_est_c_7");	
    para_c2[ 8]    = reg_mems::daq_regfile.get("Q2_state_est_c_8");
    para_c2[ 9]    = reg_mems::daq_regfile.get("Q2_state_est_c_9");	
    para_c2[10]    = reg_mems::daq_regfile.get("Q2_state_est_c_10");
    para_c2[11]    = reg_mems::daq_regfile.get("Q2_state_est_c_11");	
    para_c2[12]    = reg_mems::daq_regfile.get("Q2_state_est_c_12");
    para_c2[13]    = reg_mems::daq_regfile.get("Q2_state_est_c_13");	
    para_c2[14]    = reg_mems::daq_regfile.get("Q2_state_est_c_14");
    para_c2[15]    = reg_mems::daq_regfile.get("Q2_state_est_c_15");	
////////////////////////////////////////////////////////////////////	
//DAQ functions
////////////////////////////////////////////////////////////////////
	for(i = 0; i < NUM_QUBIT; i++)begin
		fork
			task daq_block(
				//in
				.i				(i			),
				.cw_data		(cw_data	),				
				.func_ctrl		(func_ctrl	),
				.demod_freq		(demod_freq[i]),
				.demod_width	(demod_width[i]),
				.para_ab0		(para_ab0[i]),
				.para_ab1		(para_ab1[i]),
				.para_ab2		(para_ab2[i]),
				.para_c0		(para_c0[i]),
				.para_c0		(para_c0[i]),
				.para_c1		(para_c1[i]),
				.para_c2		(para_c2[i]),
				//out
				.state_data		(state_data[i]),
				.iq_save_en		(iq_save_valid[i]),
				.i_sum			(i_sum[i]	),
				.q_sum			(q_sum[i]	),
				.count_save_en  (count_save_valid[i]),
				.count_state_0	(count_state_0[i]),
				.count_state_1	(count_state_1[i]),
				.count_state_2	(count_state_2[i]),
				.count_state_3	(count_state_3[i]),
		join
			qubit_state[i*2+: 2] = state_data[i];
	end
	
	task	data2sram(
		.qubit_total	 (qubit_total 	   ),
		.count_state_0	 (count_state_0	   ),
		.count_state_1	 (count_state_1	   ),
		.count_state_2	 (count_state_2	   ),
		.count_state_3	 (count_state_3	   ),
		.i_sum			 (i_sum			   ),
		.q_sum			 (q_sum			   )
	);	
endtask
	


task readout_daq_rm::daq_block(
	logic [31:0]i				,
	logic [31:0]cw_data		    ,
	logic [31:0]func_ctrl		,
	logic [31:0]demod_freq		,
	logic [31:0]demod_width	    ,
	logic [31:0]para_ab0		,
	logic [31:0]para_ab1		,
	logic [31:0]para_ab2		,
	logic [31:0]para_c0		    ,
	logic [31:0]para_c0		    ,
	logic [31:0]para_c1		    ,
	logic [31:0]para_c2		    ,
	logic [1 :0]state_data		,
	logic [31:0]iq_save_en		,
	logic [31:0]i_sum			,
	logic [31:0]q_sum			,
	logic [31:0]count_save_en   ,
	logic [31:0]count_state_0   ,
	logic [31:0]count_state_1   ,
	logic [31:0]count_state_2   ,
	logic [31:0]count_state_3   
	
);
	//问题：1.iq_weight存放的格式，代码与设计书不吻合；iq两路的解模数据存放在两个不同的ram里，同一个地址给到两个ram，拼接成64bit数据。
	//		2.16个qubit的解模数据的读取起始地址是相同的吗？
	//		3.pulse_generator的作用？
	//		4. daq_reg已经有iq_sum,count_state等信息，还要往sram里写吗？
	//		5. 主动数据推送是一个什么样的流程？
	//		6.解模宽度demod_width和采样深度sample_width相同？
	//		7.代码里sub_cnt没有定义位宽
	// codeword
		logic	 demod_valid	= cw_data[16+i];
        logic    iq_sum_en		= cw_data[4] 					;
        logic    count_add_en	= cw_data[5] 					;
        logic    loc_fb_en     	= cw_data[6] & !cw_data[3]) ;
        logic    glb_fb_en     	= cw_data[7] & !cw_data[3]) ;
        logic    iq_clr_en     	= cw_data[8] 					;
        logic    count_clr_en	= cw_data[9] 					;
        logic    iq_save_en		= cw_data[2:0]==3'b101) | cw_data[13]) ;
        logic    state_save_en	= cw_data[2:0]==3'b110) | cw_data[14]) ;
        logic    count_save_en	= cw_data[2:0]==3'b111) | cw_data[15]) ;
	// mtf_gen signal
		logic [7 :0] dds_cos[NUM_WAY-1 :0];
		logic [7 :0] dds_sin[NUM_WAY-1 :0];
		logic [2 :0] step_ctrl;
		logic 		 const_en;
		logic [7 :0] weight_iq;		
		logic [24:0] read_addr;
		logic [31:0] match_filter_i;
		logic [31:0] match_filter_q;	
		logic [15:0] mtf_i_temp[NUM_WAY-1:0];;
		logic [15:0] mtf_q_temp[NUM_WAY-1:0];;	
		logic [7 :0] mtf_i[NUM_WAY-1:0];;
		logic [7 :0] mtf_q[NUM_WAY-1:0];;		
	//demod_algorithm signal	
		logic [15:0] demod_i;
		logic [15:0] demod_q;	
		logic [15:0] demod_i_sum;
		logic [15:0] demod_q_sum;
		logic		 iq_valid;	
	//iq_sum signal
		logic [15:0] scale_data_i;
		logic [15:0] scale_data_q;	
		logic [15:0] i_sum;
		logic [15:0] q_sum;	
	//state_estimate		
		logic [1 :0] state_data;
		logic [31:0] count_state_0;
		logic [31:0] count_state_1;
		logic [31:0] count_state_2;
		logic [31:0] count_state_3;		
		
	//循环次数		
		for(k = 0; k < demod_width ; k++)begin
	//mtf_gen
		//dds 每个循环出8路
			logic [19:0]	fcw		= demod_freq[31:12];
			logic [19:0]	fcw_buf = {demod_freq[31:12],3'b0};
			logic [19:0]	pcw_buf 	[NUM_WAY-1 :0];	
			logic [19:0] 	accumulator	[NUM_WAY-1 :0];	
		
			for(j = 0; j < NUM_WAY; j++)begin
				pcw_buf[j] 		= {demod_freq[11:0],8'b0} + fcw*(j+1);
				accumulator[j] 	= accumulator[j] + fcw_buf ;
				address[j]		= {accumulator[j]+pcw_buf[j]}[19:10];
				dds(address[j],dds_cos[j][k],dds_sin[j][k]);
			end

		//step_ctrl，解模算法步长，用于控制每个权重采样点持续时钟周期
		//0: 1个时钟周期
		//1: 2个时钟周期
		//2: 4个时钟周期
		//3: 8个时钟周期
		//4: 16个时钟周期
			step_ctrl = func_ctrl[6:4];
			const_en  = func_ctrl[7];
			weight_iq = func_ctrl[15:8];
			if(const_en)begin
				i_mult = weight_iq;
				q_mult = weight_iq;
			end else begin
				case(step_ctrl)
				3'b000	:	read_addr = read_addr + 16;
				3'b001	:	read_addr = read_addr + 8;
				3'b010	:	read_addr = read_addr + 4;
				3'b011	:	read_addr = read_addr + 2;
				3'b100	:	read_addr = read_addr + 1;
				defalut :	read_addr = read_addr ;
				
				reg_mems::match_filter.get32bit({read_addr[12:6],2'b0}, match_filter_i);
				reg_mems::match_filter.get32bit({read_addr[12:6],2'b0}, match_filter_q);
				
				byte_sel = read_addr[5:4];
				i_mult = match_filter_i[byte_sel*8+:8];
				q_mult = match_filter_q[byte_sel*8+:8];
			end

			for(j = 0; j < NUM_WAY; j++)begin
				mtf_i_temp[j][k] 	= i_mult*dds_cos[j][k];
				mtf_q_temp[j][k] 	= q_mult*dds_sin[j][k];//i和q的地址相差多少
				mtf_i[j][k] 		= {mtf_i_temp[15][k],mtf_i_temp[14:7][k]}+mtf_i_temp[6][k];
				mtf_q[j][k] 		= {mtf_q_temp[15][k],mtf_q_temp[14:7][k]}+mtf_q_temp[6][k];;			
			end	
	
	//demod_algorithm
			adc_wave = EZQ_readout_adc_item.adc_wave;
			for(j = 0; j < NUM_WAY; j++)begin
				demod_i[j][k] 	= adc_wave[j*8:j*8+7]*mtf_i[j][k];
				demod_q[j][k] 	= adc_wave[j*8:j*8+7]*mtf_q[j][k];
				//第一次求和，滤掉除直流之外的频率，先对demod_width长的8路数据进行求和，再对8路进行求和
				demod_i_queue[j].push_back(demod_i[j][k]);	
				demod_q_queue[j].push_back(demod_q[j][k]);	
				
				demod_i_sum = demod_i_sum + demod_i[j][k];
				demod_q_sum = demod_q_sum + demod_q[j][k];
			end	
				//求和结束，valid拉高
				//if(k == demod_width-1) iq_valid = 1;
		end
	//iq_sum
			//第二次求和，对多次解模的结果求和
			//分动态范围
			scale_data_i = func_ctrl[3] ? demod_i_sum[31:12] : demod_i_sum[27:8];
			scale_data_q = func_ctrl[3] ? demod_q_sum[31:12] : demod_q_sum[27:8];	
			if(iq_sum_en) begin
				i_sum = i_sum + scale_data_i;
				q_sum = q_sum + scale_data_q;	
			end 
			else if(iq_clr_en)begin
				i_sum =	0;
				q_sum =	0;
			end
				
	//state_estimate
			para_a0 = para_ab0[15:0];		para_b0 = para_ab0[31:16];
			para_a1 = para_ab1[15:0];		para_b1 = para_ab1[31:16];	
			para_a2 = para_ab2[15:0];		para_b2 = para_ab2[31:16];
			if(iq_valid)begin
				compare[0] = para_a0*demod_i	+	para_b0*demod_q <= para_c0;
				compare[1] = para_a1*demod_i	+	para_b1*demod_q <= para_c1;
				compare[2] = para_a2*demod_i	+	para_b2*demod_q <= para_c2;
				
				if(compare[0][i] & (~compare[1][i])
					state_data = 2'b00;
				else if (compare[1][i] & (~compare[2][i])
					state_data = 2'b01;
				else if (compare[2][i] & (~compare[0][i])
					state_data = 2'b10;
				else 
					state_data = 2'b11;					
			end
			
	//state_statistics	
			if(count_clr_en)begin
                count_state_0 = 32'd0;
                count_state_1 = 32'd0;
                count_state_2 = 32'd0;
                count_state_3 = 32'd0;  
			end 
			else if(count_add_en)begin
				count_state_0 = (state_data == 2'b00)	? count_state_0 + 1 : count_state_0;
				count_state_1 = (state_data == 2'b01)	? count_state_1 + 1 : count_state_1;
				count_state_2 = (state_data == 2'b10)	? count_state_2 + 1 : count_state_2;
				count_state_3 = (state_data == 2'b11)	? count_state_3 + 1 : count_state_3;
			end
				
	end	
		
endtask
	
	
task readout_daq_rm::dds(
		logic [9 :0]	address,
		logic [7 :0]	dds_cos[NUM_WAY-1:0],
		logic [7 :0]	dds_sin[NUM_WAY-1:0],
		);
    // 系数表定义
    localparam [6:0] coefficients [0:255] = '{
        7'd0, 7'd1, 7'd2, 7'd2, 7'd3, 7'd4, 7'd5, 7'd5, 7'd6, 7'd7, 7'd8, 7'd9, 7'd9, 7'd10, 7'd11, 7'd12,
        7'd12, 7'd13, 7'd14, 7'd15, 7'd16, 7'd16, 7'd17, 7'd18, 7'd19, 7'd19, 7'd20, 7'd21, 7'd22, 7'd23, 7'd23,
        7'd24, 7'd25, 7'd26, 7'd26, 7'd27, 7'd28, 7'd29, 7'd29, 7'd30, 7'd31, 7'd32, 7'd32, 7'd33, 7'd34, 7'd35,
        7'd36, 7'd36, 7'd37, 7'd38, 7'd39, 7'd39, 7'd40, 7'd41, 7'd41, 7'd42, 7'd43, 7'd44, 7'd44, 7'd45, 7'd46,
        7'd47, 7'd47, 7'd48, 7'd49, 7'd50, 7'd50, 7'd51, 7'd52, 7'd52, 7'd53, 7'd54, 7'd55, 7'd55, 7'd56, 7'd57,
        7'd57, 7'd58, 7'd59, 7'd59, 7'd60, 7'd61, 7'd61, 7'd62, 7'd63, 7'd64, 7'd64, 7'd65, 7'd66, 7'd66, 7'd67,
        7'd68, 7'd68, 7'd69, 7'd70, 7'd70, 7'd71, 7'd71, 7'd72, 7'd73, 7'd73, 7'd74, 7'd75, 7'd75, 7'd76, 7'd77,
        7'd77, 7'd78, 7'd78, 7'd79, 7'd80, 7'd80, 7'd81, 7'd81, 7'd82, 7'd83, 7'd83, 7'd84, 7'd84, 7'd85, 7'd86,
        7'd86, 7'd87, 7'd87, 7'd88, 7'd88, 7'd89, 7'd90, 7'd90, 7'd91, 7'd91, 7'd92, 7'd92, 7'd93, 7'd93, 7'd94,
        7'd94, 7'd95, 7'd96, 7'd96, 7'd97, 7'd97, 7'd98, 7'd98, 7'd99, 7'd99, 7'd100, 7'd100, 7'd101, 7'd101,
        7'd101, 7'd102, 7'd102, 7'd103, 7'd103, 7'd104, 7'd104, 7'd105, 7'd105, 7'd106, 7'd106, 7'd106, 7'd107,
        7'd107, 7'd108, 7'd108, 7'd109, 7'd109, 7'd109, 7'd110, 7'd110, 7'd111, 7'd111, 7'd111, 7'd112, 7'd112,
        7'd112, 7'd113, 7'd113, 7'd114, 7'd114, 7'd114, 7'd115, 7'd115, 7'd115, 7'd116, 7'd116, 7'd116, 7'd117,
        7'd117, 7'd117, 7'd117, 7'd118, 7'd118, 7'd118, 7'd119, 7'd119, 7'd119, 7'd120, 7'd120, 7'd120, 7'd120,
        7'd121, 7'd121, 7'd121, 7'd121, 7'd122, 7'd122, 7'd122, 7'd122, 7'd122, 7'd123, 7'd123, 7'd123, 7'd123,
        7'd123, 7'd124, 7'd124, 7'd124, 7'd124, 7'd124, 7'd125, 7'd125, 7'd125, 7'd125, 7'd125, 7'd125, 7'd125,
        7'd126, 7'd126, 7'd126, 7'd126, 7'd126, 7'd126, 7'd126, 7'd126, 7'd127, 7'd127, 7'd127, 7'd127, 7'd127,
        7'd127, 7'd127, 7'd127, 7'd127, 7'd127, 7'd127, 7'd127, 7'd127, 7'd127, 7'd127, 7'd127, 7'd127, 7'd127,
        7'd127, 7'd127
    };
		
        if (address[9:8] == 2'b00) begin
            dds_sin = coefficients(address[7:0]); 
        end
		else if(address[9:8] == 2'b01) begin
			dds_sin = coefficients(511-address[7:0]); 
		end 
        else if (address[9:8] == 2'b10) begin
            dds_sin = -coefficients(address[7:0]-512); 
        end
		else if(address[9:8] == 2'b11) begin
			dds_sin = -coefficients(1023-address[7:0]); 
		end 		

        if (address[9:8] == 2'b00) begin
            dds_cos = coefficients(255-address[7:0]); 
        end
		else if(address[9:8] == 2'b01) begin
			dds_cos = -coefficients(address[7:0]-256); 
		end 
        else if (address[9:8] == 2'b10) begin
            dds_cos = -coefficients(767-address[7:0]); 
        end
		else if(address[9:8] == 2'b11) begin
			dds_cos = -coefficients(address[7:0]-768); 
		end         
endtask : dds


task readout_daq_rm::data2sram(
		logic [31:0] qubit_state	,		
		logic [31:0] state0_count	[15:0],		
		logic [31:0] state0_count	[15:0],
		logic [31:0] state1_count	[15:0],
		logic [31:0] state2_count	[15:0],
		logic [31:0] state3_count	[15:0],
		logic [31:0] i_sum			[15:0],
		logic [31:0] q_sum			[15:0],
		);	
//将qubit_state、iq_sum，count_state写入寄存器
		reg_mems::daq_regfile.set("qubit_state", qubit_state);
		
		reg_mems::daq_regfile.set("Q0_i_sum", i_sum[0]);
		reg_mems::daq_regfile.set("Q1_i_sum", i_sum[1]);
		reg_mems::daq_regfile.set("Q2_i_sum", i_sum[2]);
		reg_mems::daq_regfile.set("Q3_i_sum", i_sum[3]);
		reg_mems::daq_regfile.set("Q4_i_sum", i_sum[4]);
		reg_mems::daq_regfile.set("Q5_i_sum", i_sum[5]);
		reg_mems::daq_regfile.set("Q6_i_sum", i_sum[6]);
		reg_mems::daq_regfile.set("Q7_i_sum", i_sum[7]);
		reg_mems::daq_regfile.set("Q8_i_sum", i_sum[8]);
		reg_mems::daq_regfile.set("Q9_i_sum", i_sum[9]);
		reg_mems::daq_regfile.set("Q10_i_sum", i_sum[10]);
		reg_mems::daq_regfile.set("Q11_i_sum", i_sum[11]);
		reg_mems::daq_regfile.set("Q12_i_sum", i_sum[12]);
		reg_mems::daq_regfile.set("Q13_i_sum", i_sum[13]);
		reg_mems::daq_regfile.set("Q14_i_sum", i_sum[14]);
		reg_mems::daq_regfile.set("Q15_i_sum", i_sum[15]);
		
		reg_mems::daq_regfile.set("Q0_q_sum", q_sum[0]);
		reg_mems::daq_regfile.set("Q1_q_sum", q_sum[1]);
		reg_mems::daq_regfile.set("Q2_q_sum", q_sum[2]);
		reg_mems::daq_regfile.set("Q3_q_sum", q_sum[3]);
		reg_mems::daq_regfile.set("Q4_q_sum", q_sum[4]);
		reg_mems::daq_regfile.set("Q5_q_sum", q_sum[5]);
		reg_mems::daq_regfile.set("Q6_q_sum", q_sum[6]);
		reg_mems::daq_regfile.set("Q7_q_sum", q_sum[7]);
		reg_mems::daq_regfile.set("Q8_q_sum", q_sum[8]);
		reg_mems::daq_regfile.set("Q9_q_sum", q_sum[9]);
		reg_mems::daq_regfile.set("Q10_q_sum", q_sum[10]);
		reg_mems::daq_regfile.set("Q11_q_sum", q_sum[11]);
		reg_mems::daq_regfile.set("Q12_q_sum", q_sum[12]);
		reg_mems::daq_regfile.set("Q13_q_sum", q_sum[13]);
		reg_mems::daq_regfile.set("Q14_q_sum", q_sum[14]);
		reg_mems::daq_regfile.set("Q15_q_sum", q_sum[15]);		
		
	
		reg_mems::daq_regfile.set("Q0_state0_statistics", count_state_0[0]);
		reg_mems::daq_regfile.set("Q1_state0_statistics", count_state_0[1]);		
		reg_mems::daq_regfile.set("Q2_state0_statistics", count_state_0[2]);		
		reg_mems::daq_regfile.set("Q3_state0_statistics", count_state_0[3]);		
		reg_mems::daq_regfile.set("Q4_state0_statistics", count_state_0[4]);		
		reg_mems::daq_regfile.set("Q5_state0_statistics", count_state_0[5]);		
		reg_mems::daq_regfile.set("Q6_state0_statistics", count_state_0[6]);		
		reg_mems::daq_regfile.set("Q7_state0_statistics", count_state_0[7]);		
		reg_mems::daq_regfile.set("Q8_state0_statistics", count_state_0[8]);		
		reg_mems::daq_regfile.set("Q9_state0_statistics", count_state_0[9]);		
		reg_mems::daq_regfile.set("Q10_state0_statistics", count_state_0[10]);		
		reg_mems::daq_regfile.set("Q11_state0_statistics", count_state_0[11]);		
		reg_mems::daq_regfile.set("Q12_state0_statistics", count_state_0[12]);		
		reg_mems::daq_regfile.set("Q13_state0_statistics", count_state_0[13]);		
		reg_mems::daq_regfile.set("Q14_state0_statistics", count_state_0[14]);		
		reg_mems::daq_regfile.set("Q15_state0_statistics", count_state_0[15]);	
		
		reg_mems::daq_regfile.set("Q0_state1_statistics", count_state_1[0]);
		reg_mems::daq_regfile.set("Q1_state1_statistics", count_state_1[1]);		
		reg_mems::daq_regfile.set("Q2_state1_statistics", count_state_1[2]);		
		reg_mems::daq_regfile.set("Q3_state1_statistics", count_state_1[3]);		
		reg_mems::daq_regfile.set("Q4_state1_statistics", count_state_1[4]);		
		reg_mems::daq_regfile.set("Q5_state1_statistics", count_state_1[5]);		
		reg_mems::daq_regfile.set("Q6_state1_statistics", count_state_1[6]);		
		reg_mems::daq_regfile.set("Q7_state1_statistics", count_state_1[7]);		
		reg_mems::daq_regfile.set("Q8_state1_statistics", count_state_1[8]);		
		reg_mems::daq_regfile.set("Q9_state1_statistics", count_state_1[9]);		
		reg_mems::daq_regfile.set("Q10_state1_statistics", count_state_1[10]);		
		reg_mems::daq_regfile.set("Q11_state1_statistics", count_state_1[11]);		
		reg_mems::daq_regfile.set("Q12_state1_statistics", count_state_1[12]);		
		reg_mems::daq_regfile.set("Q13_state1_statistics", count_state_1[13]);		
		reg_mems::daq_regfile.set("Q14_state1_statistics", count_state_1[14]);		
		reg_mems::daq_regfile.set("Q15_state1_statistics", count_state_1[15]);	
		
		reg_mems::daq_regfile.set("Q0_state2_statistics", count_state_2[0]);
		reg_mems::daq_regfile.set("Q1_state2_statistics", count_state_2[1]);		
		reg_mems::daq_regfile.set("Q2_state2_statistics", count_state_2[2]);		
		reg_mems::daq_regfile.set("Q3_state2_statistics", count_state_2[3]);		
		reg_mems::daq_regfile.set("Q4_state2_statistics", count_state_2[4]);		
		reg_mems::daq_regfile.set("Q5_state2_statistics", count_state_2[5]);		
		reg_mems::daq_regfile.set("Q6_state2_statistics", count_state_2[6]);		
		reg_mems::daq_regfile.set("Q7_state2_statistics", count_state_2[7]);		
		reg_mems::daq_regfile.set("Q8_state2_statistics", count_state_2[8]);		
		reg_mems::daq_regfile.set("Q9_state2_statistics", count_state_2[9]);		
		reg_mems::daq_regfile.set("Q10_state2_statistics", count_state_2[10]);		
		reg_mems::daq_regfile.set("Q11_state2_statistics", count_state_2[11]);		
		reg_mems::daq_regfile.set("Q12_state2_statistics", count_state_2[12]);		
		reg_mems::daq_regfile.set("Q13_state2_statistics", count_state_2[13]);		
		reg_mems::daq_regfile.set("Q14_state2_statistics", count_state_2[14]);		
		reg_mems::daq_regfile.set("Q15_state2_statistics", count_state_2[15]);	
		
		reg_mems::daq_regfile.set("Q0_state3_statistics", count_state_3[0]);
		reg_mems::daq_regfile.set("Q1_state3_statistics", count_state_3[1]);		
		reg_mems::daq_regfile.set("Q2_state3_statistics", count_state_3[2]);		
		reg_mems::daq_regfile.set("Q3_state3_statistics", count_state_3[3]);		
		reg_mems::daq_regfile.set("Q4_state3_statistics", count_state_3[4]);		
		reg_mems::daq_regfile.set("Q5_state3_statistics", count_state_3[5]);		
		reg_mems::daq_regfile.set("Q6_state3_statistics", count_state_3[6]);		
		reg_mems::daq_regfile.set("Q7_state3_statistics", count_state_3[7]);		
		reg_mems::daq_regfile.set("Q8_state3_statistics", count_state_3[8]);		
		reg_mems::daq_regfile.set("Q9_state3_statistics", count_state_3[9]);		
		reg_mems::daq_regfile.set("Q10_state3_statistics", count_state_3[10]);		
		reg_mems::daq_regfile.set("Q11_state3_statistics", count_state_3[11]);		
		reg_mems::daq_regfile.set("Q12_state3_statistics", count_state_3[12]);		
		reg_mems::daq_regfile.set("Q13_state3_statistics", count_state_3[13]);		
		reg_mems::daq_regfile.set("Q14_state3_statistics", count_state_3[14]);		
		reg_mems::daq_regfile.set("Q15_state3_statistics", count_state_3[15]);
		
//将wave数据、iq_sum、qubit_state、count_state存入队列，并根据需要进行推送		
	endtask


`endif



 