spiOverJtag: introduce a new spiOverJtag (v2) core able to work with complex JTAG chain
This commit is contained in:
parent
40a588fb2c
commit
971a8db4e9
|
|
@ -40,7 +40,7 @@ tmp_efinix_%/efinix_spiOverJtag.bit : efinix_spiOverJtag.v
|
||||||
|
|
||||||
$(XILINX_BIT_FILES) : spiOverJtag_%.bit.gz : tmp_%/spiOverJtag.bit
|
$(XILINX_BIT_FILES) : spiOverJtag_%.bit.gz : tmp_%/spiOverJtag.bit
|
||||||
gzip -9 -c $< > $@
|
gzip -9 -c $< > $@
|
||||||
tmp_%/spiOverJtag.bit : xilinx_spiOverJtag.v
|
tmp_%/spiOverJtag.bit : xilinx_spiOverJtag.v spiOverJtag_core.v
|
||||||
./build.py $*
|
./build.py $*
|
||||||
|
|
||||||
$(ALTERA_BIT_FILES): spiOverJtag_%.rbf.gz: tmp_%/spiOverJtag.rbf
|
$(ALTERA_BIT_FILES): spiOverJtag_%.rbf.gz: tmp_%/spiOverJtag.rbf
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,9 @@ else:
|
||||||
'file_type': 'SDC'})
|
'file_type': 'SDC'})
|
||||||
tool_options = {'device': full_part, 'family':family}
|
tool_options = {'device': full_part, 'family':family}
|
||||||
|
|
||||||
|
files.append({'name': currDir + 'spiOverJtag_core.v',
|
||||||
|
'file_type': 'verilogSource'})
|
||||||
|
|
||||||
parameters[family.lower().replace(' ', '')]= {
|
parameters[family.lower().replace(' ', '')]= {
|
||||||
'datatype': 'int',
|
'datatype': 'int',
|
||||||
'paramtype': 'vlogdefine',
|
'paramtype': 'vlogdefine',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,250 @@
|
||||||
|
`default_nettype none
|
||||||
|
/*
|
||||||
|
* JTAG: rising edge: sampling
|
||||||
|
* falling esge: update
|
||||||
|
* SPI:
|
||||||
|
*/
|
||||||
|
|
||||||
|
module spiOverJtag_core (
|
||||||
|
/* JTAG state/controls */
|
||||||
|
input wire sel,
|
||||||
|
input wire capture,
|
||||||
|
input wire update,
|
||||||
|
input wire shift,
|
||||||
|
input wire drck,
|
||||||
|
input wire tdi,
|
||||||
|
output wire tdo,
|
||||||
|
|
||||||
|
/* JTAG endpoint to version */
|
||||||
|
input wire ver_sel,
|
||||||
|
input wire ver_cap,
|
||||||
|
input wire ver_shift,
|
||||||
|
input wire ver_drck,
|
||||||
|
input wire ver_tdi,
|
||||||
|
output wire ver_tdo,
|
||||||
|
/* phys */
|
||||||
|
output reg csn,
|
||||||
|
output wire sck,
|
||||||
|
output reg sdi_dq0,
|
||||||
|
input wire sdo_dq1,
|
||||||
|
output wire wpn_dq2,
|
||||||
|
output wire hldn_dq3,
|
||||||
|
|
||||||
|
/* debug signals */
|
||||||
|
output wire [ 6:0] dbg_header1,
|
||||||
|
output wire [13:0] dbg_header,
|
||||||
|
output wire [ 3:0] dbg_hdr_cnt,
|
||||||
|
output wire [ 2:0] dbg_jtag_state,
|
||||||
|
output wire dbg_rst,
|
||||||
|
output wire dbg_clk,
|
||||||
|
output wire dbg_start_header,
|
||||||
|
|
||||||
|
output wire dbg_ver_start,
|
||||||
|
output wire dbg_ver_rst,
|
||||||
|
output wire dbg_ver_state,
|
||||||
|
output wire [15:0] dbg_ver_cnt,
|
||||||
|
output wire [39:0] dbg_ver_shft
|
||||||
|
);
|
||||||
|
|
||||||
|
/* no global reset at start time:
|
||||||
|
* reset system at capture time (before shift)
|
||||||
|
* and at update time (after shift)
|
||||||
|
*/
|
||||||
|
wire rst = ((capture | update) & sel);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if the FPGAs executing this code is somewhere in a complex
|
||||||
|
* JTAG chain first bit isn't necessary for him
|
||||||
|
* Fortunately dummy bits sent are equal to '0' -> we sent a 'start bit'
|
||||||
|
*/
|
||||||
|
wire start_header = (tdi & shift & sel);
|
||||||
|
|
||||||
|
localparam hdr_len = 16;
|
||||||
|
reg [hdr_len-1:0] header; /* number of bits to receive / send in XFER state */
|
||||||
|
reg [hdr_len-1:0] header_d;
|
||||||
|
/* Primary header with mode and length LSB
|
||||||
|
* 6:5: mode (00: normal, 01: no header2, 10: infinite loop)
|
||||||
|
* 4:0: Byte length LSB
|
||||||
|
*/
|
||||||
|
reg [ 6:0] header1;
|
||||||
|
reg [ 6:0] header1_d;
|
||||||
|
wire [ 6:0] header1_next = {tdi, header1[6:1]};
|
||||||
|
wire [ 1:0] mode = header1[1:0];
|
||||||
|
/* Secondary header with extended length */
|
||||||
|
wire [hdr_len-1:0] header_next = {tdi, header[hdr_len-1:1]};
|
||||||
|
reg [ 3:0] hdr_cnt; /* counter of bit received in RECV_HEADERx states */
|
||||||
|
reg [ 3:0] hdr_cnt_d;
|
||||||
|
|
||||||
|
/* ---------------- */
|
||||||
|
/* FSM */
|
||||||
|
/* ---------------- */
|
||||||
|
|
||||||
|
localparam IDLE = 3'b000,
|
||||||
|
RECV_HEADER1 = 3'b001,
|
||||||
|
RECV_HEADER2 = 3'b010,
|
||||||
|
XFER = 3'b011,
|
||||||
|
WAIT_END = 3'b100;
|
||||||
|
|
||||||
|
reg [2:0] jtag_state, jtag_state_d;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. receives 8bits (
|
||||||
|
*/
|
||||||
|
always @(*) begin
|
||||||
|
jtag_state_d = jtag_state;
|
||||||
|
hdr_cnt_d = hdr_cnt;
|
||||||
|
header_d = header;
|
||||||
|
header1_d = header1;
|
||||||
|
case (jtag_state)
|
||||||
|
IDLE: begin /* nothing: wait for the 'start bit' */
|
||||||
|
hdr_cnt_d = 6;
|
||||||
|
if (start_header) begin
|
||||||
|
jtag_state_d = RECV_HEADER1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
RECV_HEADER1: begin /* first header with 1:0 : mode, 6:2: XFER length (LSB) */
|
||||||
|
hdr_cnt_d = hdr_cnt - 1'b1;
|
||||||
|
header1_d = header1_next;
|
||||||
|
if (hdr_cnt == 0) begin
|
||||||
|
if (header1_next[1:0] == 2'b00) begin
|
||||||
|
hdr_cnt_d = 7;
|
||||||
|
header_d = {header1_next[6:2], 3'b000, 8'd0};
|
||||||
|
jtag_state_d = RECV_HEADER2;
|
||||||
|
end else begin
|
||||||
|
header_d = {8'b0, header1_next[6:2], 3'b000};
|
||||||
|
jtag_state_d = XFER;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RECV_HEADER2: begin /* fill a counter with 16bits (number of bits to pass to the flash) */
|
||||||
|
hdr_cnt_d = hdr_cnt - 1'b1;
|
||||||
|
header_d = header_next;
|
||||||
|
if (hdr_cnt == 0) begin
|
||||||
|
jtag_state_d = XFER;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
XFER: begin
|
||||||
|
header_d = header - 1;
|
||||||
|
if (header == 1 && mode != 2'b10)
|
||||||
|
jtag_state_d = WAIT_END;
|
||||||
|
end
|
||||||
|
WAIT_END: begin /* move to this state when header bits have been transfered to the SPI flash */
|
||||||
|
// /* nothing to do: rst will move automagically state in IDLE */
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
jtag_state_d = IDLE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge drck) begin
|
||||||
|
header <= header_d;
|
||||||
|
header1 <= header1_d;
|
||||||
|
hdr_cnt <= hdr_cnt_d;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge drck or posedge rst) begin
|
||||||
|
if (rst) begin
|
||||||
|
jtag_state <= IDLE;
|
||||||
|
end else begin
|
||||||
|
jtag_state <= jtag_state_d;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
/* JTAG <-> phy SPI */
|
||||||
|
always @(posedge drck or posedge rst) begin
|
||||||
|
if (rst) begin
|
||||||
|
sdi_dq0 <= 1'b0;
|
||||||
|
csn <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
sdi_dq0 <= tdi;
|
||||||
|
csn <= ~(jtag_state == XFER);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign sck = ~drck;
|
||||||
|
assign tdo = sdo_dq1;
|
||||||
|
assign wpn_dq2 = 1'b1;
|
||||||
|
assign hldn_dq3 = 1'b1;
|
||||||
|
|
||||||
|
/* ------------- */
|
||||||
|
/* Version */
|
||||||
|
/* ------------- */
|
||||||
|
/* no global reset at start time: reset system at capture time (before shift) */
|
||||||
|
wire ver_rst = (ver_cap & ver_sel);
|
||||||
|
|
||||||
|
/* start bit */
|
||||||
|
wire ver_start = (ver_tdi & ver_shift & ver_sel);
|
||||||
|
|
||||||
|
localparam VER_VALUE = 40'h30_30_2E_32_30; // 02.00
|
||||||
|
reg [ 6:0] ver_cnt, ver_cnt_d;
|
||||||
|
reg [39:0] ver_shft, ver_shft_d;
|
||||||
|
|
||||||
|
reg [2:0] ver_state, ver_state_d;
|
||||||
|
always @(*) begin
|
||||||
|
ver_state_d = ver_state;
|
||||||
|
ver_cnt_d = ver_cnt;
|
||||||
|
ver_shft_d = ver_shft;
|
||||||
|
case (ver_state)
|
||||||
|
IDLE: begin /* nothing: wait for the 'start bit' */
|
||||||
|
ver_cnt_d = 6;
|
||||||
|
if (ver_start) begin
|
||||||
|
ver_state_d = RECV_HEADER1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
RECV_HEADER1: begin
|
||||||
|
ver_cnt_d = ver_cnt - 1'b1;
|
||||||
|
if (ver_cnt == 0) begin
|
||||||
|
ver_state_d = XFER;
|
||||||
|
ver_cnt_d = 39;
|
||||||
|
ver_shft_d = VER_VALUE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
XFER: begin
|
||||||
|
ver_cnt_d = ver_cnt - 1;
|
||||||
|
ver_shft_d = {1'b1, ver_shft[39:1]};
|
||||||
|
if (ver_cnt == 0)
|
||||||
|
ver_state_d = WAIT_END;
|
||||||
|
end
|
||||||
|
WAIT_END: begin /* move to this state when header bits have been transfered to the SPI flash */
|
||||||
|
// /* nothing to do: rst will move automagically state in IDLE */
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
ver_state_d = IDLE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge ver_drck) begin
|
||||||
|
ver_cnt <= ver_cnt_d;
|
||||||
|
ver_shft <= ver_shft_d;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge ver_drck or posedge ver_rst) begin
|
||||||
|
if (ver_rst)
|
||||||
|
ver_state <= IDLE;
|
||||||
|
else
|
||||||
|
ver_state <= ver_state_d;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign ver_tdo = ver_shft[0];
|
||||||
|
|
||||||
|
/* --------- */
|
||||||
|
/* debug */
|
||||||
|
/* --------- */
|
||||||
|
assign dbg_header1 = header1;
|
||||||
|
assign dbg_header = header;
|
||||||
|
assign dbg_hdr_cnt = hdr_cnt;
|
||||||
|
assign dbg_jtag_state = jtag_state;
|
||||||
|
assign dbg_rst = rst;
|
||||||
|
assign dbg_clk = ~drck;
|
||||||
|
assign dbg_start_header = start_header;
|
||||||
|
|
||||||
|
assign dbg_ver_start = ver_start;
|
||||||
|
assign dbg_ver_state = ver_state;
|
||||||
|
assign dbg_ver_cnt = ver_cnt;
|
||||||
|
assign dbg_ver_shft = ver_shft;
|
||||||
|
assign dbg_ver_rst = ver_rst;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -1,85 +1,83 @@
|
||||||
|
`default_nettype none
|
||||||
module spiOverJtag
|
module spiOverJtag
|
||||||
(
|
(
|
||||||
|
`ifndef xilinxultrascale
|
||||||
|
output wire csn,
|
||||||
|
|
||||||
`ifdef spartan6
|
`ifdef spartan6
|
||||||
output sck,
|
output wire sck,
|
||||||
output csn,
|
|
||||||
output sdi_dq0,
|
|
||||||
input sdo_dq1,
|
|
||||||
output wpn_dq2,
|
|
||||||
output hldn_dq3
|
|
||||||
`define QSPI
|
|
||||||
`elsif spartan3e
|
|
||||||
output sck,
|
|
||||||
output csn,
|
|
||||||
output sdi_dq0,
|
|
||||||
input sdo_dq1
|
|
||||||
`elsif virtex6
|
|
||||||
output csn,
|
|
||||||
output sdi_dq0
|
|
||||||
`elsif xilinxultrascale
|
|
||||||
`else
|
|
||||||
// Xilinx 7 but not ultrascale
|
|
||||||
output csn,
|
|
||||||
output sdi_dq0,
|
|
||||||
input sdo_dq1,
|
|
||||||
output wpn_dq2,
|
|
||||||
output hldn_dq3
|
|
||||||
`define QSPI
|
|
||||||
`endif
|
`endif
|
||||||
|
`ifdef spartan3e
|
||||||
|
output wire sck,
|
||||||
|
`endif
|
||||||
|
output wire sdi_dq0,
|
||||||
|
input wire sdo_dq1,
|
||||||
|
output wire wpn_dq2,
|
||||||
|
output wire hldn_dq3
|
||||||
|
`endif // xilinxultrascale
|
||||||
|
|
||||||
`ifdef secondaryflash
|
`ifdef secondaryflash
|
||||||
output sdi_sec_dq0,
|
output wire sdi_sec_dq0,
|
||||||
input sdo_sec_dq1,
|
input wire sdo_sec_dq1,
|
||||||
output wpn_sec_dq2,
|
output wire wpn_sec_dq2,
|
||||||
output hldn_sec_dq3,
|
output wire hldn_sec_dq3,
|
||||||
output csn_sec
|
output wire csn_sec
|
||||||
`endif // secondaryflash
|
`endif // secondaryflash
|
||||||
);
|
);
|
||||||
|
|
||||||
wire capture, drck, sel, update;
|
wire capture, drck, sel, update, shift;
|
||||||
wire runtest;
|
wire tdi, tdo;
|
||||||
wire tdi;
|
wire spi_clk;
|
||||||
reg fsm_csn;
|
|
||||||
|
|
||||||
`ifdef QSPI
|
`ifndef spartan3e
|
||||||
assign wpn_dq2 = 1'b1;
|
/* Version Interface. */
|
||||||
assign hldn_dq3 = 1'b1;
|
wire ver_sel, ver_cap, ver_shift, ver_drck, ver_tdi, ver_tdo;
|
||||||
|
|
||||||
|
spiOverJtag_core spiOverJtag_core_prim (
|
||||||
|
/* JTAG state/controls */
|
||||||
|
.sel(sel),
|
||||||
|
.capture(capture),
|
||||||
|
.update(update),
|
||||||
|
.shift(shift),
|
||||||
|
.drck(drck),
|
||||||
|
.tdi(tdi),
|
||||||
|
.tdo(tdo),
|
||||||
|
|
||||||
|
/* JTAG endpoint to version */
|
||||||
|
.ver_sel(ver_sel),
|
||||||
|
.ver_cap(ver_cap),
|
||||||
|
.ver_shift(ver_shift),
|
||||||
|
.ver_drck(ver_drck),
|
||||||
|
.ver_tdi(ver_tdi),
|
||||||
|
.ver_tdo(ver_tdo),
|
||||||
|
|
||||||
|
/* phys */
|
||||||
|
.csn(csn),
|
||||||
|
.sck(spi_clk),
|
||||||
|
.sdi_dq0(sdi_dq0),
|
||||||
|
.sdo_dq1(sdo_dq1),
|
||||||
|
.wpn_dq2(wpn_dq2),
|
||||||
|
.hldn_dq3(hldn_dq3)
|
||||||
|
);
|
||||||
`endif
|
`endif
|
||||||
// jtag -> spi flash
|
|
||||||
assign sdi_dq0 = tdi;
|
|
||||||
`ifdef virtex6
|
|
||||||
wire di;
|
|
||||||
wire tdo = (sel) ? di : tdi;
|
|
||||||
`else
|
|
||||||
wire tdo = (sel) ? sdo_dq1 : tdi;
|
|
||||||
`endif
|
|
||||||
assign csn = fsm_csn;
|
|
||||||
|
|
||||||
wire tmp_cap_s = capture && sel;
|
|
||||||
wire tmp_up_s = update && sel;
|
|
||||||
|
|
||||||
always @(posedge drck, posedge runtest) begin
|
|
||||||
if (runtest) begin
|
|
||||||
fsm_csn <= 1'b1;
|
|
||||||
end else begin
|
|
||||||
if (tmp_cap_s) begin
|
|
||||||
fsm_csn <= 1'b0;
|
|
||||||
end else if (tmp_up_s) begin
|
|
||||||
fsm_csn <= 1'b1;
|
|
||||||
end else begin
|
|
||||||
fsm_csn <= fsm_csn;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
`ifdef spartan6
|
||||||
|
assign sck = spi_clk;
|
||||||
|
`else // !spartan6
|
||||||
|
`ifdef spartan3e
|
||||||
|
assign sck = spi_clk;
|
||||||
|
`else // !spartan6 && !spartan3e
|
||||||
`ifdef xilinxultrascale
|
`ifdef xilinxultrascale
|
||||||
assign sck = drck;
|
assign sck = drck;
|
||||||
wire [3:0] di;
|
wire [3:0] di;
|
||||||
assign wpn_dq2 = 1'b1;
|
|
||||||
assign hldn_dq3 = 1'b1;
|
|
||||||
assign sdo_dq1 = di[1];
|
assign sdo_dq1 = di[1];
|
||||||
wire [3:0] do = {hldn_dq3, wpn_dq2, 1'b0, sdi_dq0};
|
wire [3:0] do = {hldn_dq3, wpn_dq2, 1'b0, sdi_dq0};
|
||||||
wire [3:0] dts = 4'b0010;
|
wire [3:0] dts = 4'b0010;
|
||||||
|
// secondary BSCANE3 signals
|
||||||
|
wire sel_sec, spi_clk_sec;
|
||||||
|
|
||||||
|
wire sck = (sel_sec) ? spi_clk_sec : spi_clk;
|
||||||
|
|
||||||
STARTUPE3 #(
|
STARTUPE3 #(
|
||||||
.PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams.
|
.PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams.
|
||||||
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency (ns) for simulation.
|
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency (ns) for simulation.
|
||||||
|
|
@ -102,53 +100,57 @@ module spiOverJtag
|
||||||
.USRDONEO (1'b1), // 1-bit input: User DONE pin output control.
|
.USRDONEO (1'b1), // 1-bit input: User DONE pin output control.
|
||||||
.USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output.
|
.USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output.
|
||||||
);
|
);
|
||||||
`elsif spartan3e
|
`else // !spartan6 && !spartan3e && !xilinxultrascale
|
||||||
assign sck = drck;
|
|
||||||
assign runtest = tmp_up_s;
|
|
||||||
`elsif spartan6
|
|
||||||
assign sck = drck;
|
|
||||||
`elsif virtex6
|
|
||||||
STARTUP_VIRTEX6 #(
|
|
||||||
.PROG_USR("FALSE")
|
|
||||||
) startup_virtex6_inst (
|
|
||||||
.CFGCLK(), // unused
|
|
||||||
.CFGMCLK(), // unused
|
|
||||||
.CLK(1'b0), // unused
|
|
||||||
.DINSPI(di), // data from SPI flash
|
|
||||||
.EOS(),
|
|
||||||
.GSR(1'b0), // unused
|
|
||||||
.GTS(1'b0), // unused
|
|
||||||
.KEYCLEARB(1'b0), // not used
|
|
||||||
.PACK(1'b1), // tied low for 'safe' operations
|
|
||||||
.PREQ(), // unused
|
|
||||||
.TCKSPI(), // echo of CCLK from TCK pin
|
|
||||||
.USRCCLKO (drck), // user FPGA -> CCLK pin
|
|
||||||
.USRCCLKTS(1'b0), // drive CCLK not in high-Z
|
|
||||||
.USRDONEO (1'b1), // why both USRDONE are high?
|
|
||||||
.USRDONETS(1'b1) // ??
|
|
||||||
);
|
|
||||||
`else
|
|
||||||
STARTUPE2 #(
|
STARTUPE2 #(
|
||||||
.PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams.
|
.PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams.
|
||||||
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation.
|
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation.
|
||||||
) startupe2_inst (
|
) startupe2_inst (
|
||||||
.CFGCLK (), // 1-bit output: Configuration main clock output
|
.CFGCLK (), // 1-bit output: Configuration main clock output
|
||||||
.CFGMCLK (), // 1-bit output: Configuration internal oscillator clock output
|
.CFGMCLK (), // 1-bit output: Configuration internal oscillator clock output
|
||||||
.EOS (), // 1-bit output: Active high output signal indicating the End Of Startup.
|
.EOS (), // 1-bit output: Active high output signal indicating the End Of Startup.
|
||||||
.PREQ (), // 1-bit output: PROGRAM request to fabric output
|
.PREQ (), // 1-bit output: PROGRAM request to fabric output
|
||||||
.CLK (1'b0), // 1-bit input: User start-up clock input
|
.CLK (1'b0), // 1-bit input: User start-up clock input
|
||||||
.GSR (1'b0), // 1-bit input: Global Set/Reset input (GSR cannot be used for the port name)
|
.GSR (1'b0), // 1-bit input: Global Set/Reset input (GSR cannot be used for the port name)
|
||||||
.GTS (1'b0), // 1-bit input: Global 3-state input (GTS cannot be used for the port name)
|
.GTS (1'b0), // 1-bit input: Global 3-state input (GTS cannot be used for the port name)
|
||||||
.KEYCLEARB(1'b0), // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
|
.KEYCLEARB(1'b0), // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
|
||||||
.PACK (1'b1), // 1-bit input: PROGRAM acknowledge input
|
.PACK (1'b1), // 1-bit input: PROGRAM acknowledge input
|
||||||
.USRCCLKO (drck), // 1-bit input: User CCLK input
|
.USRCCLKO (spi_clk), // 1-bit input: User CCLK input
|
||||||
.USRCCLKTS(1'b0), // 1-bit input: User CCLK 3-state enable input
|
.USRCCLKTS(1'b0), // 1-bit input: User CCLK 3-state enable input
|
||||||
.USRDONEO (1'b1), // 1-bit input: User DONE pin output control
|
.USRDONEO (1'b1), // 1-bit input: User DONE pin output control
|
||||||
.USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output
|
.USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output
|
||||||
);
|
);
|
||||||
`endif
|
`endif
|
||||||
|
`endif
|
||||||
|
`endif
|
||||||
|
|
||||||
`ifdef spartan3e
|
`ifdef spartan3e
|
||||||
|
wire runtest;
|
||||||
|
reg fsm_csn;
|
||||||
|
assign wpn_dq2 = 1'b1;
|
||||||
|
assign hldn_dq3 = 1'b1;
|
||||||
|
// jtag -> spi flash
|
||||||
|
assign sdi_dq0 = tdi;
|
||||||
|
wire tdo = (sel) ? sdo_dq1 : tdi;
|
||||||
|
assign csn = fsm_csn;
|
||||||
|
|
||||||
|
wire tmp_cap_s = capture && sel;
|
||||||
|
wire tmp_up_s = update && sel;
|
||||||
|
assign runtest = tmp_up_s;
|
||||||
|
|
||||||
|
always @(posedge drck, posedge runtest) begin
|
||||||
|
if (runtest) begin
|
||||||
|
fsm_csn <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
if (tmp_cap_s) begin
|
||||||
|
fsm_csn <= 1'b0;
|
||||||
|
end else if (tmp_up_s) begin
|
||||||
|
fsm_csn <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
fsm_csn <= fsm_csn;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
BSCAN_SPARTAN3 bscane2_inst (
|
BSCAN_SPARTAN3 bscane2_inst (
|
||||||
.CAPTURE(capture), // 1-bit output: CAPTURE output from TAP controller.
|
.CAPTURE(capture), // 1-bit output: CAPTURE output from TAP controller.
|
||||||
.DRCK1 (drck), // 1-bit output: Gated TCK output. When SEL
|
.DRCK1 (drck), // 1-bit output: Gated TCK output. When SEL
|
||||||
|
|
@ -167,9 +169,7 @@ module spiOverJtag
|
||||||
.TDO2 () // 1-bit input: USER2 function
|
.TDO2 () // 1-bit input: USER2 function
|
||||||
);
|
);
|
||||||
`else
|
`else
|
||||||
`ifdef virtex6
|
`ifdef spartan6
|
||||||
BSCAN_VIRTEX6 #(
|
|
||||||
`elsif spartan6
|
|
||||||
BSCAN_SPARTAN6 #(
|
BSCAN_SPARTAN6 #(
|
||||||
`else
|
`else
|
||||||
BSCANE2 #(
|
BSCANE2 #(
|
||||||
|
|
@ -181,10 +181,10 @@ module spiOverJtag
|
||||||
// is asserted, DRCK toggles when
|
// is asserted, DRCK toggles when
|
||||||
// CAPTURE or SHIFT are asserted.
|
// CAPTURE or SHIFT are asserted.
|
||||||
.RESET (), // 1-bit output: Reset output for TAP controller.
|
.RESET (), // 1-bit output: Reset output for TAP controller.
|
||||||
.RUNTEST(runtest), // 1-bit output: Output asserted when TAP
|
.RUNTEST(), // 1-bit output: Output asserted when TAP
|
||||||
// controller is in Run Test/Idle state.
|
// controller is in Run Test/Idle state.
|
||||||
.SEL (sel), // 1-bit output: USER instruction active output.
|
.SEL (sel), // 1-bit output: USER instruction active output.
|
||||||
.SHIFT (), // 1-bit output: SHIFT output from TAP controller.
|
.SHIFT (shift), // 1-bit output: SHIFT output from TAP controller.
|
||||||
.TCK (), // 1-bit output: Test Clock output.
|
.TCK (), // 1-bit output: Test Clock output.
|
||||||
// Fabric connection to TAP Clock pin.
|
// Fabric connection to TAP Clock pin.
|
||||||
.TDI (tdi), // 1-bit output: Test Data Input (TDI) output
|
.TDI (tdi), // 1-bit output: Test Data Input (TDI) output
|
||||||
|
|
@ -195,38 +195,58 @@ module spiOverJtag
|
||||||
.TDO (tdo) // 1-bit input: Test Data Output (TDO) input
|
.TDO (tdo) // 1-bit input: Test Data Output (TDO) input
|
||||||
// for USER function.
|
// for USER function.
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* BSCAN for Version Interface. */
|
||||||
|
`ifdef spartan6
|
||||||
|
BSCAN_SPARTAN6 #(
|
||||||
|
`else
|
||||||
|
BSCANE2 #(
|
||||||
|
`endif
|
||||||
|
.JTAG_CHAIN(4) // Value for USER command.
|
||||||
|
) bscane2_version (
|
||||||
|
.CAPTURE(ver_cap),
|
||||||
|
.DRCK (ver_drck),
|
||||||
|
.RESET (),
|
||||||
|
.RUNTEST(),
|
||||||
|
.SEL (ver_sel),
|
||||||
|
.SHIFT (ver_shift),
|
||||||
|
.TCK (),
|
||||||
|
.TDI (ver_tdi),
|
||||||
|
.TMS (),
|
||||||
|
.UPDATE (),
|
||||||
|
.TDO (ver_tdo)
|
||||||
|
);
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
`ifdef secondaryflash
|
`ifdef secondaryflash
|
||||||
reg fsm_csn_sec;
|
wire drck_sec;
|
||||||
wire tdo_sec;
|
|
||||||
// secondary BSCANE3 signals
|
|
||||||
wire sel_sec, drck_sec;
|
|
||||||
|
|
||||||
wire sck = (sel_sec) ? drck_sec : drck;
|
spiOverJtag_core spiOverJtag_core_sec (
|
||||||
|
/* JTAG state/controls */
|
||||||
|
.sel(sel_sec),
|
||||||
|
.capture(capture),
|
||||||
|
.update(update),
|
||||||
|
.shift(shift),
|
||||||
|
.drck(drck_sec),
|
||||||
|
.tdi(tdi),
|
||||||
|
.tdo(tdo_sec),
|
||||||
|
|
||||||
assign wpn_sec_dq2 = 1'b1;
|
/* JTAG endpoint to version (Unused) */
|
||||||
assign hldn_sec_dq3 = 1'b1;
|
.ver_sel(1'b0),
|
||||||
assign sdi_sec_dq0 = tdi;
|
.ver_cap(1'b0),
|
||||||
assign tdo_sec = (sel_sec) ? sdo_sec_dq1 : tdi;
|
.ver_shift(1'b0),
|
||||||
assign csn_sec = fsm_csn_sec;
|
.ver_drck(1'b0),
|
||||||
|
.ver_tdi(1'b0),
|
||||||
|
.ver_tdo(),
|
||||||
|
|
||||||
wire tmp_cap_sec_s = capture && sel_sec;
|
/* phys */
|
||||||
wire tmp_up_sec_s = update && sel_sec;
|
.csn(csn_sec),
|
||||||
|
.sck(spi_clk_sec),
|
||||||
always @(posedge drck_sec, posedge runtest) begin
|
.sdi_dq0(sdi_sec_dq0),
|
||||||
if (runtest) begin
|
.sdo_dq1(sdo_sec_dq1),
|
||||||
fsm_csn_sec <= 1'b1;
|
.wpn_dq2(wpn_sec_dq2),
|
||||||
end else begin
|
.hldn_dq3(hldn_sec_dq3)
|
||||||
if (tmp_cap_sec_s) begin
|
);
|
||||||
fsm_csn_sec <= 1'b0;
|
|
||||||
end else if (tmp_up_sec_s) begin
|
|
||||||
fsm_csn_sec <= 1'b1;
|
|
||||||
end else begin
|
|
||||||
fsm_csn_sec <= fsm_csn_sec;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
BSCANE2 #(
|
BSCANE2 #(
|
||||||
.JTAG_CHAIN(2) // Value for USER command.
|
.JTAG_CHAIN(2) // Value for USER command.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue