blob: 4da194136bf0c74ca1bab702abcce2a480313e34 [file] [log] [blame]
module generic_service_unit
#(
parameter APB_ADDR_WIDTH = 12 //APB slaves are 4KB by default
)
(
HCLK,
HRESETn,
PADDR,
PWDATA,
PWRITE,
PSEL,
PENABLE,
PRDATA,
PREADY,
PSLVERR,
signal_i,
irq_o
);
//parameter APB_ADDR_WIDTH = 12;
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 wire PREADY;
output wire PSLVERR;
input wire [31:0] signal_i;
output reg [31:0] irq_o;
reg [127:0] regs_q;
reg [127:0] regs_n;
reg [4:0] highest_pending_int;
wire [1:0] register_adr;
reg [31:0] irq_n;
assign register_adr = PADDR[3:2];
always @(*) begin : sv2v_autoblock_1
reg [0:1] _sv2v_jump;
_sv2v_jump = 2'b00;
highest_pending_int = 'b0;
irq_n = 32'b00000000000000000000000000000000;
begin : sv2v_autoblock_2
reg signed [31:0] i;
for (i = 0; i < 32; i = i + 1)
if (_sv2v_jump < 2'b10) begin
_sv2v_jump = 2'b00;
if (regs_q[64 + i]) begin
highest_pending_int = i;
_sv2v_jump = 2'b10;
end
end
if (_sv2v_jump != 2'b11)
_sv2v_jump = 2'b00;
end
if (_sv2v_jump == 2'b00)
if (regs_q[64+:32] != 'b0)
irq_n[highest_pending_int] = 1'b1;
end
assign PREADY = 1'b1;
assign PSLVERR = 1'b0;
reg [31:0] pending_int;
always @(*) begin
regs_n = regs_q;
regs_n[32+:32] = 32'b00000000000000000000000000000000;
regs_n[0+:32] = 32'b00000000000000000000000000000000;
pending_int = (regs_q[96+:32] & signal_i) | regs_q[64+:32];
pending_int = pending_int | regs_q[32+:32];
begin : sv2v_autoblock_3
reg signed [31:0] i;
for (i = 0; i < 32; i = i + 1)
if (regs_q[i])
pending_int[i] = 1'b0;
end
if ((PSEL && PENABLE) && PWRITE)
case (register_adr)
2'b00: regs_n[96+:32] = PWDATA;
2'b01: pending_int = PWDATA;
2'b10: regs_n[32+:32] = PWDATA;
2'b11: regs_n[0+:32] = PWDATA;
endcase
regs_n[64+:32] = pending_int;
end
always @(*) begin
PRDATA = 'b0;
if ((PSEL && PENABLE) && !PWRITE)
case (register_adr)
2'b00: PRDATA = regs_q[96+:32];
2'b01: PRDATA = regs_q[64+:32];
default: PRDATA = 'b0;
endcase
end
always @(posedge HCLK or negedge HRESETn)
if (~HRESETn) begin
regs_q <= {4 {32'b00000000000000000000000000000000}};
irq_o <= 32'b00000000000000000000000000000000;
end
else begin
regs_q <= regs_n;
irq_o <= irq_n;
end
endmodule