PPA: Register instruction injection output from DM, to reduce routing impact on frontend prefetch queue
This commit is contained in:
		
							parent
							
								
									360b034f76
								
							
						
					
					
						commit
						78a5cb98ea
					
				| 
						 | 
				
			
			@ -62,8 +62,8 @@ module hazard3_dm #(
 | 
			
		|||
	input  wire [N_HARTS-1:0]        hart_data0_wen,
 | 
			
		||||
 | 
			
		||||
	// Hart instruction injection
 | 
			
		||||
	output wire [N_HARTS*XLEN-1:0]   hart_instr_data,
 | 
			
		||||
	output wire [N_HARTS-1:0]        hart_instr_data_vld,
 | 
			
		||||
	output wire [N_HARTS*32-1:0]     hart_instr_data,
 | 
			
		||||
	output reg  [N_HARTS-1:0]        hart_instr_data_vld,
 | 
			
		||||
	input  wire [N_HARTS-1:0]        hart_instr_data_rdy,
 | 
			
		||||
	input  wire [N_HARTS-1:0]        hart_instr_caught_exception,
 | 
			
		||||
	input  wire [N_HARTS-1:0]        hart_instr_caught_ebreak,
 | 
			
		||||
| 
						 | 
				
			
			@ -569,7 +569,9 @@ localparam CMDERR_EXCEPTION = 3'h3;
 | 
			
		|||
localparam CMDERR_HALTRESUME = 3'h4;
 | 
			
		||||
 | 
			
		||||
reg [2:0]         abstractcs_cmderr;
 | 
			
		||||
reg [2:0]         abstractcs_cmderr_nxt;
 | 
			
		||||
reg [W_STATE-1:0] acmd_state;
 | 
			
		||||
reg [W_STATE-1:0] acmd_state_nxt;
 | 
			
		||||
 | 
			
		||||
