jtag memory interface working
This commit is contained in:
@@ -12,120 +12,64 @@ module top_jtag(
|
||||
wire clk_100;
|
||||
wire clk_15;
|
||||
assign clk_100 = aclk;
|
||||
clk_gen clocking(
|
||||
clk_gen clk(
|
||||
.clk_in(clk_100),
|
||||
.clk_out_15(clk_15)
|
||||
);
|
||||
|
||||
localparam integer JTAG_DATA_BITS = 8;
|
||||
wire [JTAG_DATA_BITS-1:0] jtag_data;
|
||||
wire i_rst;
|
||||
assign i_rst = !aresetn;
|
||||
|
||||
jtag_write_reg #(
|
||||
.DATA_BITS(JTAG_DATA_BITS),
|
||||
.CHAIN(1)
|
||||
) jtag_writer (
|
||||
.clk_i(clk_15),
|
||||
.rst_n_i(aresetn),
|
||||
.data_o(jtag_data)
|
||||
wire [31:0] wb_adr;
|
||||
wire [31:0] wb_dat;
|
||||
wire [31:0] wb_rdt;
|
||||
wire [3:0] wb_sel;
|
||||
wire wb_cyc;
|
||||
wire wb_we;
|
||||
wire wb_stb;
|
||||
wire wb_ack;
|
||||
wire cmd_reset;
|
||||
|
||||
jtag_wb_bridge #(
|
||||
.chain(1)
|
||||
) jtag_wb (
|
||||
.i_clk(clk_15),
|
||||
.i_rst(!aresetn),
|
||||
|
||||
.o_wb_adr(wb_adr),
|
||||
.o_wb_dat(wb_dat),
|
||||
.o_wb_sel(wb_sel),
|
||||
.o_wb_we(wb_we),
|
||||
.o_wb_cyc(wb_cyc),
|
||||
.o_wb_stb(wb_stb),
|
||||
.i_wb_rdt(wb_rdt),
|
||||
.i_wb_ack(wb_ack),
|
||||
.o_cmd_reset(cmd_reset)
|
||||
);
|
||||
|
||||
assign LED = jtag_data[7:0];
|
||||
assign led_green = jtag_data[0];
|
||||
assign led_red = jtag_data[7];
|
||||
assign r2r = jtag_data[5:0];
|
||||
wire [31:0] gpio;
|
||||
wire [31:0] gpio_in;
|
||||
assign gpio_in = 32'h0;
|
||||
|
||||
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)
|
||||
wb_gpio #(
|
||||
.address(32'h00000000)
|
||||
) u_wb_gpio (
|
||||
.i_wb_clk(clk_15),
|
||||
.i_wb_rst(i_rst | cmd_reset),
|
||||
.i_wb_adr(wb_adr),
|
||||
.i_wb_dat(wb_dat),
|
||||
.i_wb_sel(wb_sel),
|
||||
.i_wb_we(wb_we),
|
||||
.i_wb_stb(wb_stb & wb_cyc),
|
||||
.i_gpio(gpio_in),
|
||||
.o_wb_rdt(wb_rdt),
|
||||
.o_wb_ack(wb_ack),
|
||||
.o_gpio(gpio)
|
||||
);
|
||||
|
||||
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
|
||||
assign LED = gpio[7:0];
|
||||
assign r2r = gpio[13:8];
|
||||
assign led_green = gpio[30];
|
||||
assign led_red = gpio[31];
|
||||
|
||||
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