添加读出refm顶层

This commit is contained in:
zhangyz 2025-03-20 15:51:20 +08:00
parent cdc0bef9d9
commit 5266c27908
1 changed files with 789 additions and 0 deletions

789
EZQ_readout_refm.sv Normal file
View File

@ -0,0 +1,789 @@
//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