DM: add missing w1c to abstract cmderr, add capture of last abstract command for use with abstractauto
This commit is contained in:
parent
42632e325a
commit
4b650ac437
|
@ -264,7 +264,7 @@ always @ (posedge clk or negedge rst_n) begin
|
||||||
end else if (!dmactive) begin
|
end else if (!dmactive) begin
|
||||||
abstractauto_autoexecdata <= 1'b0;
|
abstractauto_autoexecdata <= 1'b0;
|
||||||
end else if (dmi_write && dmi_paddr == ADDR_ABSTRACTAUTO) begin
|
end else if (dmi_write && dmi_paddr == ADDR_ABSTRACTAUTO) begin
|
||||||
abstractauto_autoexecdata <= dmi_pwdata[1];
|
abstractauto_autoexecdata <= dmi_pwdata[0];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -307,31 +307,71 @@ wire dmi_access_illegal_when_busy =
|
||||||
(dmi_read && (
|
(dmi_read && (
|
||||||
dmi_paddr == ADDR_DATA0 || dmi_paddr == ADDR_PROGBUF0 || dmi_paddr == ADDR_PROGBUF0));
|
dmi_paddr == ADDR_DATA0 || dmi_paddr == ADDR_PROGBUF0 || dmi_paddr == ADDR_PROGBUF0));
|
||||||
|
|
||||||
wire acmd_unsupported =
|
// Decode what acmd may be triggered on this cycle, and whether it is
|
||||||
|
// supported -- command source may be a registered version of most recent
|
||||||
|
// command (if abstractauto is used) or a fresh command off the bus. We don't
|
||||||
|
// register the entire write data; repeats of unsupported commands are
|
||||||
|
// detected by just registering that the last written command was
|
||||||
|
// unsupported.
|
||||||
|
|
||||||
|
wire acmd_new = dmi_write && dmi_paddr == ADDR_COMMAND;
|
||||||
|
|
||||||
|
wire acmd_new_postexec = dmi_pwdata[18];
|
||||||
|
wire acmd_new_transfer = dmi_pwdata[17];
|
||||||
|
wire acmd_new_write = dmi_pwdata[16];
|
||||||
|
wire [4:0] acmd_new_regno = dmi_pwdata[4:0];
|
||||||
|
|
||||||
|
wire acmd_new_unsupported =
|
||||||
dmi_pwdata[31:24] != 8'h00 || // Only Access Register command supported
|
dmi_pwdata[31:24] != 8'h00 || // Only Access Register command supported
|
||||||
dmi_pwdata[22:20] != 3'h2 || // Must be 32 bits in size
|
dmi_pwdata[22:20] != 3'h2 || // Must be 32 bits in size
|
||||||
dmi_pwdata[19] || // aarpostincrement not supported
|
dmi_pwdata[19] || // aarpostincrement not supported
|
||||||
dmi_pwdata[15:12] != 4'h1 || // Only core register access supported
|
dmi_pwdata[15:12] != 4'h1 || // Only core register access supported
|
||||||
dmi_pwdata[11:5] != 7'h0; // Only GPRs supported
|
dmi_pwdata[11:5] != 7'h0; // Only GPRs supported
|
||||||
|
|
||||||
wire acmd_postexec = dmi_pwdata[18];
|
reg acmd_prev_postexec;
|
||||||
wire acmd_transfer = dmi_pwdata[17];
|
reg acmd_prev_transfer;
|
||||||
wire acmd_write = dmi_pwdata[16];
|
reg acmd_prev_write;
|
||||||
wire [4:0] acmd_regno = dmi_pwdata[4:0];
|
reg [4:0] acmd_prev_regno;
|
||||||
|
reg acmd_prev_unsupported;
|
||||||
|
|
||||||
reg acmd_postexec_r;
|
always @ (posedge clk or negedge rst_n) begin
|
||||||
reg [4:0] acmd_regno_r;
|
if (!rst_n) begin
|
||||||
|
acmd_prev_postexec <= 1'b0;
|
||||||
|
acmd_prev_transfer <= 1'b0;
|
||||||
|
acmd_prev_write <= 1'b0;
|
||||||
|
acmd_prev_regno <= 5'h0;
|
||||||
|
acmd_prev_unsupported <= 1'b1;
|
||||||
|
end else if (!dmactive) begin
|
||||||
|
acmd_prev_postexec <= 1'b0;
|
||||||
|
acmd_prev_transfer <= 1'b0;
|
||||||
|
acmd_prev_write <= 1'b0;
|
||||||
|
acmd_prev_regno <= 5'h0;
|
||||||
|
acmd_prev_unsupported <= 1'b1;
|
||||||
|
end else if (start_abstract_cmd && acmd_new) begin
|
||||||
|
acmd_prev_postexec <= acmd_new_postexec;
|
||||||
|
acmd_prev_transfer <= acmd_new_transfer;
|
||||||
|
acmd_prev_write <= acmd_new_write;
|
||||||
|
acmd_prev_regno <= acmd_new_regno;
|
||||||
|
acmd_prev_unsupported <= acmd_new_unsupported;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire acmd_postexec = acmd_new ? acmd_new_postexec : acmd_prev_postexec ;
|
||||||
|
wire acmd_transfer = acmd_new ? acmd_new_transfer : acmd_prev_transfer ;
|
||||||
|
wire acmd_write = acmd_new ? acmd_new_write : acmd_prev_write ;
|
||||||
|
wire [4:0] acmd_regno = acmd_new ? acmd_new_regno : acmd_prev_regno ;
|
||||||
|
wire acmd_unsupported = acmd_new ? acmd_new_unsupported : acmd_prev_unsupported;
|
||||||
|
|
||||||
always @ (posedge clk or negedge rst_n) begin
|
always @ (posedge clk or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
abstractcs_cmderr <= CMDERR_OK;
|
abstractcs_cmderr <= CMDERR_OK;
|
||||||
acmd_state <= S_IDLE;
|
acmd_state <= S_IDLE;
|
||||||
acmd_postexec_r <= 1'b0;
|
|
||||||
acmd_regno_r <= 5'h0;
|
|
||||||
end else if (!dmactive) begin
|
end else if (!dmactive) begin
|
||||||
abstractcs_cmderr <= CMDERR_OK;
|
abstractcs_cmderr <= CMDERR_OK;
|
||||||
acmd_state <= S_IDLE;
|
acmd_state <= S_IDLE;
|
||||||
end else begin
|
end else begin
|
||||||
|
if (dmi_write && dmi_paddr == ADDR_ABSTRACTCS && !abstractcs_busy)
|
||||||
|
abstractcs_cmderr <= abstractcs_cmderr & ~dmi_pwdata[10:8];
|
||||||
if (abstractcs_cmderr == CMDERR_OK && abstractcs_busy && dmi_access_illegal_when_busy)
|
if (abstractcs_cmderr == CMDERR_OK && abstractcs_busy && dmi_access_illegal_when_busy)
|
||||||
abstractcs_cmderr <= CMDERR_BUSY;
|
abstractcs_cmderr <= CMDERR_BUSY;
|
||||||
if (acmd_state != S_IDLE && hart_instr_caught_exception)
|
if (acmd_state != S_IDLE && hart_instr_caught_exception)
|
||||||
|
@ -344,8 +384,6 @@ always @ (posedge clk or negedge rst_n) begin
|
||||||
end else if (acmd_unsupported) begin
|
end else if (acmd_unsupported) begin
|
||||||
abstractcs_cmderr <= CMDERR_UNSUPPORTED;
|
abstractcs_cmderr <= CMDERR_UNSUPPORTED;
|
||||||
end else begin
|
end else begin
|
||||||
acmd_postexec_r <= acmd_postexec;
|
|
||||||
acmd_regno_r <= acmd_regno;
|
|
||||||
if (acmd_transfer && acmd_write)
|
if (acmd_transfer && acmd_write)
|
||||||
acmd_state <= S_ISSUE_REGWRITE;
|
acmd_state <= S_ISSUE_REGWRITE;
|
||||||
else if (acmd_transfer && !acmd_write)
|
else if (acmd_transfer && !acmd_write)
|
||||||
|
@ -372,7 +410,7 @@ always @ (posedge clk or negedge rst_n) begin
|
||||||
end
|
end
|
||||||
S_WAIT_REGEBREAK: begin
|
S_WAIT_REGEBREAK: begin
|
||||||
if (hart_instr_caught_ebreak) begin
|
if (hart_instr_caught_ebreak) begin
|
||||||
if (acmd_postexec_r)
|
if (acmd_prev_postexec)
|
||||||
acmd_state <= S_ISSUE_PROGBUF0;
|
acmd_state <= S_ISSUE_PROGBUF0;
|
||||||
else
|
else
|
||||||
acmd_state <= S_IDLE;
|
acmd_state <= S_IDLE;
|
||||||
|
@ -412,8 +450,8 @@ assign hart_instr_data_vld = {{N_HARTS{1'b0}},
|
||||||
} << hartsel;
|
} << hartsel;
|
||||||
|
|
||||||
assign hart_instr_data = {N_HARTS{
|
assign hart_instr_data = {N_HARTS{
|
||||||
acmd_state == S_ISSUE_REGWRITE ? 32'h7b202073 | {20'd0, acmd_regno_r, 7'd0} : // csrr xx, data0
|
acmd_state == S_ISSUE_REGWRITE ? 32'h7b202073 | {20'd0, acmd_prev_regno, 7'd0} : // csrr xx, data0
|
||||||
acmd_state == S_ISSUE_REGREAD ? 32'h7b201073 | {12'd0, acmd_regno_r, 15'd0} : // csrw data0, xx
|
acmd_state == S_ISSUE_REGREAD ? 32'h7b201073 | {12'd0, acmd_prev_regno, 15'd0} : // csrw data0, xx
|
||||||
acmd_state == S_ISSUE_PROGBUF0 ? progbuf0 :
|
acmd_state == S_ISSUE_PROGBUF0 ? progbuf0 :
|
||||||
acmd_state == S_ISSUE_PROGBUF1 ? progbuf1 :
|
acmd_state == S_ISSUE_PROGBUF1 ? progbuf1 :
|
||||||
32'h00100073 // ebreak
|
32'h00100073 // ebreak
|
||||||
|
|
Loading…
Reference in New Issue