basic illegal instruction support

This commit is contained in:
Eric Matthews 2020-05-07 16:41:35 -07:00
parent ccfc93de2e
commit 59554ff15e
4 changed files with 191 additions and 23 deletions

View file

@ -182,7 +182,7 @@ module decode_and_issue (
////////////////////////////////////////////////////
//Issue Determination
assign issue_valid = fb_valid & ti.id_available & ~gc_issue_hold & ~gc_fetch_flush;
assign issue_valid = fb_valid & ti.id_available & ~gc_issue_hold & ~gc_fetch_flush & ~illegal_instruction_pattern;
assign operands_ready = ~rf_issue.rs1_conflict & ~rf_issue.rs2_conflict;
@ -375,21 +375,17 @@ module decode_and_issue (
endgenerate
////////////////////////////////////////////////////
//Illegal Opcode check
always_comb begin
illegal_instruction = !(opcode inside {LUI, AUIPC, JAL, JALR, BRANCH, LOAD, STORE, ARITH, ARITH_IMM, FENCE, AMO, SYSTEM});
if (opcode == ARITH) begin
if (!USE_MUL && !USE_DIV)
illegal_instruction = fb.instruction[25];
else if (!USE_MUL && USE_DIV)
illegal_instruction = fb.instruction[25] & ~fn3[2];
else if (!USE_MUL && !USE_DIV)
illegal_instruction = fb.instruction[25] & fn3[2];
else
illegal_instruction = 0;
end
end
//Illegal Instruction check
generate if (ENABLE_M_MODE) begin
logic illegal_instruction_pattern;
illegal_instruction_checker illegal_op_check (
.instruction(fb.instruction), .illegal_instruction(illegal_instruction_pattern)
);
//Illegal instruction if the instruction is invalid, but could otherwise be issued
assign illegal_instruction = illegal_instruction_pattern & fb_valid & ti.id_available & ~gc_issue_hold & ~gc_fetch_flush;
end endgenerate
////////////////////////////////////////////////////
//End of Implementation
////////////////////////////////////////////////////

View file

@ -40,7 +40,9 @@ module gc_unit(
//instruction misalignement
input logic potential_branch_exception,
input exception_packet_t br_exception,
input branch_exception_is_jump,
input logic branch_exception_is_jump,
//Illegal instruction
input logic illegal_instruction,
//Load Store Unit
input exception_packet_t ls_exception,
@ -267,21 +269,29 @@ module gc_unit(
assign ls_exception_ack = processing_ls_exception && (prev_state inside {IDLE_STATE, IQ_DRAIN}) && (state == IQ_DISCARD);
assign exception_id = potential_branch_exception ? br_exception.id : ls_exception.id;
assign exception_id =
potential_branch_exception ? br_exception.id :
(ls_exception.valid ? ls_exception.id : issue.instruction_id);
always_ff @(posedge clk) begin
if (gc_exception.valid)
exception_id_r <= exception_id;
end
//TODO: check if possible to convert to unique if, verify potential for overlap
always_comb begin
if (ls_exception.valid) begin
gc_exception.code = ls_exception.code;
gc_exception.pc = ls_exception.pc;
gc_exception.tval = ls_exception.tval;
end else if (br_exception.valid) begin
if (br_exception.valid) begin
gc_exception.code = br_exception.code;
gc_exception.pc = br_exception.pc;
gc_exception.tval = br_exception.tval;
end else if (illegal_instruction) begin
gc_exception.code = ILLEGAL_INST;
gc_exception.pc = gc_inputs.pc;
gc_exception.tval = gc_inputs.instruction;//optional, can be zero instead
end else if (ls_exception.valid) begin
gc_exception.code = ls_exception.code;
gc_exception.pc = ls_exception.pc;
gc_exception.tval = ls_exception.tval;
end else if (gc_inputs.is_ecall) begin
gc_exception.code = ecall_code;
gc_exception.pc = gc_inputs.pc;
@ -294,7 +304,7 @@ module gc_unit(
end
logic ecall_break_exception;
assign ecall_break_exception = issue.new_request & (gc_inputs.is_ecall | gc_inputs.is_ebreak);
assign gc_exception.valid = ENABLE_M_MODE & (ecall_break_exception | ls_exception.valid | br_exception.valid);
assign gc_exception.valid = ENABLE_M_MODE & (ecall_break_exception | ls_exception.valid | br_exception.valid | illegal_instruction);
//PC determination (trap, flush or return)
//Two cycles: on first cycle the processor front end is flushed,

View file

@ -0,0 +1,161 @@
/*
* Copyright © 2020 Eric Matthews, Lesley Shannon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Initial code developed under the supervision of Dr. Lesley Shannon,
* Reconfigurable Computing Lab, Simon Fraser University.
*
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
module illegal_instruction_checker
import taiga_config::*;
(
input logic [31:0] instruction,
output logic illegal_instruction
);
////////////////////////////////////////////////////
//Instruction Patterns for Illegal Instruction Checking
//Base ISA
localparam [31:0] BEQ = 32'b?????????????????000?????1100011;
localparam [31:0] BNE = 32'b?????????????????001?????1100011;
localparam [31:0] BLT = 32'b?????????????????100?????1100011;
localparam [31:0] BGE = 32'b?????????????????101?????1100011;
localparam [31:0] BLTU = 32'b?????????????????110?????1100011;
localparam [31:0] BGEU = 32'b?????????????????111?????1100011;
localparam [31:0] JALR = 32'b?????????????????000?????1100111;
localparam [31:0] JAL = 32'b?????????????????????????1101111;
localparam [31:0] LUI = 32'b?????????????????????????0110111;
localparam [31:0] AUIPC = 32'b?????????????????????????0010111;
localparam [31:0] ADDI = 32'b?????????????????000?????0010011;
localparam [31:0] SLLI = 32'b000000???????????001?????0010011;
localparam [31:0] SLTI = 32'b?????????????????010?????0010011;
localparam [31:0] SLTIU = 32'b?????????????????011?????0010011;
localparam [31:0] XORI = 32'b?????????????????100?????0010011;
localparam [31:0] SRLI = 32'b000000???????????101?????0010011;
localparam [31:0] SRAI = 32'b010000???????????101?????0010011;
localparam [31:0] ORI = 32'b?????????????????110?????0010011;
localparam [31:0] ANDI = 32'b?????????????????111?????0010011;
localparam [31:0] ADD = 32'b0000000??????????000?????0110011;
localparam [31:0] SUB = 32'b0100000??????????000?????0110011;
localparam [31:0] SLL = 32'b0000000??????????001?????0110011;
localparam [31:0] SLT = 32'b0000000??????????010?????0110011;
localparam [31:0] SLTU = 32'b0000000??????????011?????0110011;
localparam [31:0] XOR = 32'b0000000??????????100?????0110011;
localparam [31:0] SRL = 32'b0000000??????????101?????0110011;
localparam [31:0] SRA = 32'b0100000??????????101?????0110011;
localparam [31:0] OR = 32'b0000000??????????110?????0110011;
localparam [31:0] AND = 32'b0000000??????????111?????0110011;
localparam [31:0] LB = 32'b?????????????????000?????0000011;
localparam [31:0] LH = 32'b?????????????????001?????0000011;
localparam [31:0] LW = 32'b?????????????????010?????0000011;
localparam [31:0] LBU = 32'b?????????????????100?????0000011;
localparam [31:0] LHU = 32'b?????????????????101?????0000011;
localparam [31:0] SB = 32'b?????????????????000?????0100011;
localparam [31:0] SH = 32'b?????????????????001?????0100011;
localparam [31:0] SW = 32'b?????????????????010?????0100011;
localparam [31:0] FENCE = 32'b?????????????????000?????0001111;
localparam [31:0] FENCE_I = 32'b?????????????????001?????0001111;
localparam [31:0] ECALL = 32'b00000000000000000000000001110011;
localparam [31:0] EBREAK = 32'b00000000000100000000000001110011;
localparam [31:0] CSRRW = 32'b?????????????????001?????1110011;
localparam [31:0] CSRRS = 32'b?????????????????010?????1110011;
localparam [31:0] CSRRC = 32'b?????????????????011?????1110011;
localparam [31:0] CSRRWI = 32'b?????????????????101?????1110011;
localparam [31:0] CSRRSI = 32'b?????????????????110?????1110011;
localparam [31:0] CSRRCI = 32'b?????????????????111?????1110011;
//Mul
localparam [31:0] MUL = 32'b0000001??????????000?????0110011;
localparam [31:0] MULH = 32'b0000001??????????001?????0110011;
localparam [31:0] MULHSU = 32'b0000001??????????010?????0110011;
localparam [31:0] MULHU = 32'b0000001??????????011?????0110011;
//Div
localparam [31:0] DIV = 32'b0000001??????????100?????0110011;
localparam [31:0] DIVU = 32'b0000001??????????101?????0110011;
localparam [31:0] REM = 32'b0000001??????????110?????0110011;
localparam [31:0] REMU = 32'b0000001??????????111?????0110011;
//AMO
localparam [31:0] AMO_ADD = 32'b00000????????????010?????0101111;
localparam [31:0] AMO_XOR = 32'b00100????????????010?????0101111;
localparam [31:0] AMO_OR = 32'b01000????????????010?????0101111;
localparam [31:0] AMO_AND = 32'b01100????????????010?????0101111;
localparam [31:0] AMO_MIN = 32'b10000????????????010?????0101111;
localparam [31:0] AMO_MAX = 32'b10100????????????010?????0101111;
localparam [31:0] AMO_MINU = 32'b11000????????????010?????0101111;
localparam [31:0] AMO_MAXU = 32'b11100????????????010?????0101111;
localparam [31:0] AMO_SWAP = 32'b00001????????????010?????0101111;
localparam [31:0] LR = 32'b00010??00000?????010?????0101111;
localparam [31:0] SC = 32'b00011????????????010?????0101111;
//Machine/Supervisor
localparam [31:0] SRET = 32'b00010000001000000000000001110011;
localparam [31:0] MRET = 32'b00110000001000000000000001110011;
localparam [31:0] SFENCE_VMA = 32'b0001001??????????000000001110011;
localparam [31:0] WFI = 32'b00010000010100000000000001110011;
logic base_legal;
logic mul_legal;
logic div_legal;
logic amo_legal;
logic machine_legal;
logic supervisor_legal;
////////////////////////////////////////////////////
//Implementation
assign base_legal = instruction inside {
BEQ, BNE, BLT, BGE, BLTU, BGEU, JALR, JAL, LUI, AUIPC,
ADDI, SLLI, SLTI, SLTIU, XORI, SRLI, SRAI, ORI, ANDI,
ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND,
LB, LH, LW, LBU, LHU, SB, SH, SW,
FENCE, FENCE_I,
CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI
};
assign mul_legal = instruction inside {
MUL, MULH, MULHSU, MULHU
};
assign div_legal = instruction inside {
DIV, DIVU, REM, REMU
};
assign amo_legal = instruction inside {
AMO_ADD, AMO_XOR, AMO_OR, AMO_AND, AMO_MIN, AMO_MAX, AMO_MINU, AMO_MAXU, AMO_SWAP,
LR, SC
};
assign machine_legal = instruction inside {
MRET, ECALL, EBREAK
};
assign supervisor_legal = instruction inside {
SRET, SFENCE_VMA, WFI
};
assign illegal_instruction = ~(
base_legal |
(USE_MUL & mul_legal) |
(USE_DIV & div_legal) |
(USE_AMO & amo_legal) |
(ENABLE_M_MODE & machine_legal) |
(ENABLE_S_MODE & supervisor_legal)
);
endmodule

View file

@ -95,6 +95,7 @@
../core/branch_predictor.sv
../core/fetch.sv
../core/pre_decode.sv
../core/illegal_instruction_checker.sv
../core/decode_and_issue.sv
../core/id_inuse.sv