JTAGVPI: remove it in favor of remote bitbang
This commit is contained in:
@ -1,2 +0,0 @@
|
||||
$send_result_to_server call=send_result_to_server acc=rw:*
|
||||
$check_for_command call=check_for_command acc=rw:*
|
301
vsrc/jtag_vpi.v
301
vsrc/jtag_vpi.v
@ -1,301 +0,0 @@
|
||||
// See LICENSE.SiFive for license details.
|
||||
|
||||
/*
|
||||
* TCP/IP controlled VPI JTAG Interface.
|
||||
* Based on Julius Baxter's work on jp_vpi.c
|
||||
*
|
||||
* Copyright (C) 2012 Franck Jullien, <franck.jullien@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of any
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
//VCS coverage exclude_file
|
||||
`define CMD_RESET 0
|
||||
`define CMD_TMS_SEQ 1
|
||||
`define CMD_SCAN_CHAIN 2
|
||||
`define CMD_SCAN_CHAIN_FLIP_TMS 3
|
||||
`define CMD_STOP_SIMU 4
|
||||
|
||||
module JTAGVPI
|
||||
#( parameter DEBUG_INFO = 0,
|
||||
parameter TP = 1,
|
||||
parameter TCK_HALF_PERIOD = 2,// 50, // Clock half period (Clock period = 100 ns => 10 MHz)
|
||||
parameter CMD_DELAY = 2, // 1000
|
||||
parameter INIT_DELAY = 200
|
||||
)
|
||||
(
|
||||
output jtag_TMS,
|
||||
output jtag_TCK,
|
||||
output jtag_TDI,
|
||||
input jtag_TDO_data,
|
||||
input jtag_TDO_driven,
|
||||
|
||||
input enable,
|
||||
input init_done);
|
||||
|
||||
reg tms;
|
||||
reg tck;
|
||||
reg tdi;
|
||||
wire tdo;
|
||||
|
||||
assign jtag_TMS = tms;
|
||||
assign jtag_TCK = tck;
|
||||
assign jtag_TDI = tdi;
|
||||
assign tdo = jtag_TDO_driven ? jtag_TDO_data : 1'bz;
|
||||
|
||||
integer cmd;
|
||||
integer length;
|
||||
integer nb_bits;
|
||||
|
||||
reg [31:0] buffer_out [0:4095]; // Data storage from the jtag server
|
||||
reg [31:0] buffer_in [0:4095]; // Data storage to the jtag server
|
||||
|
||||
integer flip_tms;
|
||||
|
||||
reg [31:0] data_out;
|
||||
reg [31:0] data_in;
|
||||
|
||||
integer debug;
|
||||
|
||||
initial
|
||||
begin
|
||||
tck <= #TP 1'b0;
|
||||
tdi <= #TP 1'bz;
|
||||
tms <= #TP 1'b0;
|
||||
|
||||
data_out <= 32'h0;
|
||||
data_in <= 32'h0;
|
||||
|
||||
// Small delay to get past reset instability
|
||||
// before checking for init_done
|
||||
#INIT_DELAY
|
||||
|
||||
wait(init_done)
|
||||
if($test$plusargs("jtag_vpi_enable")) main;
|
||||
end
|
||||
|
||||
task main;
|
||||
begin
|
||||
$display("JTAG debug module with VPI interface enabled\n");
|
||||
|
||||
reset_tap;
|
||||
goto_run_test_idle_from_reset;
|
||||
|
||||
while (1) begin
|
||||
|
||||
// Check for incoming command
|
||||
// wait until a command is sent
|
||||
// poll with a delay here
|
||||
cmd = -1;
|
||||
|
||||
while (cmd == -1)
|
||||
begin
|
||||
#CMD_DELAY $check_for_command(cmd, length, nb_bits, buffer_out);
|
||||
end
|
||||
|
||||
// now switch on the command
|
||||
case (cmd)
|
||||
|
||||
`CMD_RESET :
|
||||
begin
|
||||
if (DEBUG_INFO)
|
||||
$display("%t ----> CMD_RESET %h\n", $time, length);
|
||||
reset_tap;
|
||||
goto_run_test_idle_from_reset;
|
||||
end
|
||||
|
||||
`CMD_TMS_SEQ :
|
||||
begin
|
||||
if (DEBUG_INFO)
|
||||
$display("%t ----> CMD_TMS_SEQ\n", $time);
|
||||
do_tms_seq;
|
||||
end
|
||||
|
||||
`CMD_SCAN_CHAIN :
|
||||
begin
|
||||
if (DEBUG_INFO)
|
||||
$display("%t ----> CMD_SCAN_CHAIN\n", $time);
|
||||
flip_tms = 0;
|
||||
do_scan_chain;
|
||||
$send_result_to_server(length, buffer_in);
|
||||
end
|
||||
|
||||
`CMD_SCAN_CHAIN_FLIP_TMS :
|
||||
begin
|
||||
if(DEBUG_INFO)
|
||||
$display("%t ----> CMD_SCAN_CHAIN\n", $time);
|
||||
flip_tms = 1;
|
||||
do_scan_chain;
|
||||
$send_result_to_server(length, buffer_in);
|
||||
end
|
||||
|
||||
`CMD_STOP_SIMU :
|
||||
begin
|
||||
if(DEBUG_INFO)
|
||||
$display("%t ----> End of simulation\n", $time);
|
||||
$finish();
|
||||
end
|
||||
|
||||
default:
|
||||
begin
|
||||
$display("Somehow got to the default case in the command case statement.");
|
||||
$display("Command was: %x", cmd);
|
||||
$display("Exiting...");
|
||||
$finish();
|
||||
end
|
||||
|
||||
endcase // case (cmd)
|
||||
|
||||
end // while (1)
|
||||
end
|
||||
|
||||
endtask // main
|
||||
|
||||
|
||||
// Generation of the TCK signal
|
||||
task gen_clk;
|
||||
input [31:0] number;
|
||||
integer i;
|
||||
|
||||
begin
|
||||
for (i = 0; i < number; i = i + 1)
|
||||
begin
|
||||
#TCK_HALF_PERIOD tck <= 1;
|
||||
#TCK_HALF_PERIOD tck <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endtask
|
||||
|
||||
// TAP reset
|
||||
task reset_tap;
|
||||
begin
|
||||
if (DEBUG_INFO)
|
||||
$display("(%0t) Task reset_tap", $time);
|
||||
tms <= #1 1'b1;
|
||||
gen_clk(5);
|
||||
end
|
||||
|
||||
endtask
|
||||
|
||||
|
||||
// Goes to RunTestIdle state
|
||||
task goto_run_test_idle_from_reset;
|
||||
begin
|
||||
if (DEBUG_INFO)
|
||||
$display("(%0t) Task goto_run_test_idle_from_reset", $time);
|
||||
tms <= #1 1'b0;
|
||||
gen_clk(1);
|
||||
end
|
||||
|
||||
endtask
|
||||
|
||||
//
|
||||
task do_tms_seq;
|
||||
|
||||
integer i,j;
|
||||
reg [31:0] data;
|
||||
integer nb_bits_rem;
|
||||
integer nb_bits_in_this_byte;
|
||||
|
||||
begin
|
||||
if (DEBUG_INFO)
|
||||
$display("(%0t) Task do_tms_seq of %d bits (length = %d)", $time, nb_bits, length);
|
||||
|
||||
// Number of bits to send in the last byte
|
||||
nb_bits_rem = nb_bits % 8;
|
||||
|
||||
for (i = 0; i < length; i = i + 1)
|
||||
begin
|
||||
// If we are in the last byte, we have to send only
|
||||
// nb_bits_rem bits. If not, we send the whole byte.
|
||||
nb_bits_in_this_byte = (i == (length - 1)) ? nb_bits_rem : 8;
|
||||
|
||||
data = buffer_out[i];
|
||||
for (j = 0; j < nb_bits_in_this_byte; j = j + 1)
|
||||
begin
|
||||
tms <= #1 1'b0;
|
||||
if (data[j] == 1) begin
|
||||
tms <= #1 1'b1;
|
||||
end
|
||||
gen_clk(1);
|
||||
end
|
||||
end
|
||||
|
||||
tms <= #1 1'b0;
|
||||
end
|
||||
|
||||
endtask
|
||||
|
||||
|
||||
//
|
||||
task do_scan_chain;
|
||||
|
||||
integer _bit;
|
||||
integer nb_bits_rem;
|
||||
integer nb_bits_in_this_byte;
|
||||
integer index;
|
||||
|
||||
begin
|
||||
if(DEBUG_INFO)
|
||||
$display("(%0t) Task do_scan_chain of %d bits (length = %d)", $time, nb_bits, length);
|
||||
|
||||
// Number of bits to send in the last byte
|
||||
nb_bits_rem = nb_bits % 8;
|
||||
|
||||
for (index = 0; index < length; index = index + 1)
|
||||
begin
|
||||
// If we are in the last byte, we have to send only
|
||||
// nb_bits_rem bits if it's not zero.
|
||||
// If not, we send the whole byte.
|
||||
nb_bits_in_this_byte = (index == (length - 1)) ? ((nb_bits_rem == 0) ? 8 : nb_bits_rem) : 8;
|
||||
|
||||
data_out = buffer_out[index];
|
||||
for (_bit = 0; _bit < nb_bits_in_this_byte; _bit = _bit + 1)
|
||||
begin
|
||||
tdi <= 1'b0;
|
||||
if (data_out[_bit] == 1'b1) begin
|
||||
tdi <= 1'b1;
|
||||
end
|
||||
|
||||
// On the last bit, set TMS to '1'
|
||||
if (((_bit == (nb_bits_in_this_byte - 1)) && (index == (length - 1))) && (flip_tms == 1)) begin
|
||||
tms <= 1'b1;
|
||||
end
|
||||
|
||||
#TCK_HALF_PERIOD tck <= 1;
|
||||
data_in[_bit] <= tdo;
|
||||
#TCK_HALF_PERIOD tck <= 0;
|
||||
end
|
||||
buffer_in[index] = data_in;
|
||||
end
|
||||
|
||||
tdi <= 1'b0;
|
||||
tms <= 1'b0;
|
||||
end
|
||||
|
||||
endtask
|
||||
|
||||
endmodule
|
Reference in New Issue
Block a user