OpenCores
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/] [rtl/] [src_peripheral/] [ext_int/] [ext_int.v] - Rev 48

Compare with Previous | Blame | View Log

 
/**********************************************************************
**	File:  ext_int.v
**	
**    
**	Copyright (C) 2014-2017  Alireza Monemi
**    
**	This file is part of ProNoC 
**
**	ProNoC ( stands for Prototype Network-on-chip)  is free software: 
**	you can redistribute it and/or modify it under the terms of the GNU
**	Lesser General Public License as published by the Free Software Foundation,
**	either version 2 of the License, or (at your option) any later version.
**
** 	ProNoC is distributed in the hope that it will be useful, but WITHOUT
** 	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** 	or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
** 	Public License for more details.
**
** 	You should have received a copy of the GNU Lesser General Public
** 	License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
**
**
**	Description: 
**	Wishbone bus based external intrrupt module
**
*******************************************************************/
 
 
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
 
module ext_int #(
	parameter EXT_INT_NUM	=	3,//max 32
	parameter Aw		=	3,
	parameter SELw		=	4,
	parameter TAGw      =   3,
	parameter Dw		=	32
 
)(
    clk,
    reset,
 
    //wishbone bus interface
	sa_dat_i,
    sa_sel_i,
    sa_addr_i,  
    sa_tag_i,
    sa_stb_i,
    sa_cyc_i,
    sa_we_i,    
    sa_dat_o,
    sa_ack_o,
    sa_err_o,
    sa_rty_o,
 
    //interrupt ports
    ext_int_i,  
    ext_int_o 
);
 
    input                               clk;
    input                               reset;
 
    //wishbone bus interface
    input       [Dw-1       :   0]      sa_dat_i;
    input       [SELw-1     :   0]      sa_sel_i;
    input       [Aw-1       :   0]      sa_addr_i;  
    input       [TAGw-1     :   0]      sa_tag_i;
    input                               sa_stb_i;
    input                               sa_cyc_i;
    input                               sa_we_i;
 
    output      [Dw-1       :   0]      sa_dat_o;
    output  reg                         sa_ack_o;
    output                              sa_err_o;
    output                              sa_rty_o;
 
 
    //interrupt ports
    input   [EXT_INT_NUM-1      :   0]  ext_int_i;  
    output                              ext_int_o; //output to the interrupt controller
 
 
 
 
//interrupt registers							
 
	localparam	[Aw-1		:	0]		GER_REG_ADDR			=	0;
	localparam	[Aw-1		:	0]		IER_RISING_REG_ADDR	=	1;
	localparam	[Aw-1		:	0]		IER_FALLING_REG_ADDR	=	2;
	localparam	[Aw-1		:	0]		ISR_REG_ADDR			=	3;
	localparam	[Aw-1		:	0]		PIN_REG_ADDR			=	4;
 
 
	reg										ger,ger_next;
	reg	[EXT_INT_NUM-1			:	0]	ier_rise,ier_fall,isr,read,int_reg1,int_reg2;//2	
	reg	[EXT_INT_NUM-1			:	0]	ier_rise_next,ier_fall_next,isr_next,read_next,int_reg1_next,int_reg2_next;
 
	wire 	[EXT_INT_NUM-1			:	0]	triggered,rise_edge,fall_edge;
 
 
   	assign  sa_err_o=1'b0;
   	assign  sa_rty_o=1'b0;
	assign rise_edge = (ger)? 	ier_rise & ~int_reg2	& int_reg1	:	{EXT_INT_NUM{1'b0}};
	assign fall_edge = (ger)?	ier_fall & int_reg2 	& ~int_reg1	: 	{EXT_INT_NUM{1'b0}};
 
	assign	triggered	=	rise_edge |  fall_edge;
 
`ifdef SYNC_RESET_MODE 
    always @ (posedge clk )begin 
`else 
    always @ (posedge clk or posedge reset)begin 
`endif  
		if(reset) begin 
			ger		<=	1'b0;
			ier_rise	<= {EXT_INT_NUM{1'b0}};
			ier_fall	<= {EXT_INT_NUM{1'b0}};
			isr		<=	{EXT_INT_NUM{1'b0}};
			read		<=	{EXT_INT_NUM{1'b0}};	
			int_reg1	<=	{EXT_INT_NUM{1'b0}};
			int_reg2	<=	{EXT_INT_NUM{1'b0}};	
			sa_ack_o	<=	1'b0;
 
		end else begin 
			ger		<=	ger_next;
			ier_rise	<= ier_rise_next;
			ier_fall	<=	ier_fall_next;
			isr		<=	isr_next;
			read		<=	read_next;	
			int_reg1	<=	int_reg1_next;
			int_reg2	<=	int_reg2_next;	
			sa_ack_o	<=	 sa_stb_i && ~sa_ack_o;	
		end//			
	end//always
 
	always@(*) begin 
		int_reg2_next 	= int_reg1;
		int_reg1_next 	= ext_int_i;
		ger_next			= ger;
		ier_rise_next	= ier_rise;
		ier_fall_next	= ier_fall;
		isr_next			= isr | triggered; // set isr if the intrrupt is triggered 
		read_next		= read;
		if(sa_stb_i && sa_we_i ) begin 
			if( sa_addr_i 	==	GER_REG_ADDR			)		ger_next			= 	sa_dat_i[0];
			if( sa_addr_i 	== IER_RISING_REG_ADDR 	)		ier_rise_next	=	sa_dat_i[EXT_INT_NUM-1'b1		:	0];
			if( sa_addr_i 	== IER_FALLING_REG_ADDR	)		ier_fall_next	=	sa_dat_i[EXT_INT_NUM-1'b1		:	0];
			if( sa_addr_i 	== ISR_REG_ADDR  			) 		isr_next			=	isr & ~sa_dat_i[EXT_INT_NUM-1'b1		:	0];// reset isr by writting 1
		end
		if(sa_stb_i && ~sa_we_i) begin 
			case(sa_addr_i) 
				GER_REG_ADDR:				read_next	=	{{(EXT_INT_NUM-1){1'b0}},ger};
				IER_RISING_REG_ADDR:		read_next	=	ier_rise;
				IER_FALLING_REG_ADDR:	read_next	=	ier_fall;
				ISR_REG_ADDR:				read_next	=	isr;
				PIN_REG_ADDR:				read_next	=	ext_int_i;
				default						read_next	=	read; 
			endcase
		end
	end//always
 
 
	generate 
		if(EXT_INT_NUM!=Dw)begin
			assign sa_dat_o ={{(Dw-EXT_INT_NUM){1'b0}}, read};
		end else begin
			assign sa_dat_o = read;
		end
	endgenerate
 
	assign ext_int_o = |isr;
 
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.