⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpio_v.htm

📁 这是一个通用可编程接口的Verilog代码
💻 HTM
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0102)http://www.opencores.org/cvsweb.cgi/~checkout~/gpio/rtl/Attic/gpio.v?rev=1.2;content-type=text%2Fplain -->
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2900.3020" name=GENERATOR></HEAD>
<BODY><PRE>//////////////////////////////////////////////////////////////////////
////                                                              ////
////  WISHBONE General-Purpose I/O                                ////
////                                                              ////
////  This file is part of the GPIO project                       ////
////                                                              ////
////  Description                                                 ////
////  Implementation of GPIO IP core according to                 ////
////  GPIO IP core specification document.                        ////
////                                                              ////
////  To Do:                                                      ////
////   Nothing                                                    ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
//// This source file 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.1 of the License, or (at your option) any   ////
//// later version.                                               ////
////                                                              ////
//// This source 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 this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: gpio.v,v $
// Revision 1.2  2001/07/14 20:39:26  lampret
// Better configurability.
//
// Revision 1.1  2001/06/05 07:45:26  lampret
// Added initial RTL and test benches. There are still some issues with these files.
//
//

// synopsys translate_off
`include "timescale.vh"
// synopsys translate_on
`include "defines.vh"

module gpio(
	// WISHBONE Interface
	clk_i, rst_i, cyc_i, adr_i, dat_i, sel_i, we_i, stb_i,
	dat_o, ack_o, err_o, inta_o,

	// Auxiliary inputs interface
	gpio_aux,

	// External GPIO Interface
	gpio_in, gpio_eclk, gpio_out, gpio_oen
);

parameter dw = 32;
parameter aw = `GPIO_ADDRHH+1;
parameter gw = `GPIO_IOS;

//
// WISHBONE Interface
//
input			clk_i;	// Clock
input			rst_i;	// Reset
input			cyc_i;	// cycle valid input
input 	[aw-1:0]	adr_i;	// address bus inputs
input	[dw-1:0]	dat_i;	// input data bus
input	[3:0]		sel_i;	// byte select inputs
input			we_i;	// indicates write transfer
input			stb_i;	// strobe input
output	[dw-1:0]	dat_o;	// output data bus
output			ack_o;	// normal termination
output			err_o;	// termination w/ error
output			inta_o;	// Interrupt request output

// Auxiliary Inputs Interface
input	[gw-1:0]	gpio_aux; // Auxiliary inputs

//
// External GPIO Interface
//
input	[gw-1:0]	gpio_in;	// GPIO Inputs
input			gpio_eclk;	// GPIO Eclk
output	[gw-1:0]	gpio_out;	// GPIO Outputs
output	[gw-1:0]	gpio_oen;	// GPIO output drivers enables

`ifdef GPIO_IMPLEMENTED

//
// GPIO Input Register (or no register)
//
`ifdef RGPIO_IN
reg	[gw-1:0]	rgpio_in;	// RGPIO_IN register
`else
wire	[gw-1:0]	rgpio_in;	// No register
`endif

//
// GPIO Output Register (or no register)
//
`ifdef RGPIO_OUT
reg	[gw-1:0]	rgpio_out;	// RGPIO_OUT register
`else
wire	[gw-1:0]	rgpio_out;	// No register
`endif

//
// GPIO Output Driver Enable Register (or no register)
//
`ifdef RGPIO_OE
reg	[gw-1:0]	rgpio_oe;	// RGPIO_OE register
`else
wire	[gw-1:0]	rgpio_oe;	// No register
`endif

//
// GPIO Interrupt Enable Register (or no register)
//
`ifdef RGPIO_INTE
reg	[gw-1:0]	rgpio_inte;	// RGPIO_INTE register
`else
wire	[gw-1:0]	rgpio_inte;	// No register
`endif

//
// GPIO Positive edge Triggered Register (or no register)
//
`ifdef RGPIO_PTRIG
reg	[gw-1:0]	rgpio_ptrig;	// RGPIO_PTRIG register
`else
wire	[gw-1:0]	rgpio_ptrig;	// No register
`endif

//
// GPIO Auxiliary select Register (or no register)
//
`ifdef RGPIO_AUX
reg	[gw-1:0]	rgpio_aux;	// RGPIO_AUX register
`else
wire	[gw-1:0]	rgpio_aux;	// No register
`endif

//
// GPIO Control Register (or no register)
//
`ifdef RGPIO_CTRL
reg	[3:0]		rgpio_ctrl;	// RGPIO_CTRL register
`else
wire	[3:0]		rgpio_ctrl;	// No register
`endif

