mirror of
https://github.com/lowRISC/ibex.git
synced 2025-06-27 17:00:41 -04:00
This change has been informed by advice from the lowRISC legal committee. The Solderpad 0.51 license states "the Licensor permits any Work licensed under this License, at the option of the Licensee, to be treated as licensed under the Apache License Version 2.0". We use this freedom to convert license markings to Apache 2.0. This commit ensures that we retain all authorship and copyright attribution information.
103 lines
3.1 KiB
Systemverilog
103 lines
3.1 KiB
Systemverilog
// Copyright lowRISC contributors.
|
|
// Copyright 2018 ETH Zurich and University of Bologna.
|
|
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Engineer: Davide Schiavone - pschiavo@iis.ee.ethz.ch //
|
|
// //
|
|
// Additional contributions by: //
|
|
// //
|
|
// Design Name: Interrupt Controller //
|
|
// Project Name: ibex //
|
|
// Language: SystemVerilog //
|
|
// //
|
|
// Description: Interrupt Controller of the pipelined processor //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
import ibex_defines::*;
|
|
|
|
module ibex_int_controller
|
|
(
|
|
input logic clk,
|
|
input logic rst_n,
|
|
|
|
// irq_req for controller
|
|
output logic irq_req_ctrl_o,
|
|
output logic [4:0] irq_id_ctrl_o,
|
|
|
|
// handshake signals to controller
|
|
input logic ctrl_ack_i,
|
|
input logic ctrl_kill_i,
|
|
|
|
// external interrupt lines
|
|
input logic irq_i, // level-triggered interrupt inputs
|
|
input logic [4:0] irq_id_i, // interrupt id [0,1,....31]
|
|
|
|
input logic m_IE_i // interrupt enable bit from CSR (M mode)
|
|
);
|
|
|
|
enum logic [1:0] { IDLE, IRQ_PENDING, IRQ_DONE} exc_ctrl_cs;
|
|
|
|
logic irq_enable_ext;
|
|
logic [4:0] irq_id_q;
|
|
|
|
assign irq_enable_ext = m_IE_i;
|
|
assign irq_req_ctrl_o = exc_ctrl_cs == IRQ_PENDING;
|
|
assign irq_id_ctrl_o = irq_id_q;
|
|
|
|
always_ff @(posedge clk, negedge rst_n)
|
|
begin
|
|
if (rst_n == 1'b0) begin
|
|
|
|
irq_id_q <= '0;
|
|
exc_ctrl_cs <= IDLE;
|
|
|
|
end else begin
|
|
|
|
unique case (exc_ctrl_cs)
|
|
|
|
IDLE:
|
|
begin
|
|
if(irq_enable_ext & irq_i) begin
|
|
exc_ctrl_cs <= IRQ_PENDING;
|
|
irq_id_q <= irq_id_i;
|
|
end
|
|
end
|
|
|
|
IRQ_PENDING:
|
|
begin
|
|
unique case(1'b1)
|
|
ctrl_ack_i:
|
|
exc_ctrl_cs <= IRQ_DONE;
|
|
ctrl_kill_i:
|
|
exc_ctrl_cs <= IDLE;
|
|
default:
|
|
exc_ctrl_cs <= IRQ_PENDING;
|
|
endcase
|
|
end
|
|
|
|
IRQ_DONE:
|
|
begin
|
|
exc_ctrl_cs <= IDLE;
|
|
end
|
|
|
|
endcase
|
|
|
|
end
|
|
end
|
|
|
|
`ifndef SYNTHESIS
|
|
// synopsys translate_off
|
|
// evaluate at falling edge to avoid duplicates during glitches
|
|
// Removed this message as it pollutes too much the output and makes tests fail
|
|
//always_ff @(negedge clk)
|
|
//begin
|
|
// if (rst_n && exc_ctrl_cs == IRQ_DONE)
|
|
// $display("%t: Entering interrupt service routine. [%m]", $time);
|
|
//end
|
|
// synopsys translate_on
|
|
`endif
|
|
|
|
endmodule
|