789 lines
38 KiB
Systemverilog
789 lines
38 KiB
Systemverilog
//FILE_HEADER-------------------------------------------------------
|
|
//FILE_NAME : EZQ_readout_refm.sv
|
|
//DEPARTEMENT : Hfnl-cmos
|
|
//AUTHOR :
|
|
//EMAIL :
|
|
//*******************************************************************
|
|
//DESCRIPTION : reference model define
|
|
//*******************************************************************
|
|
//END_HEADER*********************************************************
|
|
`ifndef EZQ_READOUT_REFM
|
|
`define EZQ_READOUT_REFM
|
|
|
|
`include "../testbench/refm/mcu_cw_item.sv"
|
|
`include "../testbench/refm/spi_rw.sv"
|
|
`include "../testbench/refm/reg_mems.sv"
|
|
|
|
class EZQ_readout_refm extends uvm_component;
|
|
|
|
`uvm_component_utils(EZQ_readout_refm);
|
|
|
|
virtual rm_if rm_if;
|
|
uvm_blocking_get_export #(spi_item) spi_get_port;
|
|
uvm_blocking_get_export #(EZQ_readout_adc_item) adc_get_port;
|
|
uvm_analysis_port #(spi_item) spi_rm2scb_port;
|
|
uvm_analysis_port #(EZQ_readout_dac_item) dac_rm2scb_port;
|
|
uvm_analysis_port #(mcu_cw_item) mcu_2awgrm_port;
|
|
uvm_analysis_port #(mcu_cw_item) mcu_2daqrm_port;
|
|
mcu_cw_item awg_mcu_cw_item_q[$];
|
|
mcu_cw_item daq_mcu_cw_item_q[$];
|
|
|
|
bit [31:0] ram_data[bit[31:0]];
|
|
|
|
|
|
//bit[31:0] awg_mcu_inst_ram[bit[14:0]];
|
|
//bit[31:0] awg_mcu_ram_data[bit[31:0]];
|
|
bit[31:0] awg_mcu_reg[bit[31:0]];
|
|
bit awg_mcu_finish;
|
|
|
|
//bit[31:0] daq_mcu_inst_ram[bit[14:0]];
|
|
//bit[31:0] daq_mcu_ram_data[bit[31:0]];
|
|
bit[31:0] daq_mcu_reg[bit[31:0]];
|
|
bit daq_mcu_finish;
|
|
mcu_cw_item awg_mcu_cw_item_2scb_q[$];
|
|
mcu_cw_item daq_mcu_cw_item_2scb_q[$];
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
parameter RW_TEST = 32'h0;
|
|
parameter INTR_MASK = 32'h14;
|
|
parameter SYS_FUNC = 32'h1c;
|
|
parameter AWG_AMPLITUDE = 32'h900034;
|
|
parameter AWG_FREQUENCY = 32'h900038;
|
|
parameter AWG_PHASE = 32'h90003c;
|
|
parameter AWG_FUNC = 32'h900044;
|
|
parameter AWG_PUMP_CTRL = 32'h900048;
|
|
parameter AWG_MARKER_CTRL = 32'h90004c;
|
|
parameter DAQ_SEND_DATA = 32'h400034;
|
|
parameter DAQ_FREQUENCY = 32'h400038;
|
|
parameter DAQ_PHASE = 32'h40003c;
|
|
parameter DAQ_FUNC = 32'h400044;
|
|
parameter WAVE_SAMPLE_DEPTH = 32'h400048;
|
|
parameter DEMOD_WIN_WIDTH = 32'h40004c;
|
|
parameter READ_THRESHOLD = 32'h400050;
|
|
parameter READ_REQ_CTRL = 32'h400058;
|
|
parameter DEMOD_WIDTH_Q0 = 32'h400080;
|
|
parameter DEMOD_WIDTH_Q1 = 32'h400084;
|
|
parameter DEMOD_WIDTH_Q2 = 32'h400088;
|
|
parameter DEMOD_WIDTH_Q3 = 32'h40008c;
|
|
parameter DEMOD_WIDTH_Q4 = 32'h400090;
|
|
parameter DEMOD_WIDTH_Q5 = 32'h400094;
|
|
parameter DEMOD_WIDTH_Q6 = 32'h400098;
|
|
parameter DEMOD_WIDTH_Q7 = 32'h40009c;
|
|
parameter DEMOD_WIDTH_Q8 = 32'h4000a0;
|
|
parameter DEMOD_WIDTH_Q9 = 32'h4000a4;
|
|
parameter DEMOD_WIDTH_Q10 = 32'h4000a8;
|
|
parameter DEMOD_WIDTH_Q11 = 32'h4000ac;
|
|
parameter DEMOD_WIDTH_Q12 = 32'h4000b0;
|
|
parameter DEMOD_WIDTH_Q13 = 32'h4000b4;
|
|
parameter DEMOD_WIDTH_Q14 = 32'h4000b8;
|
|
parameter DEMOD_WIDTH_Q15 = 32'h4000bc;
|
|
*/
|
|
|
|
bit[31:0] rw_test;
|
|
bit[31:0] intr_mask;
|
|
bit[31:0] sys_func;
|
|
bit[31:0] awg_amplitude;
|
|
bit[31:0] awg_frequency;
|
|
bit[31:0] awg_phase;
|
|
bit[31:0] awg_func;
|
|
bit[31:0] awg_pump_ctrl;
|
|
bit[31:0] awg_marker_en;
|
|
bit[31:0] daq_send_data;
|
|
bit[31:0] daq_frequency;
|
|
bit[31:0] daq_phase;
|
|
bit[31:0] wave_smaple_depth;
|
|
bit[31:0] demod_win_width;
|
|
bit[31:0] read_threshold;
|
|
bit[31:0] read_req_ctrl;
|
|
bit[31:0] demod_width_q0;
|
|
bit[31:0] demod_width_q1;
|
|
bit[31:0] demod_width_q2;
|
|
bit[31:0] demod_width_q3;
|
|
bit[31:0] demod_width_q4;
|
|
bit[31:0] demod_width_q5;
|
|
bit[31:0] demod_width_q6;
|
|
bit[31:0] demod_width_q7;
|
|
bit[31:0] demod_width_q8;
|
|
bit[31:0] demod_width_q9;
|
|
bit[31:0] demod_width_q10;
|
|
bit[31:0] demod_width_q11;
|
|
bit[31:0] demod_width_q12;
|
|
bit[31:0] demod_width_q13;
|
|
bit[31:0] demod_width_q14;
|
|
bit[31:0] demod_width_q15;
|
|
|
|
bit awg_mcu_finish;
|
|
bit daq_mcu_finish;
|
|
|
|
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_spi_item;
|
|
extern task get_config_data();
|
|
extern task mcu_process(bit [31:0] base_addr,ref bit[31:0] inst_ram[bit[31:0]],ref bit[31:0] mcu_reg[bit[31:0]],ref bit [31:0]ram_data[bit[31:0]],ref bit mcu_finish,ref mcu_cw_item mcu_cw_item_q[$]);
|
|
extern task send_awg_codeword();
|
|
extern task send_daq_codeword();
|
|
|
|
|
|
endclass : EZQ_readout_refm
|
|
|
|
function EZQ_readout_refm::new(string name,uvm_component parent);
|
|
|
|
super.new(name,parent);
|
|
|
|
endfunction : new
|
|
|
|
function void EZQ_readout_refm::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"});
|
|
spi_get_port = new("spi_get_port",this);
|
|
adc_get_port = new("adc_get_port",this);
|
|
spi_rm2scb_port = new("spi_rm2scb_port",this);
|
|
dac_rm2scb_port = new("dac_rm2scb_port",this);
|
|
endfunction
|
|
|
|
task EZQ_readout_refm::get_spi_item();
|
|
forever begin
|
|
spi_item spi_item;
|
|
bit [31:0] wr_addr;
|
|
bit [31:0] wr_data;
|
|
bit [31:0] data_size;
|
|
spi_get_port.get(spi_item);
|
|
data_size = spi_item.data.size();
|
|
for (int i=0;i<data_size;i++) begin
|
|
wr_addr = spi_item.addr+i*32'h4;
|
|
wr_data = spi_item.data.pop_front();
|
|
/* if(wr_addr==`DAQ_FREQUENCY || wr_addr== `DAQ_PHASE || wr_addr==`DAQ_SEND_DATA) begin
|
|
`uvm_error(get_type_name(),$sformatf("spi can read this addr(%h) only",wr_addr))
|
|
end*/
|
|
`uvm_info(get_type_name(),$sformatf("write ram_data[%0h]=%0h",wr_addr,wr_data),UVM_LOW)
|
|
ram_data[wr_addr] = wr_data;
|
|
|
|
spi_rw spi_rw;
|
|
spi_rw.rw(spi_item);
|
|
end
|
|
end
|
|
endtask
|
|
|
|
task EZQ_readout_refm::init_reg_mems();
|
|
reg_mems reg_mems;
|
|
reg_mems = new();
|
|
reg_mems.init();
|
|
endtask
|
|
|
|
task EZQ_readout_refm::get_config_data();
|
|
forever begin
|
|
@(posedge `CLK);
|
|
if(ram_data.exists(`RW_TEST)) begin
|
|
rw_test = ram_data[`RW_TEST];
|
|
end
|
|
if(ram_data.exists(`INTR_MASK)) begin
|
|
intr_mask = ram_data[`INTR_MASK];
|
|
end
|
|
if(ram_data.exists(`SYS_FUNC)) begin
|
|
sys_func = ram_data[`SYS_FUNC];
|
|
end
|
|
if(ram_data.exists(`AWG_AMPLITUDE)) begin
|
|
awg_amplitude = ram_data[`AWG_AMPLITUDE];
|
|
end
|
|
if(ram_data.exists(`AWG_FREQUENCY)) begin
|
|
awg_frequency = ram_data[`AWG_FREQUENCY];
|
|
end
|
|
if(ram_data.exists(`AWG_PHASE)) begin
|
|
awg_phase = ram_data[`AWG_PHASE];
|
|
end
|
|
if(ram_data.exists(`AWG_PUMP_CTRL)) begin
|
|
awg_pump_ctrl = ram_data[`AWG_PUMP_CTRL];
|
|
end
|
|
if(ram_data.exists(`AWG_MARKER_CTRL)) begin
|
|
awg_marker_en = ram_data[`AWG_MARKER_CTRL];
|
|
end
|
|
if(ram_data.exists(`DAQ_SEND_DATA)) begin
|
|
daq_send_data = ram_data[`DAQ_SEND_DATA];
|
|
end
|
|
if(ram_data.exists(`DAQ_FREQUENCY)) begin
|
|
daq_frequency = ram_data[`DAQ_FREQUENCY];
|
|
end
|
|
if(ram_data.exists(`DAQ_PHASE)) begin
|
|
daq_phase = ram_data[`DAQ_PHASE];
|
|
end
|
|
if(ram_data.exists(`WAVE_SAMPLE_DEPTH)) begin
|
|
wave_smaple_depth = ram_data[`WAVE_SAMPLE_DEPTH];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIN_WIDTH)) begin
|
|
demod_win_width = ram_data[`DEMOD_WIN_WIDTH];
|
|
end
|
|
if(ram_data.exists(`READ_THRESHOLD)) begin
|
|
read_threshold = ram_data[`READ_THRESHOLD];
|
|
end
|
|
if(ram_data.exists(`READ_REQ_CTRL)) begin
|
|
read_req_ctrl = ram_data[`READ_REQ_CTRL];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q0)) begin
|
|
demod_width_q0 = ram_data[`DEMOD_WIDTH_Q0];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q1)) begin
|
|
demod_width_q1 = ram_data[`DEMOD_WIDTH_Q1];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q2)) begin
|
|
demod_width_q2 = ram_data[`DEMOD_WIDTH_Q2];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q3)) begin
|
|
demod_width_q3 = ram_data[`DEMOD_WIDTH_Q3];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q4)) begin
|
|
demod_width_q4 = ram_data[`DEMOD_WIDTH_Q4];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q5)) begin
|
|
demod_width_q5 = ram_data[`DEMOD_WIDTH_Q5];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q6)) begin
|
|
demod_width_q6 = ram_data[`DEMOD_WIDTH_Q6];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q7)) begin
|
|
demod_width_q7 = ram_data[`DEMOD_WIDTH_Q7];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q8)) begin
|
|
demod_width_q8 = ram_data[`DEMOD_WIDTH_Q8];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q9)) begin
|
|
demod_width_q9 = ram_data[`DEMOD_WIDTH_Q9];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q10)) begin
|
|
demod_width_q10 = ram_data[`DEMOD_WIDTH_Q10];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q11)) begin
|
|
demod_width_q11 = ram_data[`DEMOD_WIDTH_Q11];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q12)) begin
|
|
demod_width_q12 = ram_data[`DEMOD_WIDTH_Q12];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q13)) begin
|
|
demod_width_q13 = ram_data[`DEMOD_WIDTH_Q13];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q14)) begin
|
|
demod_width_q14 = ram_data[`DEMOD_WIDTH_Q14];
|
|
end
|
|
if(ram_data.exists(`DEMOD_WIDTH_Q15)) begin
|
|
demod_width_q15 = ram_data[`DEMOD_WIDTH_Q15];
|
|
end
|
|
end
|
|
endtask
|
|
|
|
|
|
task EZQ_readout_refm::mcu_process(bit[31:0] base_addr,ref bit[31:0] inst_ram[bit[31:0]],ref bit[31:0] mcu_reg[bit[31:0]],ref bit[31:0]ram_data[bit[31:0]],ref bit mcu_finish,ref mcu_cw_item mcu_cw_item_q[$]);
|
|
bit feedback;
|
|
bit [31:0] mcu_addr;
|
|
bit [31:0] mcu_data;
|
|
bit [6:0] opcode;
|
|
bit [2:0] funct3;
|
|
bit [6:0] funct7;
|
|
bit des_reg_wr;
|
|
bit [4:0] des_reg_addr;
|
|
int des_reg_data;
|
|
int des_reg_data_com;
|
|
bit [4:0] src_reg1_addr;
|
|
bit [4:0] src_reg2_addr;
|
|
int src1_data;
|
|
int src2_data;
|
|
int src1_data_com;
|
|
int src2_data_com;
|
|
bit [31:0] src1_data_unsigned;
|
|
bit [31:0] src2_data_unsigned;
|
|
bit signed [11:0] imm_data;
|
|
bit signed [11:0] imm_data_com;
|
|
bit [11:0] imm_data_unsigned;
|
|
bit signed [11:0] b_imm_data;
|
|
bit signed [11:0] b_imm_data_com;
|
|
bit [11:0] b_imm_data_unsigned;
|
|
bit b_condition;
|
|
bit signed [19:0] u_imm_data;
|
|
bit signed [20:0] j_imm_data_21;
|
|
bit signed [11:0] j_imm_data_12;
|
|
bit [63:0] clock_cnt;
|
|
mcu_cw_item mcu_cw_item;
|
|
bit ram_wr;
|
|
bit [3:0] ram_mask;
|
|
bit [1:0] ram_byte;
|
|
bit [31:0] wr_ram_data;
|
|
bit signed [31:0] imm_32;
|
|
bit unsigned [31:0] imm_32_unsigned;
|
|
bit signed [31:0] imm_com_32;
|
|
int inst_cnt;
|
|
bit [31:0] ram_addr;
|
|
bit [31:0] rd_ram_data;
|
|
bit [1:0] ram_offset;
|
|
|
|
mcu_addr = base_addr;
|
|
mcu_finish = 0;
|
|
feedback = 0;
|
|
clock_cnt = 3;
|
|
`uvm_info(get_type_name(),"wait sync_in",UVM_LOW)
|
|
wait (`SYNC_IN);
|
|
`uvm_info(get_type_name(),"wait sync_in",UVM_LOW)
|
|
forever begin
|
|
if(inst_ram.exists(mcu_addr) && mcu_finish==0) begin
|
|
inst_cnt++;
|
|
`uvm_info(get_type_name(),$sformatf("mcu reference model is processing %0d th instruction",inst_cnt),UVM_LOW)
|
|
mcu_data = inst_ram[mcu_addr];
|
|
`uvm_info(get_type_name(),$sformatf("mcu_addr=%0h,get mcu_data %0h",mcu_addr,mcu_data),UVM_LOW)
|
|
opcode = mcu_data[6:0];
|
|
des_reg_addr = mcu_data[11:7];
|
|
funct3 = mcu_data[14:12];
|
|
src_reg1_addr = mcu_data[19:15];
|
|
src_reg2_addr = mcu_data[24:20];
|
|
`uvm_info(get_type_name(),$sformatf("src_reg1_addr=%0h,src_reg2_addr=%0h",src_reg1_addr,src_reg2_addr),UVM_LOW)
|
|
funct7 = mcu_data[31:25];
|
|
if(opcode == 7'b0110011) begin //R type
|
|
src1_data = mcu_reg.exists(src_reg1_addr) ? mcu_reg[src_reg1_addr] : 0;
|
|
src2_data = mcu_reg.exists(src_reg2_addr) ? mcu_reg[src_reg2_addr] : 0;
|
|
`uvm_info(get_type_name(),$sformatf("src1_data=%0h,src2_data=%0h",src1_data,src2_data),UVM_LOW)
|
|
src1_data_com = (src1_data[31]==0) ? src1_data : {src1_data[31],~src1_data[30:0]} + 1'b1;
|
|
src2_data_com = (src2_data[31]==0) ? src2_data : {src2_data[31],~src2_data[30:0]} + 1'b1;
|
|
`uvm_info(get_type_name(),$sformatf("src1_data_com=%0h,src2_data_com=%0h",src1_data_com,src2_data_com),UVM_LOW)
|
|
src1_data_unsigned = src1_data;
|
|
src2_data_unsigned = src2_data;
|
|
des_reg_wr = 1;
|
|
if (funct7 == 7'b0000000) begin
|
|
if(funct3 == 3'b000) begin // R add
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type add",opcode),UVM_LOW)
|
|
des_reg_data = src1_data + src2_data;
|
|
end
|
|
else if(funct3 == 3'b001) begin //R sll
|
|
des_reg_data = src1_data << src2_data[4:0];
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type sll",opcode),UVM_LOW)
|
|
end
|
|
else if (funct3 == 3'b010) begin //R slt
|
|
des_reg_data = src1_data < src2_data ? 1 : 0;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type slt",opcode),UVM_LOW)
|
|
end
|
|
else if (funct3 == 3'b011) begin //R sltu (set less than unsigned)
|
|
des_reg_data = src1_data_unsigned < src2_data_unsigned ? 1 : 0;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type sltu",opcode),UVM_LOW)
|
|
end
|
|
else if (funct3 == 3'b100) begin //R xor
|
|
des_reg_data = src1_data ^ src2_data;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type xor",opcode),UVM_LOW)
|
|
end
|
|
else if (funct3 == 3'b101) begin //R srl
|
|
des_reg_data = src1_data >> src2_data[4:0];
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type srl",opcode),UVM_LOW)
|
|
end
|
|
else if (funct3 == 3'b110) begin //R or
|
|
des_reg_data = src1_data | src2_data;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type or",opcode),UVM_LOW)
|
|
end
|
|
else if (funct3 == 3'b111) begin //R and
|
|
des_reg_data = src1_data & src2_data;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type and",opcode),UVM_LOW)
|
|
end
|
|
end
|
|
else if (funct7 == 7'b0100000) begin
|
|
if(funct3 == 3'b000) begin //R sub
|
|
des_reg_data = src1_data - src2_data;
|
|
`uvm_info(get_type_name(),$sformatf("des_reg_data_com=%0h,des_reg_data=%0h",des_reg_data,des_reg_data_com),UVM_LOW)
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type sub",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3==3'b101) begin //R sra
|
|
des_reg_data = src1_data >>> src2_data[4:0];
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type sra",opcode),UVM_LOW)
|
|
end
|
|
else begin
|
|
des_reg_wr = 0;
|
|
`uvm_error(get_type_name(),$sformatf("R type opcode,funct7 is 7'b000000,but funct3(%b)is illegal",funct3))
|
|
end
|
|
end
|
|
else begin
|
|
des_reg_wr = 0;
|
|
`uvm_error(get_type_name(),$sformatf("R type opcode,funct7(%b)is illegal",funct7))
|
|
end
|
|
mcu_addr = mcu_addr+32'h4;
|
|
end
|
|
else if(opcode == 7'b0010011) begin //I type
|
|
des_reg_wr = 1;
|
|
src1_data = mcu_reg.exists(src_reg1_addr) ? mcu_reg[src_reg1_addr] : 0;
|
|
src1_data_com = (src1_data[31]==0) ? src1_data : {src1_data[31],~src1_data[30:0]} + 1'b1;
|
|
imm_data = mcu_data[31:20];
|
|
imm_32 = {{21{imm_data[11]}},imm_data[10:0]};
|
|
imm_32_unsigned = imm_32;
|
|
//imm_com_32 = (imm_32[31]==0) ? imm_32 : {imm_32[31],~imm_32[30:0]} + 1;
|
|
src1_data_unsigned = src1_data;
|
|
imm_data_unsigned = imm_data;
|
|
`uvm_info(get_type_name(),$sformatf("src1_data = %0h,imm_data = %0h",src1_data,imm_data),UVM_LOW)
|
|
`uvm_info(get_type_name(),$sformatf("src1_data_com = %0h,imm_32 = %0h,imm_com_32=%0h",src1_data_com,imm_32,imm_com_32),UVM_LOW)
|
|
`uvm_info(get_type_name(),$sformatf("src1_data_unsigned = %0h,imm_data_unsigned = %0h",src1_data_unsigned,imm_data_unsigned),UVM_LOW)
|
|
if(funct3 == 3'b000) begin //I addi
|
|
des_reg_data = src1_data + imm_32;
|
|
`uvm_info(get_type_name(),$sformatf("des_reg_data_com = %0h,des_reg_data = %0h",des_reg_data_com,des_reg_data),UVM_LOW)
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type addi",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b010) begin //I slti
|
|
des_reg_data = src1_data < imm_32 ? 1 : 0;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type slti",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b011) begin //I sltiu(set less than imm unsigned)
|
|
des_reg_data = src1_data_unsigned < imm_32_unsigned ? 1 : 0;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type sltiu",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b100) begin //I xori
|
|
des_reg_data = src1_data ^ imm_32;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type xori",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b110) begin //I ori
|
|
des_reg_data = src1_data | imm_32;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type ori",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b111) begin //I andi
|
|
des_reg_data = src1_data & imm_32;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type andi",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b001 && funct7 == 7'b0000000) begin //slli
|
|
des_reg_data = src1_data << imm_data;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type slli",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b101 && funct7 == 7'b0000000) begin //srli
|
|
des_reg_data = src1_data >> imm_data;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type srli",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b101 && funct7 == 7'b0100000) begin //sali
|
|
des_reg_data = src1_data >>> imm_data;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type sali",opcode),UVM_LOW)
|
|
end
|
|
mcu_addr = mcu_addr+32'h4;
|
|
end
|
|
else if(opcode == 7'b0000011) begin //I type
|
|
des_reg_wr = 1;
|
|
src1_data = mcu_reg.exists(src_reg1_addr) ? mcu_reg[src_reg1_addr] : 0;
|
|
src1_data_com = {src1_data[31],~src1_data[30:0]} + 1'b1;
|
|
imm_data = mcu_data[31:20];
|
|
imm_data_com = {imm_data[11],~mcu_data[10:0]} + 1;
|
|
imm_data_unsigned = imm_data;
|
|
ram_addr = ((src1_data+imm_data)/4)*4;
|
|
ram_offset = (src1_data+imm_data)%4;
|
|
rd_ram_data = ram_data.exists(ram_addr) ? ram_data[ram_addr] : 0;
|
|
`uvm_info(get_type_name(),$sformatf("src1_data = %h,imm_data = %0h",src1_data,imm_data),UVM_LOW)
|
|
`uvm_info(get_type_name(),$sformatf("ram_addr=%0h,ram_data.exists = %h,rd_ram_data = %0h",ram_addr,ram_data.exists(ram_addr),rd_ram_data),UVM_LOW)
|
|
if (funct3 == 3'b000) begin //I lb
|
|
//des_reg_data = {{25{rd_ram_data[7+ram_offset*8]}},rd_ram_data[6+ram_offset*8:0+ram_offset*8]};
|
|
if(ram_offset == 0) begin
|
|
des_reg_data = {{25{rd_ram_data[7]}},rd_ram_data[6:0]};
|
|
end
|
|
else if(ram_offset == 1) begin
|
|
des_reg_data = {{25{rd_ram_data[15]}},rd_ram_data[14:8]};
|
|
end
|
|
else if(ram_offset == 2) begin
|
|
des_reg_data = {{25{rd_ram_data[23]}},rd_ram_data[22:16]};
|
|
end
|
|
else begin
|
|
des_reg_data = {{25{rd_ram_data[31]}},rd_ram_data[30:24]};
|
|
end
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type lb",opcode),UVM_LOW)
|
|
end
|
|
else if (funct3 == 3'b001) begin //I lh
|
|
des_reg_data[31:16] = 'h0;
|
|
if((src1_data+imm_data)%2 != 0) begin
|
|
`uvm_error(get_type_name(),$sformatf("instruction lh but read address(%0h) is illegal",src1_data+imm_data))
|
|
end
|
|
des_reg_data = ram_offset == 0 ? {{17{rd_ram_data[15]}},rd_ram_data[14:0]} : {{17{rd_ram_data[31]}},rd_ram_data[30:16]};
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type lh",opcode),UVM_LOW)
|
|
end
|
|
else if (funct3 == 3'b010) begin //I lw
|
|
if((src1_data+imm_data)%4 !=0 ) begin
|
|
`uvm_error(get_type_name(),$sformatf("instruction lw but read address(%0h) is illegal",src1_data+imm_data))
|
|
end
|
|
des_reg_data = rd_ram_data;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type lw",opcode),UVM_LOW)
|
|
end
|
|
else if (funct3 == 3'b100) begin //I lbu
|
|
//des_reg_data = {{25{rd_ram_data[7+ram_offset*8]}},rd_ram_data[6+ram_offset*8:0+ram_offset*8]};
|
|
if(ram_offset == 0) begin
|
|
des_reg_data = rd_ram_data[7:0];
|
|
end
|
|
else if(ram_offset == 1) begin
|
|
des_reg_data = rd_ram_data[15:8];
|
|
end
|
|
else if(ram_offset == 2) begin
|
|
des_reg_data = rd_ram_data[23:16];
|
|
end
|
|
else begin
|
|
des_reg_data = rd_ram_data[31:24];
|
|
end
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type lbu",opcode),UVM_LOW)
|
|
end
|
|
else if (funct3 == 3'b101) begin //I lhu
|
|
if((src1_data+imm_data)%2 !=0 ) begin
|
|
`uvm_error(get_type_name(),$sformatf("instruction lhu but read address(%0h) is illegal",src1_data+imm_data))
|
|
end
|
|
des_reg_data = ram_offset == 0 ? {16'h0,rd_ram_data[15:0]} : {16'h0,rd_ram_data[31:16]};
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type lhu",opcode),UVM_LOW)
|
|
end
|
|
else begin
|
|
`uvm_error(get_type_name(),$sformatf("I type opcode,funct3(%b)is illegal",funct3))
|
|
end
|
|
mcu_addr = mcu_addr+32'h4;
|
|
end
|
|
else if(opcode == 7'b0100011) begin // S type
|
|
imm_data = {mcu_data[31:25],mcu_data[11:7]};
|
|
imm_data_com = {imm_data[11],~mcu_data[10:0]} + 1;
|
|
imm_data_unsigned = imm_data;
|
|
src1_data = mcu_reg.exists(src_reg1_addr) ? mcu_reg[src_reg1_addr] : 0;
|
|
src2_data = mcu_reg.exists(src_reg2_addr) ? mcu_reg[src_reg2_addr] : 0;
|
|
`uvm_info(get_type_name(),$sformatf("src1_data=%0h,src2_data=%0h",src1_data,src2_data),UVM_LOW)
|
|
src1_data_com = {src1_data[31],~src1_data[30:0]} + 1'b1;
|
|
src2_data_com = {src2_data[31],~src2_data[30:0]} + 1'b1;
|
|
src1_data_unsigned = src1_data;
|
|
src2_data_unsigned = src2_data;
|
|
if(funct3 == 3'b000) begin //S sb
|
|
ram_data[src1_data+imm_data][31:8] = ram_data.exists(src1_data+imm_data) ? ram_data[src1_data+imm_data][31:8] : 24'h0;
|
|
ram_data[src1_data+imm_data][7:0] = src2_data[7:0];
|
|
ram_byte = (src1_data + imm_data)%4;
|
|
ram_wr = 1;
|
|
wr_ram_data = {4{src2_data[7:0]}};
|
|
ram_mask = 4'b0000;
|
|
ram_mask[ram_byte] = 1'b1;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type sb",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b001) begin //S sh
|
|
ram_data[src1_data+imm_data][31:16] = ram_data.exists(src1_data+imm_data) ? ram_data[src1_data+imm_data][31:16] : 16'h0;
|
|
ram_data[src1_data+imm_data][15:0] = src2_data[15:0];
|
|
ram_byte = (src1_data + imm_data)%4;
|
|
ram_wr = 1;
|
|
wr_ram_data = {2{src2_data[15:0]}};
|
|
if (ram_byte == 0 || ram_byte ==2) begin
|
|
ram_mask = (ram_byte == 0) ? 4'b0011 : 4'b1100;
|
|
end
|
|
else begin
|
|
ram_mask = 0;
|
|
`uvm_error(get_type_name(),$sformatf("instruction sh,but write address(%0h) is illegal",src1_data+imm_data))
|
|
end
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type sh",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b010) begin //S sw
|
|
ram_data[src1_data+imm_data] = src2_data;
|
|
ram_wr = 1;
|
|
wr_ram_data = src2_data;
|
|
ram_mask = 4'b1111;
|
|
if((src1_data+imm_data)%4!=0) begin
|
|
`uvm_error(get_type_name(),$sformatf("instruction sw but write address(%0h) is illegal",src1_data+imm_data))
|
|
end
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type sw",opcode),UVM_LOW)
|
|
end
|
|
else begin
|
|
ram_wr = 0;
|
|
wr_ram_data = 0;
|
|
ram_mask = 0;
|
|
`uvm_error(get_type_name(),$sformatf("S type opcode,funct3(%b)is illegal",funct3))
|
|
end
|
|
mcu_addr = mcu_addr+32'h4;
|
|
if(ram_wr==1) begin
|
|
ram_wr = 0;
|
|
mcu_cw_item = new();
|
|
mcu_cw_item.clock_cycle = clock_cnt + 1;
|
|
mcu_cw_item.cw_data = 0;
|
|
mcu_cw_item.wr_ram = 1;
|
|
mcu_cw_item.wr_ram_addr = src1_data+imm_data;
|
|
mcu_cw_item.wr_ram_data = wr_ram_data;
|
|
mcu_cw_item.wr_ram_mask = ram_mask;
|
|
mcu_cw_item.wr_reg = 0;
|
|
mcu_cw_item.wr_reg_addr = 0;
|
|
mcu_cw_item.wr_reg_data = 0;
|
|
`uvm_info(get_type_name(),"mcu_rm send mcu_cw_item to scoreboard",UVM_LOW)
|
|
mcu_cw_item.print();
|
|
mcu_cw_item_q.push_back(mcu_cw_item);
|
|
end
|
|
end
|
|
else if(opcode == 7'b1100011) begin //B type
|
|
src1_data = mcu_reg.exists(src_reg1_addr) ? mcu_reg[src_reg1_addr] : 0;
|
|
src2_data = mcu_reg.exists(src_reg2_addr) ? mcu_reg[src_reg2_addr] : 0;
|
|
src1_data_unsigned = src1_data;
|
|
src2_data_unsigned = src2_data;
|
|
`uvm_info(get_type_name(),$sformatf("src1_data=%0h,src2_data=%0h",src1_data,src2_data),UVM_LOW)
|
|
b_imm_data = {mcu_data[31],mcu_data[7],mcu_data[30:25],mcu_data[11:8],1'b0};
|
|
if(funct3 == 3'b000) begin //B beq
|
|
b_condition = (src1_data == src2_data) ? 1 : 0;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type beq",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b001) begin //B bne
|
|
b_condition = (src1_data != src2_data) ? 1 : 0;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type bne",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b100) begin //B blt
|
|
b_condition = (src1_data < src2_data) ? 1 : 0;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type blt",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b101) begin //B bge
|
|
b_condition = (src1_data >= src2_data) ? 1 : 0;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type bge",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b110) begin //B bltu
|
|
b_condition = (src1_data_unsigned < src2_data_unsigned) ? 1 : 0;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type bltu",opcode),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b111) begin //B bgeu
|
|
b_condition = (src1_data_unsigned >= src2_data_unsigned) ? 1 : 0;
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type bgeu",opcode),UVM_LOW)
|
|
end
|
|
else begin
|
|
`uvm_error(get_type_name(),$sformatf("B type opcode,funct3(%0b) is illegal",funct3))
|
|
end
|
|
if(b_condition == 1) begin
|
|
mcu_addr = mcu_addr + b_imm_data;
|
|
b_condition = 0;
|
|
end
|
|
else begin
|
|
mcu_addr = mcu_addr + 32'h4;
|
|
end
|
|
end
|
|
else if(opcode == 7'b0110111) begin //U type lui
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type lui",opcode),UVM_LOW)
|
|
u_imm_data = mcu_data[31:12];
|
|
des_reg_wr = 1;
|
|
des_reg_data = {u_imm_data,12'h0};
|
|
mcu_addr = mcu_addr + 32'h4;
|
|
end
|
|
else if(opcode == 7'b0010111) begin //U type auipc
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type auipc",opcode),UVM_LOW)
|
|
u_imm_data = mcu_data[31:12];
|
|
des_reg_wr = 1;
|
|
des_reg_data = mcu_addr + {u_imm_data,12'h0};
|
|
mcu_addr = mcu_addr + 32'h4;
|
|
end
|
|
else if(opcode == 7'b1101111) begin //J type jal
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type jal",opcode),UVM_LOW)
|
|
j_imm_data_21 = {mcu_data[31],mcu_data[19:12],mcu_data[20],mcu_data[30:21],1'b0};
|
|
`uvm_info(get_type_name(),$sformatf("mcu_data = %h,j_imm_data_21 = %0h",mcu_data,j_imm_data_21),UVM_LOW)
|
|
des_reg_wr = 1;
|
|
des_reg_data = mcu_addr +32'h4;
|
|
mcu_addr = mcu_addr + j_imm_data_21;
|
|
end
|
|
else if(opcode == 7'b1100111) begin //J type jalr
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type jalr",opcode),UVM_LOW)
|
|
src1_data = mcu_reg.exists(src_reg1_addr) ? mcu_reg[src_reg1_addr] : 0;
|
|
j_imm_data_12 = mcu_data[31:20];
|
|
des_reg_wr = 1;
|
|
des_reg_data = mcu_addr + 32'h4;
|
|
mcu_addr = src1_data + j_imm_data_12;
|
|
end
|
|
else if(opcode == 7'b0001011) begin
|
|
src1_data = mcu_reg.exists(src_reg1_addr) ? mcu_reg[src_reg1_addr] : 0;
|
|
src1_data_com = (src1_data[31]==0) ? src1_data : {src1_data[31],~src1_data[30:0]} + 1'b1;
|
|
imm_data = mcu_data[31:20];
|
|
imm_32 = {{21{imm_data[11]}},imm_data[10:0]};
|
|
//imm_data_com = {imm_data[11],~mcu_data[10:0]} + 1;
|
|
`uvm_info(get_type_name(),$sformatf("src_reg1_addr=%0h,src1_data=%0h,imm_data=%0h,imm_32=%0h",src_reg1_addr,src1_data,imm_data,imm_32),UVM_LOW)
|
|
if(funct3 == 3'b000) begin //WAIT
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type wait",opcode),UVM_LOW)
|
|
clock_cnt = clock_cnt + src1_data + imm_32;
|
|
des_reg_data = src1_data + imm_32;
|
|
des_reg_wr = 1;
|
|
`uvm_info(get_type_name(),$sformatf("wait %0d cycle,clock_cnt=%0d",src1_data+imm_32,clock_cnt),UVM_LOW)
|
|
end
|
|
else if(funct3 == 3'b010) begin //SEND
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type send",opcode),UVM_LOW)
|
|
mcu_cw_item = new();
|
|
mcu_cw_item.clock_cycle = clock_cnt+1;
|
|
`uvm_info(get_type_name(),$sformatf("clock_cnt=%0d",clock_cnt),UVM_LOW)
|
|
des_reg_data = src1_data + imm_32;
|
|
des_reg_wr = 1;
|
|
mcu_cw_item.cw_data = src1_data + imm_32;
|
|
`uvm_info(get_type_name(),"mcu_rm send mcu_cw_item to scoreboard",UVM_LOW)
|
|
mcu_cw_item.print();
|
|
mcu_cw_item_q.push_back(mcu_cw_item);
|
|
end
|
|
else if(funct3 == 3'b011) begin //SENDC
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type sendc",opcode),UVM_LOW)
|
|
mcu_cw_item = new();
|
|
mcu_cw_item.clock_cycle = clock_cnt+1;
|
|
des_reg_data = src1_data + imm_32 + feedback;
|
|
des_reg_wr = 1;
|
|
mcu_cw_item.cw_data = src1_data + imm_32 + feedback;
|
|
`uvm_info(get_type_name(),"mcu_rm send mcu_cw_item to scoreboard",UVM_LOW)
|
|
mcu_cw_item.print();
|
|
mcu_cw_item_q.push_back(mcu_cw_item);
|
|
end
|
|
mcu_addr = mcu_addr + 32'h4;
|
|
end
|
|
else if(opcode == 7'b0101011 && mcu_data[31:7]==25'h0) begin //EXIT
|
|
`uvm_info(get_type_name(),$sformatf("mcu opcode = %b,instruction is type exit",opcode),UVM_LOW)
|
|
mcu_finish = 1;
|
|
clock_cnt = 0;
|
|
end
|
|
if(des_reg_wr == 1 && des_reg_addr!=0) begin
|
|
mcu_cw_item = new();
|
|
mcu_cw_item.clock_cycle = clock_cnt + 2;
|
|
mcu_cw_item.cw_data = 0;
|
|
mcu_cw_item.wr_ram = 0;
|
|
mcu_cw_item.wr_ram_addr = 0;
|
|
mcu_cw_item.wr_ram_data = 0;
|
|
mcu_cw_item.wr_reg = 1;
|
|
mcu_cw_item.wr_reg_addr = des_reg_addr;
|
|
mcu_cw_item.wr_reg_data = des_reg_data;
|
|
`uvm_info(get_type_name(),"mcu_rm send mcu_cw_item to scoreboard",UVM_LOW)
|
|
mcu_cw_item.print();
|
|
mcu_cw_item_q.push_back(mcu_cw_item);
|
|
mcu_reg[des_reg_addr] = des_reg_data;
|
|
des_reg_wr = 0;
|
|
end
|
|
clock_cnt = clock_cnt + 3;
|
|
//`uvm_info(get_type_name(),$sformatf("clock_cnt=%0d",clock_cnt),UVM_LOW)
|
|
@(posedge `CLK);
|
|
end
|
|
else begin
|
|
@(posedge `CLK);
|
|
mcu_finish = 1;
|
|
clock_cnt = 0;
|
|
end
|
|
end
|
|
endtask
|
|
|
|
|
|
|
|
|
|
|
|
task EZQ_readout_refm::send_awg_codeword();
|
|
mcu_cw_item mcu_cw_item;
|
|
forever begin
|
|
if(awg_mcu_cw_item_q.size()>0) begin
|
|
mcu_cw_item = awg_mcu_cw_item_q.pop_front();
|
|
`uvm_info(get_type_name(),"awg send mcu_cw_item",UVM_LOW)
|
|
mcu_cw_item.print();
|
|
mcu_2awgrm_port.write(mcu_cw_item);
|
|
end
|
|
@(posedge `CLK);
|
|
end
|
|
endtask
|
|
|
|
task EZQ_readout_refm::send_daq_codeword();
|
|
mcu_cw_item mcu_cw_item;
|
|
forever begin
|
|
if(daq_mcu_cw_item_q.size()>0) begin
|
|
mcu_cw_item = daq_mcu_cw_item_q.pop_front();
|
|
`uvm_info(get_type_name(),"daq send mcu_cw_item",UVM_LOW)
|
|
mcu_cw_item.print();
|
|
mcu_2daqrm_port.write(mcu_cw_item);
|
|
end
|
|
@(posedge `CLK);
|
|
end
|
|
endtask
|
|
|
|
task EZQ_readout_refm::run_phase(uvm_phase phase);
|
|
fork
|
|
get_spi_item();
|
|
get_config_data();
|
|
mcu_process(32'h700000,ram_data,awg_mcu_reg,ram_data,awg_mcu_finish,awg_mcu_cw_item_q);
|
|
mcu_process(32'h200000,ram_data,daq_mcu_reg,ram_data,daq_mcu_finish,daq_mcu_cw_item_q);
|
|
|
|
send_awg_codeword();
|
|
send_daq_codeword();
|
|
join_none
|
|
wait(awg_mcu_finish && daq_mcu_finish);
|
|
disable fork;
|
|
|
|
endtask : run_phase
|
|
|
|
`endif //EZQ_READOUT_REFM
|