//
// Internal wires &amp; regs
//
wire			rgpio_in_sel;	// RGPIO_IN select
wire			rgpio_out_sel;	// RGPIO_OUT select
wire			rgpio_oe_sel;	// RGPIO_OE select
wire			rgpio_inte_sel;	// RGPIO_INTE select
wire			rgpio_ptrig_sel;// RGPIO_PTRIG select
wire			rgpio_aux_sel;	// RGPIO_AUX select
wire			rgpio_ctrl_sel;	// RGPIO_CTRL select
wire			latch_clk;	// Latch clock
wire			full_decoding;	// Full address decoding qualification
reg	[dw-1:0]	dat_o;		// Data out

//
// All WISHBONE transfer terminations are successful except when:
// a) full address decoding is enabled and address doesn't match
//    any of the GPIO registers
// b) sel_i evaluation is enabled and one of the sel_i inputs is zero
//
assign ack_o = cyc_i &amp; stb_i &amp; !err_o;
`ifdef FULL_DECODE
`ifdef STRICT_32BIT_ACCESS
assign err_o = cyc_i &amp; stb_i &amp; !full_decoding | (sel_i != 4'b1111);
`else
assign err_o = cyc_i &amp; stb_i &amp; !full_decoding;
`endif
`else
`ifdef STRICT_32BIT_ACCESS
assign err_o = (sel_i != 4'b1111);
`else
assign err_o = 1'b0;
`endif
`endif

//
// Latch clock is selected by RGPIO_CTRL[ECLK]. When it is set,
// external clock is used.
//
assign latch_clk = rgpio_ctrl[`RGPIO_CTRL_ECLK] ?
		gpio_eclk ^ rgpio_ctrl[`RGPIO_CTRL_NEC] : clk_i;

//
// Full address decoder
//
`ifdef FULL_DECODE
assign full_decoding = (adr_i[`GPIO_ADDRHH:`GPIO_ADDRHL] == {`GPIO_ADDRHH-`GPIO_ADDRHL+1{1'b0}}) &amp;
			(adr_i[`GPIO_ADDRLH:`GPIO_ADDRLL] == {`GPIO_ADDRLH-`GPIO_ADDRLL+1{1'b0}});
`else
assign full_decoding = 1'b1;
`endif

//
// GPIO registers address decoder
//
assign rgpio_in_sel = cyc_i &amp; stb_i &amp; (adr_i[`GPIOOFS_BITS] == `RGPIO_IN) &amp; full_decoding;
assign rgpio_out_sel = cyc_i &amp; stb_i &amp; (adr_i[`GPIOOFS_BITS] == `RGPIO_OUT) &amp; full_decoding;
assign rgpio_oe_sel = cyc_i &amp; stb_i &amp; (adr_i[`GPIOOFS_BITS] == `RGPIO_OE) &amp; full_decoding;
assign rgpio_inte_sel = cyc_i &amp; stb_i &amp; (adr_i[`GPIOOFS_BITS] == `RGPIO_INTE) &amp; full_decoding;
assign rgpio_ptrig_sel = cyc_i &amp; stb_i &amp; (adr_i[`GPIOOFS_BITS] == `RGPIO_PTRIG) &amp; full_decoding;
assign rgpio_aux_sel = cyc_i &amp; stb_i &amp; (adr_i[`GPIOOFS_BITS] == `RGPIO_AUX) &amp; full_decoding;
assign rgpio_ctrl_sel = cyc_i &amp; stb_i &amp; (adr_i[`GPIOOFS_BITS] == `RGPIO_CTRL) &amp; full_decoding;

//
// Write to RGPIO_CTRL or update of RGPIO_CTRL[INT] bit
//
`ifdef RGPIO_CTRL
always @(posedge clk_i or posedge rst_i)
	if (rst_i)
		rgpio_ctrl &lt;= #1 4'b0;
	else if (rgpio_ctrl_sel &amp;&amp; we_i)
		rgpio_ctrl &lt;= #1 dat_i[3:0];
	else if (rgpio_ctrl[`RGPIO_CTRL_INTE])
		rgpio_ctrl[`RGPIO_CTRL_INT] &lt;= #1 rgpio_ctrl[`RGPIO_CTRL_INT] | inta_o;
`else
assign rgpio_ctrl = 4'h01;	// RGPIO_CTRL[EN] = 1
`endif

//
// Write to RGPIO_OUT
//
`ifdef RGPIO_OUT
always @(posedge clk_i or posedge rst_i)
	if (rst_i)
		rgpio_out &lt;= #1 {gw{1'b0}};
	else if (rgpio_out_sel &amp;&amp; we_i)
		rgpio_out &lt;= #1 dat_i[gw-1:0];
`else
assign rgpio_out = `DEF_RPGIO_OUT;	// RGPIO_OUT = 0x0
`endif

//
// Write to RGPIO_OE
//
`ifdef RGPIO_OE
always @(posedge clk_i or posedge rst_i)
	if (rst_i)
		rgpio_oe &lt;= #1 {gw{1'b0}};
	else if (rgpio_oe_sel &amp;&amp; we_i)
		rgpio_oe &lt;= #1 dat_i[gw-1:0];
`else
assign rgpio_oe = `DEF_RPGIO_OE;	// RGPIO_OE = 0x0
`endif

//
// Write to RGPIO_INTE
//
`ifdef RGPIO_INTE
always @(posedge clk_i or posedge rst_i)
	if (rst_i)
		rgpio_inte &lt;= #1 {gw{1'b0}};
	else if (rgpio_inte_sel &amp;&amp; we_i)
		rgpio_inte &lt;= #1 dat_i[gw-1:0];
`else
assign rgpio_inte = `DEF_RPGIO_INTE;	// RGPIO_INTE = 0x0
`endif

//
// Write to RGPIO_PTRIG
//
`ifdef RGPIO_PTRIG
always @(posedge clk_i or posedge rst_i)
	if (rst_i)
		rgpio_ptrig &lt;= #1 {gw{1'b0}};
	else if (rgpio_ptrig_sel &amp;&amp; we_i)
		rgpio_ptrig &lt;= #1 dat_i[gw-1:0];
`else
assign rgpio_ptrig = `DEF_RPGIO_PTRIG;	// RGPIO_PTRIG = 0x0
`endif

//
// Write to RGPIO_AUX
//
`ifdef RGPIO_AUX
always @(posedge clk_i or posedge rst_i)
	if (rst_i)
		rgpio_aux &lt;= #1 {gw{1'b0}};
	else if (rgpio_aux_sel &amp;&amp; we_i)
		rgpio_aux &lt;= #1 dat_i[gw-1:0];
`else
assign rgpio_aux = `DEF_RPGIO_AUX;	// RGPIO_AUX = 0x0
`endif

//
// Latch into RGPIO_IN
//
`ifdef RGPIO_IN
always @(posedge latch_clk or posedge rst_i)
	if (rst_i)
		rgpio_in &lt;= #1 {gw{1'b0}};
	else
		rgpio_in &lt;= #1 gpio_in;
`else
assign rgpio_in = gpio_in;
`endif

//
// Read GPIO registers
//
always @(adr_i or rgpio_in or rgpio_out or rgpio_oe or rgpio_inte or
		rgpio_ptrig or rgpio_aux or rgpio_ctrl)
	case (adr_i[`GPIOOFS_BITS])	// synopsys full_case parallel_case
`ifdef GPIO_READREGS
		`RGPIO_OUT: begin
			dat_o[dw-1:0] &lt;= {{dw-gw{1'b0}}, rgpio_out};
//			dat_o[dw-1:gw] &lt;= {dw-gw{1'b0}};
		end
		`RGPIO_OE: begin
			dat_o[dw-1:0] &lt;= {{dw-gw{1'b0}}, rgpio_oe};
//			dat_o[dw-1:gw] &lt;= {dw-gw{1'b0}};
		end
		`RGPIO_INTE: begin
			dat_o[dw-1:0] &lt;= {{dw-gw{1'b0}}, rgpio_inte};
//			dat_o[dw-1:gw] &lt;= {dw-gw{1'b0}};
		end
		`RGPIO_PTRIG: begin
			dat_o[dw-1:0] &lt;= {{dw-gw{1'b0}}, rgpio_ptrig};
//			dat_o[dw-1:gw] &lt;= {dw-gw{1'b0}};
		end
		`RGPIO_AUX: begin
			dat_o[dw-1:0] &lt;= {{dw-gw{1'b0}}, rgpio_aux};
//			dat_o[dw-1:gw] &lt;= {dw-gw{1'b0}};
		end
		`RGPIO_CTRL: begin
			dat_o[3:0] &lt;= rgpio_ctrl;
			dat_o[dw-1:4] &lt;= {dw-4{1'b0}};
		end
`endif
		default: begin
			dat_o[dw-1:0] &lt;= {{dw-gw{1'b0}}, rgpio_in};
//			dat_o[dw-1:gw] &lt;= {dw-gw{1'b0}};
		end
	endcase

//
// Generate interrupt request
//
assign inta_o = ((gpio_in ^ ~rgpio_ptrig) &amp; rgpio_inte) ? rgpio_ctrl[`RGPIO_CTRL_INTE] : 1'b0;

//
// Generate output enables from inverted RGPIO_OE bits
//
assign gpio_oen = ~rgpio_oe;

//
// Generate outputs
//
assign gpio_out = rgpio_out &amp; ~rgpio_aux | gpio_aux &amp; rgpio_aux;

`else

//
// When GPIO is not implemented, drive all outputs as would when RGPIO_CTRL
// is cleared and WISHBONE transfers complete with errors
//
assign inta_o = 1'b0;
assign ack_o = 1'b0;
assign err_o = cyc_i &amp; stb_i;
assign gpio_oen = {gw{1'b1}};
assign gpio_out = {gw{1'b0}};

//
// Read GPIO registers
//
assign dat_o = {dw{1'b0}};

`endif

endmodule
</PRE></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -