blob: 39ef403a9d98c7b2edda1c97f3b22514947a6ade [file] [log] [blame]
module apb_event_unit
#(
parameter APB_ADDR_WIDTH = 12 //APB slaves are 4KB by default
)
(
clk_i,
HCLK,
HRESETn,
PADDR,
PWDATA,
PWRITE,
PSEL,
PENABLE,
PRDATA,
PREADY,
PSLVERR,
irq_i,
event_i,
irq_o,
fetch_enable_i,
fetch_enable_o,
clk_gate_core_o,
core_busy_i
);
//parameter APB_ADDR_WIDTH = 12;
input wire clk_i;
input wire HCLK;
input wire HRESETn;
input wire [APB_ADDR_WIDTH - 1:0] PADDR;
input wire [31:0] PWDATA;
input wire PWRITE;
input wire PSEL;
input wire PENABLE;
output reg [31:0] PRDATA;
output reg PREADY;
output reg PSLVERR;
input wire [31:0] irq_i;
input wire [31:0] event_i;
output wire [31:0] irq_o;
input wire fetch_enable_i;
output wire fetch_enable_o;
output wire clk_gate_core_o;
input wire core_busy_i;
wire [31:0] events;
reg [2:0] psel_int;
wire [2:0] pready;
wire [2:0] pslverr;
wire [1:0] slave_address_int;
wire [95:0] prdata;
reg fetch_enable_ff1;
reg fetch_enable_ff2;
wire fetch_enable_int;
assign fetch_enable_o = fetch_enable_ff2 & fetch_enable_int;
assign slave_address_int = PADDR[5:4];
always @(*) begin
psel_int = 3'b000;
psel_int[slave_address_int] = PSEL;
end
always @(*)
if (psel_int != 2'b00) begin
PRDATA = prdata[slave_address_int * 32+:32];
PREADY = pready[slave_address_int];
PSLVERR = pslverr[slave_address_int];
end
else begin
PRDATA = 1'sb0;
PREADY = 1'b1;
PSLVERR = 1'b0;
end
generic_service_unit #(.APB_ADDR_WIDTH(APB_ADDR_WIDTH)) i_interrupt_unit(
.HCLK(HCLK),
.HRESETn(HRESETn),
.PADDR(PADDR),
.PWDATA(PWDATA),
.PWRITE(PWRITE),
.PSEL(psel_int[0]),
.PENABLE(PENABLE),
.PRDATA(prdata[0+:32]),
.PREADY(pready[0]),
.PSLVERR(pslverr[0]),
.signal_i(irq_i),
.irq_o(irq_o)
);
generic_service_unit #(.APB_ADDR_WIDTH(APB_ADDR_WIDTH)) i_event_unit(
.HCLK(HCLK),
.HRESETn(HRESETn),
.PADDR(PADDR),
.PWDATA(PWDATA),
.PWRITE(PWRITE),
.PSEL(psel_int[1]),
.PENABLE(PENABLE),
.PRDATA(prdata[32+:32]),
.PREADY(pready[1]),
.PSLVERR(pslverr[1]),
.signal_i(event_i),
.irq_o(events)
);
sleep_unit #(.APB_ADDR_WIDTH(APB_ADDR_WIDTH)) i_sleep_unit(
.HCLK(HCLK),
.HRESETn(HRESETn),
.PADDR(PADDR),
.PWDATA(PWDATA),
.PWRITE(PWRITE),
.PSEL(psel_int[2]),
.PENABLE(PENABLE),
.PRDATA(prdata[64+:32]),
.PREADY(pready[2]),
.PSLVERR(pslverr[2]),
.irq_i(|irq_o),
.event_i(|events),
.core_busy_i(core_busy_i),
.fetch_en_o(fetch_enable_int),
.clk_gate_core_o(clk_gate_core_o)
);
always @(posedge clk_i or negedge HRESETn)
if (~HRESETn) begin
fetch_enable_ff1 <= 1'b0;
fetch_enable_ff2 <= 1'b0;
end
else begin
fetch_enable_ff1 <= fetch_enable_i;
fetch_enable_ff2 <= fetch_enable_ff1;
end
endmodule