Line 4... |
Line 4... |
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//// This file is part of the SoC/OpenRISC Development Interface ////
|
//// This file is part of the SoC/OpenRISC Development Interface ////
|
//// http://www.opencores.org/projects/DebugInterface/ ////
|
//// http://www.opencores.org/projects/DebugInterface/ ////
|
//// ////
|
//// ////
|
//// ////
|
|
//// Author(s): ////
|
//// Author(s): ////
|
//// Igor Mohor ////
|
//// Igor Mohor (igorm@opencores.org) ////
|
//// igorm@opencores.org ////
|
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//// All additional information is avaliable in the README.txt ////
|
//// All additional information is avaliable in the README.txt ////
|
//// file. ////
|
//// file. ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2000,2001 Authors ////
|
//// Copyright (C) 2000 - 2003 Authors ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
Line 43... |
Line 41... |
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.14 2003/10/23 16:16:30 mohor
|
|
// CRC logic changed.
|
|
//
|
// Revision 1.13 2003/08/28 13:54:33 simons
|
// Revision 1.13 2003/08/28 13:54:33 simons
|
// Three more chains added for cpu debug access.
|
// Three more chains added for cpu debug access.
|
//
|
//
|
// Revision 1.12 2002/05/07 14:44:52 mohor
|
// Revision 1.12 2002/05/07 14:44:52 mohor
|
// mon_cntl_o signals that controls monitor mux added.
|
// mon_cntl_o signals that controls monitor mux added.
|
Line 98... |
Line 99... |
//
|
//
|
|
|
|
|
`include "timescale.v"
|
`include "timescale.v"
|
`include "dbg_defines.v"
|
`include "dbg_defines.v"
|
`include "dbg_tb_defines.v"
|
`include "dbg_wb_defines.v"
|
|
//`include "dbg_tb_defines.v"
|
|
|
// Test bench
|
// Test bench
|
module dbg_tb;
|
module dbg_tb;
|
|
|
parameter Tp = 1;
|
parameter TCLK = 50; // Clock half period (Clok period = 100 ns => 10 MHz)
|
parameter Tclk = 50; // Clock half period (Clok period = 100 ns => 10 MHz)
|
|
|
|
|
reg tms_pad_i;
|
|
reg tck_pad_i;
|
|
reg trst_pad_i;
|
|
reg tdi_pad_i;
|
|
wire tdo_pad_o;
|
|
wire tdo_padoe_o;
|
|
|
|
wire shift_dr_o;
|
|
wire pause_dr_o;
|
|
wire update_dr_o;
|
|
|
|
wire extest_select_o;
|
|
wire sample_preload_select_o;
|
|
wire mbist_select_o;
|
|
wire debug_select_o;
|
|
|
reg P_TMS, P_TCK;
|
// WISHBONE common signals
|
reg P_TRST, P_TDI;
|
|
reg wb_rst_i;
|
reg wb_rst_i;
|
reg Mclk;
|
reg wb_clk_i;
|
|
|
reg [10:0] Wp;
|
// WISHBONE master interface
|
reg Bp;
|
wire [31:0] wb_adr_o;
|
reg [3:0] LsStatus;
|
wire [31:0] wb_dat_o;
|
reg [1:0] IStatus;
|
wire [31:0] wb_dat_i;
|
reg BS_CHAIN_I;
|
wire wb_cyc_o;
|
reg MBIST_I;
|
wire wb_stb_o;
|
|
wire [3:0] wb_sel_o;
|
|
wire wb_we_o;
|
|
wire wb_ack_i;
|
|
wire wb_cab_o;
|
|
wire wb_err_i;
|
|
wire [2:0] wb_cti_o;
|
|
wire [1:0] wb_bte_o;
|
|
|
wire P_TDO;
|
|
wire [31:0] ADDR_CPU;
|
|
wire [31:0] DATAIN_CPU; // DATAIN_CPU is connect to DATAOUT
|
|
|
|
wire [31:0] DATAOUT_CPU; // DATAOUT_CPU is connect to DATAIN
|
|
|
|
wire [`OPSELECTWIDTH-1:0] OpSelect;
|
|
|
|
wire [31:0] wb_adr_i;
|
|
wire [31:0] wb_dat_i;
|
|
reg [31:0] wb_dat_o;
|
|
wire wb_cyc_i;
|
|
wire wb_stb_i;
|
|
wire [3:0] wb_sel_i;
|
|
wire wb_we_i;
|
|
reg wb_ack_o;
|
|
wire wb_cab_i;
|
|
reg wb_err_o;
|
|
|
|
wire ShiftDR;
|
|
wire Exit1DR;
|
|
wire UpdateDR;
|
|
wire UpdateDR_q;
|
|
wire CaptureDR;
|
|
wire SelectDRScan;
|
|
wire IDCODESelected;
|
|
wire CHAIN_SELECTSelected;
|
|
wire DEBUGSelected;
|
|
wire TDOData_dbg;
|
|
wire BypassRegister;
|
|
wire EXTESTSelected;
|
|
wire MBISTSelected;
|
|
wire [3:0] mon_cntl_o;
|
|
wire CpuDebugScanChain0;
|
|
wire CpuDebugScanChain1;
|
|
wire CpuDebugScanChain2;
|
|
wire CpuDebugScanChain3;
|
|
|
|
|
|
// Connecting TAP module
|
wire tdo_o;
|
tap_top i_tap_top
|
|
(.tms_pad_i(P_TMS), .tck_pad_i(P_TCK), .trst_pad_i(P_TRST), .tdi_pad_i(P_TDI),
|
|
.tdo_pad_o(P_TDO), .tdo_padoe_o(tdo_padoe_o),
|
|
|
|
// TAP states
|
wire debug_tdi_i;
|
.ShiftDR(ShiftDR), .Exit1DR(Exit1DR), .UpdateDR(UpdateDR), .UpdateDR_q(UpdateDR_q),
|
wire bs_chain_tdi_i;
|
.CaptureDR(CaptureDR), .SelectDRScan(SelectDRScan),
|
wire mbist_tdi_i;
|
|
|
// Instructions
|
reg test_enabled;
|
.IDCODESelected(IDCODESelected), .CHAIN_SELECTSelected(CHAIN_SELECTSelected),
|
|
.DEBUGSelected(DEBUGSelected), .EXTESTSelected(EXTESTSelected),
|
|
.MBISTSelected(MBISTSelected),
|
|
|
|
// TDO from dbg module
|
|
.TDOData_dbg(TDOData_dbg), .BypassRegister(BypassRegister),
|
|
|
|
// Boundary Scan Chain
|
|
.bs_chain_i(BS_CHAIN_I),
|
|
|
|
// From Mbist Chain
|
|
.mbist_so_i(MBIST_I),
|
|
|
|
// Selected chains
|
|
.RegisterScanChain(RegisterScanChain),
|
|
.CpuDebugScanChain0(CpuDebugScanChain0),
|
|
.CpuDebugScanChain1(CpuDebugScanChain1),
|
|
.CpuDebugScanChain2(CpuDebugScanChain2),
|
|
.CpuDebugScanChain3(CpuDebugScanChain3),
|
|
.WishboneScanChain(WishboneScanChain)
|
|
|
|
);
|
reg [31:0] result;
|
|
|
|
wire tdo;
|
|
|
|
assign tdo = tdo_padoe_o? tdo_pad_o : 1'hz;
|
|
|
dbg_top i_dbg_top
|
// Connecting TAP module
|
(
|
tap_top i_tap_top (
|
.cpu_clk_i(Mclk), .cpu_addr_o(ADDR_CPU), .cpu_data_i(DATAOUT_CPU),
|
.tms_pad_i(tms_pad_i),
|
.cpu_data_o(DATAIN_CPU), .wp_i(Wp), .bp_i(Bp), .opselect_o(OpSelect),
|
.tck_pad_i(tck_pad_i),
|
.lsstatus_i(LsStatus), .istatus_i(IStatus), .cpu_stall_o(),
|
.trst_pad_i(!trst_pad_i),
|
.cpu_stall_all_o(), .cpu_sel_o(), .reset_o(),
|
.tdi_pad_i(tdi_pad_i),
|
|
.tdo_pad_o(tdo_pad_o),
|
.wb_rst_i(wb_rst_i), .wb_clk_i(Mclk),
|
.tdo_padoe_o(tdo_padoe_o),
|
|
|
.wb_adr_o(wb_adr_i), .wb_dat_o(wb_dat_i), .wb_dat_i(wb_dat_o),
|
|
.wb_cyc_o(wb_cyc_i), .wb_stb_o(wb_stb_i), .wb_sel_o(wb_sel_i),
|
|
.wb_we_o(wb_we_i), .wb_ack_i(wb_ack_o), .wb_cab_o(wb_cab_i),
|
|
.wb_err_i(wb_err_o),
|
|
|
|
// TAP states
|
// TAP states
|
.ShiftDR(ShiftDR), .Exit1DR(Exit1DR), .UpdateDR(UpdateDR), .UpdateDR_q(UpdateDR_q),
|
.shift_dr_o(shift_dr_o),
|
.SelectDRScan(SelectDRScan),
|
.pause_dr_o(pause_dr_o),
|
|
.update_dr_o(update_dr_o),
|
|
|
|
// Select signals for boundary scan or mbist
|
|
.extest_select_o(extest_select_o),
|
|
.sample_preload_select_o(sample_preload_select_o),
|
|
.mbist_select_o(mbist_select_o),
|
|
.debug_select_o(debug_select_o),
|
|
|
|
// TDO signal that is connected to TDI of sub-modules.
|
|
.tdo_o(tdo_o),
|
|
|
|
// TDI signals from sub-modules
|
|
.debug_tdi_i(debug_tdi_i), // from debug module
|
|
.bs_chain_tdi_i(bs_chain_tdi_i), // from Boundary Scan Chain
|
|
.mbist_tdi_i(mbist_tdi_i) // from Mbist Chain
|
|
|
// Instructions
|
);
|
.IDCODESelected(IDCODESelected), .CHAIN_SELECTSelected(CHAIN_SELECTSelected),
|
|
.DEBUGSelected(DEBUGSelected),
|
|
|
|
// TAP signals
|
|
.trst_in(P_TRST), .tck(P_TCK), .tdi(P_TDI), .TDOData(TDOData_dbg),
|
|
|
|
.BypassRegister(BypassRegister),
|
dbg_top i_dbg_top (
|
|
|
|
.trst_i(!trst_pad_i),
|
|
.tck_i(tck_pad_i),
|
|
.tdi_i(tdo_o),
|
|
.tdo_o(debug_tdi_i),
|
|
|
.mon_cntl_o(mon_cntl_o),
|
// TAP states
|
|
.shift_dr_i (shift_dr_o),
|
|
.pause_dr_i (pause_dr_o),
|
|
.update_dr_i (update_dr_o),
|
|
|
// Selected chains
|
// Instructions
|
.RegisterScanChain(RegisterScanChain),
|
.debug_select_i(debug_select_o),
|
.CpuDebugScanChain0(CpuDebugScanChain0),
|
|
.CpuDebugScanChain1(CpuDebugScanChain1),
|
|
.CpuDebugScanChain2(CpuDebugScanChain2),
|
|
.CpuDebugScanChain3(CpuDebugScanChain3),
|
|
.WishboneScanChain(WishboneScanChain)
|
|
|
|
|
// WISHBONE common signals
|
|
.wb_rst_i (wb_rst_i),
|
|
.wb_clk_i (wb_clk_i),
|
|
|
|
// WISHBONE master interface
|
|
.wb_adr_o (wb_adr_o),
|
|
.wb_dat_o (wb_dat_o),
|
|
.wb_dat_i (wb_dat_i),
|
|
.wb_cyc_o (wb_cyc_o),
|
|
.wb_stb_o (wb_stb_o),
|
|
.wb_sel_o (wb_sel_o),
|
|
.wb_we_o (wb_we_o),
|
|
.wb_ack_i (wb_ack_i),
|
|
.wb_cab_o (wb_cab_o),
|
|
.wb_err_i (wb_err_i),
|
|
.wb_cti_o (wb_cti_o),
|
|
.wb_bte_o (wb_bte_o)
|
);
|
);
|
|
|
reg TestEnabled;
|
|
|
|
|
wb_slave_behavioral wb_slave
|
|
(
|
|
.CLK_I(wb_clk_i),
|
|
.RST_I(wb_rst_i),
|
|
.ACK_O(wb_ack_i),
|
|
.ADR_I(wb_adr_o),
|
|
.CYC_I(wb_cyc_o),
|
|
.DAT_O(wb_dat_i),
|
|
.DAT_I(wb_dat_o),
|
|
.ERR_O(wb_err_i),
|
|
.RTY_O(), // NOT USED for now!
|
|
.SEL_I(wb_sel_o),
|
|
.STB_I(wb_stb_o),
|
|
.WE_I (wb_we_o),
|
|
.CAB_I(1'b0)
|
|
);
|
|
|
|
|
|
// Initial values
|
initial
|
initial
|
begin
|
begin
|
TestEnabled<=#Tp 0;
|
test_enabled = 1'b0;
|
P_TMS<=#Tp 'hz;
|
trst_pad_i = 1'b1;
|
P_TCK<=#Tp 'hz;
|
tms_pad_i = 1'hz;
|
P_TDI<=#Tp 'hz;
|
tck_pad_i = 1'hz;
|
BS_CHAIN_I = 0;
|
tdi_pad_i = 1'hz;
|
MBIST_I = 0;
|
|
|
#100;
|
Wp<=#Tp 0;
|
trst_pad_i = 1'b0;
|
Bp<=#Tp 0;
|
#100;
|
LsStatus<=#Tp 0;
|
trst_pad_i = 1'b1;
|
IStatus<=#Tp 0;
|
#1 test_enabled<=#1 1'b1;
|
|
|
wb_dat_o<=#Tp 32'h0;
|
|
wb_ack_o<=#Tp 1'h0;
|
|
wb_err_o<=#Tp 1'h0;
|
|
|
|
|
|
|
|
wb_rst_i<=#Tp 0;
|
|
P_TRST<=#Tp 0;
|
|
#100 wb_rst_i<=#Tp 1;
|
|
P_TRST<=#Tp 1;
|
|
#100 wb_rst_i<=#Tp 0;
|
|
P_TRST<=#Tp 0;
|
|
#Tp TestEnabled<=#Tp 1;
|
|
end
|
end
|
|
|
|
|
// Generating master clock (cpu clock) 200 MHz
|
|
initial
|
initial
|
begin
|
begin
|
Mclk<=#Tp 0;
|
wb_rst_i = 1'b0;
|
#1 forever #`CPU_CLOCK Mclk<=~Mclk;
|
#1000;
|
end
|
wb_rst_i = 1'b1;
|
|
#1000;
|
|
wb_rst_i = 1'b0;
|
|
|
|
// Initial values for wishbone slave model
|
|
wb_slave.cycle_response(`ACK_RESPONSE, 8'h55, 8'h2); // (`ACK_RESPONSE, wbs_waits, wbs_retries);
|
|
end
|
|
|
// Generating random number for use in DATAOUT_CPU[31:0]
|
initial
|
reg [31:0] RandNumb;
|
|
always @ (posedge Mclk or posedge wb_rst_i)
|
|
begin
|
begin
|
if(wb_rst_i)
|
wb_clk_i = 1'b0;
|
RandNumb[31:0]<=#Tp 0;
|
forever #5 wb_clk_i = ~wb_clk_i;
|
else
|
|
RandNumb[31:0]<=#Tp RandNumb[31:0] + 1;
|
|
end
|
end
|
|
|
|
always @ (posedge test_enabled)
|
assign DATAOUT_CPU[31:0] = RandNumb[31:0];
|
|
|
|
|
|
always @ (posedge TestEnabled)
|
|
begin
|
begin
|
|
|
$display("//////////////////////////////////////////////////////////////////////////////////////");
|
$display("//////////////////////////////////////////////////////////////////");
|
$display("// //");
|
$display("// //");
|
$display("// (%0t) dbg_tb starting //", $time);
|
$display("// (%0t) dbg_tb starting //", $time);
|
$display("// //");
|
$display("// //");
|
$display("//////////////////////////////////////////////////////////////////////////////////////");
|
$display("//////////////////////////////////////////////////////////////////");
|
|
|
fork
|
initialize_memory(32'h12340000, 32'h00100000); // Initialize 0x100000 bytes starting from address 0x12340000
|
|
|
|
reset_tap;
|
|
goto_run_test_idle;
|
|
|
begin
|
// Testing read and write to internal registers
|
EnableWishboneSlave; // enabling WISHBONE slave
|
#10000;
|
end
|
set_instruction(`IDCODE);
|
|
read_id_code;
|
|
|
|
set_instruction(`DEBUG);
|
|
#10000;
|
|
|
begin
|
chain_select(`WISHBONE_SCAN_CHAIN, 32'hf2bcd929);
|
ResetTAP;
|
|
GotoRunTestIdle;
|
|
|
|
// Testing read and write to WISHBONE (WB and CPU chain are the same)
|
// #10000;
|
SetInstruction(`CHAIN_SELECT);
|
// xxx(4'b1001, 32'he579b242);
|
ChainSelect(`WISHBONE_SCAN_CHAIN, 8'h36); // {chain, crc}
|
|
SetInstruction(`DEBUG);
|
|
WriteCPURegister(32'h18273645, 32'hbeefbeef, 8'haa); // {data, addr, crc}
|
|
|
|
#10000;
|
#10000;
|
ReadCPURegister(32'h87654321, 8'hfd); // {addr, crc} // Wishbone and CPU accesses are similar
|
|
ReadCPURegister(32'h87654321, 8'hfd); // {addr, crc} // Wishbone and CPU accesses are similar
|
|
|
|
// Testing read and write to CPU0 registers
|
// debug_wishbone(`WB_READ8, 32'h12345678, 32'h0, 16'h4, 32'h08359131, result); // {command, addr, data, length, crc, result}
|
#10000;
|
// debug_wishbone(`WB_READ8, 32'h12345679, 32'h0, 16'h4, 32'hadfeabe2, result); // {command, addr, data, length, crc, result}
|
SetInstruction(`CHAIN_SELECT);
|
// debug_wishbone(`WB_READ8, 32'h1234567a, 32'h0, 16'h4, 32'hd8b08283, result); // {command, addr, data, length, crc, result}
|
ChainSelect(`CPU_DEBUG_CHAIN_0, 8'h12); // {chain, crc}
|
|
SetInstruction(`DEBUG);
|
|
WriteCPURegister(32'h11001100, 32'h00110011, 8'h86); // {data, addr, crc}
|
|
|
|
ReadCPURegister(32'h11001100, 8'hdb); // {addr, crc}
|
// debug_wishbone(`WB_READ16, 32'h12345678, 32'h0, 16'h4, 32'haf07fce0, result); // {command, addr, data, length, crc, result}
|
ReadCPURegister(32'h11001100, 8'hdb); // {addr, crc}
|
// debug_wishbone(`WB_READ16, 32'h1234567a, 32'h0, 16'h4, 32'h7f82ef52, result); // {command, addr, data, length, crc, result}
|
|
|
// Testing read and write to CPU1 registers
|
debug_wishbone(`WB_READ32, 32'h12345678, 32'h0, 16'h4, 32'h969b4113, result); // {command, addr, data, length, crc, result}
|
#10000;
|
|
SetInstruction(`CHAIN_SELECT);
|
|
ChainSelect(`CPU_DEBUG_CHAIN_1, 8'h2a); // {chain, crc}
|
|
SetInstruction(`DEBUG);
|
|
WriteCPURegister(32'h22002200, 32'h00220022, 8'h10); // {data, addr, crc}
|
|
|
|
ReadCPURegister(32'h22002200, 8'hee); // {addr, crc}
|
// debug_wishbone(`WB_READ16, 32'h12345679, 32'h0, 16'h4, 32'h0accc633, result); // {command, addr, data, length, crc, result}
|
ReadCPURegister(32'h22002200, 8'hee); // {addr, crc}
|
|
|
|
// Testing read and write to CPU2 registers
|
|
#10000;
|
#10000;
|
SetInstruction(`CHAIN_SELECT);
|
// xxx(4'b1001, 32'he579b242);
|
ChainSelect(`CPU_DEBUG_CHAIN_2, 8'h38); // {chain, crc}
|
|
SetInstruction(`DEBUG);
|
|
WriteCPURegister(32'h33003300, 32'h00330033, 8'hf4); // {data, addr, crc}
|
|
|
|
ReadCPURegister(32'h33003300, 8'h35); // {addr, crc}
|
wb_slave.cycle_response(`NO_RESPONSE, 8'h03, 8'h2); // (`NO_RESPONSE, wbs_waits, wbs_retries);
|
ReadCPURegister(32'h33003300, 8'h35); // {addr, crc}
|
debug_wishbone_shift_dr(`WB_READ32, 32'h12345678, 32'h0, 16'h4, 32'h969b4113, result); // {command, addr, data, length, crc, result}
|
|
wb_slave.cycle_response(`ACK_RESPONSE, 8'h55, 8'h2); // (`ACK_RESPONSE, wbs_waits, wbs_retries);
|
|
|
// Testing read and write to CPU3 registers
|
|
#10000;
|
#10000;
|
SetInstruction(`CHAIN_SELECT);
|
debug_wishbone_shift_dr(`WB_READ32, 32'h12346668, 32'h0, 16'h4, 32'h2ec6ae56, result); // {command, addr, data, length, crc, result}
|
ChainSelect(`CPU_DEBUG_CHAIN_3, 8'h07); // {chain, crc}
|
|
SetInstruction(`DEBUG);
|
|
WriteCPURegister(32'h44004400, 32'h00440044, 8'h5b); // {data, addr, crc}
|
|
|
|
ReadCPURegister(32'h44004400, 8'h77); // {addr, crc}
|
|
ReadCPURegister(32'h44004400, 8'h77); // {addr, crc}
|
|
|
|
// Testing read and write to internal registers
|
|
#10000;
|
#10000;
|
SetInstruction(`IDCODE);
|
debug_wishbone_shift_dr(`WB_READ32, 32'h12346668, 32'h0, 16'h4, 32'h2ec6ae56, result); // {command, addr, data, length, crc, result}
|
ReadIDCode;
|
|
|
|
SetInstruction(`CHAIN_SELECT);
|
|
ChainSelect(`REGISTER_SCAN_CHAIN, 8'h0e); // {chain, crc}
|
|
SetInstruction(`DEBUG);
|
|
|
|
|
|
// Testing internal registers
|
|
WriteRegister(32'h00000001, `CPUOP_ADR, 8'h4a); // {data, addr, crc}
|
|
WriteRegister(32'h00000002, `CPUOP_ADR, 8'he0); // {data, addr, crc}
|
|
WriteRegister(32'h00000004, `CPUOP_ADR, 8'hb5); // {data, addr, crc}
|
|
WriteRegister(32'h00000000, `CPUSEL_ADR, 8'h1f); // {data, addr, crc}
|
|
WriteRegister(32'h00000001, `CPUSEL_ADR, 8'h2e); // {data, addr, crc}
|
|
WriteRegister(32'h00000002, `CPUSEL_ADR, 8'h84); // {data, addr, crc}
|
|
|
|
ReadRegister(`CPUOP_ADR, 8'h19); // {addr, crc}
|
|
ReadRegister(`CPUOP_ADR, 8'h19); // {addr, crc}
|
|
ReadRegister(`CPUSEL_ADR, 8'h7d); // {addr, crc}
|
|
ReadRegister(`CPUSEL_ADR, 8'h7d); // {addr, crc}
|
|
|
|
//ReadRegister(`MODER_ADR, 8'h00); // {addr, crc}
|
|
//ReadRegister(`TSEL_ADR, 8'h64); // {addr, crc}
|
|
//ReadRegister(`QSEL_ADR, 8'h32); // {addr, crc}
|
|
//ReadRegister(`SSEL_ADR, 8'h56); // {addr, crc}
|
|
//ReadRegister(`RECSEL_ADR, 8'hc4); // {addr, crc}
|
|
//ReadRegister(`MON_CNTL_ADR, 8'ha0); // {addr, crc}
|
|
//ReadRegister(5'h1f, 8'h04); // {addr, crc} // Register address don't exist. Read should return high-Z.
|
|
//ReadRegister(5'h1f, 8'h04); // {addr, crc} // Register address don't exist. Read should return high-Z.
|
|
|
|
//WriteRegister(32'h00000001, `MODER_ADR, 8'h53); // {data, addr, crc}
|
|
//WriteRegister(32'h00000020, `TSEL_ADR, 8'h5e); // {data, addr, crc}
|
|
//WriteRegister(32'h00000300, `QSEL_ADR, 8'hdd); // {data, addr, crc}
|
|
//WriteRegister(32'h00004000, `SSEL_ADR, 8'he2); // {data, addr, crc}
|
|
//WriteRegister(32'h0000dead, `RECSEL_ADR, 8'hfb); // {data, addr, crc}
|
|
//WriteRegister(32'h0000000d, `MON_CNTL_ADR, 8'h5a); // {data, addr, crc}
|
|
|
|
|
|
// testing trigger and qualifier
|
|
`ifdef TRACE_ENABLED
|
|
// Anything starts trigger and qualifier
|
|
#1000 WriteRegister(32'h00000000, `QSEL_ADR, 8'h50); // Any qualifier
|
|
#1000 WriteRegister(32'h00000000, `TSEL_ADR, 8'h06); // Any trigger
|
|
#1000 WriteRegister(32'h00000003, `RECSEL_ADR, 8'h0c); // Two samples are selected for recording (RECPC and RECLSEA)
|
|
#100 WriteRegister(32'h00000000, `SSEL_ADR, 8'h34); // No stop signal
|
|
#1000 WriteRegister(`ENABLE, `MODER_ADR, 8'hd4); // Trace enabled
|
|
// End: Anything starts trigger and qualifier //
|
|
|
|
/* Anything starts trigger, breakpoint starts qualifier
|
|
// Uncomment this part when you want to test it.
|
|
#1000 WriteRegister(`QUALIFOP_OR | `BPQUALIFVALID | `BPQUALIF, `QSEL_ADR, 8'had); // Any qualifier
|
|
#1000 WriteRegister(32'h00000000, `TSEL_ADR, 8'h06); // Any trigger
|
|
#1000 WriteRegister(32'h0000000c, `RECSEL_ADR, 8'h0f); // Two samples are selected for recording (RECSDATA and RECLDATA)
|
|
#1000 WriteRegister(32'h00000000, `SSEL_ADR, 8'h34); // No stop signal
|
|
#1000 WriteRegister(`ENABLE, `MODER_ADR, 8'hd4); // Trace enabled
|
|
wait(dbg_tb.i_dbg_top.TraceEnable)
|
|
@ (posedge Mclk);
|
|
#1 Bp = 1; // Set breakpoint
|
|
repeat(8) @(posedge Mclk);
|
|
wait(dbg_tb.i_dbg_top.dbgTrace1.CpuStall)
|
|
#1 Bp = 0; // Clear breakpoint
|
|
// End: Anything starts trigger, breakpoint starts qualifier */
|
|
|
|
/* Anything starts qualifier, breakpoint starts trigger
|
|
// Uncomment this part when you want to test it.
|
|
#1000 WriteRegister(32'h00000000, `QSEL_ADR, 8'h50); // Any qualifier
|
|
#1000 WriteRegister(`LSSTRIG_0 | `LSSTRIG_2 | `LSSTRIGVALID | `WPTRIG_4 | `WPTRIGVALID | `TRIGOP_AND, `TSEL_ADR, 8'had); // Trigger is AND of Watchpoint4 and LSSTRIG[0] and LSSTRIG[2]
|
|
#1000 WriteRegister(32'h00000003, `RECSEL_ADR, 8'h0c); // Two samples are selected for recording (RECPC and RECLSEA)
|
|
#1000 WriteRegister(32'h00000000, `SSEL_ADR, 8'h34); // No stop signal
|
|
#1000 WriteRegister(`ENABLE, `MODER_ADR, 8'hd4); // Trace enabled
|
|
wait(dbg_tb.i_dbg_top.TraceEnable)
|
|
@ (posedge Mclk)
|
|
Wp[4] = 1; // Set watchpoint[4]
|
|
LsStatus = 4'h5; // LsStatus[0] and LsStatus[2] are active
|
|
@ (posedge Mclk)
|
|
Wp[4] = 0; // Clear watchpoint[4]
|
|
LsStatus = 4'h0; // LsStatus[0] and LsStatus[2] are cleared
|
|
// End: Anything starts trigger and qualifier */
|
|
|
|
// Reading data from the trace buffer
|
|
SetInstruction(`CHAIN_SELECT);
|
|
ChainSelect(`TRACE_TEST_CHAIN, 8'h24); // {chain, crc}
|
|
SetInstruction(`DEBUG);
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
ReadTraceBuffer;
|
|
`endif // TRACE_ENABLED
|
|
|
|
|
|
|
/*
|
|
// Testing read and write to CPU0 registers
|
|
#10000;
|
|
set_instruction(`CHAIN_SELECT);
|
|
chain_select(`CPU_DEBUG_CHAIN_0, 8'h12); // {chain, crc}
|
|
set_instruction(`DEBUG);
|
|
WriteCPURegister(32'h11001100, 32'h00110011, 8'h86); // {data, addr, crc}
|
|
|
|
ReadCPURegister(32'h11001100, 8'hdb); // {addr, crc}
|
|
ReadCPURegister(32'h11001100, 8'hdb); // {addr, crc}
|
|
*/
|
|
#5000 gen_clk(1); // One extra TCLK for debugging purposes
|
|
#1000 $stop;
|
|
|
|
end
|
|
|
#5000 GenClk(1); // One extra TCLK for debugging purposes
|
|
#1000 $stop;
|
|
|
|
|
task initialize_memory;
|
|
input [31:0] start_addr;
|
|
input [31:0] length;
|
|
integer i;
|
|
reg [31:0] addr;
|
|
begin
|
|
for (i=0; i<length; i=i+4)
|
|
begin
|
|
addr = start_addr + i;
|
|
wb_slave.wr_mem(addr, {addr[7:0], addr[15:8], addr[23:16], addr[31:24]}, 4'hf); // adr, data, sel
|
end
|
end
|
join
|
|
end
|
end
|
|
endtask
|
|
|
|
|
|
|
// Generation of the TCLK signal
|
// Generation of the TCLK signal
|
task GenClk;
|
task gen_clk;
|
input [7:0] Number;
|
input [7:0] num;
|
integer i;
|
integer i;
|
begin
|
begin
|
for(i=0; i<Number; i=i+1)
|
for(i=0; i<num; i=i+1)
|
begin
|
begin
|
#Tclk P_TCK<=1;
|
#TCLK tck_pad_i<=1;
|
#Tclk P_TCK<=0;
|
#TCLK tck_pad_i<=0;
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// TAP reset
|
// TAP reset
|
task ResetTAP;
|
task reset_tap;
|
begin
|
begin
|
$display("(%0t) Task ResetTAP", $time);
|
$display("(%0t) Task reset_tap", $time);
|
P_TMS<=#Tp 1;
|
tms_pad_i<=#1 1'b1;
|
GenClk(7);
|
gen_clk(7);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// Goes to RunTestIdle state
|
// Goes to RunTestIdle state
|
task GotoRunTestIdle;
|
task goto_run_test_idle;
|
begin
|
begin
|
$display("(%0t) Task GotoRunTestIdle", $time);
|
$display("(%0t) Task goto_run_test_idle", $time);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 1'b0;
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// sets the instruction to the IR register and goes to the RunTestIdle state
|
// sets the instruction to the IR register and goes to the RunTestIdle state
|
task SetInstruction;
|
task set_instruction;
|
input [3:0] Instr;
|
input [3:0] instr;
|
integer i;
|
integer i;
|
|
|
begin
|
begin
|
$display("(%0t) Task SetInstruction", $time);
|
$display("(%0t) Task set_instruction", $time);
|
P_TMS<=#Tp 1;
|
tms_pad_i<=#1 1;
|
GenClk(2);
|
gen_clk(2);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(2); // we are in shiftIR
|
gen_clk(2); // we are in shiftIR
|
|
|
for(i=0; i<`IR_LENGTH-1; i=i+1)
|
for(i=0; i<`IR_LENGTH-1; i=i+1)
|
begin
|
begin
|
P_TDI<=#Tp Instr[i];
|
tdi_pad_i<=#1 instr[i];
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
P_TDI<=#Tp Instr[i]; // last shift
|
tdi_pad_i<=#1 instr[i]; // last shift
|
P_TMS<=#Tp 1; // going out of shiftIR
|
tms_pad_i<=#1 1; // going out of shiftIR
|
GenClk(1);
|
gen_clk(1);
|
P_TDI<=#Tp 'hz; // tri-state
|
tdi_pad_i<=#1 'hz; // tri-state
|
GenClk(1);
|
gen_clk(1);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(1); // we are in RunTestIdle
|
gen_clk(1); // we are in RunTestIdle
|
|
end
|
|
endtask
|
|
|
|
|
|
// Reads the ID code
|
|
task read_id_code;
|
|
begin
|
|
$display("(%0t) Task read_id_code", $time);
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1);
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(2); // we are in shiftDR
|
|
|
|
tdi_pad_i<=#1 0;
|
|
gen_clk(31);
|
|
|
|
tms_pad_i<=#1 1; // going out of shiftIR
|
|
gen_clk(1);
|
|
|
|
tdi_pad_i<=#1 'hz; // tri-state
|
|
gen_clk(1);
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(1); // we are in RunTestIdle
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// sets the selected scan chain and goes to the RunTestIdle state
|
// sets the selected scan chain and goes to the RunTestIdle state
|
task ChainSelect;
|
task chain_select;
|
input [3:0] Data;
|
input [3:0] data;
|
input [7:0] Crc;
|
input [31:0] crc;
|
integer i;
|
integer i;
|
|
|
begin
|
begin
|
$display("(%0t) Task ChainSelect", $time);
|
$display("(%0t) Task chain_select", $time);
|
P_TMS<=#Tp 1;
|
tms_pad_i<=#1 1;
|
GenClk(1);
|
gen_clk(1);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
|
tdi_pad_i<=#1 1'b1; // chain_select bit
|
|
gen_clk(1);
|
|
|
for(i=0; i<`CHAIN_ID_LENGTH; i=i+1)
|
for(i=0; i<`CHAIN_ID_LENGTH; i=i+1)
|
begin
|
begin
|
P_TDI<=#Tp Data[i];
|
tdi_pad_i<=#1 data[i];
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// for(i=0; i<`CRC_LENGTH-1; i=i+1)
|
for(i=0; i<`CRC_LEN; i=i+1)
|
for(i=0; i<`CRC_LENGTH; i=i+1) // +1 because crc is 9 bit long
|
|
begin
|
begin
|
P_TDI<=#Tp Crc[i];
|
tdi_pad_i<=#1 crc[`CRC_LEN -1-i];
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// P_TDI<=#Tp Crc[i]; // last shift
|
gen_clk(`STATUS_LEN); // Generating 5 clocks to read out status.
|
P_TDI<=#Tp 1'b0; // Crc[i]; // last shift
|
|
P_TMS<=#Tp 1; // going out of shiftIR
|
|
GenClk(1);
|
for(i=0; i<`CRC_LEN -1; i=i+1)
|
P_TDI<=#Tp 'hz; // tri-state
|
begin
|
GenClk(1);
|
tdi_pad_i<=#1 1'b0;
|
P_TMS<=#Tp 0;
|
gen_clk(1);
|
GenClk(1); // we are in RunTestIdle
|
end
|
|
|
|
tdi_pad_i<=#1 crc[i]; // last crc
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1); // to exit1_dr
|
|
|
|
tdi_pad_i<=#1 'hz; // tri-state
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1); // to update_dr
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(1); // to run_test_idle
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// Reads the ID code
|
// Performs 32-bit read to the selected chain
|
task ReadIDCode;
|
task debug_wishbone;
|
|
input [2:0] command;
|
|
input [31:0] addr;
|
|
input [31:0] data;
|
|
input [15:0] length;
|
|
input [31:0] crc;
|
|
output [31:0] result;
|
|
integer i;
|
|
|
|
begin
|
|
$write("(%0t) Task debug_wishbone: ", $time);
|
|
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1);
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(2); // we are in shiftDR
|
|
|
|
tdi_pad_i<=#1 1'b0; // chain_select bit = 0
|
|
gen_clk(1);
|
|
|
|
case (command)
|
|
`WB_STATUS :
|
|
begin
|
|
$display("wb_status");
|
|
end
|
|
`WB_READ8 :
|
|
begin
|
|
$display("wb_read8 (adr=0x%0x, length=0x%0x, crc=0x%0x)", addr, length, crc);
|
|
end
|
|
`WB_READ16 :
|
|
begin
|
|
$display("wb_read16 (adr=0x%0x, length=0x%0x, crc=0x%0x)", addr, length, crc);
|
|
end
|
|
`WB_READ32 :
|
|
begin
|
|
$display("wb_read32 (adr=0x%0x, length=0x%0x, crc=0x%0x)", addr, length, crc);
|
|
end
|
|
`WB_WRITE8 :
|
|
begin
|
|
$display("wb_write8 (adr=0x%0x, data=0x%0x, length=0x%0x, crc=0x%0x)", addr, data, length, crc);
|
|
end
|
|
`WB_WRITE16 :
|
|
begin
|
|
$display("wb_write16 (adr=0x%0x, data=0x%0x, length=0x%0x, crc=0x%0x)", addr, data, length, crc);
|
|
end
|
|
`WB_WRITE32 :
|
|
begin
|
|
$display("wb_write32 (adr=0x%0x, data=0x%0x, length=0x%0x, crc=0x%0x)", addr, data, length, crc);
|
|
end
|
|
`WB_GO :
|
|
begin
|
|
$display("wb_go, crc=0x%0x)", crc);
|
|
end
|
|
endcase
|
|
|
|
|
|
|
|
|
|
for(i=0; i<3; i=i+1)
|
|
begin
|
|
tdi_pad_i<=#1 command[i]; // command
|
|
gen_clk(1);
|
|
end
|
|
|
|
for(i=0; i<32; i=i+1) // address
|
|
begin
|
|
tdi_pad_i<=#1 addr[i];
|
|
gen_clk(1);
|
|
end
|
|
|
|
for(i=0; i<16; i=i+1) // length
|
begin
|
begin
|
$display("(%0t) Task ReadIDCode", $time);
|
tdi_pad_i<=#1 length[i];
|
P_TMS<=#Tp 1;
|
gen_clk(1);
|
GenClk(1);
|
end
|
P_TMS<=#Tp 0;
|
|
GenClk(2); // we are in shiftDR
|
for(i=0; i<`CRC_LEN; i=i+1)
|
|
begin
|
P_TDI<=#Tp 0;
|
tdi_pad_i<=#1 crc[`CRC_LEN -1-i];
|
GenClk(31);
|
gen_clk(1);
|
|
end
|
P_TMS<=#Tp 1; // going out of shiftIR
|
|
GenClk(1);
|
gen_clk(`STATUS_LEN); // Generating 5 clocks to read out status.
|
|
|
P_TDI<=#Tp 'hz; // tri-state
|
|
GenClk(1);
|
for(i=0; i<`CRC_LEN -1; i=i+1)
|
P_TMS<=#Tp 0;
|
begin
|
GenClk(1); // we are in RunTestIdle
|
tdi_pad_i<=#1 1'b0;
|
|
gen_clk(1);
|
|
end
|
|
|
|
tdi_pad_i<=#1 crc[i]; // last crc
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1); // to exit1_dr
|
|
|
|
tdi_pad_i<=#1 'hz; // tri-state
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1); // to update_dr
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(1); // to run_test_idle
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Performs 32-bit read to the selected chain waiting some time in shift_dr
|
|
task debug_wishbone_shift_dr;
|
|
input [2:0] command;
|
|
input [31:0] addr;
|
|
input [31:0] data;
|
|
input [15:0] length;
|
|
input [31:0] crc;
|
|
output [31:0] result;
|
|
integer i;
|
|
|
|
begin
|
|
$write("(%0t) Task debug_wishbone_shift_dr: ", $time);
|
|
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1);
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(2); // we are in shiftDR
|
|
|
|
tdi_pad_i<=#1 1'b0; // chain_select bit = 0
|
|
gen_clk(1);
|
|
|
|
case (command)
|
|
`WB_STATUS :
|
|
begin
|
|
$display("wb_status");
|
|
end
|
|
`WB_READ8 :
|
|
begin
|
|
$display("wb_read8 (adr=0x%0x, length=0x%0x, crc=0x%0x)", addr, length, crc);
|
|
end
|
|
`WB_READ16 :
|
|
begin
|
|
$display("wb_read16 (adr=0x%0x, length=0x%0x, crc=0x%0x)", addr, length, crc);
|
|
end
|
|
`WB_READ32 :
|
|
begin
|
|
$display("wb_read32 (adr=0x%0x, length=0x%0x, crc=0x%0x)", addr, length, crc);
|
|
end
|
|
`WB_WRITE8 :
|
|
begin
|
|
$display("wb_write8 (adr=0x%0x, data=0x%0x, length=0x%0x, crc=0x%0x)", addr, data, length, crc);
|
|
end
|
|
`WB_WRITE16 :
|
|
begin
|
|
$display("wb_write16 (adr=0x%0x, data=0x%0x, length=0x%0x, crc=0x%0x)", addr, data, length, crc);
|
|
end
|
|
`WB_WRITE32 :
|
|
begin
|
|
$display("wb_write32 (adr=0x%0x, data=0x%0x, length=0x%0x, crc=0x%0x)", addr, data, length, crc);
|
|
end
|
|
`WB_GO :
|
|
begin
|
|
$display("wb_go, crc=0x%0x)", crc);
|
|
end
|
|
endcase
|
|
|
|
|
|
|
|
|
|
for(i=0; i<3; i=i+1)
|
|
begin
|
|
tdi_pad_i<=#1 command[i]; // command
|
|
gen_clk(1);
|
|
end
|
|
|
|
for(i=0; i<32; i=i+1) // address
|
|
begin
|
|
tdi_pad_i<=#1 addr[i];
|
|
gen_clk(1);
|
|
end
|
|
|
|
for(i=0; i<16; i=i+1) // length
|
|
begin
|
|
tdi_pad_i<=#1 length[i];
|
|
gen_clk(1);
|
|
end
|
|
|
|
for(i=0; i<`CRC_LEN; i=i+1)
|
|
begin
|
|
tdi_pad_i<=#1 crc[`CRC_LEN -1-i];
|
|
gen_clk(1);
|
|
end
|
|
|
|
gen_clk(`STATUS_LEN -1); // Generating 4 clocks to read out status. Going to pause_dr at the end
|
|
|
|
tdi_pad_i<=#1 'hz;
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1); // to exit1_dr
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(1); // to pause_dr
|
|
|
|
while (dbg_tb.tdo_pad_o) // waiting for wb to send "ready"
|
|
begin
|
|
gen_clk(1); // staying in pause_dr
|
|
end
|
|
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1); // to exit2_dr
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(1); // to shift_dr
|
|
|
|
for(i=0; i<`CRC_LEN -1; i=i+1)
|
|
begin
|
|
tdi_pad_i<=#1 1'b0;
|
|
gen_clk(1);
|
|
end
|
|
|
|
tdi_pad_i<=#1 crc[i]; // last crc
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1); // to exit1_dr
|
|
|
|
tdi_pad_i<=#1 'hz; // tri-state
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1); // to update_dr
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(1); // to run_test_idle
|
|
end
|
|
endtask
|
|
|
|
|
|
|
|
|
|
|
|
|
// Reads sample from the Trace Buffer
|
// Reads sample from the Trace Buffer
|
task ReadTraceBuffer;
|
task ReadTraceBuffer;
|
begin
|
begin
|
$display("(%0t) Task ReadTraceBuffer", $time);
|
$display("(%0t) Task ReadTraceBuffer", $time);
|
P_TMS<=#Tp 1;
|
tms_pad_i<=#1 1;
|
GenClk(1);
|
gen_clk(1);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
P_TDI<=#Tp 0;
|
tdi_pad_i<=#1 0;
|
GenClk(47);
|
gen_clk(47);
|
P_TMS<=#Tp 1; // going out of shiftIR
|
tms_pad_i<=#1 1; // going out of shiftIR
|
GenClk(1);
|
gen_clk(1);
|
P_TDI<=#Tp 'hz; // tri-state
|
tdi_pad_i<=#1 'hz; // tri-state
|
GenClk(1);
|
gen_clk(1);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(1); // we are in RunTestIdle
|
gen_clk(1); // we are in RunTestIdle
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// Reads the CPU register and latches the data so it is ready for reading
|
// Reads the CPU register and latches the data so it is ready for reading
|
task ReadCPURegister;
|
task ReadCPURegister;
|
input [31:0] Address;
|
input [31:0] Address;
|
input [7:0] Crc;
|
input [7:0] crc;
|
integer i;
|
integer i;
|
|
|
begin
|
begin
|
$display("(%0t) Task ReadCPURegister", $time);
|
$display("(%0t) Task ReadCPURegister", $time);
|
P_TMS<=#Tp 1;
|
tms_pad_i<=#1 1;
|
GenClk(1);
|
gen_clk(1);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
for(i=0; i<32; i=i+1)
|
for(i=0; i<32; i=i+1)
|
begin
|
begin
|
P_TDI<=#Tp Address[i]; // Shifting address
|
tdi_pad_i<=#1 Address[i]; // Shifting address
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
P_TDI<=#Tp 0; // shifting RW bit = read
|
tdi_pad_i<=#1 0; // shifting RW bit = read
|
GenClk(1);
|
gen_clk(1);
|
|
|
for(i=0; i<32; i=i+1)
|
for(i=0; i<32; i=i+1)
|
begin
|
begin
|
P_TDI<=#Tp 0; // Shifting data. Data is not important in read cycle.
|
tdi_pad_i<=#1 0; // Shifting data. Data is not important in read cycle.
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// for(i=0; i<`CRC_LENGTH-1; i=i+1)
|
// for(i=0; i<`CRC_LEN -1; i=i+1)
|
for(i=0; i<`CRC_LENGTH; i=i+1) // crc is 9 bit long
|
for(i=0; i<`CRC_LEN; i=i+1) // crc is 9 bit long
|
begin
|
begin
|
P_TDI<=#Tp Crc[i]; // Shifting CRC.
|
tdi_pad_i<=#1 crc[i]; // Shifting CRC.
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// P_TDI<=#Tp Crc[i]; // Shifting last bit of CRC.
|
// tdi_pad_i<=#1 crc[i]; // Shifting last bit of CRC.
|
P_TDI<=#Tp 1'b0; // Crc[i]; // Shifting last bit of CRC.
|
tdi_pad_i<=#1 1'b0; // crc[i]; // Shifting last bit of CRC.
|
P_TMS<=#Tp 1; // going out of shiftIR
|
tms_pad_i<=#1 1; // going out of shiftIR
|
GenClk(1);
|
gen_clk(1);
|
P_TDI<=#Tp 'hz; // Tristate TDI.
|
tdi_pad_i<=#1 'hz; // Tristate TDI.
|
GenClk(1);
|
gen_clk(1);
|
|
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(1); // we are in RunTestIdle
|
gen_clk(1); // we are in RunTestIdle
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// Write the CPU register
|
// Write the CPU register
|
task WriteCPURegister;
|
task WriteCPURegister;
|
input [31:0] Data;
|
input [31:0] data;
|
input [31:0] Address;
|
input [31:0] Address;
|
input [`CRC_LENGTH-1:0] Crc;
|
input [`CRC_LEN -1:0] crc;
|
integer i;
|
integer i;
|
|
|
begin
|
begin
|
$display("(%0t) Task WriteCPURegister", $time);
|
$display("(%0t) Task WriteCPURegister", $time);
|
P_TMS<=#Tp 1;
|
tms_pad_i<=#1 1;
|
GenClk(1);
|
gen_clk(1);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
for(i=0; i<32; i=i+1)
|
for(i=0; i<32; i=i+1)
|
begin
|
begin
|
P_TDI<=#Tp Address[i]; // Shifting address
|
tdi_pad_i<=#1 Address[i]; // Shifting address
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
P_TDI<=#Tp 1; // shifting RW bit = write
|
tdi_pad_i<=#1 1; // shifting RW bit = write
|
GenClk(1);
|
gen_clk(1);
|
|
|
for(i=0; i<32; i=i+1)
|
for(i=0; i<32; i=i+1)
|
begin
|
begin
|
P_TDI<=#Tp Data[i]; // Shifting data
|
tdi_pad_i<=#1 data[i]; // Shifting data
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// for(i=0; i<`CRC_LENGTH-1; i=i+1)
|
// for(i=0; i<`CRC_LEN -1; i=i+1)
|
for(i=0; i<`CRC_LENGTH; i=i+1) // crc is 9 bit long
|
for(i=0; i<`CRC_LEN; i=i+1) // crc is 9 bit long
|
begin
|
begin
|
P_TDI<=#Tp Crc[i]; // Shifting CRC
|
tdi_pad_i<=#1 crc[i]; // Shifting CRC
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// P_TDI<=#Tp Crc[i]; // shifting last bit of CRC
|
// tdi_pad_i<=#1 crc[i]; // shifting last bit of CRC
|
P_TDI<=#Tp 1'b0; // Crc[i]; // shifting last bit of CRC
|
tdi_pad_i<=#1 1'b0; // crc[i]; // shifting last bit of CRC
|
P_TMS<=#Tp 1; // going out of shiftIR
|
tms_pad_i<=#1 1; // going out of shiftIR
|
GenClk(1);
|
gen_clk(1);
|
P_TDI<=#Tp 'hz; // tristate TDI
|
tdi_pad_i<=#1 'hz; // tristate TDI
|
GenClk(1);
|
gen_clk(1);
|
|
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(1); // we are in RunTestIdle
|
gen_clk(1); // we are in RunTestIdle
|
|
|
GenClk(10); // Generating few clock cycles needed for the write operation to accomplish
|
gen_clk(10); // Generating few clock cycles needed for the write operation to accomplish
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// Reads the register and latches the data so it is ready for reading
|
// Reads the register and latches the data so it is ready for reading
|
task ReadRegister;
|
task ReadRegister;
|
input [4:0] Address;
|
input [4:0] Address;
|
input [7:0] Crc;
|
input [7:0] crc;
|
integer i;
|
integer i;
|
|
|
begin
|
begin
|
$display("(%0t) Task ReadRegister", $time);
|
$display("(%0t) Task ReadRegister", $time);
|
P_TMS<=#Tp 1;
|
tms_pad_i<=#1 1;
|
GenClk(1);
|
gen_clk(1);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
for(i=0; i<5; i=i+1)
|
for(i=0; i<5; i=i+1)
|
begin
|
begin
|
P_TDI<=#Tp Address[i]; // Shifting address
|
tdi_pad_i<=#1 Address[i]; // Shifting address
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
P_TDI<=#Tp 0; // shifting RW bit = read
|
tdi_pad_i<=#1 0; // shifting RW bit = read
|
GenClk(1);
|
gen_clk(1);
|
|
|
for(i=0; i<32; i=i+1)
|
for(i=0; i<32; i=i+1)
|
begin
|
begin
|
P_TDI<=#Tp 0; // Shifting data. Data is not important in read cycle.
|
tdi_pad_i<=#1 0; // Shifting data. Data is not important in read cycle.
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// for(i=0; i<`CRC_LENGTH-1; i=i+1)
|
// for(i=0; i<`CRC_LEN -1; i=i+1)
|
for(i=0; i<`CRC_LENGTH; i=i+1) // crc is 9 bit long
|
for(i=0; i<`CRC_LEN; i=i+1) // crc is 9 bit long
|
begin
|
begin
|
P_TDI<=#Tp Crc[i]; // Shifting CRC. CRC is not important in read cycle.
|
tdi_pad_i<=#1 crc[i]; // Shifting CRC. CRC is not important in read cycle.
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// P_TDI<=#Tp Crc[i]; // Shifting last bit of CRC.
|
// tdi_pad_i<=#1 crc[i]; // Shifting last bit of CRC.
|
P_TDI<=#Tp 1'b0; // Crc[i]; // Shifting last bit of CRC.
|
tdi_pad_i<=#1 1'b0; // crc[i]; // Shifting last bit of CRC.
|
P_TMS<=#Tp 1; // going out of shiftIR
|
tms_pad_i<=#1 1; // going out of shiftIR
|
GenClk(1);
|
gen_clk(1);
|
P_TDI<=#Tp 'hz; // Tri state TDI
|
tdi_pad_i<=#1 'hz; // Tri state TDI
|
GenClk(1);
|
gen_clk(1);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(1); // we are in RunTestIdle
|
gen_clk(1); // we are in RunTestIdle
|
|
|
GenClk(10); // Generating few clock cycles needed for the read operation to accomplish
|
gen_clk(10); // Generating few clock cycles needed for the read operation to accomplish
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// Write the register
|
// Write the register
|
task WriteRegister;
|
task WriteRegister;
|
input [31:0] Data;
|
input [31:0] data;
|
input [4:0] Address;
|
input [4:0] Address;
|
input [`CRC_LENGTH-1:0] Crc;
|
input [`CRC_LEN -1:0] crc;
|
integer i;
|
integer i;
|
|
|
begin
|
begin
|
$display("(%0t) Task WriteRegister", $time);
|
$display("(%0t) Task WriteRegister", $time);
|
P_TMS<=#Tp 1;
|
tms_pad_i<=#1 1;
|
GenClk(1);
|
gen_clk(1);
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
for(i=0; i<5; i=i+1)
|
for(i=0; i<5; i=i+1)
|
begin
|
begin
|
P_TDI<=#Tp Address[i]; // Shifting address
|
tdi_pad_i<=#1 Address[i]; // Shifting address
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
P_TDI<=#Tp 1; // shifting RW bit = write
|
tdi_pad_i<=#1 1; // shifting RW bit = write
|
GenClk(1);
|
gen_clk(1);
|
|
|
for(i=0; i<32; i=i+1)
|
for(i=0; i<32; i=i+1)
|
begin
|
begin
|
P_TDI<=#Tp Data[i]; // Shifting data
|
tdi_pad_i<=#1 data[i]; // Shifting data
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// for(i=0; i<`CRC_LENGTH-1; i=i+1)
|
// for(i=0; i<`CRC_LEN -1; i=i+1)
|
for(i=0; i<`CRC_LENGTH; i=i+1) // crc is 9 bit long
|
for(i=0; i<`CRC_LEN; i=i+1) // crc is 9 bit long
|
begin
|
begin
|
P_TDI<=#Tp Crc[i]; // Shifting CRC
|
tdi_pad_i<=#1 crc[i]; // Shifting CRC
|
GenClk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// P_TDI<=#Tp Crc[i]; // Shifting last bit of CRC
|
// tdi_pad_i<=#1 crc[i]; // Shifting last bit of CRC
|
P_TDI<=#Tp 1'b0; // Crc[i]; // Shifting last bit of CRC
|
tdi_pad_i<=#1 1'b0; // crc[i]; // Shifting last bit of CRC
|
P_TMS<=#Tp 1; // going out of shiftIR
|
tms_pad_i<=#1 1; // going out of shiftIR
|
GenClk(1);
|
gen_clk(1);
|
P_TDI<=#Tp 'hz; // Tri state TDI
|
tdi_pad_i<=#1 'hz; // Tri state TDI
|
GenClk(1);
|
gen_clk(1);
|
|
|
P_TMS<=#Tp 0;
|
tms_pad_i<=#1 0;
|
GenClk(1); // we are in RunTestIdle
|
gen_clk(1); // we are in RunTestIdle
|
|
|
GenClk(5); // Extra clocks needed for operations to finish
|
gen_clk(5); // Extra clocks needed for operations to finish
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
/*
|
task EnableWishboneSlave;
|
task EnableWishboneSlave;
|
begin
|
begin
|
$display("(%0t) Task EnableWishboneSlave", $time);
|
$display("(%0t) Task EnableWishboneSlave", $time);
|
while(1)
|
while(1)
|
begin
|
begin
|
@ (posedge Mclk);
|
@ (posedge Mclk);
|
if(wb_stb_i & wb_cyc_i) // WB access
|
if(wb_stb_i & wb_cyc_i) // WB access
|
// wait (wb_stb_i & wb_cyc_i) // WB access
|
// wait (wb_stb_i & wb_cyc_i) // WB access
|
begin
|
begin
|
@ (posedge Mclk);
|
@ (posedge Mclk);
|
@ (posedge Mclk);
|
@ (posedge Mclk);
|
@ (posedge Mclk);
|
@ (posedge Mclk);
|
#1 wb_ack_o = 1;
|
#1 wb_ack_o = 1;
|
if(~wb_we_i) // read
|
if(~wb_we_i) // read
|
wb_dat_o = 32'hbeefdead;
|
wb_dat_o = 32'hbeefdead;
|
wb_dat_o = {wb_adr_i[3:0], wb_adr_i[7:4], wb_adr_i[11:8], wb_adr_i[15:12],
|
wb_dat_o = {wb_adr_i[3:0], wb_adr_i[7:4], wb_adr_i[11:8], wb_adr_i[15:12],
|
wb_adr_i[19:16], wb_adr_i[23:20], wb_adr_i[27:24], wb_adr_i[31:28]};
|
wb_adr_i[19:16], wb_adr_i[23:20], wb_adr_i[27:24], wb_adr_i[31:28]};
|
if(wb_we_i & wb_stb_i & wb_cyc_i) // write
|
if(wb_we_i & wb_stb_i & wb_cyc_i) // write
|
$display("\nWISHBONE write Data=%0h, Addr=%0h", wb_dat_i, wb_adr_i);
|
$display("\nWISHBONE write data=%0h, Addr=%0h", wb_dat_i, wb_adr_i);
|
if(~wb_we_i & wb_stb_i & wb_cyc_i) // read
|
if(~wb_we_i & wb_stb_i & wb_cyc_i) // read
|
$display("\nWISHBONE read Data=%0h, Addr=%0h", wb_dat_o, wb_adr_i);
|
$display("\nWISHBONE read data=%0h, Addr=%0h", wb_dat_o, wb_adr_i);
|
end
|
end
|
@ (posedge Mclk);
|
@ (posedge Mclk);
|
#1 wb_ack_o = 0;
|
#1 wb_ack_o = 0;
|
wb_dat_o = 32'h0;
|
wb_dat_o = 32'h0;
|
end
|
end
|
end
|
|
endtask
|
end
|
|
endtask
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Line 862... |
Line 997... |
* *
|
* *
|
* Printing the information to the screen *
|
* Printing the information to the screen *
|
* *
|
* *
|
**********************************************************************************/
|
**********************************************************************************/
|
|
|
// Print samples that are recorded to the trace buffer
|
always @ (posedge tck_pad_i)
|
`ifdef TRACE_ENABLED
|
begin
|
always @ (posedge Mclk)
|
if(dbg_tb.i_tap_top.update_ir)
|
begin
|
case(dbg_tb.i_tap_top.jtag_ir[`IR_LENGTH-1:0])
|
if(dbg_tb.i_dbg_top.dbgTrace1.WriteSample)
|
`EXTEST : $display("\tInstruction EXTEST entered");
|
$write("\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tWritten to Trace buffer: WritePointer=0x%x, Data=0x%x", dbg_tb.i_dbg_top.dbgTrace1.WritePointer, {dbg_tb.i_dbg_top.dbgTrace1.DataIn, 1'b0, dbg_tb.i_dbg_top.dbgTrace1.OpSelect[`OPSELECTWIDTH-1:0]});
|
`SAMPLE_PRELOAD : $display("\tInstruction SAMPLE_PRELOAD entered");
|
end
|
`IDCODE : $display("\tInstruction IDCODE entered");
|
`endif
|
`MBIST : $display("\tInstruction MBIST entered");
|
|
`DEBUG : $display("\tInstruction DEBUG entered");
|
|
`BYPASS : $display("\tInstruction BYPASS entered");
|
// Print selected instruction
|
default : $display("\n\tInstruction not valid. Instruction BYPASS activated !!!");
|
reg UpdateIR_q;
|
|
always @ (posedge P_TCK)
|
|
begin
|
|
UpdateIR_q<=#Tp dbg_tb.i_tap_top.UpdateIR;
|
|
end
|
|
|
|
always @ (posedge P_TCK)
|
|
begin
|
|
if(UpdateIR_q)
|
|
case(dbg_tb.i_tap_top.LatchedJTAG_IR[`IR_LENGTH-1:0])
|
|
`EXTEST : $write("\tInstruction EXTEST entered");
|
|
`SAMPLE_PRELOAD : $write("\tInstruction SAMPLE_PRELOAD entered");
|
|
`IDCODE : $write("\tInstruction IDCODE entered");
|
|
`CHAIN_SELECT : $write("\tInstruction CHAIN_SELECT entered");
|
|
`INTEST : $write("\tInstruction INTEST entered");
|
|
`CLAMP : $write("\tInstruction CLAMP entered");
|
|
`CLAMPZ : $write("\tInstruction CLAMPZ entered");
|
|
`HIGHZ : $write("\tInstruction HIGHZ entered");
|
|
`DEBUG : $write("\tInstruction DEBUG entered");
|
|
`BYPASS : $write("\tInstruction BYPASS entered");
|
|
default : $write("\n\tInstruction not valid. Instruction BYPASS activated !!!");
|
|
endcase
|
endcase
|
end
|
end
|
|
|
|
|
|
|
// Print selected chain
|
// Print selected chain
|
always @ (posedge P_TCK)
|
/*
|
begin
|
always @ (posedge tck_pad_i)
|
if(dbg_tb.i_tap_top.CHAIN_SELECTSelected & dbg_tb.i_tap_top.UpdateDR_q)
|
begin
|
case(dbg_tb.i_dbg_top.Chain[`CHAIN_ID_LENGTH-1:0])
|
if(dbg_tb.i_tap_top.chain_select & dbg_tb.i_dbg_top.update_dr_q)
|
`GLOBAL_BS_CHAIN : $write("\nChain GLOBAL_BS_CHAIN");
|
case(dbg_tb.i_dbg_top.Chain[`CHAIN_ID_LENGTH-1:0])
|
`CPU_DEBUG_CHAIN_0 : $write("\nChain CPU_DEBUG_CHAIN_0");
|
`GLOBAL_BS_CHAIN : $write("\nChain GLOBAL_BS_CHAIN");
|
`CPU_DEBUG_CHAIN_1 : $write("\nChain CPU_DEBUG_CHAIN_1");
|
`CPU_DEBUG_CHAIN_0 : $write("\nChain CPU_DEBUG_CHAIN_0");
|
`CPU_DEBUG_CHAIN_2 : $write("\nChain CPU_DEBUG_CHAIN_2");
|
`CPU_DEBUG_CHAIN_1 : $write("\nChain CPU_DEBUG_CHAIN_1");
|
`CPU_DEBUG_CHAIN_3 : $write("\nChain CPU_DEBUG_CHAIN_3");
|
`CPU_DEBUG_CHAIN_2 : $write("\nChain CPU_DEBUG_CHAIN_2");
|
`CPU_TEST_CHAIN : $write("\nChain CPU_TEST_CHAIN");
|
`CPU_DEBUG_CHAIN_3 : $write("\nChain CPU_DEBUG_CHAIN_3");
|
`TRACE_TEST_CHAIN : $write("\nChain TRACE_TEST_CHAIN");
|
`CPU_TEST_CHAIN : $write("\nChain CPU_TEST_CHAIN");
|
`REGISTER_SCAN_CHAIN : $write("\nChain REGISTER_SCAN_CHAIN");
|
`TRACE_TEST_CHAIN : $write("\nChain TRACE_TEST_CHAIN");
|
`WISHBONE_SCAN_CHAIN : $write("\nChain WISHBONE_SCAN_CHAIN");
|
`REGISTER_SCAN_CHAIN : $write("\nChain REGISTER_SCAN_CHAIN");
|
endcase
|
`WISHBONE_SCAN_CHAIN : $write("\nChain WISHBONE_SCAN_CHAIN");
|
end
|
endcase
|
|
end
|
|
*/
|
|
|
// print CPU registers read/write
|
// print CPU registers read/write
|
always @ (posedge Mclk)
|
/*
|
begin
|
always @ (posedge Mclk)
|
if(dbg_tb.i_dbg_top.CPUAccess0 & ~dbg_tb.i_dbg_top.CPUAccess_q & dbg_tb.i_dbg_top.RW)
|
begin
|
$write("\n\t\tWrite to CPU Register (addr=0x%h, data=0x%h)", dbg_tb.i_dbg_top.ADDR[31:0], dbg_tb.i_dbg_top.DataOut[31:0]);
|
if(dbg_tb.i_dbg_top.CPUAccess0 & ~dbg_tb.i_dbg_top.CPUAccess_q & dbg_tb.i_dbg_top.RW)
|
else
|
$write("\n\t\tWrite to CPU Register (addr=0x%h, data=0x%h)", dbg_tb.i_dbg_top.ADDR[31:0], dbg_tb.i_dbg_top.DataOut[31:0]);
|
if(dbg_tb.i_dbg_top.CPUAccess_q & ~dbg_tb.i_dbg_top.CPUAccess_q2 & ~dbg_tb.i_dbg_top.RW)
|
else
|
$write("\n\t\tRead from CPU Register (addr=0x%h, data=0x%h)", dbg_tb.i_dbg_top.ADDR[31:0], dbg_tb.i_dbg_top.cpu_data_i[31:0]);
|
if(dbg_tb.i_dbg_top.CPUAccess_q & ~dbg_tb.i_dbg_top.CPUAccess_q2 & ~dbg_tb.i_dbg_top.RW)
|
end
|
$write("\n\t\tRead from CPU Register (addr=0x%h, data=0x%h)", dbg_tb.i_dbg_top.ADDR[31:0], dbg_tb.i_dbg_top.cpu_data_i[31:0]);
|
|
end
|
|
*/
|
|
|
// print registers read/write
|
// print registers read/write
|
always @ (posedge Mclk)
|
/*
|
begin
|
always @ (posedge Mclk)
|
if(dbg_tb.i_dbg_top.RegAccess_q & ~dbg_tb.i_dbg_top.RegAccess_q2)
|
begin
|
begin
|
if(dbg_tb.i_dbg_top.RegAccess_q & ~dbg_tb.i_dbg_top.RegAccess_q2)
|
if(dbg_tb.i_dbg_top.RW)
|
begin
|
$write("\n\t\tWrite to Register (addr=0x%h, data=0x%h)", dbg_tb.i_dbg_top.ADDR[4:0], dbg_tb.i_dbg_top.DataOut[31:0]);
|
if(dbg_tb.i_dbg_top.RW)
|
else
|
$write("\n\t\tWrite to Register (addr=0x%h, data=0x%h)", dbg_tb.i_dbg_top.ADDR[4:0], dbg_tb.i_dbg_top.DataOut[31:0]);
|
$write("\n\t\tRead from Register (addr=0x%h, data=0x%h). This data will be shifted out on next read request.", dbg_tb.i_dbg_top.ADDR[4:0], dbg_tb.i_dbg_top.RegDataIn[31:0]);
|
else
|
end
|
$write("\n\t\tRead from Register (addr=0x%h, data=0x%h). This data will be shifted out on next read request.", dbg_tb.i_dbg_top.ADDR[4:0], dbg_tb.i_dbg_top.RegDataIn[31:0]);
|
end
|
end
|
|
end
|
|
*/
|
|
|
// print CRC error
|
// print CRC error
|
`ifdef TRACE_ENABLED
|
/*
|
wire CRCErrorReport = ~(dbg_tb.i_dbg_top.CrcMatch & (dbg_tb.i_dbg_top.CHAIN_SELECTSelected | dbg_tb.i_dbg_top.DEBUGSelected & RegisterScanChain | dbg_tb.i_dbg_top.DEBUGSelected & (CpuDebugScanChain0 | CpuDebugScanChain1 | CpuDebugScanChain2 | CpuDebugScanChain3) | dbg_tb.i_dbg_top.DEBUGSelected & dbg_tb.i_dbg_top.TraceTestScanChain | dbg_tb.i_dbg_top.DEBUGSelected & WishboneScanChain));
|
`ifdef TRACE_ENABLED
|
`else // TRACE_ENABLED not enabled
|
wire CRCErrorReport = ~(dbg_tb.i_dbg_top.CrcMatch & (dbg_tb.i_dbg_top.chain_select | dbg_tb.i_dbg_top.debug_select & register_scan_chain | dbg_tb.i_dbg_top.debug_select & (cpu_debug_scan_chain0 | cpu_debug_scan_chain1 | cpu_debug_scan_chain2 | cpu_debug_scan_chain3) | dbg_tb.i_dbg_top.debug_select & dbg_tb.i_dbg_top.TraceTestScanChain | dbg_tb.i_dbg_top.debug_select & wishbone_scan_chain));
|
wire CRCErrorReport = ~(dbg_tb.i_dbg_top.CrcMatch & (dbg_tb.i_tap_top.CHAIN_SELECTSelected | dbg_tb.i_tap_top.DEBUGSelected & RegisterScanChain | dbg_tb.i_tap_top.DEBUGSelected & (CpuDebugScanChain0 | CpuDebugScanChain1 | CpuDebugScanChain2 | CpuDebugScanChain3) | dbg_tb.i_tap_top.DEBUGSelected & WishboneScanChain));
|
`else // TRACE_ENABLED not enabled
|
`endif
|
wire CRCErrorReport = ~(dbg_tb.i_dbg_top.CrcMatch & (dbg_tb.i_tap_top.chain_select | dbg_tb.i_tap_top.debug_select & register_scan_chain | dbg_tb.i_tap_top.debug_select & (cpu_debug_scan_chain0 | cpu_debug_scan_chain1 | cpu_debug_scan_chain2 | cpu_debug_scan_chain3) | dbg_tb.i_tap_top.debug_select & wishbone_scan_chain));
|
|
`endif
|
|
*/
|
|
|
|
/*
|
|
// print crc
|
|
always @ (posedge P_TCK)
|
|
begin
|
|
if(dbg_tb.i_tap_top.update_dr & ~dbg_tb.i_tap_top.idcode_select)
|
|
begin
|
|
if(dbg_tb.i_tap_top.chain_select)
|
|
$write("\t\tCrcIn=0x%h, CrcOut=0x%h", dbg_tb.i_dbg_top.JTAG_DR_IN[11:4], dbg_tb.i_dbg_top.CalculatedCrcOut[`CRC_LEN -1:0]);
|
|
else
|
|
if(register_scan_chain & ~dbg_tb.i_tap_top.chain_select)
|
|
$write("\t\tCrcIn=0x%h, CrcOut=0x%h", dbg_tb.i_dbg_top.JTAG_DR_IN[45:38], dbg_tb.i_dbg_top.CalculatedCrcOut[`CRC_LEN -1:0]);
|
|
else
|
|
if((cpu_debug_scan_chain0 | cpu_debug_scan_chain1 | cpu_debug_scan_chain2 | cpu_debug_scan_chain3) & ~dbg_tb.i_tap_top.chain_select)
|
|
$write("\t\tCrcIn=0x%h, CrcOut=0x%h", dbg_tb.i_dbg_top.JTAG_DR_IN[72:65], dbg_tb.i_dbg_top.CalculatedCrcOut[`CRC_LEN -1:0]);
|
|
if(wishbone_scan_chain & ~dbg_tb.i_tap_top.chain_select)
|
|
$write("\t\tCrcIn=0x%h, CrcOut=0x%h", dbg_tb.i_dbg_top.JTAG_DR_IN[72:65], dbg_tb.i_dbg_top.CalculatedCrcOut[`CRC_LEN -1:0]);
|
|
|
|
if(CRCErrorReport)
|
|
begin
|
|
$write("\n\t\t\t\tCrc Error when receiving data (read or write) !!! CrcIn should be: 0x%h\n", dbg_tb.i_dbg_top.CalculatedCrcIn);
|
|
#1000 $stop;
|
|
end
|
|
$display("\n");
|
|
end
|
|
end
|
|
*/
|
|
|
always @ (posedge P_TCK)
|
// Print shifted IDCode
|
|
reg [31:0] tmp_data;
|
|
always @ (posedge tck_pad_i)
|
begin
|
begin
|
if(dbg_tb.i_tap_top.UpdateDR & ~dbg_tb.i_tap_top.IDCODESelected)
|
if(dbg_tb.i_tap_top.idcode_select)
|
begin
|
begin
|
if(dbg_tb.i_tap_top.CHAIN_SELECTSelected)
|
if(dbg_tb.i_tap_top.shift_dr)
|
$write("\t\tCrcIn=0x%h, CrcOut=0x%h", dbg_tb.i_dbg_top.JTAG_DR_IN[11:4], dbg_tb.i_dbg_top.CalculatedCrcOut[`CRC_LENGTH-1:0]);
|
tmp_data[31:0]<=#1 {dbg_tb.tdo, tmp_data[31:1]};
|
else
|
|
if(RegisterScanChain & ~dbg_tb.i_tap_top.CHAIN_SELECTSelected)
|
|
$write("\t\tCrcIn=0x%h, CrcOut=0x%h", dbg_tb.i_dbg_top.JTAG_DR_IN[45:38], dbg_tb.i_dbg_top.CalculatedCrcOut[`CRC_LENGTH-1:0]);
|
|
else
|
else
|
if((CpuDebugScanChain0 | CpuDebugScanChain1 | CpuDebugScanChain2 | CpuDebugScanChain3) & ~dbg_tb.i_tap_top.CHAIN_SELECTSelected)
|
if(dbg_tb.i_tap_top.update_dr)
|
$write("\t\tCrcIn=0x%h, CrcOut=0x%h", dbg_tb.i_dbg_top.JTAG_DR_IN[72:65], dbg_tb.i_dbg_top.CalculatedCrcOut[`CRC_LENGTH-1:0]);
|
if (tmp_data[31:0] != `IDCODE_VALUE)
|
if(WishboneScanChain & ~dbg_tb.i_tap_top.CHAIN_SELECTSelected)
|
|
$write("\t\tCrcIn=0x%h, CrcOut=0x%h", dbg_tb.i_dbg_top.JTAG_DR_IN[72:65], dbg_tb.i_dbg_top.CalculatedCrcOut[`CRC_LENGTH-1:0]);
|
|
|
|
if(CRCErrorReport)
|
|
begin
|
begin
|
$write("\n\t\t\t\tCrc Error when receiving data (read or write) !!! CrcIn should be: 0x%h\n", dbg_tb.i_dbg_top.CalculatedCrcIn);
|
$display("(%0t) ERROR: IDCODE not correct", $time);
|
#1000 $stop;
|
$stop;
|
end
|
end
|
$display("\n");
|
else
|
|
$display("\t\tIDCode = 0x%h", tmp_data[31:0]);
|
end
|
end
|
end
|
end
|
|
|
|
|
// Print shifted IDCode
|
// We never use following states: exit2_ir, exit2_dr, pause_ir or pause_dr
|
reg [31:0] TempData;
|
always @ (posedge tck_pad_i)
|
always @ (posedge P_TCK)
|
|
begin
|
begin
|
if(dbg_tb.i_tap_top.IDCODESelected)
|
if(dbg_tb.i_tap_top.pause_ir | dbg_tb.i_tap_top.exit2_ir)
|
begin
|
begin
|
if(dbg_tb.i_tap_top.ShiftDR)
|
$display("\n(%0t) ERROR: State pause_ir or exit2_ir detected.", $time);
|
TempData[31:0]<=#Tp {dbg_tb.i_tap_top.tdo_pad_o, TempData[31:1]};
|
$display("(%0t) Simulation stopped !!!", $time);
|
else
|
|
if(dbg_tb.i_tap_top.UpdateDR)
|
|
if (TempData[31:0] != `IDCODE_VALUE)
|
|
begin
|
|
$display("(%0t) ERROR: IDCODE not correct", $time);
|
|
$stop;
|
$stop;
|
end
|
end
|
else
|
|
$write("\n\t\tIDCode = 0x%h", TempData[31:0]);
|
|
end
|
|
end
|
end
|
|
|
|
|
// Print data from the trace buffer
|
// sets the selected scan chain and goes to the RunTestIdle state
|
reg [47:0] TraceData;
|
task xxx;
|
always @ (posedge P_TCK)
|
input [3:0] data;
|
|
input [31:0] crc;
|
|
integer i;
|
|
|
begin
|
begin
|
if(dbg_tb.i_tap_top.DEBUGSelected & (dbg_tb.i_dbg_top.Chain==`TRACE_TEST_CHAIN))
|
$display("(%0t) Task xxx", $time);
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1);
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(2); // we are in shiftDR
|
|
|
|
for(i=0; i<4; i=i+1)
|
begin
|
begin
|
if(dbg_tb.i_tap_top.ShiftDR)
|
tdi_pad_i<=#1 data[i];
|
TraceData[47:0]<=#Tp {dbg_tb.i_tap_top.tdo_pad_o, TraceData[47:1]};
|
gen_clk(1);
|
else
|
|
if(dbg_tb.i_tap_top.UpdateDR)
|
|
$write("\n\t\TraceData = 0x%h + Crc = 0x%h", TraceData[39:0], TraceData[47:40]);
|
|
end
|
end
|
|
|
|
for(i=0; i<`CRC_LEN; i=i+1)
|
|
begin
|
|
tdi_pad_i<=#1 crc[`CRC_LEN - 1 - i];
|
|
gen_clk(1);
|
end
|
end
|
|
|
|
gen_clk(`STATUS_LEN); // Generating 5 clocks to read out status.
|
|
|
// We never use following states: Exit2IR, Exit2DR, PauseIR or PauseDR
|
|
always @ (posedge P_TCK)
|
for(i=0; i<`CRC_LEN -1; i=i+1)
|
begin
|
|
if(dbg_tb.i_tap_top.Exit2IR | dbg_tb.i_tap_top.Exit2DR | dbg_tb.i_tap_top.PauseIR | dbg_tb.i_tap_top.PauseDR)
|
|
begin
|
begin
|
$display("\n(%0t) ERROR: Exit2IR, Exit2DR, PauseIR or PauseDR state detected.", $time);
|
tdi_pad_i<=#1 1'b0;
|
$display("(%0t) Simulation stopped !!!", $time);
|
gen_clk(1);
|
$stop;
|
|
end
|
|
end
|
end
|
|
|
|
tdi_pad_i<=#1 crc[i]; // last crc
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1); // to exit1_dr
|
|
|
|
tdi_pad_i<=#1 'hz; // tri-state
|
|
tms_pad_i<=#1 1;
|
|
gen_clk(1); // to update_dr
|
|
tms_pad_i<=#1 0;
|
|
gen_clk(1); // to run_test_idle
|
|
end
|
|
endtask
|
|
|
|
|
|
|
|
|
|
|
endmodule // TB
|
endmodule // dbg_tb
|
|
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|