assign abstractcs_busy = acmd_state != S_IDLE;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -621,19 +623,16 @@ always @ (posedge clk or negedge 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
 | 
			
		||||
| 
						 | 
				
			
			@ -641,9 +640,87 @@ 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 @ (*) begin
 | 
			
		||||
	// Default: no state change
 | 
			
		||||
	acmd_state_nxt = acmd_state;
 | 
			
		||||
	abstractcs_cmderr_nxt = abstractcs_cmderr;
 | 
			
		||||
 | 
			
		||||
	if (dmi_write && dmi_regaddr == ADDR_ABSTRACTCS && !abstractcs_busy)
 | 
			
		||||
		abstractcs_cmderr_nxt = abstractcs_cmderr & ~dmi_pwdata[10:8];
 | 
			
		||||
	if (abstractcs_cmderr == CMDERR_OK && abstractcs_busy && dmi_access_illegal_when_busy)
 | 
			
		||||
		abstractcs_cmderr_nxt = CMDERR_BUSY;
 | 
			
		||||
	if (acmd_state != S_IDLE && hart_instr_caught_exception[hartsel])
 | 
			
		||||
		abstractcs_cmderr_nxt = CMDERR_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
	case (acmd_state)
 | 
			
		||||
		S_IDLE: begin
 | 
			
		||||
			if (start_abstract_cmd) begin
 | 
			
		||||
				if (!hart_halted[hartsel] || !hart_available[hartsel]) begin
 | 
			
		||||
					abstractcs_cmderr_nxt = CMDERR_HALTRESUME;
 | 
			
		||||
				end else if (acmd_unsupported) begin
 | 
			
		||||
					abstractcs_cmderr_nxt = CMDERR_UNSUPPORTED;
 | 
			
		||||
				end else begin
 | 
			
		||||
					if (acmd_transfer && acmd_write)
 | 
			
		||||
						acmd_state_nxt = S_ISSUE_REGWRITE;
 | 
			
		||||
					else if (acmd_transfer && !acmd_write)
 | 
			
		||||
						acmd_state_nxt = S_ISSUE_REGREAD;
 | 
			
		||||
					else if (acmd_postexec)
 | 
			
		||||
						acmd_state_nxt = S_ISSUE_PROGBUF0;
 | 
			
		||||
					else
 | 
			
		||||
						acmd_state_nxt = S_IDLE;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		S_ISSUE_REGREAD: begin
 | 
			
		||||
			if (hart_instr_data_rdy[hartsel])
 | 
			
		||||
				acmd_state_nxt = S_ISSUE_REGEBREAK;
 | 
			
		||||
		end
 | 
			
		||||
		S_ISSUE_REGWRITE: begin
 | 
			
		||||
			if (hart_instr_data_rdy[hartsel])
 | 
			
		||||
				acmd_state_nxt = S_ISSUE_REGEBREAK;
 | 
			
		||||
		end
 | 
			
		||||
		S_ISSUE_REGEBREAK: begin
 | 
			
		||||
			if (hart_instr_data_rdy[hartsel])
 | 
			
		||||
				acmd_state_nxt = S_WAIT_REGEBREAK;
 | 
			
		||||
		end
 | 
			
		||||
		S_WAIT_REGEBREAK: begin
 | 
			
		||||
			if (hart_instr_caught_ebreak[hartsel]) begin
 | 
			
		||||
				if (acmd_prev_postexec)
 | 
			
		||||
					acmd_state_nxt = S_ISSUE_PROGBUF0;
 | 
			
		||||
				else
 | 
			
		||||
					acmd_state_nxt = S_IDLE;
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		S_ISSUE_PROGBUF0: begin
 | 
			
		||||
			if (hart_instr_data_rdy[hartsel])
 | 
			
		||||
				acmd_state_nxt = S_ISSUE_PROGBUF1;
 | 
			
		||||
		end
 | 
			
		||||
		S_ISSUE_PROGBUF1: begin
 | 
			
		||||
			if (hart_instr_caught_exception[hartsel] || hart_instr_caught_ebreak[hartsel]) begin
 | 
			
		||||
				acmd_state_nxt = S_IDLE;
 | 
			
		||||
			end else if (hart_instr_data_rdy[hartsel]) begin
 | 
			
		||||
				acmd_state_nxt = S_ISSUE_IMPEBREAK;
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		S_ISSUE_IMPEBREAK: begin
 | 
			
		||||
			if (hart_instr_caught_exception[hartsel] || hart_instr_caught_ebreak[hartsel]) begin
 | 
			
		||||
				acmd_state_nxt = S_IDLE;
 | 
			
		||||
			end else if (hart_instr_data_rdy[hartsel]) begin
 | 
			
		||||
				acmd_state_nxt = S_WAIT_IMPEBREAK;
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		S_WAIT_IMPEBREAK: begin
 | 
			
		||||
			if (hart_instr_caught_exception[hartsel] || hart_instr_caught_ebreak[hartsel]) begin
 | 
			
		||||
				acmd_state_nxt = S_IDLE;
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	endcase
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always @ (posedge clk or negedge rst_n) begin
 | 
			
		||||
	if (!rst_n) begin
 | 
			
		||||
		abstractcs_cmderr <= CMDERR_OK;
 | 
			
		||||
| 
						 | 
				
			
			@ -652,92 +729,37 @@ always @ (posedge clk or negedge rst_n) begin
 | 
			
		|||
		abstractcs_cmderr <= CMDERR_OK;
 | 
			
		||||
		acmd_state <= S_IDLE;
 | 
			
		||||
	end else begin
 | 
			
		||||
		if (dmi_write && dmi_regaddr == ADDR_ABSTRACTCS && !abstractcs_busy)
 | 
			
		||||
			abstractcs_cmderr <= abstractcs_cmderr & ~dmi_pwdata[10:8];
 | 
			
		||||
		if (abstractcs_cmderr == CMDERR_OK && abstractcs_busy && dmi_access_illegal_when_busy)
 | 
			
		||||
			abstractcs_cmderr <= CMDERR_BUSY;
 | 
			
		||||
		if (acmd_state != S_IDLE && hart_instr_caught_exception[hartsel])
 | 
			
		||||
			abstractcs_cmderr <= CMDERR_EXCEPTION;
 | 
			
		||||
		case (acmd_state)
 | 
			
		||||
			S_IDLE: begin
 | 
			
		||||
				if (start_abstract_cmd) begin
 | 
			
		||||
					if (!hart_halted[hartsel] || !hart_available[hartsel]) begin
 | 
			
		||||
						abstractcs_cmderr <= CMDERR_HALTRESUME;
 | 
			
		||||
					end else if (acmd_unsupported) begin
 | 
			
		||||
						abstractcs_cmderr <= CMDERR_UNSUPPORTED;
 | 
			
		||||
					end else begin
 | 
			
		||||
						if (acmd_transfer && acmd_write)
 | 
			
		||||
							acmd_state <= S_ISSUE_REGWRITE;
 | 
			
		||||
						else if (acmd_transfer && !acmd_write)
 | 
			
		||||
							acmd_state <= S_ISSUE_REGREAD;
 | 
			
		||||
						else if (acmd_postexec)
 | 
			
		||||
							acmd_state <= S_ISSUE_PROGBUF0;
 | 
			
		||||
						else
 | 
			
		||||
							acmd_state <= S_IDLE;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			S_ISSUE_REGREAD: begin
 | 
			
		||||
				if (hart_instr_data_rdy[hartsel])
 | 
			
		||||
					acmd_state <= S_ISSUE_REGEBREAK;
 | 
			
		||||
			end
 | 
			
		||||
			S_ISSUE_REGWRITE: begin
 | 
			
		||||
				if (hart_instr_data_rdy[hartsel])
 | 
			
		||||
					acmd_state <= S_ISSUE_REGEBREAK;
 | 
			
		||||
			end
 | 
			
		||||
			S_ISSUE_REGEBREAK: begin
 | 
			
		||||
				if (hart_instr_data_rdy[hartsel])
 | 
			
		||||
					acmd_state <= S_WAIT_REGEBREAK;
 | 
			
		||||
			end
 | 
			
		||||
			S_WAIT_REGEBREAK: begin
 | 
			
		||||
				if (hart_instr_caught_ebreak[hartsel]) begin
 | 
			
		||||
					if (acmd_prev_postexec)
 | 
			
		||||
						acmd_state <= S_ISSUE_PROGBUF0;
 | 
			
		||||
					else
 | 
			
		||||
						acmd_state <= S_IDLE;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			S_ISSUE_PROGBUF0: begin
 | 
			
		||||
				if (hart_instr_data_rdy[hartsel])
 | 
			
		||||
					acmd_state <= S_ISSUE_PROGBUF1;
 | 
			
		||||
			end
 | 
			
		||||
			S_ISSUE_PROGBUF1: begin
 | 
			
		||||
				if (hart_instr_caught_exception[hartsel] || hart_instr_caught_ebreak[hartsel]) begin
 | 
			
		||||
					acmd_state <= S_IDLE;
 | 
			
		||||
				end else if (hart_instr_data_rdy[hartsel]) begin
 | 
			
		||||
					acmd_state <= S_ISSUE_IMPEBREAK;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			S_ISSUE_IMPEBREAK: begin
 | 
			
		||||
				if (hart_instr_caught_exception[hartsel] || hart_instr_caught_ebreak[hartsel]) begin
 | 
			
		||||
					acmd_state <= S_IDLE;
 | 
			
		||||
				end else if (hart_instr_data_rdy[hartsel]) begin
 | 
			
		||||
					acmd_state <= S_WAIT_IMPEBREAK;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			S_WAIT_IMPEBREAK: begin
 | 
			
		||||
				if (hart_instr_caught_exception[hartsel] || hart_instr_caught_ebreak[hartsel]) begin
 | 
			
		||||
					acmd_state <= S_IDLE;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		endcase
 | 
			
		||||
		abstractcs_cmderr <= abstractcs_cmderr_nxt;
 | 
			
		||||
		acmd_state <= acmd_state_nxt;
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
assign hart_instr_data_vld = {{N_HARTS{1'b0}},
 | 
			
		||||
	acmd_state == S_ISSUE_REGREAD || acmd_state == S_ISSUE_REGWRITE || acmd_state == S_ISSUE_REGEBREAK ||
 | 
			
		||||
	acmd_state == S_ISSUE_PROGBUF0 || acmd_state == S_ISSUE_PROGBUF1 || acmd_state == S_ISSUE_IMPEBREAK
 | 
			
		||||
wire hart_instr_data_vld_nxt = {{N_HARTS{1'b0}},
 | 
			
		||||
	acmd_state_nxt == S_ISSUE_REGREAD || acmd_state_nxt == S_ISSUE_REGWRITE || acmd_state_nxt == S_ISSUE_REGEBREAK ||
 | 
			
		||||
	acmd_state_nxt == S_ISSUE_PROGBUF0 || acmd_state_nxt == S_ISSUE_PROGBUF1 || acmd_state_nxt == S_ISSUE_IMPEBREAK
 | 
			
		||||
} << hartsel;
 | 
			
		||||
 | 
			
		||||
assign hart_instr_data = {N_HARTS{
 | 
			
		||||
	acmd_state == S_ISSUE_REGWRITE  ? 32'hbff02073 | {20'd0, acmd_prev_regno,  7'd0} : // csrr xx, dmdata0
 | 
			
		||||
	acmd_state == S_ISSUE_REGREAD   ? 32'hbff01073 | {12'd0, acmd_prev_regno, 15'd0} : // csrw dmdata0, xx
 | 
			
		||||
	acmd_state == S_ISSUE_PROGBUF0  ? progbuf0                                       :
 | 
			
		||||
	acmd_state == S_ISSUE_PROGBUF1  ? progbuf1                                       :
 | 
			
		||||
	                                  32'h00100073                                     // ebreak
 | 
			
		||||
}};
 | 
			
		||||
wire [31:0] hart_instr_data_nxt =
 | 
			
		||||
	acmd_state_nxt == S_ISSUE_REGWRITE  ? 32'hbff02073 | {20'd0, acmd_new_regno,  7'd0} : // csrr xx, dmdata0
 | 
			
		||||
	acmd_state_nxt == S_ISSUE_REGREAD   ? 32'hbff01073 | {12'd0, acmd_new_regno, 15'd0} : // csrw dmdata0, xx
 | 
			
		||||
	acmd_state_nxt == S_ISSUE_PROGBUF0  ? progbuf0                                      :
 | 
			
		||||
	acmd_state_nxt == S_ISSUE_PROGBUF1  ? progbuf1                                      :
 | 
			
		||||
	                                      32'h00100073;                                   // ebreak
 | 
			
		||||
 | 
			
		||||
reg [31:0] hart_instr_data_reg;
 | 
			
		||||
assign hart_instr_data = {N_HARTS{hart_instr_data_reg}};
 | 
			
		||||
 | 
			
		||||
always @ (posedge clk or negedge rst_n) begin
 | 
			
		||||
	if (!rst_n) begin
 | 
			
		||||
		hart_instr_data_vld <= 1'b0;
 | 
			
		||||
		hart_instr_data_reg <= 32'h00000000;
 | 
			
		||||
	end else begin
 | 
			
		||||
		hart_instr_data_vld <= hart_instr_data_vld_nxt;
 | 
			
		||||
		if (hart_instr_data_vld_nxt) begin
 | 
			
		||||
			hart_instr_data_reg <= hart_instr_data_nxt;
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
// Status helper functions
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue