abstractaccelerator/opene906/smart_run/logical/tb/had_drv.h

603 lines
17 KiB
C

/*Copyright 2020-2021 T-Head Semiconductor Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//signal remaning
`ifdef JTAG_5
`define jtag_tdo tb.jtg_tdo
`define jtag_tdi tb.jtg_tdi
`endif
`define jtag_tclk tb.jclk
`define jtag_tms tb.jtg_tms
`define jtag_trst_b tb.jrst_b
//-----------------------------------------------
//define the instructions opcodes
`define BKPT32 32'h80000000
`define BKPT16 16'h0
`define MOV_R0_R0 32'hc4004820
`define MOV_R1_R1 32'hc4014821
`define MOV_R2_R2 32'hc4024822
`define MOV_R3_R3 32'hc4034823
`define MOV_R4_R4 32'hc4044824
`define MOV_R5_R5 32'hc4054825
`define MOV_R6_R6 32'hc4064826
`define MOV_R7_R7 32'hc4074827
`define MOV_R8_R8 32'hc4084828
`define MOV_R9_R9 32'hc4094829
`define MOV_R10_R10 32'hc40a482a
`define MOV_R11_R11 32'hc40b482b
`define MOV_R12_R12 32'hc40c482c
`define MOV_R13_R13 32'hc40d482d
`define MOV_R14_R14 32'hc40e482e
`define MOV_R15_R15 32'hc40f482f
`define MOV_R16_R16 32'hc4104830
`define MOV_R17_R17 32'hc4114831
`define MOV_R18_R18 32'hc4124832
`define MOV_R19_R19 32'hc4134833
`define MOV_R20_R20 32'hc4144834
`define MOV_R21_R21 32'hc4154835
`define MOV_R22_R22 32'hc4164836
`define MOV_R23_R23 32'hc4174837
`define MOV_R24_R24 32'hc4184838
`define MOV_R25_R25 32'hc4194839
`define MOV_R26_R26 32'hc41a483a
`define MOV_R27_R27 32'hc41b483b
`define MOV_R28_R28 32'hc41c483c
`define MOV_R29_R29 32'hc41d483d
`define MOV_R30_R30 32'hc41e483e
`define MOV_R31_R31 32'hc41f483f
`define MFCR_R1_CR0 32'hc0006021
`define MFCR_R1_CR1 32'hc0016021
`define MFCR_R1_CR2 32'hc0026021
`define MFCR_R1_CR3 32'hc0036021
`define MFCR_R1_CR4 32'hc0046021
`define MFCR_R1_CR5 32'hc0056021
`define MFCR_R1_CR6 32'hc0066021
`define MFCR_R1_CR7 32'hc0076021
`define MFCR_R1_CR8 32'hc0086021
`define MFCR_R1_CR9 32'hc0096021
`define MFCR_R1_CR10 32'hc00a6021
`define MFCR_R1_CR11 32'hc00b6021
`define MFCR_R1_CR12 32'hc00c6021
`define MFCR_R1_CR13 32'hc00d6021
`define MFCR_R1_CR14 32'hc00e6021
`define MFCR_R1_CR15 32'hc00f6021
`define MFCR_R1_CR16 32'hc0106021
`define MFCR_R1_CR17 32'hc0116021
`define MFCR_R1_CR18 32'hc0126021
`define MFCR_R1_CR19 32'hc0136021
`define MFCR_R1_CR20 32'hc0146021
`define MFCR_R1_CR21 32'hc0156021
`define MTCR_R1_CR0 32'hc0016420
`define MTCR_R1_CR1 32'hc0016421
`define MTCR_R1_CR2 32'hc0016422
`define MTCR_R1_CR3 32'hc0016423
`define MTCR_R1_CR4 32'hc0016424
`define MTCR_R1_CR5 32'hc0016425
`define MTCR_R1_CR6 32'hc0016426
`define MTCR_R1_CR7 32'hc0016427
`define MTCR_R1_CR8 32'hc0016428
`define MTCR_R1_CR9 32'hc0016429
`define MTCR_R1_CR10 32'hc001642a
`define MTCR_R1_CR11 32'hc001642b
`define MTCR_R1_CR12 32'hc001642c
`define MTCR_R1_CR13 32'hc001642d
`define LDW_R1_R2_0x0 32'hd8222000
`define LDW_R1_R2_0x4 32'hd8222001
`define LDW_R1_R2_0x8 32'hd8222002
`define LDW_R1_R2_0xc 32'hd8222003
`define LDW_R1_R2_0x10 32'hd8222004
`define LDW_R1_R2_0x14 32'hd8222005
`define LDW_R1_R2_0x18 32'hd8222006
`define LDW_R1_R2_0x1c 32'hd8222007
`define LDW_R1_R2_0x20 32'hd8222008
`define LDW_R1_R2_0x24 32'hd8222009
`define LDW_R1_R2_0x28 32'hd822200a
`define LDW_R1_R2_0x2c 32'hd822200b
`define LDW_R1_R2_0x30 32'hd822200c
`define LDW_R1_R2_0x34 32'hd822200d
`define LDW_R1_R2_0x38 32'hd822200e
`define LDW_R1_R2_0x3c 32'hd822200f
`define LDW_R1_R2_0x40 32'hd8222010
`define LDW_R1_R2_0x44 32'hd8222011
`define LDW_R1_R2_0x48 32'hd8222012
`define LDW_R1_R2_0x4c 32'hd8222013
`define LDW_R1_R2_0x50 32'hd8222014
`define LDW_R1_R2_0x54 32'hd8222015
`define LDW_R1_R6_0x0 32'hd8262000
`define LDW_R1_R6_0x4 32'hd8262001
`define STW_R1_R2_0x0 32'hdc222000
`define STW_R1_R5_0x0 32'hdc252000
`define STW_R1_R5_0x4 32'hdc252001
`define STW_R1_R5_0x8 32'hdc252002
`define STW_R1_R5_0xc 32'hdc252003
`define STW_R1_R5_0x10 32'hdc252004
//-----------------------------------------------
//define the HAD registers
`define id 7'b0000010
`define tracer 7'b0000011
`define mbca 7'b0000100
`define mbcb 7'b0000101
`define pcfifo 7'b0000110
`define baba 7'b0000111
`define babb 7'b0001000
`define bama 7'b0001001
`define bamb 7'b0001010
`define cpuscr 7'b0001011
`define bypass 7'b0001100
`define hcr 7'b0001101
`define hsr 7'b0001110
`define daddr 7'b0011000
`define ddata 7'b0011001
`define wbbr 7'b0010001
`define psr 7'b0010010
`define pc 7'b0010011
`define ir 7'b0010100
`define csr 7'b0010101
`define wbbr_go_ex 7'b1110001
`define wbbr_go_nex 7'b1010001
`define wbbr_ngo_ex 7'b0110001
`define wbbr_ngo_nex 7'b0010001
`define psr_go_ex 7'b1110010
`define psr_go_nex 7'b1010010
`define psr_ngo_ex 7'b0110010
`define psr_ngo_nex 7'b0010010
`define pc_go_ex 7'b1110011
`define pc_go_nex 7'b1010011
`define pc_ngo_ex 7'b0110011
`define pc_ngo_nex 7'b0010011
`define ir_go_ex 7'b1110100
`define ir_go_nex 7'b1010100
`define ir_ngo_ex 7'b0110100
`define ir_ngo_nex 7'b0010100
`define csr_go_ex 7'b1110101
`define csr_go_nex 7'b1010101
`define csr_ngo_ex 7'b0110101
`define csr_ngo_nex 7'b0010101
`define cpuscr_go_ex 7'b1101011
`define cpuscr_go_nex 7'b1001011
`define bypass_go_ex 7'b1101100
`define bypass_go_nex 7'b1001100
`define bypass_ngo_ex 7'b0101100
`define bypass_ngo_nex 7'b0001100
`ifdef JTAG_5
// Task for JTAG 5
//jtag reset, for example: jtag_rst(100)
task jtag_rst;
input[31:0] rst_cycle;
integer i;
begin
force `jtag_trst_b = 1'b1;
force `jtag_tms = 1'b0;
//wait until posedge tclk
@(negedge `jtag_tclk);
force `jtag_trst_b = 1'b0;
//wait for user specified cycles
for(i=0; i<rst_cycle; i=i+1)
@(negedge `jtag_tclk);
force `jtag_trst_b = 1'b1;
//drive TAP state machine into IDLE state
@(negedge `jtag_tclk);
@(negedge `jtag_tclk);
force `jtag_tms = 1'b0;
end
endtask
//write IR
task write_ir;
input [7:0] ir_value;
integer i;
reg parity;
begin
@(negedge `jtag_tclk); //drive to Select DR Scan
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); //drive to Select IR Scan
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); //drive to Capture IR
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk); //drive to Shift IR
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk);
for(i=0;i<7;i=i+1)begin
force `jtag_tms = 1'b0;
force `jtag_tdi = ir_value[i];
@(negedge `jtag_tclk); //stay at Shift IR cycle
end
force `jtag_tms = 1'b1; //stay at Shift IR cycle 8,drive to EXIT IR
force `jtag_tdi = ir_value[7];
@(negedge `jtag_tclk); //drive to Update IR
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); //drive to IDLE
force `jtag_tms = 1'b0;
end
endtask
//write DR
task write_dr;
input [143:0] jtag_data_in;
input [8:0] jtag_data_len;
integer i;
reg parity;
begin
@(negedge `jtag_tclk); //drive to Select DR Scan
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); //drive to Capture DR
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk); //drive to Shift DR
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk);
for(i=0;i<jtag_data_len-1;i=i+1)begin
force `jtag_tms = 1'b0;
force `jtag_tdi = jtag_data_in[i];
@(negedge `jtag_tclk); //stay at Shift DR cycle i
end
force `jtag_tms = 1'b1; //stay at Shift DR last cycle
force `jtag_tdi = jtag_data_in[i];
@(negedge `jtag_tclk); //drive to Update DR
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); //drive to IDLE
force `jtag_tms = 1'b0;
end
endtask
//Read DR
task read_dr;
input [8:0] jtag_data_len;
output [143:0] jtag_data_out;
reg [143:0] jtag_data_out;
integer i;
reg parity;
begin
@(negedge `jtag_tclk); //drive to Select DR Scan
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); //drive to Capture DR
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk); //drive to Shift DR
force `jtag_tms = 1'b0;
for(i=0;i<jtag_data_len-1;i=i+1)begin
@(negedge `jtag_tclk); //stay at Shift DR cycle i
force `jtag_tms = 1'b0;
@(posedge `jtag_tclk);
jtag_data_out[i] = `jtag_tdo;
end
@(negedge `jtag_tclk); //stay at Shift DR last cycle
force `jtag_tms = 1'b1;
@(posedge `jtag_tclk);
jtag_data_out[i] = `jtag_tdo;
@(negedge `jtag_tclk); //drive to Update DR
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); //drive to IDLE
force `jtag_tms = 1'b0;
end
endtask
`else
// Task for JTAG 2
//jtag reset, for example: jtag_rst(100)
task jtag_rst;
input[31:0] rst_cycle;
integer i;
begin
force `jtag_trst_b = 1'b1;
force `jtag_tms = 1'b1;
//wait until posedge tclk
@(negedge `jtag_tclk);
force `jtag_trst_b = 1'b0;
//wait for user specified cycles
for(i=0; i<rst_cycle; i=i+1)
@(negedge `jtag_tclk);
force `jtag_trst_b = 1'b1;
//drive TAP state machine into IDLE state
@(negedge `jtag_tclk);
@(negedge `jtag_tclk);
force `jtag_tms = 1'b1;
end
endtask
//write IR
task write_ir;
input [7:0] ir_value;
integer i;
reg parity;
begin
parity = 1'b1;
@(negedge `jtag_tclk); // start
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk); // read/write
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk); // RS[0]
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk); // RS[1]
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); // Trn
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk);
for(i=0; i<8; i=i+1)begin
force `jtag_tms = ir_value[i];
parity = parity ^ ir_value[i];
@(negedge `jtag_tclk); // Shift IR
end
force `jtag_tms = parity;
@(negedge `jtag_tclk); // Parity
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); // Trn
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); // IDLE
end
endtask
//write DR
task write_dr;
input [143:0] jtag_data_in;
input [8:0] jtag_data_len;
integer i;
reg parity;
begin
parity = 1'b1;
@(negedge `jtag_tclk); // start
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk); // read/write
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk); // RS[0]
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); // RS[1]
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); // Trn
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk);
for(i=0; i<32; i=i+1)begin
force `jtag_tms = jtag_data_in[i];
parity = parity ^ jtag_data_in[i];
@(negedge `jtag_tclk); // Shift DR
end
force `jtag_tms = parity; // Parity
@(negedge `jtag_tclk); // Trn
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); // Drive to IDLE
force `jtag_tms = 1'b1;
end
endtask
//Read DR
task read_dr;
input [8:0] jtag_data_len;
output [143:0] jtag_data_out;
reg [143:0] jtag_data_out;
integer i;
reg parity;
begin
parity = 1'b1;
@(negedge `jtag_tclk); // start
force `jtag_tms = 1'b0;
@(negedge `jtag_tclk); // read/write
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); // RS[0]
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); // RS[1]
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); // Trn
force `jtag_tms = 1'b1;
@(posedge `jtag_tclk);
release `jtag_tms;
@(posedge `jtag_tclk); // Sync cycle
for(i=0; i<32; i=i+1)begin
@(posedge `jtag_tclk); // Shift DR
jtag_data_out[i] = `jtag_tms;
end
@(posedge `jtag_tclk); // Parity
parity = `jtag_tms;
@(negedge `jtag_tclk); // Trn
force `jtag_tms = 1'b1;
@(negedge `jtag_tclk); // to IDLE
force `jtag_tms = 1'b1;
end
endtask
`endif
/*****************************************************
The following task has defined the task write_hadreg.
User can invoke this task to write the target register.
If user want to write register and set go,ex simultan
-eously,just add some identifiers in agreement such as
_go_ex,_go_nex,_ngo_ex,_ngo_nex.
Special condition:the registor Bypass was cut,just reserve
the interface to keep the compatibility with CK6xx and CK5xx
usage: write_hadreg(`target_reg_name,value)
write_hadreg(`wbbr_go_ex,value)
*******************************************************/
task write_hadreg;
input[6:0] reg_select;
input[143:0] reg_value;
// input[143:0] cpuscr_value;
begin
case(reg_select & 7'b0011111)
`id,
`pcfifo,
`baba,
`babb,
`wbbr,
`psr,
`pc,
`ir,
`hcr,
`daddr,
`ddata : begin
write_ir({1'b0,reg_select[6:0]});//select id
write_dr(reg_value,32);
end
`tracer,
`mbca,
`mbcb,
`bama,
`bamb,
`bypass: begin
write_ir({1'b0,reg_select[6:0]});//select mbcb
write_dr(reg_value,8);
end
`hsr,
`csr : begin
write_ir({1'b0,reg_select[6:0]});//select hsr
write_dr(reg_value,16);
end
`cpuscr : begin
write_ir({1'b0,reg_select[6:0]});
write_dr(reg_value,128);
end
default:$display("There is no target!");
endcase
end
endtask
/*****************************************************
The following task has defined the task read_hadreg.
User can invoke this task to read the target
register.
Special condition:the same to write_hadreg.
usage:read_hadreg(`target_reg_name,value)
*******************************************************/
task read_hadreg;
input[6:0] reg_select;
// output[143:0] jtag_cpuscr_out;
output[143:0] jtag_data_out;
reg[143:0] jtag_data_out;
// reg[143:0] jtag_cpuscr_out;
begin
case(reg_select & 7'b0011111)
`id,
`pcfifo,
`baba,
`babb,
`wbbr,
`psr,
`pc,
`ir,
`hcr,
`daddr,
`ddata : begin
write_ir({1'b1,reg_select[6:0]});//select id
read_dr(32, jtag_data_out);
end
`tracer,
`mbca,
`mbcb,
`bama,
`bamb,
`bypass:begin
write_ir({1'b1,reg_select[6:0]});//select mbcb
read_dr(8, jtag_data_out);
end
`hsr,
`csr : begin
write_ir({1'b1,reg_select[6:0]});//select hsr
read_dr(16, jtag_data_out);
end
`cpuscr : begin
write_ir({1'b1,reg_select[6:0]});
read_dr(128, jtag_data_out);
end
default:$display("There is no target!");
endcase
end
endtask
/***********************************************************
The following task was defined to wait CPU enter into debug
mode.
************************************************************/
task wait_debug_mode;
reg[15:0] hsr_data_out;
begin
read_hadreg(`hsr,hsr_data_out);
$display("---------------------------------------");
$display("wait into debug mode...... |");
$display("<wait_begin> The hsr is: 0x%h |",
hsr_data_out[15:0]);
while(hsr_data_out[1:0]!=2'b10)
read_hadreg(`hsr,hsr_data_out);
$display("<wait_end> The hsr is: 0x%h |",
hsr_data_out[15:0]);
$display("Now, CPU is in Debug Mode! |");
$display("---------------------------------------");
end
endtask
/***********************************************************
The following task was defined to check the cpu mode.
If the cpu has into debug mode,
************************************************************/
task check_cpu_mode;
reg[15:0] hsr_data_out;
begin
read_hadreg(`hsr,hsr_data_out);
if(hsr_data_out[1:0]==2'b00)
begin
$display("----------------------------------------");
$display("*** <CHECK> hsr value is:0x%h *** |",
hsr_data_out[15:0]);
$display("*** CPU is in Normal Mode! *** |");
$display("----------------------------------------");
end
else if(hsr_data_out[1:0]==2'b01)
begin
$display("----------------------------------------");
$display("*** <CHECK> hsr value is:0x%h *** |",
hsr_data_out[15:0]);
$display("*** CPU is in LowPower Mode! *** |");
$display("----------------------------------------");
end
else if(hsr_data_out[1:0]==2'b10)
begin
$display("----------------------------------------");
$display("*** <CHECK> hsr value is:0x%h *** |",
hsr_data_out[15:0]);
$display("*** CPU is in Debug Mode! *** |");
$display("----------------------------------------");
end
else
begin
$display("----------------------------------------");
$display("*** <CHECK> hsr value is:0x%h *** |",
hsr_data_out[15:0]);
$display("*** CPU is in Reserve Mode! *** |");
$display("----------------------------------------");
end
end
endtask