URL
https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk
Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc
[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_processor/] [mor1kx-5.0/] [rtl/] [verilog/] [mor1kx_pic.v] - Rev 48
Compare with Previous | Blame | View Log
/* **************************************************************************** This Source Code Form is subject to the terms of the Open Hardware Description License, v. 1.0. If a copy of the OHDL was not distributed with this file, You can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt Description: mor1kx PIC Copyright (C) 2012 Authors Author(s): Julius Baxter <juliusbaxter@gmail.com> ***************************************************************************** */ `include "mor1kx-defines.v" module mor1kx_pic (/*AUTOARG*/ // Outputs spr_picmr_o, spr_picsr_o, spr_bus_ack, spr_dat_o, // Inputs clk, rst, irq_i, spr_access_i, spr_we_i, spr_addr_i, spr_dat_i ); parameter OPTION_PIC_TRIGGER="LEVEL"; parameter OPTION_PIC_NMI_WIDTH = 0; input clk; input rst; input [31:0] irq_i; output [31:0] spr_picmr_o; output [31:0] spr_picsr_o; // SPR Bus interface input spr_access_i; input spr_we_i; input [15:0] spr_addr_i; input [31:0] spr_dat_i; output spr_bus_ack; output [31:0] spr_dat_o; // Registers reg [31:0] spr_picmr; reg [31:0] spr_picsr; wire spr_picmr_access; wire spr_picsr_access; wire [31:0] irq_unmasked; assign spr_picmr_o = spr_picmr; assign spr_picsr_o = spr_picsr; assign spr_picmr_access = spr_access_i & (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PICMR_ADDR)); assign spr_picsr_access = spr_access_i & (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PICSR_ADDR)); assign spr_bus_ack = spr_access_i; assign spr_dat_o = (spr_access_i & spr_picsr_access) ? spr_picsr : (spr_access_i & spr_picmr_access) ? spr_picmr : 0; assign irq_unmasked = spr_picmr & irq_i; generate genvar irqline; if (OPTION_PIC_TRIGGER=="EDGE") begin : edge_triggered reg [31:0] irq_unmasked_r; wire [31:0] irq_unmasked_edge; always @(posedge clk `OR_ASYNC_RST) if (rst) irq_unmasked_r <= 0; else irq_unmasked_r <= irq_unmasked; for(irqline=0;irqline<32;irqline=irqline+1) begin: picgenerate assign irq_unmasked_edge[irqline] = irq_unmasked[irqline] & !irq_unmasked_r[irqline]; // PIC status register always @(posedge clk `OR_ASYNC_RST) if (rst) spr_picsr[irqline] <= 0; // Set else if (irq_unmasked_edge[irqline]) spr_picsr[irqline] <= 1; // Clear else if (spr_we_i & spr_picsr_access & spr_dat_i[irqline]) spr_picsr[irqline] <= 0; end end else if (OPTION_PIC_TRIGGER=="LEVEL") begin : level_triggered for(irqline=0;irqline<32;irqline=irqline+1) begin: picsrlevelgenerate // PIC status register always @(*) spr_picsr[irqline] = irq_unmasked[irqline]; end end // if (OPTION_PIC_TRIGGER=="LEVEL") else if (OPTION_PIC_TRIGGER=="LATCHED_LEVEL") begin : latched_level for(irqline=0;irqline<32;irqline=irqline+1) begin: piclatchedlevelgenerate // PIC status register always @(posedge clk `OR_ASYNC_RST) if (rst) spr_picsr[irqline] <= 0; else if (spr_we_i && spr_picsr_access) spr_picsr[irqline] <= irq_unmasked[irqline] | spr_dat_i[irqline]; else spr_picsr[irqline] <= spr_picsr[irqline] | irq_unmasked[irqline]; end // block: picgenerate end // if (OPTION_PIC_TRIGGER=="EDGE") else begin : invalid initial begin $display("Error - invalid PIC level detection option %s", OPTION_PIC_TRIGGER); $finish; end end // else: !if(OPTION_PIC_TRIGGER=="LEVEL") endgenerate // PIC (un)mask register always @(posedge clk `OR_ASYNC_RST) if (rst) spr_picmr <= {{(32-OPTION_PIC_NMI_WIDTH){1'b0}}, {OPTION_PIC_NMI_WIDTH{1'b1}}}; else if (spr_we_i && spr_picmr_access) spr_picmr <= {spr_dat_i[31:OPTION_PIC_NMI_WIDTH], {OPTION_PIC_NMI_WIDTH{1'b1}}}; endmodule // mor1kx_pic