//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// ORPSoC Testbench ////
|
//// ORPSoC Testbench ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// ORPSoC VPI Debugging Testbench file ////
|
//// ORPSoC VPI Debugging Testbench file ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - jb, jb@orsoc.se ////
|
//// - jb, jb@orsoc.se ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// 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. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
`timescale 1ns/10ps
|
`timescale 1ns/10ps
|
|
|
`include "vpi_debug_defines.v"
|
`include "vpi_debug_defines.v"
|
|
|
// uncomment the following line to get more debug output for this module
|
// uncomment the following line to get more debug output for this module
|
//`define DEBUG_INFO
|
//`define DEBUG_INFO
|
//`define VPI_DEBUG_INFO
|
//`define VPI_DEBUG_INFO
|
|
|
module vpi_debug_module(tms, tck, tdi, tdo);
|
module vpi_debug_module(tms, tck, tdi, tdo);
|
|
|
output tms;
|
output tms;
|
output tck;
|
output tck;
|
output tdi;
|
output tdi;
|
input tdo;
|
input tdo;
|
|
|
reg tms;
|
reg tms;
|
reg tck;
|
reg tck;
|
reg tdi;
|
reg tdi;
|
|
|
reg [31:0] in_data_le, in_data_be;
|
reg [31:0] in_data_le, in_data_be;
|
|
reg [31:0] incoming_word;
|
reg err;
|
reg err;
|
integer i;
|
integer i;
|
|
|
reg [31:0] id;
|
reg [31:0] id;
|
reg [31:0] npc;
|
reg [31:0] npc;
|
reg [31:0] ppc;
|
reg [31:0] ppc;
|
reg [31:0] r1;
|
reg [31:0] r1;
|
reg [31:0] insn;
|
reg [31:0] insn;
|
reg [31:0] result;
|
reg [31:0] result;
|
reg [31:0] tmp;
|
reg [31:0] tmp;
|
|
|
reg [31:0] crc_out;
|
reg [31:0] crc_out;
|
reg [31:0] crc_in;
|
reg [31:0] crc_in;
|
wire crc_match_in;
|
wire crc_match_in;
|
|
|
reg [`DBG_TOP_STATUS_LEN -1:0] status;
|
reg [`DBG_TOP_STATUS_LEN -1:0] status;
|
reg [`DBG_WB_STATUS_LEN -1:0] status_wb;
|
reg [`DBG_WB_STATUS_LEN -1:0] status_wb;
|
reg [`DBG_CPU_STATUS_LEN -1:0] status_cpu;
|
reg [`DBG_CPU_STATUS_LEN -1:0] status_cpu;
|
|
|
// Text used for easier debugging
|
// Text used for easier debugging
|
reg [199:0] test_text;
|
reg [199:0] test_text;
|
reg [`DBG_WB_CMD_LEN -1:0] last_wb_cmd;
|
reg [`DBG_WB_CMD_LEN -1:0] last_wb_cmd;
|
reg [`DBG_CPU_CMD_LEN -1:0] last_cpu_cmd;
|
reg [`DBG_CPU_CMD_LEN -1:0] last_cpu_cmd;
|
reg [199:0] last_wb_cmd_text;
|
reg [199:0] last_wb_cmd_text;
|
reg [199:0] last_cpu_cmd_text;
|
reg [199:0] last_cpu_cmd_text;
|
|
|
reg [31:0] data_storage [0:4095]; // Data storage (for write and read operations).
|
reg [31:0] data_storage [0:4095]; // Data storage (for write and read operations).
|
reg [18:0] length_global;
|
reg [18:0] length_global;
|
|
|
parameter Tp = 1;
|
parameter Tp = 1;
|
//parameter Tck = 25; // Clock half period (Clok period = 50 ns => 20 MHz)
|
//parameter Tck = 25; // Clock half period (Clok period = 50 ns => 20 MHz)
|
parameter Tck = 50; // Clock half period (Clok period = 100 ns => 10 MHz)
|
parameter Tck = 50; // Clock half period (Clok period = 100 ns => 10 MHz)
|
|
|
integer cmd;
|
integer cmd;
|
integer block_cmd_length;
|
integer block_cmd_length;
|
integer jtag_instn_val;
|
integer jtag_instn_val;
|
integer set_chain_val;
|
integer set_chain_val;
|
|
|
reg [1:0] cpu_ctrl_val; // two important bits for the ctrl reg
|
reg [1:0] cpu_ctrl_val; // two important bits for the ctrl reg
|
reg [31:0] cmd_adr;
|
reg [31:0] cmd_adr;
|
reg [31:0] cmd_size;
|
reg [31:0] cmd_size;
|
reg [31:0] cmd_data;
|
reg [31:0] cmd_data;
|
|
|
|
|
initial
|
initial
|
begin
|
begin
|
$display("JTAG debug module with VPI interface enabled\n");
|
$display("JTAG debug module with VPI interface enabled\n");
|
tck <=#Tp 1'b0;
|
tck <=#Tp 1'b0;
|
tdi <=#Tp 1'bz;
|
tdi <=#Tp 1'bz;
|
tms <=#Tp 1'b0;
|
tms <=#Tp 1'b0;
|
|
|
// Insert a #delay here because we need to
|
// Insert a #delay here because we need to
|
// wait until the PC isn't pointing to flash anymore
|
// wait until the PC isn't pointing to flash anymore
|
// (this is around 20k ns if the flash_crash boot code
|
// (this is around 20k ns if the flash_crash boot code
|
// is being booted from, else much bigger, around 10mil ns)
|
// is being booted from, else much bigger, around 10mil ns)
|
|
|
#200_000 main;
|
#2_000 main;
|
|
|
end
|
end
|
|
|
task main;
|
task main;
|
begin
|
begin
|
|
|
id <=#Tp 32'h00;
|
id <=#Tp 32'h00;
|
npc <=#Tp 32'h00;
|
npc <=#Tp 32'h00;
|
ppc <=#Tp 32'h00;
|
ppc <=#Tp 32'h00;
|
insn <=#Tp 32'h00;
|
insn <=#Tp 32'h00;
|
result <=#Tp 32'h00;
|
result <=#Tp 32'h00;
|
err <=#Tp 1'b0;
|
err <=#Tp 1'b0;
|
tmp <=#Tp 32'h00;
|
tmp <=#Tp 32'h00;
|
|
|
// execute some cycles
|
// execute some cycles
|
#50000;
|
#50000;
|
|
|
reset_tap;
|
reset_tap;
|
goto_run_test_idle;
|
goto_run_test_idle;
|
|
|
//$init_rsp_server();
|
//$init_rsp_server();
|
|
|
while (1) begin
|
while (1) begin
|
|
|
// Check for incoming command
|
// Check for incoming command
|
|
|
// wait until a command is sent
|
// wait until a command is sent
|
// poll with a delay here
|
// poll with a delay here
|
cmd = -1;
|
cmd = -1;
|
|
|
while (cmd == -1)
|
while (cmd == -1)
|
begin
|
begin
|
#1000 $check_for_command(cmd);
|
#1000 $check_for_command(cmd);
|
end
|
end
|
|
|
// now switch on the command
|
// now switch on the command
|
case (cmd)
|
case (cmd)
|
|
|
`CMD_RESET : // reset
|
`CMD_RESET : // reset
|
begin
|
begin
|
|
|
// call reset task
|
// call reset task
|
reset_tap;
|
reset_tap;
|
// and put TAP into run_test_idle state
|
// and put TAP into run_test_idle state
|
goto_run_test_idle;
|
goto_run_test_idle;
|
|
|
end
|
end
|
|
|
`CMD_JTAG_SET_IR : // set jtag instruction register
|
`CMD_JTAG_SET_IR : // set jtag instruction register
|
begin
|
begin
|
|
|
$get_command_data(jtag_instn_val);
|
$get_command_data(jtag_instn_val);
|
|
|
set_instruction(jtag_instn_val);
|
set_instruction(jtag_instn_val);
|
|
|
end
|
end
|
`CMD_SET_DEBUG_CHAIN : // set debug chain
|
`CMD_SET_DEBUG_CHAIN : // set debug chain
|
begin
|
begin
|
|
|
$get_command_data(set_chain_val);
|
$get_command_data(set_chain_val);
|
|
|
module_select(set_chain_val, 1'b0); // {chain, gen_crc_err}
|
module_select(set_chain_val, 1'b0); // {chain, gen_crc_err}
|
|
|
end
|
end
|
`CMD_CPU_CTRL_WR : // cpu CTRL write
|
`CMD_CPU_CTRL_WR : // cpu CTRL write
|
begin
|
begin
|
|
|
$get_command_data(cpu_ctrl_val);
|
$get_command_data(cpu_ctrl_val);
|
|
|
debug_cpu_wr_ctrl(cpu_ctrl_val, "");
|
debug_cpu_wr_ctrl(cpu_ctrl_val, "");
|
|
|
end
|
end
|
|
|
`CMD_CPU_CTRL_RD : // cpu CTRL read
|
`CMD_CPU_CTRL_RD : // cpu CTRL read
|
begin
|
begin
|
|
|
debug_cpu_rd_ctrl(cpu_ctrl_val);
|
debug_cpu_rd_ctrl(cpu_ctrl_val);
|
|
|
$return_command_data(cpu_ctrl_val);
|
$return_command_data(4,cpu_ctrl_val);
|
|
|
end
|
end
|
|
|
`CMD_CPU_WR_REG :
|
`CMD_CPU_WR_REG :
|
begin
|
begin
|
|
|
$get_command_address(cmd_adr);
|
$get_command_address(cmd_adr);
|
|
|
$get_command_data(block_cmd_length);
|
$get_command_data(block_cmd_length);
|
|
|
$get_command_block_data(block_cmd_length, data_storage);
|
$get_command_block_data(block_cmd_length, data_storage);
|
|
|
if (block_cmd_length > 4)
|
if (block_cmd_length > 4)
|
cpu_write_block(cmd_adr, block_cmd_length);
|
cpu_write_block(cmd_adr, block_cmd_length);
|
else
|
else
|
begin
|
begin
|
cmd_data = data_storage[0]; // Get the single word we'll write
|
cmd_data = data_storage[0]; // Get the single word we'll write
|
cpu_write_32(cmd_data, cmd_adr,16'h3);
|
cpu_write_32(cmd_data, cmd_adr,16'h3);
|
`ifdef VPI_DEBUG_INFO
|
`ifdef VPI_DEBUG_INFO
|
$display("CPU reg write. adr: 0x%x (reg group: %d reg#: %d), val: 0x%x",
|
$display("CPU reg write. adr: 0x%x (reg group: %d reg#: %d), val: 0x%x",
|
cmd_adr,cmd_adr[15:11], cmd_adr[10:0], cmd_data);
|
cmd_adr,cmd_adr[15:11], cmd_adr[10:0], cmd_data);
|
`endif
|
`endif
|
end
|
end
|
|
|
|
|
|
|
end
|
end
|
|
|
`CMD_CPU_RD_REG :
|
`CMD_CPU_RD_REG :
|
begin
|
begin
|
|
|
$get_command_address(cmd_adr);
|
$get_command_address(cmd_adr);
|
|
|
$get_command_data(block_cmd_length); // Added 090901 --jb
|
$get_command_data(block_cmd_length); // Added 090901 --jb
|
|
|
/* Depending on size, issue a block or single read */
|
/* Depending on size, issue a block or single read */
|
if (block_cmd_length > 4 )
|
if (block_cmd_length > 4 )
|
cpu_read_block(cmd_adr, block_cmd_length);
|
cpu_read_block(cmd_adr, block_cmd_length);
|
else
|
else
|
cpu_read_32(cmd_data, cmd_adr, 16'h3);
|
cpu_read_32(cmd_data, cmd_adr, 16'h3);
|
|
|
|
|
`ifdef VPI_DEBUG_INFO
|
`ifdef VPI_DEBUG_INFO
|
if (cmd_size > 4 )
|
if (cmd_size > 4 )
|
$display("CPU reg read. block adr: 0x%x (reg group: %d reg#: %d), num: %d",
|
$display("CPU reg read. block adr: 0x%x (reg group: %d reg#: %d), num: %d",
|
cmd_adr,cmd_adr[15:11], cmd_adr[10:0], block_cmd_length);
|
cmd_adr,cmd_adr[15:11], cmd_adr[10:0], block_cmd_length);
|
else
|
else
|
$display("CPU reg read. adr: 0x%x (reg group: %d reg#: %d), val: 0x%x",
|
$display("CPU reg read. adr: 0x%x (reg group: %d reg#: %d), val: 0x%x",
|
cmd_adr,cmd_adr[15:11], cmd_adr[10:0], cmd_data);
|
cmd_adr,cmd_adr[15:11], cmd_adr[10:0], cmd_data);
|
`endif
|
`endif
|
|
|
|
|
$return_command_block_data(block_cmd_length, data_storage);
|
$return_command_block_data(block_cmd_length, data_storage);
|
|
|
end
|
end
|
|
|
`CMD_WB_WR :
|
`CMD_WB_WR :
|
begin
|
begin
|
|
|
$get_command_address(cmd_adr);
|
$get_command_address(cmd_adr);
|
|
|
$get_command_data(cmd_size);
|
$get_command_data(cmd_size);
|
|
|
$get_command_data(cmd_data);
|
$get_command_data(cmd_data);
|
|
|
case (cmd_size)
|
case (cmd_size)
|
4 :
|
4 :
|
begin
|
begin
|
wb_write_32(cmd_data, cmd_adr, 16'h3);
|
wb_write_32(cmd_data, cmd_adr, 16'h3);
|
end
|
end
|
2 :
|
2 :
|
begin
|
begin
|
wb_write_16(cmd_data[15:0], cmd_adr, 16'h1);
|
wb_write_16(cmd_data[15:0], cmd_adr, 16'h1);
|
end
|
end
|
1 :
|
1 :
|
begin
|
begin
|
wb_write_8(cmd_data[7:0], cmd_adr, 16'h0);
|
wb_write_8(cmd_data[7:0], cmd_adr, 16'h0);
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
$display("* vpi_debug_module: CMD_WB_WR size incorrect: %d\n", cmd_size);
|
$display("* vpi_debug_module: CMD_WB_WR size incorrect: %d\n", cmd_size);
|
end
|
end
|
endcase // case (cmd_size)
|
endcase // case (cmd_size)
|
|
|
end
|
end
|
|
|
`CMD_WB_RD32 :
|
`CMD_WB_RD32 :
|
begin
|
begin
|
|
|
$get_command_address(cmd_adr);
|
$get_command_address(cmd_adr);
|
|
|
wb_read_32(cmd_data, cmd_adr, 16'h3);
|
wb_read_32(cmd_data, cmd_adr, 16'h3);
|
|
|
$return_command_data(cmd_data);
|
$return_command_data(4,cmd_data);
|
|
|
|
end
|
|
|
|
`CMD_WB_RD8 :
|
|
begin
|
|
|
|
$get_command_address(cmd_adr);
|
|
|
|
wb_read_8(cmd_data, cmd_adr, 16'h0);
|
|
|
|
$return_command_data(1,cmd_data);
|
|
|
end
|
end
|
|
|
`CMD_WB_BLOCK_WR32 :
|
`CMD_WB_BLOCK_WR32 :
|
begin
|
begin
|
|
|
$get_command_address(cmd_adr);
|
$get_command_address(cmd_adr);
|
|
|
$get_command_data(block_cmd_length);
|
$get_command_data(block_cmd_length);
|
|
|
$get_command_block_data(block_cmd_length, data_storage);
|
$get_command_block_data(block_cmd_length, data_storage);
|
|
|
wb_block_write_32(cmd_adr ,block_cmd_length);
|
wb_block_write_32(cmd_adr ,block_cmd_length);
|
|
|
end
|
end
|
|
|
`CMD_WB_BLOCK_RD32 :
|
`CMD_WB_BLOCK_RD32 :
|
begin
|
begin
|
|
|
$get_command_address(cmd_adr);
|
$get_command_address(cmd_adr);
|
|
|
$get_command_data(block_cmd_length);
|
$get_command_data(block_cmd_length);
|
|
|
wb_block_read_32(cmd_adr, block_cmd_length);
|
wb_block_read_32(cmd_adr, block_cmd_length);
|
|
|
$return_command_block_data(block_cmd_length, data_storage);
|
$return_command_block_data(block_cmd_length, data_storage);
|
|
|
end
|
end
|
|
|
`CMD_READ_JTAG_ID :
|
`CMD_READ_JTAG_ID :
|
begin
|
begin
|
|
|
read_id_code(id);
|
read_id_code(id);
|
|
|
$return_command_data(id);
|
$return_command_data(4,id);
|
|
|
end
|
end
|
|
|
`CMD_GDB_DETACH :
|
`CMD_GDB_DETACH :
|
begin
|
begin
|
|
|
$display("Debugging client disconnected. Finishing simulation");
|
$display("(%t)(%m)Debugging client disconnected. Finishing simulation", $time);
|
|
|
|
|
$finish();
|
$finish();
|
|
|
end
|
end
|
|
|
default:
|
default:
|
begin
|
begin
|
$display("Somehow got to the default case in the command case statement.");
|
$display("Somehow got to the default case in the command case statement.");
|
$display("Command was: %x", cmd);
|
$display("Command was: %x", cmd);
|
$display("Exiting...");
|
$display("Exiting...");
|
|
|
$finish();//shouldn't be here
|
$finish();//shouldn't be here
|
end
|
end
|
|
|
endcase // case (cmd)
|
endcase // case (cmd)
|
|
|
// send back response, which is currently nothing
|
// send back response, which is currently nothing
|
// but could be used to signal something
|
// but could be used to signal something
|
$return_response();
|
$return_response();
|
|
|
end // while (1)
|
end // while (1)
|
end
|
end
|
|
|
endtask // main
|
endtask // main
|
|
|
|
|
|
|
// Receiving data and calculating input crc
|
// Receiving data and calculating input crc
|
always @(posedge tck)
|
always @(posedge tck)
|
begin
|
begin
|
in_data_be[31:1] <= #1 in_data_be[30:0];
|
in_data_be[31:1] <= #1 in_data_be[30:0];
|
in_data_be[0] <= #1 tdo;
|
in_data_be[0] <= #1 tdo;
|
|
|
in_data_le[31] <= #1 tdo;
|
in_data_le[31] <= #1 tdo;
|
in_data_le[30:0] <= #1 in_data_le[31:1];
|
in_data_le[30:0] <= #1 in_data_le[31:1];
|
end
|
end
|
|
|
// Generation of the TCK signal
|
// Generation of the TCK signal
|
task gen_clk;
|
task gen_clk;
|
input [31:0] number;
|
input [31:0] number;
|
integer i;
|
integer i;
|
begin
|
begin
|
for(i=0; i<number; i=i+1)
|
for(i=0; i<number; i=i+1)
|
begin
|
begin
|
#Tck tck<=1;
|
#Tck tck<=1;
|
#Tck tck<=0;
|
#Tck tck<=0;
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
// TAP reset
|
// TAP reset
|
task reset_tap;
|
task reset_tap;
|
|
|
begin
|
begin
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("(%0t) Task reset_tap", $time);
|
$display("(%0t) Task reset_tap", $time);
|
`endif
|
`endif
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(5);
|
gen_clk(5);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// Goes to RunTestIdle state
|
// Goes to RunTestIdle state
|
task goto_run_test_idle;
|
task goto_run_test_idle;
|
begin
|
begin
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("(%0t) Task goto_run_test_idle", $time);
|
$display("(%0t) Task goto_run_test_idle", $time);
|
`endif
|
`endif
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(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 set_instruction;
|
task set_instruction;
|
input [3:0] instr;
|
input [3:0] instr;
|
integer i;
|
integer i;
|
|
|
begin
|
begin
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
case (instr)
|
case (instr)
|
`EXTEST : $display("(%0t) Task set_instruction (EXTEST)", $time);
|
`EXTEST : $display("(%0t) Task set_instruction (EXTEST)", $time);
|
`SAMPLE_PRELOAD : $display("(%0t) Task set_instruction (SAMPLE_PRELOAD)", $time);
|
`SAMPLE_PRELOAD : $display("(%0t) Task set_instruction (SAMPLE_PRELOAD)", $time);
|
`IDCODE : $display("(%0t) Task set_instruction (IDCODE)", $time);
|
`IDCODE : $display("(%0t) Task set_instruction (IDCODE)", $time);
|
`DEBUG : $display("(%0t) Task set_instruction (DEBUG)", $time);
|
`DEBUG : $display("(%0t) Task set_instruction (DEBUG)", $time);
|
`MBIST : $display("(%0t) Task set_instruction (MBIST)", $time);
|
`MBIST : $display("(%0t) Task set_instruction (MBIST)", $time);
|
`BYPASS : $display("(%0t) Task set_instruction (BYPASS)", $time);
|
`BYPASS : $display("(%0t) Task set_instruction (BYPASS)", $time);
|
default
|
default
|
begin
|
begin
|
$display("(%0t) Task set_instruction (Unsupported instruction !!!)", $time);
|
$display("(%0t) Task set_instruction (Unsupported instruction !!!)", $time);
|
$display("\tERROR: Unsupported instruction !!!", $time);
|
$display("\tERROR: Unsupported instruction !!!", $time);
|
$stop;
|
$stop;
|
end
|
end
|
endcase
|
endcase
|
`endif
|
`endif
|
|
|
tms<=#1 1;
|
tms<=#1 1;
|
gen_clk(2);
|
gen_clk(2);
|
tms<=#1 0;
|
tms<=#1 0;
|
gen_clk(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
|
tdi<=#1 instr[i];
|
tdi<=#1 instr[i];
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tdi<=#1 instr[i]; // last shift
|
tdi<=#1 instr[i]; // last shift
|
tms<=#1 1; // going out of shiftIR
|
tms<=#1 1; // going out of shiftIR
|
gen_clk(1);
|
gen_clk(1);
|
tdi<=#1 'hz; // tri-state
|
tdi<=#1 'hz; // tri-state
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#1 0;
|
tms<=#1 0;
|
gen_clk(1); // we are in RunTestIdle
|
gen_clk(1); // we are in RunTestIdle
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// send 32 bits through the device
|
// send 32 bits through the device
|
task test_bypass;
|
task test_bypass;
|
input [31:0] in;
|
input [31:0] in;
|
output [31:0] out;
|
output [31:0] out;
|
integer i;
|
integer i;
|
|
|
reg [31:0] out;
|
reg [31:0] out;
|
|
|
begin
|
begin
|
tms<=#Tp 1;
|
tms<=#Tp 1;
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#Tp 0;
|
tms<=#Tp 0;
|
gen_clk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
for(i=31; i>=0; i=i-1)
|
for(i=31; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#Tp in[i];
|
tdi<=#Tp in[i];
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tms<=#Tp 1; // going out of shiftDR
|
tms<=#Tp 1; // going out of shiftDR
|
gen_clk(1);
|
gen_clk(1);
|
|
|
out <=#Tp in_data_be;
|
out <=#Tp in_data_be;
|
tdi<=#Tp 'hz;
|
tdi<=#Tp 'hz;
|
|
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#Tp 0;
|
tms<=#Tp 0;
|
gen_clk(1); // we are in RunTestIdle
|
gen_clk(1); // we are in RunTestIdle
|
end
|
end
|
endtask
|
endtask
|
|
|
// Reads the ID code
|
// Reads the ID code
|
task read_id_code;
|
task read_id_code;
|
output [31:0] code;
|
output [31:0] code;
|
reg [31:0] code;
|
reg [31:0] code;
|
begin
|
begin
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("(%0t) Task read_id_code", $time);
|
$display("(%0t) Task read_id_code", $time);
|
`endif
|
`endif
|
|
|
tms<=#1 1;
|
tms<=#1 1;
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#1 0;
|
tms<=#1 0;
|
gen_clk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
tdi<=#1 0;
|
tdi<=#1 0;
|
gen_clk(31);
|
gen_clk(31);
|
|
|
tms<=#1 1; // going out of shiftIR
|
tms<=#1 1; // going out of shiftIR
|
gen_clk(1);
|
gen_clk(1);
|
|
|
code = in_data_le;
|
code = in_data_le;
|
|
|
tdi<=#1 'hz; // tri-state
|
tdi<=#1 'hz; // tri-state
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#1 0;
|
tms<=#1 0;
|
gen_clk(1); // we are in RunTestIdle
|
gen_clk(1); // we are in RunTestIdle
|
end
|
end
|
endtask
|
endtask
|
|
|
// test bundary scan chain
|
// test bundary scan chain
|
task test_bs;
|
task test_bs;
|
input [31:0] in;
|
input [31:0] in;
|
output [31:0] out;
|
output [31:0] out;
|
integer i;
|
integer i;
|
|
|
reg [31:0] out;
|
reg [31:0] out;
|
|
|
begin
|
begin
|
tms<=#Tp 1;
|
tms<=#Tp 1;
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#Tp 0;
|
tms<=#Tp 0;
|
gen_clk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
for(i=31; i>=0; i=i-1)
|
for(i=31; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#Tp in[i];
|
tdi<=#Tp in[i];
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
gen_clk(`BS_CELL_NB-1);
|
gen_clk(`BS_CELL_NB-1);
|
tms<=#Tp 1; // going out of shiftDR
|
tms<=#Tp 1; // going out of shiftDR
|
gen_clk(1);
|
gen_clk(1);
|
|
|
out <=#Tp in_data_be;
|
out <=#Tp in_data_be;
|
|
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#Tp 0;
|
tms<=#Tp 0;
|
gen_clk(1); // we are in RunTestIdle
|
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 module_select;
|
task module_select;
|
input [`DBG_TOP_MODULE_ID_LENGTH -1:0] data;
|
input [`DBG_TOP_MODULE_ID_LENGTH -1:0] data;
|
input gen_crc_err;
|
input gen_crc_err;
|
integer i;
|
integer i;
|
|
|
begin
|
begin
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
case (data)
|
case (data)
|
`DBG_TOP_CPU1_DEBUG_MODULE : $display("(%0t) Task module_select (DBG_TOP_CPU1_DEBUG_MODULE, gen_crc_err=%0d)", $time, gen_crc_err);
|
`DBG_TOP_CPU1_DEBUG_MODULE : $display("(%0t) Task module_select (DBG_TOP_CPU1_DEBUG_MODULE, gen_crc_err=%0d)", $time, gen_crc_err);
|
`DBG_TOP_CPU0_DEBUG_MODULE : $display("(%0t) Task module_select (DBG_TOP_CPU0_DEBUG_MODULE, gen_crc_err=%0d)", $time, gen_crc_err);
|
`DBG_TOP_CPU0_DEBUG_MODULE : $display("(%0t) Task module_select (DBG_TOP_CPU0_DEBUG_MODULE, gen_crc_err=%0d)", $time, gen_crc_err);
|
`DBG_TOP_WISHBONE_DEBUG_MODULE : $display("(%0t) Task module_select (DBG_TOP_WISHBONE_DEBUG_MODULE gen_crc_err=%0d)", $time, gen_crc_err);
|
`DBG_TOP_WISHBONE_DEBUG_MODULE : $display("(%0t) Task module_select (DBG_TOP_WISHBONE_DEBUG_MODULE gen_crc_err=%0d)", $time, gen_crc_err);
|
default : $display("(%0t) Task module_select (ERROR!!! Unknown module selected)", $time);
|
default : $display("(%0t) Task module_select (ERROR!!! Unknown module selected)", $time);
|
endcase
|
endcase
|
`endif
|
`endif
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
status = {`DBG_TOP_STATUS_LEN{1'b0}}; // Initialize status to all 0's
|
status = {`DBG_TOP_STATUS_LEN{1'b0}}; // Initialize status to all 0's
|
crc_out = {`DBG_TOP_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
crc_out = {`DBG_TOP_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
tdi<=#1 1'b1; // module_select bit
|
tdi<=#1 1'b1; // module_select bit
|
calculate_crc(1'b1);
|
calculate_crc(1'b1);
|
gen_clk(1);
|
gen_clk(1);
|
|
|
for(i=`DBG_TOP_MODULE_ID_LENGTH -1; i>=0; i=i-1) // Shifting module ID
|
for(i=`DBG_TOP_MODULE_ID_LENGTH -1; i>=0; i=i-1) // Shifting module ID
|
begin
|
begin
|
tdi<=#1 data[i];
|
tdi<=#1 data[i];
|
calculate_crc(data[i]);
|
calculate_crc(data[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_TOP_CRC_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_TOP_CRC_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
if (gen_crc_err & (i==0)) // Generate crc error at last crc bit
|
if (gen_crc_err & (i==0)) // Generate crc error at last crc bit
|
tdi<=#1 ~crc_out[i]; // error crc
|
tdi<=#1 ~crc_out[i]; // error crc
|
else
|
else
|
tdi<=#1 crc_out[i]; // ok crc
|
tdi<=#1 crc_out[i]; // ok crc
|
|
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tdi<=#1 1'hz; // tri-state
|
tdi<=#1 1'hz; // tri-state
|
|
|
crc_in = {`DBG_TOP_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
crc_in = {`DBG_TOP_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
|
|
for(i=`DBG_TOP_STATUS_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_TOP_STATUS_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
gen_clk(1); // Generating 1 clock to read out a status bit.
|
gen_clk(1); // Generating 1 clock to read out a status bit.
|
status[i] = tdo;
|
status[i] = tdo;
|
end
|
end
|
|
|
for(i=0; i<`DBG_TOP_CRC_LEN -1; i=i+1)
|
for(i=0; i<`DBG_TOP_CRC_LEN -1; i=i+1)
|
gen_clk(1);
|
gen_clk(1);
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit1_dr
|
gen_clk(1); // to exit1_dr
|
|
|
if (~crc_match_in)
|
if (~crc_match_in)
|
begin
|
begin
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$stop;
|
$stop;
|
`endif
|
`endif
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to update_dr
|
gen_clk(1); // to update_dr
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to run_test_idle
|
gen_clk(1); // to run_test_idle
|
|
|
if (|status)
|
if (|status)
|
begin
|
begin
|
$write("(*E) (%0t) Module select error: ", $time);
|
$write("(*E) (%0t) Module select error: ", $time);
|
casex (status)
|
casex (status)
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'bx1xx : $display("Non-existing module selected !!!\n\n", $time);
|
4'bx1xx : $display("Non-existing module selected !!!\n\n", $time);
|
4'bxx1x : $display("Status[1] should be 1'b0 !!!\n\n", $time);
|
4'bxx1x : $display("Status[1] should be 1'b0 !!!\n\n", $time);
|
4'bxxx1 : $display("Status[0] should be 1'b0 !!!\n\n", $time);
|
4'bxxx1 : $display("Status[0] should be 1'b0 !!!\n\n", $time);
|
endcase
|
endcase
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$stop;
|
$stop;
|
`endif
|
`endif
|
end
|
end
|
end
|
end
|
endtask // module_select
|
endtask // module_select
|
|
|
|
|
|
|
// 32-bit write to the wishbone
|
// 32-bit write to the wishbone
|
task wb_write_32;
|
task wb_write_32;
|
input [31:0] data;
|
input [31:0] data;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
begin
|
begin
|
data_storage[0] = data;
|
data_storage[0] = data;
|
debug_wishbone_wr_comm(`DBG_WB_WRITE32, addr, length, 1'b0);
|
debug_wishbone_wr_comm(`DBG_WB_WRITE32, addr, length, 1'b0);
|
last_wb_cmd = `DBG_WB_WRITE32; last_wb_cmd_text = "DBG_WB_WRITE32";
|
last_wb_cmd = `DBG_WB_WRITE32; last_wb_cmd_text = "DBG_WB_WRITE32";
|
length_global = length + 1;
|
length_global = length + 1;
|
debug_wishbone_go(1'b0, 1'b0);
|
debug_wishbone_go(1'b0, 1'b0);
|
//debug_wishbone_go(1'b1, 1'b0); // maybe causes underrun/overrun error when wait for WB ready?
|
//debug_wishbone_go(1'b1, 1'b0); // maybe causes underrun/overrun error when wait for WB ready?
|
if (length>3)
|
if (length>3)
|
$display("WARNING: Only first data word is stored for writting ( See module %m)");
|
$display("WARNING: Only first data word is stored for writting ( See module %m)");
|
end
|
end
|
endtask
|
endtask
|
|
|
// block 32-bit write to the wishbone
|
// block 32-bit write to the wishbone
|
// presumes data is already in data_storage[]
|
// presumes data is already in data_storage[]
|
task wb_block_write_32;
|
task wb_block_write_32;
|
|
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
begin
|
begin
|
|
|
debug_wishbone_wr_comm(`DBG_WB_WRITE32, addr, length-1, 1'b0);
|
debug_wishbone_wr_comm(`DBG_WB_WRITE32, addr, length-1, 1'b0);
|
|
|
last_wb_cmd = `DBG_WB_WRITE32; last_wb_cmd_text = "DBG_WB_WRITE32";
|
last_wb_cmd = `DBG_WB_WRITE32; last_wb_cmd_text = "DBG_WB_WRITE32";
|
|
|
length_global = length; // number of bytes!
|
length_global = length; // number of bytes!
|
|
|
debug_wishbone_go(1'b0, 1'b0);
|
debug_wishbone_go(1'b0, 1'b0);
|
|
|
//debug_wishbone_go(1'b1, 1'b0); // maybe causes underrun/overrun error when wait for WB ready?
|
//debug_wishbone_go(1'b1, 1'b0); // maybe causes underrun/overrun error when wait for WB ready?
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
// 32-bit read from the wishbone
|
// 32-bit read from the wishbone
|
task wb_read_32;
|
task wb_read_32;
|
|
|
output [31:0] data;
|
output [31:0] data;
|
|
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
begin
|
begin
|
debug_wishbone_wr_comm(`DBG_WB_READ32, addr, length, 1'b0);
|
debug_wishbone_wr_comm(`DBG_WB_READ32, addr, length, 1'b0);
|
last_wb_cmd = `DBG_WB_READ32; last_wb_cmd_text = "DBG_WB_READ32";
|
last_wb_cmd = `DBG_WB_READ32; last_wb_cmd_text = "DBG_WB_READ32";
|
length_global = length + 1;
|
length_global = length + 1;
|
//debug_wishbone_go(1'b0, 1'b0);
|
//debug_wishbone_go(1'b0, 1'b0);
|
debug_wishbone_go(1'b1, 1'b0);
|
debug_wishbone_go(1'b1, 1'b0);
|
data = data_storage[0];
|
data = data_storage[0];
|
if (length>3)
|
if (length>3)
|
$display("WARNING: Only first data word is stored for writting ( See module %m)");
|
$display("WARNING: Only first data word is stored for writting ( See module %m)");
|
end
|
end
|
endtask
|
endtask // wb_read_32
|
|
|
|
// 8-bit read from the wishbone
|
|
task wb_read_8;
|
|
|
|
output [31:0] data;
|
|
|
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
|
begin
|
|
debug_wishbone_wr_comm(`DBG_WB_READ8, addr, length, 1'b0);
|
|
last_wb_cmd = `DBG_WB_READ8; last_wb_cmd_text = "DBG_WB_READ8";
|
|
length_global = length + 1;
|
|
debug_wishbone_go(1'b1, 1'b0);
|
|
data = data_storage[0];
|
|
end
|
|
endtask // wb_read_8
|
|
|
|
|
|
|
// block 32-bit read from the wishbone
|
// block 32-bit read from the wishbone
|
// assumes data will be stored into data_storage[]
|
// assumes data will be stored into data_storage[]
|
task wb_block_read_32;
|
task wb_block_read_32;
|
|
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
begin
|
begin
|
debug_wishbone_wr_comm(`DBG_WB_READ32, addr, length-1, 1'b0);
|
debug_wishbone_wr_comm(`DBG_WB_READ32, addr, length-1, 1'b0);
|
|
|
last_wb_cmd = `DBG_WB_READ32; last_wb_cmd_text = "DBG_WB_READ32";
|
last_wb_cmd = `DBG_WB_READ32; last_wb_cmd_text = "DBG_WB_READ32";
|
|
|
length_global = length;
|
length_global = length;
|
|
|
//debug_wishbone_go(1'b0, 1'b0);
|
//debug_wishbone_go(1'b0, 1'b0);
|
debug_wishbone_go(1'b1, 1'b0);
|
debug_wishbone_go(1'b1, 1'b0);
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// 16-bit write to the wishbone
|
// 16-bit write to the wishbone
|
task wb_write_16;
|
task wb_write_16;
|
input [15:0] data;
|
input [15:0] data;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
begin
|
begin
|
data_storage[0] = {data, 16'h0};
|
data_storage[0] = {data, 16'h0};
|
debug_wishbone_wr_comm(`DBG_WB_WRITE16, addr, length, 1'b0);
|
debug_wishbone_wr_comm(`DBG_WB_WRITE16, addr, length, 1'b0);
|
last_wb_cmd = `DBG_WB_WRITE16; last_wb_cmd_text = "DBG_WB_WRITE16";
|
last_wb_cmd = `DBG_WB_WRITE16; last_wb_cmd_text = "DBG_WB_WRITE16";
|
length_global = length + 1;
|
length_global = length + 1;
|
debug_wishbone_go(1'b0, 1'b0);
|
debug_wishbone_go(1'b0, 1'b0);
|
if (length>1)
|
if (length>1)
|
$display("WARNING: Only first data half is stored for writting ( See module %m)");
|
$display("WARNING: Only first data half is stored for writting ( See module %m)");
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
|
|
// 8-bit write to the wishbone
|
// 8-bit write to the wishbone
|
task wb_write_8;
|
task wb_write_8;
|
input [7:0] data;
|
input [7:0] data;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
begin
|
begin
|
data_storage[0] = {data, 24'h0};
|
data_storage[0] = {data, 24'h0};
|
debug_wishbone_wr_comm(`DBG_WB_WRITE8, addr, length, 1'b0);
|
debug_wishbone_wr_comm(`DBG_WB_WRITE8, addr, length, 1'b0);
|
last_wb_cmd = `DBG_WB_WRITE8; last_wb_cmd_text = "DBG_WB_WRITE8";
|
last_wb_cmd = `DBG_WB_WRITE8; last_wb_cmd_text = "DBG_WB_WRITE8";
|
length_global = length + 1;
|
length_global = length + 1;
|
debug_wishbone_go(1'b0, 1'b0);
|
debug_wishbone_go(1'b0, 1'b0);
|
if (length>0)
|
if (length>0)
|
$display("WARNING: Only first data byte is stored for writting ( See module %m)");
|
$display("WARNING: Only first data byte is stored for writting ( See module %m)");
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
|
|
task debug_wishbone_wr_comm;
|
task debug_wishbone_wr_comm;
|
input [`DBG_WB_ACC_TYPE_LEN -1:0] acc_type;
|
input [`DBG_WB_ACC_TYPE_LEN -1:0] acc_type;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input gen_crc_err;
|
input gen_crc_err;
|
integer i;
|
integer i;
|
reg [`DBG_WB_CMD_LEN -1:0] command;
|
reg [`DBG_WB_CMD_LEN -1:0] command;
|
|
|
begin
|
begin
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("(%0t) Task debug_wishbone_wr_comm: ", $time);
|
$display("(%0t) Task debug_wishbone_wr_comm: ", $time);
|
`endif
|
`endif
|
|
|
command = `DBG_WB_WR_COMM;
|
command = `DBG_WB_WR_COMM;
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
crc_out = {`DBG_WB_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
crc_out = {`DBG_WB_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
|
|
tdi<=#1 1'b0; // module_select bit = 0
|
tdi<=#1 1'b0; // module_select bit = 0
|
calculate_crc(1'b0);
|
calculate_crc(1'b0);
|
gen_clk(1);
|
gen_clk(1);
|
|
|
for(i=`DBG_WB_CMD_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_WB_CMD_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 command[i]; // command
|
tdi<=#1 command[i]; // command
|
calculate_crc(command[i]);
|
calculate_crc(command[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_WB_ACC_TYPE_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_WB_ACC_TYPE_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 acc_type[i]; // command
|
tdi<=#1 acc_type[i]; // command
|
calculate_crc(acc_type[i]);
|
calculate_crc(acc_type[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_WB_ADR_LEN -1; i>=0; i=i-1) // address
|
for(i=`DBG_WB_ADR_LEN -1; i>=0; i=i-1) // address
|
begin
|
begin
|
tdi<=#1 addr[i];
|
tdi<=#1 addr[i];
|
calculate_crc(addr[i]);
|
calculate_crc(addr[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_WB_LEN_LEN -1; i>=0; i=i-1) // length
|
for(i=`DBG_WB_LEN_LEN -1; i>=0; i=i-1) // length
|
begin
|
begin
|
tdi<=#1 length[i];
|
tdi<=#1 length[i];
|
calculate_crc(length[i]);
|
calculate_crc(length[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_WB_CRC_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_WB_CRC_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
if (gen_crc_err & (i==0)) // Generate crc error at last crc bit
|
if (gen_crc_err & (i==0)) // Generate crc error at last crc bit
|
tdi<=#1 ~crc_out[i]; // error crc
|
tdi<=#1 ~crc_out[i]; // error crc
|
else
|
else
|
tdi<=#1 crc_out[i]; // ok crc
|
tdi<=#1 crc_out[i]; // ok crc
|
|
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tdi<=#1 1'hz;
|
tdi<=#1 1'hz;
|
|
|
crc_in = {`DBG_WB_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
crc_in = {`DBG_WB_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
|
|
for(i=`DBG_WB_STATUS_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_WB_STATUS_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
gen_clk(1); // Generating clock to read out a status bit.
|
gen_clk(1); // Generating clock to read out a status bit.
|
status_wb[i] = tdo;
|
status_wb[i] = tdo;
|
end
|
end
|
|
|
if (|status_wb)
|
if (|status_wb)
|
begin
|
begin
|
$write("(*E) (%0t) debug_wishbone_wr_comm error: ", $time);
|
$write("(*E) (%0t) debug_wishbone_wr_comm error: ", $time);
|
casex (status_wb)
|
casex (status_wb)
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'bx1xx : $display("Unknown command !!!\n\n", $time);
|
4'bx1xx : $display("Unknown command !!!\n\n", $time);
|
4'bxx1x : $display("WISHBONE error !!!\n\n", $time);
|
4'bxx1x : $display("WISHBONE error !!!\n\n", $time);
|
4'bxxx1 : $display("Overrun/Underrun !!!\n\n", $time);
|
4'bxxx1 : $display("Overrun/Underrun !!!\n\n", $time);
|
endcase
|
endcase
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$stop;
|
$stop;
|
`endif
|
`endif
|
end
|
end
|
|
|
|
|
for(i=0; i<`DBG_WB_CRC_LEN -1; i=i+1) // Getting in the CRC
|
for(i=0; i<`DBG_WB_CRC_LEN -1; i=i+1) // Getting in the CRC
|
begin
|
begin
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit1_dr
|
gen_clk(1); // to exit1_dr
|
|
|
if (~crc_match_in)
|
if (~crc_match_in)
|
begin
|
begin
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$stop;
|
$stop;
|
`endif
|
`endif
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to update_dr
|
gen_clk(1); // to update_dr
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to run_test_idle
|
gen_clk(1); // to run_test_idle
|
end
|
end
|
endtask // debug_wishbone_wr_comm
|
endtask // debug_wishbone_wr_comm
|
|
|
|
|
|
|
task debug_wishbone_go;
|
task debug_wishbone_go;
|
|
|
input wait_for_wb_ready;
|
input wait_for_wb_ready;
|
input gen_crc_err;
|
input gen_crc_err;
|
integer i;
|
integer i;
|
reg [4:0] bit_pointer;
|
reg [4:0] bit_pointer;
|
integer word_pointer;
|
integer word_pointer;
|
reg [31:0] tmp_data;
|
reg [31:0] tmp_data;
|
reg [`DBG_WB_CMD_LEN -1:0] command;
|
reg [`DBG_WB_CMD_LEN -1:0] command;
|
|
|
|
|
begin
|
begin
|
|
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("(%0t) Task debug_wishbone_go (previous command was %0s): ", $time, last_wb_cmd_text);
|
$display("(%0t) Task debug_wishbone_go (previous command was %0s): ", $time, last_wb_cmd_text);
|
`endif
|
`endif
|
|
|
command = `DBG_WB_GO;
|
command = `DBG_WB_GO;
|
word_pointer = 0;
|
word_pointer = 0;
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
crc_out = {`DBG_WB_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
crc_out = {`DBG_WB_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
|
|
tdi<=#1 1'b0; // module_select bit = 0
|
tdi<=#1 1'b0; // module_select bit = 0
|
calculate_crc(1'b0);
|
calculate_crc(1'b0);
|
gen_clk(1);
|
gen_clk(1);
|
|
|
for(i=`DBG_WB_CMD_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_WB_CMD_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 command[i]; // command
|
tdi<=#1 command[i]; // command
|
calculate_crc(command[i]);
|
calculate_crc(command[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
// W R I T E
|
// W R I T E
|
if (
|
if (
|
(last_wb_cmd == `DBG_WB_WRITE8) | (last_wb_cmd == `DBG_WB_WRITE16) |
|
(last_wb_cmd == `DBG_WB_WRITE8) | (last_wb_cmd == `DBG_WB_WRITE16) |
|
(last_wb_cmd == `DBG_WB_WRITE32)
|
(last_wb_cmd == `DBG_WB_WRITE32)
|
) // When WB_WRITEx was previously activated, data needs to be shifted.
|
) // When WB_WRITEx was previously activated, data needs to be shifted.
|
begin
|
begin
|
for (i=0; i<((length_global) << 3); i=i+1)
|
for (i=0; i<((length_global) << 3); i=i+1)
|
begin
|
begin
|
|
|
if ((!(i%32)) && (i>0))
|
if ((!(i%32)) && (i>0))
|
begin
|
begin
|
word_pointer = word_pointer + 1;
|
word_pointer = word_pointer + 1;
|
end
|
end
|
|
|
tmp_data = data_storage[word_pointer];
|
tmp_data = data_storage[word_pointer];
|
|
|
bit_pointer = 31-i[4:0];
|
bit_pointer = 31-i[4:0];
|
|
|
tdi<=#1 tmp_data[bit_pointer];
|
tdi<=#1 tmp_data[bit_pointer];
|
|
|
calculate_crc(tmp_data[bit_pointer]);
|
calculate_crc(tmp_data[bit_pointer]);
|
|
|
gen_clk(1);
|
gen_clk(1);
|
|
|
end
|
end
|
end
|
end
|
|
|
for(i=`DBG_WB_CRC_LEN -1; i>=1; i=i-1)
|
for(i=`DBG_WB_CRC_LEN -1; i>=1; i=i-1)
|
begin
|
begin
|
tdi<=#1 crc_out[i];
|
tdi<=#1 crc_out[i];
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
if (gen_crc_err) // Generate crc error at last crc bit
|
if (gen_crc_err) // Generate crc error at last crc bit
|
tdi<=#1 ~crc_out[0]; // error crc
|
tdi<=#1 ~crc_out[0]; // error crc
|
else
|
else
|
tdi<=#1 crc_out[0]; // ok crc
|
tdi<=#1 crc_out[0]; // ok crc
|
|
|
if (wait_for_wb_ready)
|
if (wait_for_wb_ready)
|
begin
|
begin
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit1_dr. Last CRC is shifted on this clk
|
gen_clk(1); // to exit1_dr. Last CRC is shifted on this clk
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to pause_dr
|
gen_clk(1); // to pause_dr
|
|
|
#2; // wait a bit for tdo to activate
|
#2; // wait a bit for tdo to activate
|
while (tdo) // waiting for wb to send "ready"
|
while (tdo) // waiting for wb to send "ready"
|
begin
|
begin
|
gen_clk(1); // staying in pause_dr
|
gen_clk(1); // staying in pause_dr
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit2_dr
|
gen_clk(1); // to exit2_dr
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to shift_dr
|
gen_clk(1); // to shift_dr
|
end
|
end
|
else
|
else
|
begin
|
begin
|
gen_clk(1); // Last CRC is shifted on this clk
|
gen_clk(1); // Last CRC is shifted on this clk
|
end
|
end
|
|
|
|
|
tdi<=#1 1'hz;
|
tdi<=#1 1'hz;
|
|
|
// R E A D
|
// R E A D
|
|
|
crc_in = {`DBG_WB_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
crc_in = {`DBG_WB_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
|
|
if (
|
if (
|
(last_wb_cmd == `DBG_WB_READ8) | (last_wb_cmd == `DBG_WB_READ16) |
|
(last_wb_cmd == `DBG_WB_READ8) | (last_wb_cmd == `DBG_WB_READ16) |
|
(last_wb_cmd == `DBG_WB_READ32)
|
(last_wb_cmd == `DBG_WB_READ32)
|
) // When WB_READx was previously activated, data needs to be shifted.
|
) // When WB_READx was previously activated, data needs to be shifted.
|
begin
|
begin
|
|
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("\t\tGenerating %0d clocks to read %0d data bytes.", length_global<<3, length_global);
|
$display("\t\tGenerating %0d clocks to read %0d data bytes.", length_global<<3, length_global);
|
`endif
|
`endif
|
word_pointer = 0; // Reset pointer
|
word_pointer = 0; // Reset pointer
|
|
|
for (i=0; i<(length_global<<3); i=i+1)
|
for (i=0; i<(length_global<<3); i=i+1)
|
begin
|
begin
|
|
|
gen_clk(1);
|
gen_clk(1);
|
|
|
if (i[4:0] == 31) // Latching data
|
if (i[2:0] == 7) // Latching data
|
begin
|
incoming_word = {incoming_word[23:0],in_data_be[7:0]};
|
|
|
data_storage[word_pointer] = in_data_be;
|
if (i[4:0] == 31)
|
|
begin
|
|
data_storage[word_pointer] = incoming_word;
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("\t\tin_data_be = 0x%x", in_data_be);
|
$display("\t\tin_data_be = 0x%x", incoming_word);
|
`endif
|
`endif
|
word_pointer = word_pointer + 1;
|
word_pointer = word_pointer + 1;
|
|
|
end
|
end
|
|
end // for (i=0; i<(length_global<<3); i=i+1)
|
|
|
|
// Copy in any leftovers
|
|
if (length_global[1:0] != 0)
|
|
begin
|
|
data_storage[word_pointer] = incoming_word;
|
|
`ifdef DEBUG_INFO
|
|
$display("\t\tin_data_be = 0x%x", incoming_word);
|
|
`endif
|
end
|
end
|
end
|
end
|
|
|
for(i=`DBG_WB_STATUS_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_WB_STATUS_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
|
|
gen_clk(1); // Generating clock to read out a status bit.
|
gen_clk(1); // Generating clock to read out a status bit.
|
status_wb[i] = tdo;
|
status_wb[i] = tdo;
|
|
|
end
|
end
|
|
|
if (|status_wb)
|
if (|status_wb)
|
begin
|
begin
|
$write("(*E) (%0t) debug_wishbone_go error: ", $time);
|
$write("(*E) (%0t) debug_wishbone_go error: ", $time);
|
casex (status_wb)
|
casex (status_wb)
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'bx1xx : $display("Unknown command !!!\n\n", $time);
|
4'bx1xx : $display("Unknown command !!!\n\n", $time);
|
4'bxx1x : $display("WISHBONE error !!!\n\n", $time);
|
4'bxx1x : $display("WISHBONE error !!!\n\n", $time);
|
4'bxxx1 : $display("Overrun/Underrun !!!\n\n", $time);
|
4'bxxx1 : $display("Overrun/Underrun !!!\n\n", $time);
|
endcase
|
endcase
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$stop;
|
$stop;
|
`endif
|
`endif
|
end
|
end
|
|
|
|
|
for(i=0; i<`DBG_WB_CRC_LEN -1; i=i+1) // Getting in the CRC
|
for(i=0; i<`DBG_WB_CRC_LEN -1; i=i+1) // Getting in the CRC
|
begin
|
begin
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit1_dr
|
gen_clk(1); // to exit1_dr
|
|
|
if (~crc_match_in)
|
if (~crc_match_in)
|
begin
|
begin
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$stop;
|
$stop;
|
`endif
|
`endif
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to update_dr
|
gen_clk(1); // to update_dr
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to run_test_idle
|
gen_clk(1); // to run_test_idle
|
end
|
end
|
endtask // debug_wishbone_go
|
endtask // debug_wishbone_go
|
|
|
|
|
|
|
task debug_cpu_wr_ctrl;
|
task debug_cpu_wr_ctrl;
|
input [`DBG_CPU_DR_LEN -1:0] data;
|
input [`DBG_CPU_DR_LEN -1:0] data;
|
input [99:0] text;
|
input [99:0] text;
|
integer i;
|
integer i;
|
reg [`DBG_CPU_CMD_LEN -1:0] command;
|
reg [`DBG_CPU_CMD_LEN -1:0] command;
|
|
|
begin
|
begin
|
test_text = text;
|
test_text = text;
|
|
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("(%0t) Task debug_cpu_wr_ctrl (data=0x%0x (%0s))", $time, data, text);
|
$display("(%0t) Task debug_cpu_wr_ctrl (data=0x%0x (%0s))", $time, data, text);
|
`endif
|
`endif
|
|
|
command = `DBG_CPU_WR_CTRL;
|
command = `DBG_CPU_WR_CTRL;
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
crc_out = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
crc_out = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
|
|
tdi<=#1 1'b0; // module_select bit = 0
|
tdi<=#1 1'b0; // module_select bit = 0
|
calculate_crc(1'b0);
|
calculate_crc(1'b0);
|
gen_clk(1);
|
gen_clk(1);
|
|
|
for(i=`DBG_CPU_CMD_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_CMD_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 command[i]; // command
|
tdi<=#1 command[i]; // command
|
calculate_crc(command[i]);
|
calculate_crc(command[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
|
|
for(i=`DBG_CPU_CTRL_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_CTRL_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 data[i]; // data (used cotrol bits
|
tdi<=#1 data[i]; // data (used cotrol bits
|
calculate_crc(data[i]);
|
calculate_crc(data[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_CPU_DR_LEN - `DBG_CPU_CTRL_LEN -1; i>=0; i=i-1) // unused control bits
|
for(i=`DBG_CPU_DR_LEN - `DBG_CPU_CTRL_LEN -1; i>=0; i=i-1) // unused control bits
|
begin
|
begin
|
tdi<=#1 1'b0;
|
tdi<=#1 1'b0;
|
calculate_crc(1'b0);
|
calculate_crc(1'b0);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
|
|
for(i=`DBG_CPU_CRC_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_CRC_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 crc_out[i]; // ok crc
|
tdi<=#1 crc_out[i]; // ok crc
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tdi<=#1 1'hz;
|
tdi<=#1 1'hz;
|
|
|
crc_in = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
crc_in = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
|
|
for(i=`DBG_CPU_STATUS_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_STATUS_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
gen_clk(1); // Generating clock to read out a status bit.
|
gen_clk(1); // Generating clock to read out a status bit.
|
status_cpu[i] = tdo;
|
status_cpu[i] = tdo;
|
end
|
end
|
|
|
if (|status_cpu)
|
if (|status_cpu)
|
begin
|
begin
|
$write("(*E) (%0t) debug_cpu_wr_ctrl error: ", $time);
|
$write("(*E) (%0t) debug_cpu_wr_ctrl error: ", $time);
|
casex (status_cpu)
|
casex (status_cpu)
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'bx1xx : $display("??? error !!!\n\n", $time);
|
4'bx1xx : $display("??? error !!!\n\n", $time);
|
4'bxx1x : $display("??? error !!!\n\n", $time);
|
4'bxx1x : $display("??? error !!!\n\n", $time);
|
4'bxxx1 : $display("??? error !!!\n\n", $time);
|
4'bxxx1 : $display("??? error !!!\n\n", $time);
|
endcase
|
endcase
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$stop;
|
$stop;
|
`endif
|
`endif
|
end
|
end
|
|
|
|
|
for(i=0; i<`DBG_CPU_CRC_LEN -1; i=i+1) // Getting in the CRC
|
for(i=0; i<`DBG_CPU_CRC_LEN -1; i=i+1) // Getting in the CRC
|
begin
|
begin
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit1_dr
|
gen_clk(1); // to exit1_dr
|
|
|
if (~crc_match_in)
|
if (~crc_match_in)
|
begin
|
begin
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$stop;
|
$stop;
|
`endif
|
`endif
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to update_dr
|
gen_clk(1); // to update_dr
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to run_test_idle
|
gen_clk(1); // to run_test_idle
|
end
|
end
|
endtask // debug_cpu_wr_ctrl
|
endtask // debug_cpu_wr_ctrl
|
|
|
task debug_cpu_rd_ctrl;
|
task debug_cpu_rd_ctrl;
|
output [`DBG_CPU_DR_LEN -1:0] data;
|
output [`DBG_CPU_DR_LEN -1:0] data;
|
//input [99:0] text;
|
//input [99:0] text;
|
integer i;
|
integer i;
|
reg [`DBG_CPU_CMD_LEN -1:0] command;
|
reg [`DBG_CPU_CMD_LEN -1:0] command;
|
|
|
begin
|
begin
|
|
|
|
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("(%0t) Task debug_cpu_rd_ctrl", $time);
|
$display("(%0t) Task debug_cpu_rd_ctrl", $time);
|
`endif
|
`endif
|
|
|
command = `DBG_CPU_RD_CTRL;
|
command = `DBG_CPU_RD_CTRL;
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
crc_out = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
crc_out = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
|
|
tdi<=#1 1'b0; // module_select bit = 0
|
tdi<=#1 1'b0; // module_select bit = 0
|
calculate_crc(1'b0);
|
calculate_crc(1'b0);
|
gen_clk(1);
|
gen_clk(1);
|
|
|
for(i=`DBG_CPU_CMD_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_CMD_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 command[i]; // command
|
tdi<=#1 command[i]; // command
|
calculate_crc(command[i]);
|
calculate_crc(command[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_CPU_CRC_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_CRC_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 crc_out[i]; // ok crc
|
tdi<=#1 crc_out[i]; // ok crc
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tdi<=#1 1'hz;
|
tdi<=#1 1'hz;
|
|
|
crc_in = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
crc_in = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
|
|
// Read incoming debug ctrl data (52 bits)
|
// Read incoming debug ctrl data (52 bits)
|
//cpu_ctrl_val[1:0];
|
//cpu_ctrl_val[1:0];
|
gen_clk(1);
|
gen_clk(1);
|
//cpu_ctrl_val[0] <= #1 tdo; // cpu reset bit
|
//cpu_ctrl_val[0] <= #1 tdo; // cpu reset bit
|
data[0] <= #1 tdo; // cpu reset bit
|
data[0] <= #1 tdo; // cpu reset bit
|
gen_clk(1);
|
gen_clk(1);
|
//cpu_ctrl_val[1] <= #1 tdo; // cpu stall bit
|
//cpu_ctrl_val[1] <= #1 tdo; // cpu stall bit
|
data[1] <= #1 tdo; // cpu stall bit
|
data[1] <= #1 tdo; // cpu stall bit
|
|
|
for(i=`DBG_CPU_DR_LEN - `DBG_CPU_CTRL_LEN -1; i>=0; i=i-1) // unused control bits
|
for(i=`DBG_CPU_DR_LEN - `DBG_CPU_CTRL_LEN -1; i>=0; i=i-1) // unused control bits
|
begin
|
begin
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_CPU_STATUS_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_STATUS_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
gen_clk(1); // Generating clock to read out a status bit.
|
gen_clk(1); // Generating clock to read out a status bit.
|
status_cpu[i] = tdo;
|
status_cpu[i] = tdo;
|
end
|
end
|
|
|
if (|status_cpu)
|
if (|status_cpu)
|
begin
|
begin
|
$write("(*E) (%0t) debug_cpu_wr_ctrl error: ", $time);
|
$write("(*E) (%0t) debug_cpu_wr_ctrl error: ", $time);
|
casex (status_cpu)
|
casex (status_cpu)
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'bx1xx : $display("??? error !!!\n\n", $time);
|
4'bx1xx : $display("??? error !!!\n\n", $time);
|
4'bxx1x : $display("??? error !!!\n\n", $time);
|
4'bxx1x : $display("??? error !!!\n\n", $time);
|
4'bxxx1 : $display("??? error !!!\n\n", $time);
|
4'bxxx1 : $display("??? error !!!\n\n", $time);
|
endcase // casex (status_cpu)
|
endcase // casex (status_cpu)
|
|
|
end
|
end
|
|
|
|
|
for(i=0; i<`DBG_CPU_CRC_LEN -1; i=i+1) // Getting in the CRC
|
for(i=0; i<`DBG_CPU_CRC_LEN -1; i=i+1) // Getting in the CRC
|
begin
|
begin
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit1_dr
|
gen_clk(1); // to exit1_dr
|
|
|
if (~crc_match_in)
|
if (~crc_match_in)
|
begin
|
begin
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
|
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to update_dr
|
gen_clk(1); // to update_dr
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to run_test_idle
|
gen_clk(1); // to run_test_idle
|
end
|
end
|
endtask // debug_cpu_rd_ctrl
|
endtask // debug_cpu_rd_ctrl
|
|
|
|
|
// 32-bit read from cpu
|
// 32-bit read from cpu
|
task cpu_read_32;
|
task cpu_read_32;
|
output [31:0] data;
|
output [31:0] data;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
reg [31:0] tmp;
|
reg [31:0] tmp;
|
|
|
begin
|
begin
|
debug_cpu_wr_comm(`DBG_CPU_READ, addr, length, 1'b0);
|
debug_cpu_wr_comm(`DBG_CPU_READ, addr, length, 1'b0);
|
|
|
last_cpu_cmd = `DBG_CPU_READ; last_cpu_cmd_text = "DBG_CPU_READ";
|
last_cpu_cmd = `DBG_CPU_READ; last_cpu_cmd_text = "DBG_CPU_READ";
|
|
|
length_global = length + 1;
|
length_global = length + 1;
|
|
|
debug_cpu_go(1'b0, 1'b0);
|
debug_cpu_go(1'b0, 1'b0);
|
|
|
data = data_storage[0];
|
data = data_storage[0];
|
|
|
if (length>3)
|
if (length>3)
|
$display("WARNING: Only first data word is returned( See module %m.)");
|
$display("WARNING: Only first data word is returned( See module %m.)");
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
// block of 32-bit reads from cpu
|
// block of 32-bit reads from cpu
|
task cpu_read_block;
|
task cpu_read_block;
|
//output [31:0] data;
|
//output [31:0] data;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
reg [31:0] tmp;
|
reg [31:0] tmp;
|
|
|
begin
|
begin
|
debug_cpu_wr_comm(`DBG_CPU_READ, addr, length-1, 1'b0);
|
debug_cpu_wr_comm(`DBG_CPU_READ, addr, length-1, 1'b0);
|
|
|
last_cpu_cmd = `DBG_CPU_READ; last_cpu_cmd_text = "DBG_CPU_READ";
|
last_cpu_cmd = `DBG_CPU_READ; last_cpu_cmd_text = "DBG_CPU_READ";
|
|
|
length_global = length;
|
length_global = length;
|
|
|
debug_cpu_go(1'b0, 1'b0);
|
debug_cpu_go(1'b0, 1'b0);
|
|
|
//data = data_storage[0];
|
//data = data_storage[0];
|
|
|
//if (length>3)
|
//if (length>3)
|
// $display("WARNING: Only first data word is returned( See module %m.)");
|
// $display("WARNING: Only first data word is returned( See module %m.)");
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
// 32-bit write to cpu
|
// 32-bit write to cpu
|
task cpu_write_32;
|
task cpu_write_32;
|
input [31:0] data;
|
input [31:0] data;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
reg [31:0] tmp;
|
reg [31:0] tmp;
|
|
|
begin
|
begin
|
debug_cpu_wr_comm(`DBG_CPU_WRITE, addr, length, 1'b0);
|
debug_cpu_wr_comm(`DBG_CPU_WRITE, addr, length, 1'b0);
|
last_cpu_cmd = `DBG_CPU_WRITE; last_cpu_cmd_text = "DBG_CPU_WRITE";
|
last_cpu_cmd = `DBG_CPU_WRITE; last_cpu_cmd_text = "DBG_CPU_WRITE";
|
length_global = length + 1;
|
length_global = length + 1;
|
data_storage[0] = data;
|
data_storage[0] = data;
|
debug_cpu_go(1'b0, 1'b0);
|
debug_cpu_go(1'b0, 1'b0);
|
if (length>3)
|
if (length>3)
|
$display("WARNING: Only first data word is stored for writting ( See module %m)");
|
$display("WARNING: Only first data word is stored for writting ( See module %m)");
|
end
|
end
|
endtask
|
endtask
|
|
|
// block of 32-bit writes to cpu
|
// block of 32-bit writes to cpu
|
// Data will already be in data_storage
|
// Data will already be in data_storage
|
task cpu_write_block;
|
task cpu_write_block;
|
//input [31:0] data;
|
//input [31:0] data;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_ADR_LEN -1:0] addr;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
input [`DBG_WB_LEN_LEN -1:0] length;
|
|
|
reg [31:0] tmp;
|
reg [31:0] tmp;
|
|
|
begin
|
begin
|
debug_cpu_wr_comm(`DBG_CPU_WRITE, addr, length-1, 1'b0);
|
debug_cpu_wr_comm(`DBG_CPU_WRITE, addr, length-1, 1'b0);
|
last_cpu_cmd = `DBG_CPU_WRITE; last_cpu_cmd_text = "DBG_CPU_WRITE";
|
last_cpu_cmd = `DBG_CPU_WRITE; last_cpu_cmd_text = "DBG_CPU_WRITE";
|
length_global = length;
|
length_global = length;
|
debug_cpu_go(1'b0, 1'b0);
|
debug_cpu_go(1'b0, 1'b0);
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task debug_cpu_wr_comm;
|
task debug_cpu_wr_comm;
|
input [`DBG_CPU_ACC_TYPE_LEN -1:0] acc_type;
|
input [`DBG_CPU_ACC_TYPE_LEN -1:0] acc_type;
|
input [`DBG_CPU_ADR_LEN -1:0] addr;
|
input [`DBG_CPU_ADR_LEN -1:0] addr;
|
input [`DBG_CPU_LEN_LEN -1:0] length;
|
input [`DBG_CPU_LEN_LEN -1:0] length;
|
input gen_crc_err;
|
input gen_crc_err;
|
integer i;
|
integer i;
|
reg [`DBG_CPU_CMD_LEN -1:0] command;
|
reg [`DBG_CPU_CMD_LEN -1:0] command;
|
|
|
begin
|
begin
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("(%0t) Task debug_cpu_wr_comm: ", $time);
|
$display("(%0t) Task debug_cpu_wr_comm: ", $time);
|
`endif
|
`endif
|
|
|
command = `DBG_CPU_WR_COMM;
|
command = `DBG_CPU_WR_COMM;
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
crc_out = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
crc_out = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
|
|
tdi<=#1 1'b0; // module_select bit = 0
|
tdi<=#1 1'b0; // module_select bit = 0
|
calculate_crc(1'b0);
|
calculate_crc(1'b0);
|
gen_clk(1);
|
gen_clk(1);
|
|
|
for(i=`DBG_CPU_CMD_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_CMD_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 command[i]; // command
|
tdi<=#1 command[i]; // command
|
calculate_crc(command[i]);
|
calculate_crc(command[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_CPU_ACC_TYPE_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_ACC_TYPE_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 acc_type[i]; // command
|
tdi<=#1 acc_type[i]; // command
|
calculate_crc(acc_type[i]);
|
calculate_crc(acc_type[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_CPU_ADR_LEN -1; i>=0; i=i-1) // address
|
for(i=`DBG_CPU_ADR_LEN -1; i>=0; i=i-1) // address
|
begin
|
begin
|
tdi<=#1 addr[i];
|
tdi<=#1 addr[i];
|
calculate_crc(addr[i]);
|
calculate_crc(addr[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_CPU_LEN_LEN -1; i>=0; i=i-1) // length
|
for(i=`DBG_CPU_LEN_LEN -1; i>=0; i=i-1) // length
|
begin
|
begin
|
tdi<=#1 length[i];
|
tdi<=#1 length[i];
|
calculate_crc(length[i]);
|
calculate_crc(length[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
for(i=`DBG_CPU_CRC_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_CRC_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
if (gen_crc_err & (i==0)) // Generate crc error at last crc bit
|
if (gen_crc_err & (i==0)) // Generate crc error at last crc bit
|
tdi<=#1 ~crc_out[i]; // error crc
|
tdi<=#1 ~crc_out[i]; // error crc
|
else
|
else
|
tdi<=#1 crc_out[i]; // ok crc
|
tdi<=#1 crc_out[i]; // ok crc
|
|
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tdi<=#1 1'hz;
|
tdi<=#1 1'hz;
|
|
|
crc_in = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
crc_in = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
|
|
for(i=`DBG_CPU_STATUS_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_STATUS_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
gen_clk(1); // Generating clock to read out a status bit.
|
gen_clk(1); // Generating clock to read out a status bit.
|
status_cpu[i] = tdo;
|
status_cpu[i] = tdo;
|
end
|
end
|
|
|
if (|status_cpu)
|
if (|status_cpu)
|
begin
|
begin
|
$write("(*E) (%0t) debug_cpu_wr_comm error: ", $time);
|
$write("(*E) (%0t) debug_cpu_wr_comm error: ", $time);
|
casex (status_cpu)
|
casex (status_cpu)
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'bx1xx : $display("Unknown command !!!\n\n", $time);
|
4'bx1xx : $display("Unknown command !!!\n\n", $time);
|
4'bxx1x : $display("??? error !!!\n\n", $time);
|
4'bxx1x : $display("??? error !!!\n\n", $time);
|
4'bxxx1 : $display("Overrun/Underrun !!!\n\n", $time);
|
4'bxxx1 : $display("Overrun/Underrun !!!\n\n", $time);
|
endcase
|
endcase
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$stop;
|
$stop;
|
`endif
|
`endif
|
end
|
end
|
|
|
|
|
for(i=0; i<`DBG_CPU_CRC_LEN -1; i=i+1) // Getting in the CRC
|
for(i=0; i<`DBG_CPU_CRC_LEN -1; i=i+1) // Getting in the CRC
|
begin
|
begin
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit1_dr
|
gen_clk(1); // to exit1_dr
|
|
|
if (~crc_match_in)
|
if (~crc_match_in)
|
begin
|
begin
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$stop;
|
$stop;
|
`endif
|
`endif
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to update_dr
|
gen_clk(1); // to update_dr
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to run_test_idle
|
gen_clk(1); // to run_test_idle
|
end
|
end
|
endtask // debug_cpu_wr_comm
|
endtask // debug_cpu_wr_comm
|
|
|
|
|
|
|
task debug_cpu_go;
|
task debug_cpu_go;
|
input wait_for_cpu_ready;
|
input wait_for_cpu_ready;
|
input gen_crc_err;
|
input gen_crc_err;
|
integer i;
|
integer i;
|
reg [4:0] bit_pointer;
|
reg [4:0] bit_pointer;
|
integer word_pointer;
|
integer word_pointer;
|
reg [31:0] tmp_data;
|
reg [31:0] tmp_data;
|
reg [`DBG_CPU_CMD_LEN -1:0] command;
|
reg [`DBG_CPU_CMD_LEN -1:0] command;
|
|
|
|
|
begin
|
begin
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("(%0t) Task debug_cpu_go (previous command was %0s): ", $time, last_cpu_cmd_text);
|
$display("(%0t) Task debug_cpu_go (previous command was %0s): ", $time, last_cpu_cmd_text);
|
`endif
|
`endif
|
command = `DBG_CPU_GO;
|
command = `DBG_CPU_GO;
|
word_pointer = 0;
|
word_pointer = 0;
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1);
|
gen_clk(1);
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(2); // we are in shiftDR
|
gen_clk(2); // we are in shiftDR
|
|
|
crc_out = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
crc_out = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize outgoing CRC to all ff
|
|
|
tdi<=#1 1'b0; // module_select bit = 0
|
tdi<=#1 1'b0; // module_select bit = 0
|
calculate_crc(1'b0);
|
calculate_crc(1'b0);
|
gen_clk(1);
|
gen_clk(1);
|
|
|
for(i=`DBG_CPU_CMD_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_CMD_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
tdi<=#1 command[i]; // command
|
tdi<=#1 command[i]; // command
|
calculate_crc(command[i]);
|
calculate_crc(command[i]);
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
|
|
if (last_cpu_cmd == `DBG_CPU_WRITE) // When DBG_CPU_WRITE was previously activated, data needs to be shifted.
|
if (last_cpu_cmd == `DBG_CPU_WRITE) // When DBG_CPU_WRITE was previously activated, data needs to be shifted.
|
begin
|
begin
|
for (i=0; i<((length_global) << 3); i=i+1)
|
for (i=0; i<((length_global) << 3); i=i+1)
|
begin
|
begin
|
tmp_data = data_storage[word_pointer];
|
tmp_data = data_storage[word_pointer];
|
if ((!(i%32)) && (i>0))
|
if ((!(i%32)) && (i>0))
|
begin
|
begin
|
word_pointer = word_pointer + 1;
|
word_pointer = word_pointer + 1;
|
end
|
end
|
bit_pointer = 31-i[4:0];
|
bit_pointer = 31-i[4:0];
|
tdi<=#1 tmp_data[bit_pointer];
|
tdi<=#1 tmp_data[bit_pointer];
|
calculate_crc(tmp_data[bit_pointer]);
|
calculate_crc(tmp_data[bit_pointer]);
|
gen_clk(1);
|
gen_clk(1);
|
|
|
end
|
end
|
end
|
end
|
|
|
for(i=`DBG_CPU_CRC_LEN -1; i>=1; i=i-1)
|
for(i=`DBG_CPU_CRC_LEN -1; i>=1; i=i-1)
|
begin
|
begin
|
tdi<=#1 crc_out[i];
|
tdi<=#1 crc_out[i];
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
if (gen_crc_err) // Generate crc error at last crc bit
|
if (gen_crc_err) // Generate crc error at last crc bit
|
tdi<=#1 ~crc_out[0]; // error crc
|
tdi<=#1 ~crc_out[0]; // error crc
|
else
|
else
|
tdi<=#1 crc_out[0]; // ok crc
|
tdi<=#1 crc_out[0]; // ok crc
|
|
|
if (wait_for_cpu_ready)
|
if (wait_for_cpu_ready)
|
begin
|
begin
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit1_dr. Last CRC is shifted on this clk
|
gen_clk(1); // to exit1_dr. Last CRC is shifted on this clk
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to pause_dr
|
gen_clk(1); // to pause_dr
|
|
|
#2; // wait a bit for tdo to activate
|
#2; // wait a bit for tdo to activate
|
while (tdo) // waiting for wb to send "ready"
|
while (tdo) // waiting for wb to send "ready"
|
begin
|
begin
|
gen_clk(1); // staying in pause_dr
|
gen_clk(1); // staying in pause_dr
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit2_dr
|
gen_clk(1); // to exit2_dr
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to shift_dr
|
gen_clk(1); // to shift_dr
|
end
|
end
|
else
|
else
|
begin
|
begin
|
gen_clk(1); // Last CRC is shifted on this clk
|
gen_clk(1); // Last CRC is shifted on this clk
|
end
|
end
|
|
|
|
|
tdi<=#1 1'hz;
|
tdi<=#1 1'hz;
|
crc_in = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
crc_in = {`DBG_CPU_CRC_LEN{1'b1}}; // Initialize incoming CRC to all ff
|
|
|
if (last_cpu_cmd == `DBG_CPU_READ) // When DBG_CPU_READ was previously activated, data needs to be shifted.
|
if (last_cpu_cmd == `DBG_CPU_READ) // When DBG_CPU_READ was previously activated, data needs to be shifted.
|
begin
|
begin
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("\t\tGenerating %0d clocks to read %0d data bytes.", length_global<<3, length_global);
|
$display("\t\tGenerating %0d clocks to read %0d data bytes.", length_global<<3, length_global);
|
`endif
|
`endif
|
word_pointer = 0; // Reset pointer
|
word_pointer = 0; // Reset pointer
|
for (i=0; i<(length_global<<3); i=i+1)
|
for (i=0; i<(length_global<<3); i=i+1)
|
begin
|
begin
|
|
|
gen_clk(1);
|
gen_clk(1);
|
|
|
if (i[4:0] == 31) // Latching data
|
if (i[4:0] == 31) // Latching data
|
begin
|
begin
|
data_storage[word_pointer] = in_data_be;
|
data_storage[word_pointer] = in_data_be;
|
`ifdef DEBUG_INFO
|
`ifdef DEBUG_INFO
|
$display("\t\tin_data_be = 0x%x", in_data_be);
|
$display("\t\tin_data_be = 0x%x", in_data_be);
|
`endif
|
`endif
|
word_pointer = word_pointer + 1;
|
word_pointer = word_pointer + 1;
|
end
|
end
|
|
|
end
|
end
|
end
|
end
|
|
|
|
|
for(i=`DBG_CPU_STATUS_LEN -1; i>=0; i=i-1)
|
for(i=`DBG_CPU_STATUS_LEN -1; i>=0; i=i-1)
|
begin
|
begin
|
gen_clk(1); // Generating clock to read out a status bit.
|
gen_clk(1); // Generating clock to read out a status bit.
|
status_cpu[i] = tdo;
|
status_cpu[i] = tdo;
|
end
|
end
|
|
|
if (|status_cpu)
|
if (|status_cpu)
|
begin
|
begin
|
$write("(*E) (%0t) debug_cpu_go error: ", $time);
|
$write("(*E) (%0t) debug_cpu_go error: ", $time);
|
casex (status_cpu)
|
casex (status_cpu)
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'b1xxx : $display("CRC error !!!\n\n", $time);
|
4'bx1xx : $display("Unknown command !!!\n\n", $time);
|
4'bx1xx : $display("Unknown command !!!\n\n", $time);
|
4'bxx1x : $display("??? error !!!\n\n", $time);
|
4'bxx1x : $display("??? error !!!\n\n", $time);
|
4'bxxx1 : $display("Overrun/Underrun !!!\n\n", $time);
|
4'bxxx1 : $display("Overrun/Underrun !!!\n\n", $time);
|
endcase
|
endcase
|
$stop;
|
$stop;
|
end
|
end
|
|
|
|
|
for(i=0; i<`DBG_CPU_CRC_LEN -1; i=i+1) // Getting in the CRC
|
for(i=0; i<`DBG_CPU_CRC_LEN -1; i=i+1) // Getting in the CRC
|
begin
|
begin
|
gen_clk(1);
|
gen_clk(1);
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to exit1_dr
|
gen_clk(1); // to exit1_dr
|
|
|
if (~crc_match_in)
|
if (~crc_match_in)
|
begin
|
begin
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
$display("(%0t) Incoming CRC failed !!!", $time);
|
$stop;
|
$stop;
|
end
|
end
|
|
|
tms<=#1 1'b1;
|
tms<=#1 1'b1;
|
gen_clk(1); // to update_dr
|
gen_clk(1); // to update_dr
|
tms<=#1 1'b0;
|
tms<=#1 1'b0;
|
gen_clk(1); // to run_test_idle
|
gen_clk(1); // to run_test_idle
|
end
|
end
|
endtask // debug_cpu_go
|
endtask // debug_cpu_go
|
|
|
|
|
|
|
|
|
// Calculating outgoing CRC
|
// Calculating outgoing CRC
|
task calculate_crc;
|
task calculate_crc;
|
input data;
|
input data;
|
|
|
begin
|
begin
|
crc_out[0] <= #1 data ^ crc_out[31];
|
crc_out[0] <= #1 data ^ crc_out[31];
|
crc_out[1] <= #1 data ^ crc_out[0] ^ crc_out[31];
|
crc_out[1] <= #1 data ^ crc_out[0] ^ crc_out[31];
|
crc_out[2] <= #1 data ^ crc_out[1] ^ crc_out[31];
|
crc_out[2] <= #1 data ^ crc_out[1] ^ crc_out[31];
|
crc_out[3] <= #1 crc_out[2];
|
crc_out[3] <= #1 crc_out[2];
|
crc_out[4] <= #1 data ^ crc_out[3] ^ crc_out[31];
|
crc_out[4] <= #1 data ^ crc_out[3] ^ crc_out[31];
|
crc_out[5] <= #1 data ^ crc_out[4] ^ crc_out[31];
|
crc_out[5] <= #1 data ^ crc_out[4] ^ crc_out[31];
|
crc_out[6] <= #1 crc_out[5];
|
crc_out[6] <= #1 crc_out[5];
|
crc_out[7] <= #1 data ^ crc_out[6] ^ crc_out[31];
|
crc_out[7] <= #1 data ^ crc_out[6] ^ crc_out[31];
|
crc_out[8] <= #1 data ^ crc_out[7] ^ crc_out[31];
|
crc_out[8] <= #1 data ^ crc_out[7] ^ crc_out[31];
|
crc_out[9] <= #1 crc_out[8];
|
crc_out[9] <= #1 crc_out[8];
|
crc_out[10] <= #1 data ^ crc_out[9] ^ crc_out[31];
|
crc_out[10] <= #1 data ^ crc_out[9] ^ crc_out[31];
|
crc_out[11] <= #1 data ^ crc_out[10] ^ crc_out[31];
|
crc_out[11] <= #1 data ^ crc_out[10] ^ crc_out[31];
|
crc_out[12] <= #1 data ^ crc_out[11] ^ crc_out[31];
|
crc_out[12] <= #1 data ^ crc_out[11] ^ crc_out[31];
|
crc_out[13] <= #1 crc_out[12];
|
crc_out[13] <= #1 crc_out[12];
|
crc_out[14] <= #1 crc_out[13];
|
crc_out[14] <= #1 crc_out[13];
|
crc_out[15] <= #1 crc_out[14];
|
crc_out[15] <= #1 crc_out[14];
|
crc_out[16] <= #1 data ^ crc_out[15] ^ crc_out[31];
|
crc_out[16] <= #1 data ^ crc_out[15] ^ crc_out[31];
|
crc_out[17] <= #1 crc_out[16];
|
crc_out[17] <= #1 crc_out[16];
|
crc_out[18] <= #1 crc_out[17];
|
crc_out[18] <= #1 crc_out[17];
|
crc_out[19] <= #1 crc_out[18];
|
crc_out[19] <= #1 crc_out[18];
|
crc_out[20] <= #1 crc_out[19];
|
crc_out[20] <= #1 crc_out[19];
|
crc_out[21] <= #1 crc_out[20];
|
crc_out[21] <= #1 crc_out[20];
|
crc_out[22] <= #1 data ^ crc_out[21] ^ crc_out[31];
|
crc_out[22] <= #1 data ^ crc_out[21] ^ crc_out[31];
|
crc_out[23] <= #1 data ^ crc_out[22] ^ crc_out[31];
|
crc_out[23] <= #1 data ^ crc_out[22] ^ crc_out[31];
|
crc_out[24] <= #1 crc_out[23];
|
crc_out[24] <= #1 crc_out[23];
|
crc_out[25] <= #1 crc_out[24];
|
crc_out[25] <= #1 crc_out[24];
|
crc_out[26] <= #1 data ^ crc_out[25] ^ crc_out[31];
|
crc_out[26] <= #1 data ^ crc_out[25] ^ crc_out[31];
|
crc_out[27] <= #1 crc_out[26];
|
crc_out[27] <= #1 crc_out[26];
|
crc_out[28] <= #1 crc_out[27];
|
crc_out[28] <= #1 crc_out[27];
|
crc_out[29] <= #1 crc_out[28];
|
crc_out[29] <= #1 crc_out[28];
|
crc_out[30] <= #1 crc_out[29];
|
crc_out[30] <= #1 crc_out[29];
|
crc_out[31] <= #1 crc_out[30];
|
crc_out[31] <= #1 crc_out[30];
|
end
|
end
|
endtask // calculate_crc
|
endtask // calculate_crc
|
|
|
|
|
// Calculating and checking input CRC
|
// Calculating and checking input CRC
|
always @(posedge tck)
|
always @(posedge tck)
|
begin
|
begin
|
crc_in[0] <= #1 tdo ^ crc_in[31];
|
crc_in[0] <= #1 tdo ^ crc_in[31];
|
crc_in[1] <= #1 tdo ^ crc_in[0] ^ crc_in[31];
|
crc_in[1] <= #1 tdo ^ crc_in[0] ^ crc_in[31];
|
crc_in[2] <= #1 tdo ^ crc_in[1] ^ crc_in[31];
|
crc_in[2] <= #1 tdo ^ crc_in[1] ^ crc_in[31];
|
crc_in[3] <= #1 crc_in[2];
|
crc_in[3] <= #1 crc_in[2];
|
crc_in[4] <= #1 tdo ^ crc_in[3] ^ crc_in[31];
|
crc_in[4] <= #1 tdo ^ crc_in[3] ^ crc_in[31];
|
crc_in[5] <= #1 tdo ^ crc_in[4] ^ crc_in[31];
|
crc_in[5] <= #1 tdo ^ crc_in[4] ^ crc_in[31];
|
crc_in[6] <= #1 crc_in[5];
|
crc_in[6] <= #1 crc_in[5];
|
crc_in[7] <= #1 tdo ^ crc_in[6] ^ crc_in[31];
|
crc_in[7] <= #1 tdo ^ crc_in[6] ^ crc_in[31];
|
crc_in[8] <= #1 tdo ^ crc_in[7] ^ crc_in[31];
|
crc_in[8] <= #1 tdo ^ crc_in[7] ^ crc_in[31];
|
crc_in[9] <= #1 crc_in[8];
|
crc_in[9] <= #1 crc_in[8];
|
crc_in[10] <= #1 tdo ^ crc_in[9] ^ crc_in[31];
|
crc_in[10] <= #1 tdo ^ crc_in[9] ^ crc_in[31];
|
crc_in[11] <= #1 tdo ^ crc_in[10] ^ crc_in[31];
|
crc_in[11] <= #1 tdo ^ crc_in[10] ^ crc_in[31];
|
crc_in[12] <= #1 tdo ^ crc_in[11] ^ crc_in[31];
|
crc_in[12] <= #1 tdo ^ crc_in[11] ^ crc_in[31];
|
crc_in[13] <= #1 crc_in[12];
|
crc_in[13] <= #1 crc_in[12];
|
crc_in[14] <= #1 crc_in[13];
|
crc_in[14] <= #1 crc_in[13];
|
crc_in[15] <= #1 crc_in[14];
|
crc_in[15] <= #1 crc_in[14];
|
crc_in[16] <= #1 tdo ^ crc_in[15] ^ crc_in[31];
|
crc_in[16] <= #1 tdo ^ crc_in[15] ^ crc_in[31];
|
crc_in[17] <= #1 crc_in[16];
|
crc_in[17] <= #1 crc_in[16];
|
crc_in[18] <= #1 crc_in[17];
|
crc_in[18] <= #1 crc_in[17];
|
crc_in[19] <= #1 crc_in[18];
|
crc_in[19] <= #1 crc_in[18];
|
crc_in[20] <= #1 crc_in[19];
|
crc_in[20] <= #1 crc_in[19];
|
crc_in[21] <= #1 crc_in[20];
|
crc_in[21] <= #1 crc_in[20];
|
crc_in[22] <= #1 tdo ^ crc_in[21] ^ crc_in[31];
|
crc_in[22] <= #1 tdo ^ crc_in[21] ^ crc_in[31];
|
crc_in[23] <= #1 tdo ^ crc_in[22] ^ crc_in[31];
|
crc_in[23] <= #1 tdo ^ crc_in[22] ^ crc_in[31];
|
crc_in[24] <= #1 crc_in[23];
|
crc_in[24] <= #1 crc_in[23];
|
crc_in[25] <= #1 crc_in[24];
|
crc_in[25] <= #1 crc_in[24];
|
crc_in[26] <= #1 tdo ^ crc_in[25] ^ crc_in[31];
|
crc_in[26] <= #1 tdo ^ crc_in[25] ^ crc_in[31];
|
crc_in[27] <= #1 crc_in[26];
|
crc_in[27] <= #1 crc_in[26];
|
crc_in[28] <= #1 crc_in[27];
|
crc_in[28] <= #1 crc_in[27];
|
crc_in[29] <= #1 crc_in[28];
|
crc_in[29] <= #1 crc_in[28];
|
crc_in[30] <= #1 crc_in[29];
|
crc_in[30] <= #1 crc_in[29];
|
crc_in[31] <= #1 crc_in[30];
|
crc_in[31] <= #1 crc_in[30];
|
end
|
end
|
|
|
assign crc_match_in = crc_in == 32'h0;
|
assign crc_match_in = crc_in == 32'h0;
|
|
|
|
|
endmodule // vpi_debug_module
|
endmodule // vpi_debug_module
|
|
|