Added JTAG interface with testbench
This commit is contained in:
34
rtl/arch/spartan-6/jtag_if.v
Normal file
34
rtl/arch/spartan-6/jtag_if.v
Normal file
@@ -0,0 +1,34 @@
|
||||
`timescale 1ns/1ps
|
||||
|
||||
// =============================================================================
|
||||
// JTAG interface
|
||||
// Spartan-6 BSCAN primitive wrapper (USER1 chain).
|
||||
// =============================================================================
|
||||
module jtag_if #(
|
||||
parameter chain = 1
|
||||
)(
|
||||
input wire i_tdo,
|
||||
output wire o_tck,
|
||||
output wire o_tdi,
|
||||
output wire o_drck,
|
||||
output wire o_capture,
|
||||
output wire o_shift,
|
||||
output wire o_update,
|
||||
output wire o_runtest,
|
||||
output wire o_reset,
|
||||
output wire o_sel
|
||||
);
|
||||
BSCAN_SPARTAN6 #(
|
||||
.JTAG_CHAIN(chain)
|
||||
) bscan_i (
|
||||
.CAPTURE(o_capture),
|
||||
.DRCK(o_drck),
|
||||
.RESET(o_reset),
|
||||
.RUNTEST(o_runtest),
|
||||
.SEL(o_sel),
|
||||
.SHIFT(o_shift),
|
||||
.TCK(o_tck),
|
||||
.TDI(o_tdi),
|
||||
.UPDATE(o_update)
|
||||
);
|
||||
endmodule
|
||||
34
rtl/core/jtag_if.v
Normal file
34
rtl/core/jtag_if.v
Normal file
@@ -0,0 +1,34 @@
|
||||
`timescale 1ns/1ps
|
||||
|
||||
// =============================================================================
|
||||
// JTAG interface
|
||||
// Generic stub model with inactive/tied-off outputs.
|
||||
// =============================================================================
|
||||
module jtag_if #(
|
||||
parameter chain = 1
|
||||
)(
|
||||
input wire i_tdo,
|
||||
output wire o_tck,
|
||||
output wire o_tdi,
|
||||
output wire o_drck,
|
||||
output wire o_capture,
|
||||
output wire o_shift,
|
||||
output wire o_update,
|
||||
output wire o_runtest,
|
||||
output wire o_reset,
|
||||
output wire o_sel
|
||||
);
|
||||
assign o_tck = 1'b0;
|
||||
assign o_tdi = 1'b0;
|
||||
assign o_drck = 1'b0;
|
||||
assign o_capture = 1'b0;
|
||||
assign o_shift = 1'b0;
|
||||
assign o_update = 1'b0;
|
||||
assign o_runtest = 1'b0;
|
||||
assign o_reset = 1'b0;
|
||||
assign o_sel = 1'b0;
|
||||
|
||||
// Keep lint tools quiet in generic builds where TDO is unused.
|
||||
wire _unused_tdo;
|
||||
assign _unused_tdo = i_tdo;
|
||||
endmodule
|
||||
131
rtl/toplevel/top_jtag.v
Normal file
131
rtl/toplevel/top_jtag.v
Normal file
@@ -0,0 +1,131 @@
|
||||
module top_jtag(
|
||||
input wire aclk,
|
||||
input wire aresetn,
|
||||
|
||||
output wire led_green,
|
||||
output wire led_red,
|
||||
output wire [7:0] LED,
|
||||
|
||||
output wire [5:0] r2r
|
||||
);
|
||||
// Clocking
|
||||
wire clk_100;
|
||||
wire clk_15;
|
||||
assign clk_100 = aclk;
|
||||
clk_gen clocking(
|
||||
.clk_in(clk_100),
|
||||
.clk_out_15(clk_15)
|
||||
);
|
||||
|
||||
localparam integer JTAG_DATA_BITS = 8;
|
||||
wire [JTAG_DATA_BITS-1:0] jtag_data;
|
||||
|
||||
jtag_write_reg #(
|
||||
.DATA_BITS(JTAG_DATA_BITS),
|
||||
.CHAIN(1)
|
||||
) jtag_writer (
|
||||
.clk_i(clk_15),
|
||||
.rst_n_i(aresetn),
|
||||
.data_o(jtag_data)
|
||||
);
|
||||
|
||||
assign LED = jtag_data[7:0];
|
||||
assign led_green = jtag_data[0];
|
||||
assign led_red = jtag_data[7];
|
||||
assign r2r = jtag_data[5:0];
|
||||
|
||||
endmodule
|
||||
|
||||
module jtag_write_reg #(
|
||||
parameter integer DATA_BITS = 8,
|
||||
parameter integer CHAIN = 1
|
||||
)(
|
||||
input wire clk_i,
|
||||
input wire rst_n_i,
|
||||
output reg [DATA_BITS-1:0] data_o
|
||||
);
|
||||
wire jtag_tck;
|
||||
wire jtag_tdi;
|
||||
wire jtag_drck;
|
||||
wire jtag_capture;
|
||||
wire jtag_shift;
|
||||
wire jtag_update;
|
||||
wire jtag_runtest;
|
||||
wire jtag_reset;
|
||||
wire jtag_sel;
|
||||
reg [DATA_BITS-1:0] shift_q;
|
||||
reg [DATA_BITS-1:0] data_jtag_q;
|
||||
reg update_toggle_jtag_q;
|
||||
reg update_toggle_meta_q;
|
||||
reg update_toggle_sync_q;
|
||||
reg update_toggle_sync_d_q;
|
||||
reg [DATA_BITS-1:0] data_meta_q;
|
||||
reg [DATA_BITS-1:0] data_sync_q;
|
||||
|
||||
jtag_if #(
|
||||
.chain(CHAIN)
|
||||
) jtag (
|
||||
.i_tdo(shift_q[0]),
|
||||
.o_tck(jtag_tck),
|
||||
.o_tdi(jtag_tdi),
|
||||
.o_drck(jtag_drck),
|
||||
.o_capture(jtag_capture),
|
||||
.o_shift(jtag_shift),
|
||||
.o_update(jtag_update),
|
||||
.o_runtest(jtag_runtest),
|
||||
.o_reset(jtag_reset),
|
||||
.o_sel(jtag_sel)
|
||||
);
|
||||
|
||||
always @(posedge jtag_drck or posedge jtag_reset or negedge rst_n_i) begin
|
||||
if (!rst_n_i || jtag_reset) begin
|
||||
shift_q <= {DATA_BITS{1'b0}};
|
||||
end else if (jtag_sel && jtag_capture) begin
|
||||
shift_q <= data_jtag_q;
|
||||
end else if (jtag_sel && jtag_shift) begin
|
||||
if (DATA_BITS == 1) begin
|
||||
shift_q <= jtag_tdi;
|
||||
end else begin
|
||||
shift_q <= {jtag_tdi, shift_q[DATA_BITS-1:1]};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge jtag_update or posedge jtag_reset or negedge rst_n_i) begin
|
||||
if (!rst_n_i || jtag_reset) begin
|
||||
data_jtag_q <= {DATA_BITS{1'b0}};
|
||||
update_toggle_jtag_q <= 1'b0;
|
||||
end else if (jtag_sel) begin
|
||||
data_jtag_q <= shift_q;
|
||||
update_toggle_jtag_q <= ~update_toggle_jtag_q;
|
||||
end
|
||||
end
|
||||
|
||||
// CDC into clk_i domain: toggle synchronize + stable data sampling.
|
||||
always @(posedge clk_i or negedge rst_n_i) begin
|
||||
if (!rst_n_i) begin
|
||||
update_toggle_meta_q <= 1'b0;
|
||||
update_toggle_sync_q <= 1'b0;
|
||||
update_toggle_sync_d_q <= 1'b0;
|
||||
data_meta_q <= {DATA_BITS{1'b0}};
|
||||
data_sync_q <= {DATA_BITS{1'b0}};
|
||||
data_o <= {DATA_BITS{1'b0}};
|
||||
end else begin
|
||||
update_toggle_meta_q <= update_toggle_jtag_q;
|
||||
update_toggle_sync_q <= update_toggle_meta_q;
|
||||
update_toggle_sync_d_q <= update_toggle_sync_q;
|
||||
data_meta_q <= data_jtag_q;
|
||||
data_sync_q <= data_meta_q;
|
||||
|
||||
if (update_toggle_sync_q ^ update_toggle_sync_d_q) begin
|
||||
data_o <= data_sync_q;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Not used for this simple write-register, but kept for completeness.
|
||||
wire _unused_tck;
|
||||
wire _unused_runtest;
|
||||
assign _unused_tck = jtag_tck;
|
||||
assign _unused_runtest = jtag_runtest;
|
||||
endmodule
|
||||
Reference in New Issue
Block a user