parent
65a26842c4
commit
4da79b6046
|
@ -66,6 +66,7 @@ module jtag_dm #(
|
|||
wire halted;
|
||||
wire resumeack;
|
||||
wire sbbusy;
|
||||
wire[2:0] sberror;
|
||||
wire[DMI_OP_BITS-1:0] dm_op;
|
||||
wire[DMI_ADDR_BITS-1:0] dm_op_addr;
|
||||
wire[DMI_DATA_BITS-1:0] dm_op_data;
|
||||
|
@ -74,11 +75,15 @@ module jtag_dm #(
|
|||
reg clear_resumeack;
|
||||
reg sbaddress_write_valid;
|
||||
reg sbdata_write_valid;
|
||||
reg sbdata_read_valid;
|
||||
reg[31:0] sbcs;
|
||||
reg[31:0] dm_resp_data_d, dm_resp_data_q;
|
||||
wire[31:0] sba_sbaddress;
|
||||
wire[31:0] dm_sbaddress;
|
||||
wire resumereq;
|
||||
wire cmdbusy;
|
||||
wire sbdata_valid;
|
||||
wire[31:0] sbdata;
|
||||
|
||||
// DM regs
|
||||
reg[31:0] dmstatus;
|
||||
|
@ -173,6 +178,8 @@ module jtag_dm #(
|
|||
clear_resumeack = 1'b0;
|
||||
sbaddress_write_valid = 1'b0;
|
||||
sbdata_write_valid = 1'b0;
|
||||
sbdata_read_valid = 1'b0;
|
||||
sbcs = 32'h0;
|
||||
|
||||
data0_d = data0_q;
|
||||
sbcs_d = sbcs_q;
|
||||
|
@ -183,14 +190,22 @@ module jtag_dm #(
|
|||
// read
|
||||
if (dm_op == `DMI_OP_READ) begin
|
||||
case (dm_op_addr)
|
||||
`DMStatus: dm_resp_data_d = dmstatus;
|
||||
`DMControl: dm_resp_data_d = dmcontrol_q;
|
||||
`Hartinfo: dm_resp_data_d = HARTINFO;
|
||||
`SBCS: dm_resp_data_d = sbcs_q;
|
||||
`DMStatus :dm_resp_data_d = dmstatus;
|
||||
`DMControl :dm_resp_data_d = dmcontrol_q;
|
||||
`Hartinfo :dm_resp_data_d = HARTINFO;
|
||||
`SBCS :dm_resp_data_d = sbcs_q;
|
||||
`AbstractCS:dm_resp_data_d = abstractcs;
|
||||
`SBAddress0:dm_resp_data_d = sbaddress0_q;
|
||||
`SBData0 : begin
|
||||
if (sbbusy || sbcs_q[`Sbbusyerror]) begin
|
||||
sbcs_d[`Sbbusyerror] = 1'b1;
|
||||
end else begin
|
||||
sbdata_read_valid = (sbcs_q[`Sberror] == 3'b0);
|
||||
dm_resp_data_d = sbdata0_q;
|
||||
end
|
||||
end
|
||||
default:;
|
||||
endcase
|
||||
|
||||
// write
|
||||
end else if (dm_op == `DMI_OP_WRITE) begin
|
||||
case (dm_op_addr)
|
||||
|
@ -209,15 +224,16 @@ module jtag_dm #(
|
|||
if (sbbusy) begin
|
||||
sbcs_d[`Sbbusyerror] = 1'b1;
|
||||
end else begin
|
||||
sbcs = dm_op_data;
|
||||
sbcs_d = dm_op_data;
|
||||
// write 1 to clear
|
||||
sbcs_d[`Sbbusyerror] = sbcs_q[`Sbbusyerror] & (~sbcs_d[`Sbbusyerror]);
|
||||
sbcs_d[`Sberror] = sbcs_q[`Sberror] & (~sbcs_d[`Sberror]);
|
||||
sbcs_d[`Sbbusyerror] = sbcs_q[`Sbbusyerror] & (~sbcs[`Sbbusyerror]);
|
||||
sbcs_d[`Sberror] = sbcs_q[`Sberror] & (~sbcs[`Sberror]);
|
||||
end
|
||||
end
|
||||
|
||||
`SBAddress0: begin
|
||||
if (sbbusy | sbcs_d[`Sbbusyerror]) begin
|
||||
if (sbbusy | sbcs_q[`Sbbusyerror]) begin
|
||||
sbcs_d[`Sbbusyerror] = 1'b1;
|
||||
end else begin
|
||||
sbaddress0_d = dm_op_data;
|
||||
|
@ -226,7 +242,7 @@ module jtag_dm #(
|
|||
end
|
||||
|
||||
`SBData0: begin
|
||||
if (sbbusy | sbcs_d[`Sbbusyerror]) begin
|
||||
if (sbbusy | sbcs_q[`Sbbusyerror]) begin
|
||||
sbcs_d[`Sbbusyerror] = 1'b1;
|
||||
end else begin
|
||||
sbdata0_d = dm_op_data;
|
||||
|
@ -241,8 +257,6 @@ module jtag_dm #(
|
|||
default:;
|
||||
endcase
|
||||
// nop
|
||||
end else begin
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -267,6 +281,7 @@ module jtag_dm #(
|
|||
// sbcs
|
||||
sbcs_d[`Sbversion] = 3'd1;
|
||||
sbcs_d[`Sbbusy] = sbbusy;
|
||||
sbcs_d[`Sberror] = sberror;
|
||||
sbcs_d[`Sbasize] = 7'd32;
|
||||
sbcs_d[`Sbaccess128] = 1'b0;
|
||||
sbcs_d[`Sbaccess64] = 1'b0;
|
||||
|
@ -275,6 +290,10 @@ module jtag_dm #(
|
|||
sbcs_d[`Sbaccess8] = 1'b0;
|
||||
sbcs_d[`Sbaccess] = 3'd2;
|
||||
|
||||
if (sbdata_valid) begin
|
||||
sbdata0_d = sbdata;
|
||||
end
|
||||
|
||||
// set the havereset flag when we did a ndmreset
|
||||
if (ndmreset_o) begin
|
||||
havereset_d = 1'b1;
|
||||
|
@ -355,7 +374,21 @@ module jtag_dm #(
|
|||
) u_jtag_sba (
|
||||
.clk(clk),
|
||||
.rst_n(rst_n),
|
||||
.sbaddress_i(sbaddress0_q),
|
||||
.sbaddress_write_valid_i(sbaddress_write_valid),
|
||||
.sbreadonaddr_i(sbcs_q[`Sbreadonaddr]),
|
||||
.sbaddress_o(sba_sbaddress),
|
||||
.sbautoincrement_i(sbcs_q[`Sbautoincrement]),
|
||||
.sbaccess_i(sbcs_q[`Sbaccess]),
|
||||
.sbreadondata_i(sbcs_q[`Sbreadondata]),
|
||||
.sbdata_i(sbdata0_q),
|
||||
.sbdata_read_valid_i(sbdata_read_valid),
|
||||
.sbdata_write_valid_i(sbdata_write_valid),
|
||||
.sbdata_o(sbdata),
|
||||
.sbdata_valid_o(sbdata_valid),
|
||||
.sbbusy_o(sbbusy),
|
||||
.sberror_o(sberror),
|
||||
|
||||
.master_req_o(master_req_o),
|
||||
.master_gnt_i(master_gnt_i),
|
||||
.master_rvalid_i(master_rvalid_i),
|
||||
|
|
|
@ -19,10 +19,27 @@ module jtag_sba #(
|
|||
|
||||
)(
|
||||
|
||||
input wire clk,
|
||||
input wire rst_n,
|
||||
input wire clk,
|
||||
input wire rst_n,
|
||||
|
||||
input wire [31:0] sbaddress_i,
|
||||
input wire sbaddress_write_valid_i,
|
||||
|
||||
input wire sbreadonaddr_i,
|
||||
output wire [31:0] sbaddress_o,
|
||||
input wire sbautoincrement_i,
|
||||
input wire [2:0] sbaccess_i,
|
||||
|
||||
input wire sbreadondata_i,
|
||||
input wire [31:0] sbdata_i,
|
||||
input wire sbdata_read_valid_i,
|
||||
input wire sbdata_write_valid_i,
|
||||
|
||||
output wire [31:0] sbdata_o,
|
||||
output wire sbdata_valid_o,
|
||||
|
||||
output wire sbbusy_o,
|
||||
output wire [2:0] sberror_o,
|
||||
|
||||
output wire master_req_o,
|
||||
input wire master_gnt_i,
|
||||
|
@ -36,12 +53,147 @@ module jtag_sba #(
|
|||
|
||||
);
|
||||
|
||||
localparam S_IDLE = 5'b00001;
|
||||
localparam S_READ = 5'b00010;
|
||||
localparam S_WAIT_READ = 5'b00100;
|
||||
localparam S_WRITE = 5'b01000;
|
||||
localparam S_WAIT_WRITE = 5'b10000;
|
||||
|
||||
assign sbbusy_o = 1'b0;
|
||||
reg[4:0] state_d, state_q;
|
||||
reg[2:0] sberror;
|
||||
reg[3:0] be_mask;
|
||||
reg[1:0] be_index;
|
||||
|
||||
assign master_req_o = 1'b0;
|
||||
assign master_we_o = 1'b0;
|
||||
reg master_req;
|
||||
reg master_we;
|
||||
reg[3:0] master_be;
|
||||
reg[31:0] master_addr;
|
||||
reg[31:0] master_wdata;
|
||||
reg[31:0] sbaddress;
|
||||
|
||||
wire[31:0] sbaddress_new;
|
||||
|
||||
assign sbaddress_new = sbaddress_i + (32'h1 << sbaccess_i);
|
||||
|
||||
assign sbbusy_o = (state_q != S_IDLE);
|
||||
|
||||
always @ (*) begin
|
||||
be_mask = 4'b0;
|
||||
be_index = sbaddress_i[1:0];
|
||||
|
||||
// generate byte enable mask
|
||||
case (sbaccess_i)
|
||||
3'b000: begin
|
||||
be_mask[be_index] = 1'b1;
|
||||
end
|
||||
|
||||
3'b001: begin
|
||||
if (be_index == 2'h0) begin
|
||||
be_mask[1:0] = 2'b11;
|
||||
end else if (be_index == 2'h2) begin
|
||||
be_mask[3:2] = 2'b11;
|
||||
end
|
||||
end
|
||||
|
||||
3'b010: begin
|
||||
be_mask = 4'b1111;
|
||||
end
|
||||
|
||||
default:;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (*) begin
|
||||
state_d = state_q;
|
||||
|
||||
sbaddress = sbaddress_i;
|
||||
|
||||
master_addr = sbaddress_i;
|
||||
master_wdata = sbdata_i;
|
||||
master_req = 1'b0;
|
||||
master_be = 4'b0;
|
||||
master_we = 1'b0;
|
||||
|
||||
sberror = 3'b0;
|
||||
|
||||
case (state_q)
|
||||
S_IDLE: begin
|
||||
// debugger requested a read
|
||||
if (sbaddress_write_valid_i && sbreadonaddr_i) begin
|
||||
state_d = S_READ;
|
||||
end
|
||||
// debugger requested a write
|
||||
if (sbdata_write_valid_i) begin
|
||||
state_d = S_WRITE;
|
||||
end
|
||||
// perform another read
|
||||
if (sbdata_read_valid_i && sbreadondata_i) begin
|
||||
state_d = S_READ;
|
||||
end
|
||||
end
|
||||
|
||||
S_READ: begin
|
||||
master_req = 1'b1;
|
||||
master_be = 4'b1111;
|
||||
if (master_gnt_i) begin
|
||||
state_d = S_WAIT_READ;
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT_READ: begin
|
||||
if (master_rvalid_i) begin
|
||||
state_d = S_IDLE;
|
||||
if (sbautoincrement_i) begin
|
||||
sbaddress = sbaddress_new;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_WRITE: begin
|
||||
master_req = 1'b1;
|
||||
master_be = be_mask;
|
||||
master_we = 1'b1;
|
||||
if (master_gnt_i) begin
|
||||
state_d = S_WAIT_WRITE;
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT_WRITE: begin
|
||||
if (master_rvalid_i) begin
|
||||
state_d = S_IDLE;
|
||||
if (sbautoincrement_i) begin
|
||||
sbaddress = sbaddress_new;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
default:;
|
||||
endcase
|
||||
|
||||
if ((sbaccess_i > 3'h2) & (state_q != S_IDLE)) begin
|
||||
master_req = 1'b0;
|
||||
state_d = S_IDLE;
|
||||
sberror = 3'h3;
|
||||
end
|
||||
end
|
||||
|
||||
assign master_req_o = master_req;
|
||||
assign master_we_o = master_we;
|
||||
assign master_be_o = master_be;
|
||||
assign master_addr_o = master_addr;
|
||||
assign master_wdata_o = master_wdata;
|
||||
|
||||
assign sbdata_valid_o = master_rvalid_i;
|
||||
assign sbdata_o = master_rdata_i;
|
||||
assign sberror_o = sberror;
|
||||
assign sbaddress_o = sbaddress;
|
||||
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
state_q <= S_IDLE;
|
||||
end else begin
|
||||
state_q <= state_d;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Reference in New Issue