URL
https://opencores.org/ocsvn/minsoc/minsoc/trunk
Subversion Repositories minsoc
Compare Revisions
- This comparison shows the changes necessary to convert path
/minsoc/tags/release-0.9/utils/contributions/gpio
- from Rev 40 to Rev 42
- ↔ Reverse comparison
Rev 40 → Rev 42
/rtl/gpio_defines.v
0,0 → 1,326
////////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE GPIO Definitions //// |
//// //// |
//// This file is part of the GPIO project //// |
//// http://www.opencores.org/cores/gpio/ //// |
//// //// |
//// Description //// |
//// GPIO IP Definitions. //// |
//// //// |
//// To Do: //// |
//// Nothing //// |
//// //// |
//// Author(s): //// |
//// - Damjan Lampret, lampret@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and OPENCORES.ORG //// |
//// //// |
//// 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: not supported by cvs2svn $ |
// Revision 1.8 2003/12/17 13:00:52 gorand |
// added ECLK and NEC registers, all tests passed. |
// |
// Revision 1.7 2003/12/01 17:10:44 simons |
// ifndef directive is not supported by all tools. |
// |
// Revision 1.6 2003/11/06 13:59:07 gorand |
// added support for 8-bit access to registers. |
// |
// Revision 1.2 2003/10/02 18:54:35 simons |
// GPIO signals muxed with other peripherals, higland_board fixed. |
// |
// Revision 1.1.1.1 2003/06/24 09:09:23 simons |
// This files were moved here from toplevel folder. |
// |
// Revision 1.1.1.1 2003/06/11 18:51:13 simons |
// Initial import. |
// |
// Revision 1.5 2002/11/11 21:36:28 lampret |
// Added ifdef to remove mux from clk_pad_i if mux is not allowed. This also removes RGPIO_CTRL[NEC]. |
// |
// Revision 1.4 2002/05/06 18:25:31 lampret |
// negedge flops are enabled by default. |
// |
// Revision 1.3 2001/12/25 17:12:35 lampret |
// Added RGPIO_INTS. |
// |
// Revision 1.2 2001/11/15 02:24:37 lampret |
// Added GPIO_REGISTERED_WB_OUTPUTS, GPIO_REGISTERED_IO_OUTPUTS and GPIO_NO_NEGEDGE_FLOPS. |
// |
// Revision 1.1 2001/09/18 18:49:07 lampret |
// Changed top level ptc into gpio_top. Changed defines.v into gpio_defines.v. |
// |
// Revision 1.1 2001/08/21 21:39:28 lampret |
// Changed directory structure, port names and drfines. |
// |
// Revision 1.3 2001/07/15 00:21:10 lampret |
// Registers can be omitted and will have certain default values |
// |
// 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. |
// |
// |
|
// |
// Number of GPIO I/O signals |
// |
// This is the most important parameter of the GPIO IP core. It defines how many |
// I/O signals core has. Range is from 1 to 32. If more than 32 I/O signals are |
// required, use several instances of GPIO IP core. |
// |
// Default is 16. |
// |
`define GPIO_IOS 31 |
|
//depending on number of GPIO_IOS, define this... |
// for example: if there is 26 GPIO_IOS, define GPIO_LINES26 |
// |
|
`define GPIO_LINES31 |
|
// |
// Undefine this one if you don't want to remove GPIO block from your design |
// but you also don't need it. When it is undefined, all GPIO ports still |
// remain valid and the core can be synthesized however internally there is |
// no GPIO funationality. |
// |
// Defined by default (duhh !). |
// |
`define GPIO_IMPLEMENTED |
|
// |
// Define to register all WISHBONE outputs. |
// |
// Register outputs if you are using GPIO core as a block and synthesizing |
// and place&routing it separately from the rest of the system. |
// |
// If you do not need registered outputs, you can save some area by not defining |
// this macro. By default it is defined. |
// |
`define GPIO_REGISTERED_WB_OUTPUTS |
|
// |
// Define to register all GPIO pad outputs. |
// |
// Register outputs if you are using GPIO core as a block and synthesizing |
// and place&routing it separately from the rest of the system. |
// |
// If you do not need registered outputs, you can save some area by not defining |
// this macro. By default it is defined. |
// |
`define GPIO_REGISTERED_IO_OUTPUTS |
|
// |
// Implement aux feature. If this define is not defined also aux_i port and |
// RGPIO_AUX register will be removed |
// |
// Defined by default. |
// |
//`define GPIO_AUX_IMPLEMENT |
|
// |
// If this is not defined clk_pad_i will be removed. Input lines will be lached on |
// positive edge of system clock |
// if disabled defines GPIO_NO_NEGEDGE_FLOPS, GPIO_NO_CLKPAD_LOGIC will have no effect. |
// |
// Defined by default. |
// |
//`define GPIO_CLKPAD |
|
// |
// Define to avoid using negative edge clock flip-flops for external clock |
// (caused by NEC register. Instead an inverted external clock with |
// positive edge clock flip-flops will be used. |
// This define don't have any effect if GPIO_CLKPAD is not defined and if GPIO_SYNC_IN_CLK is defined |
// |
// By default it is not defined. |
// |
//`define GPIO_NO_NEGEDGE_FLOPS |
|
// |
// If GPIO_NO_NEGEDGE_FLOPS is defined, a mux needs to be placed on external clock |
// clk_pad_i to implement RGPIO_CTRL[NEC] functionality. If no mux is allowed on |
// clock signal, enable the following define. |
// This define don't have any effect if GPIO_CLKPAD is not defined and if GPIO_SYNC_IN_CLK is defined |
// |
// By default it is not defined. |
// |
//`define GPIO_NO_CLKPAD_LOGIC |
|
|
// |
// synchronization defines |
// |
// Two synchronization flops to input lineis added. |
// system clock synchronization. |
// |
`define GPIO_SYNC_IN_WB |
|
// |
// Add synchronization flops to external clock input line. Gpio will have just one clock domain, |
// everithing will be synchronized to wishbone clock. External clock muas be at least 2-3x slower |
// as systam clock. |
// |
`define GPIO_SYNC_CLK_WB |
|
// |
// Add synchronization to input pads. synchronization to external clock. |
// Don't hawe any effect if GPIO_SYNC_CLK_WB is defined. |
// |
//`define GPIO_SYNC_IN_CLK |
|
// |
// Add synchronization flops between system clock and external clock. |
// Only possible if external clock is enabled and clock synchroization is disabled. |
// |
//`define GPIO_SYNC_IN_CLK_WB |
|
|
|
// |
// Undefine if you don't need to read GPIO registers except for RGPIO_IN register. |
// When it is undefined all reads of GPIO registers return RGPIO_IN register. This |
// is usually useful if you want really small area (for example when implemented in |
// FPGA). |
// |
// To follow GPIO IP core specification document this one must be defined. Also to |
// successfully run the test bench it must be defined. By default it is defined. |
// |
`define GPIO_READREGS |
|
// |
// Full WISHBONE address decoding |
// |
// It is is undefined, partial WISHBONE address decoding is performed. |
// Undefine it if you need to save some area. |
// |
// By default it is defined. |
// |
`define GPIO_FULL_DECODE |
|
// |
// Strict 32-bit WISHBONE access |
// |
// If this one is defined, all WISHBONE accesses must be 32-bit. If it is |
// not defined, err_o is asserted whenever 8- or 16-bit access is made. |
// Undefine it if you need to save some area. |
// |
// By default it is defined. |
// |
//`define GPIO_STRICT_32BIT_ACCESS |
// |
`ifdef GPIO_STRICT_32BIT_ACCESS |
`else |
// added by gorand : |
// if GPIO_STRICT_32BIT_ACCESS is not defined, |
// depending on number of gpio I/O lines, the following are defined : |
// if the number of I/O lines is in range 1-8, GPIO_WB_BYTES1 is defined, |
// if the number of I/O lines is in range 9-16, GPIO_WB_BYTES2 is defined, |
// if the number of I/O lines is in range 17-24, GPIO_WB_BYTES3 is defined, |
// if the number of I/O lines is in range 25-32, GPIO_WB_BYTES4 is defined, |
|
`define GPIO_WB_BYTES4 |
//`define GPIO_WB_BYTES3 |
//`define GPIO_WB_BYTES2 |
//`define GPIO_WB_BYTES1 |
|
`endif |
|
// |
// WISHBONE address bits used for full decoding of GPIO registers. |
// |
`define GPIO_ADDRHH 7 |
`define GPIO_ADDRHL 6 |
`define GPIO_ADDRLH 1 |
`define GPIO_ADDRLL 0 |
|
// |
// Bits of WISHBONE address used for partial decoding of GPIO registers. |
// |
// Default 5:2. |
// |
`define GPIO_OFS_BITS `GPIO_ADDRHL-1:`GPIO_ADDRLH+1 |
|
// |
// Addresses of GPIO registers |
// |
// To comply with GPIO IP core specification document they must go from |
// address 0 to address 0x18 in the following order: RGPIO_IN, RGPIO_OUT, |
// RGPIO_OE, RGPIO_INTE, RGPIO_PTRIG, RGPIO_AUX and RGPIO_CTRL |
// |
// If particular register is not needed, it's address definition can be omitted |
// and the register will not be implemented. Instead a fixed default value will |
// be used. |
// |
`define GPIO_RGPIO_IN 4'h0 // Address 0x00 |
`define GPIO_RGPIO_OUT 4'h1 // Address 0x04 |
`define GPIO_RGPIO_OE 4'h2 // Address 0x08 |
`define GPIO_RGPIO_INTE 4'h3 // Address 0x0c |
`define GPIO_RGPIO_PTRIG 4'h4 // Address 0x10 |
|
`ifdef GPIO_AUX_IMPLEMENT |
`define GPIO_RGPIO_AUX 4'h5 // Address 0x14 |
`endif // GPIO_AUX_IMPLEMENT |
|
`define GPIO_RGPIO_CTRL 4'h6 // Address 0x18 |
`define GPIO_RGPIO_INTS 4'h7 // Address 0x1c |
|
`ifdef GPIO_CLKPAD |
`define GPIO_RGPIO_ECLK 4'h8 // Address 0x20 |
`define GPIO_RGPIO_NEC 4'h9 // Address 0x24 |
`endif // GPIO_CLKPAD |
|
// |
// Default values for unimplemented GPIO registers |
// |
`define GPIO_DEF_RGPIO_IN `GPIO_IOS'h0 |
`define GPIO_DEF_RGPIO_OUT `GPIO_IOS'h0 |
`define GPIO_DEF_RGPIO_OE `GPIO_IOS'h0 |
`define GPIO_DEF_RGPIO_INTE `GPIO_IOS'h0 |
`define GPIO_DEF_RGPIO_PTRIG `GPIO_IOS'h0 |
`define GPIO_DEF_RGPIO_AUX `GPIO_IOS'h0 |
`define GPIO_DEF_RGPIO_CTRL `GPIO_IOS'h0 |
`define GPIO_DEF_RGPIO_ECLK `GPIO_IOS'h0 |
`define GPIO_DEF_RGPIO_NEC `GPIO_IOS'h0 |
|
|
// |
// RGPIO_CTRL bits |
// |
// To comply with the GPIO IP core specification document they must go from |
// bit 0 to bit 1 in the following order: INTE, INT |
// |
`define GPIO_RGPIO_CTRL_INTE 0 |
`define GPIO_RGPIO_CTRL_INTS 1 |
|
|
/rtl/gpio_top.v
0,0 → 1,1135
////////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE General-Purpose I/O //// |
//// //// |
//// This file is part of the GPIO project //// |
//// http://www.opencores.org/cores/gpio/ //// |
//// //// |
//// Description //// |
//// Implementation of GPIO IP core according to //// |
//// GPIO IP core specification document. //// |
//// //// |
//// To Do: //// |
//// Nothing //// |
//// //// |
//// Author(s): //// |
//// - Damjan Lampret, lampret@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and OPENCORES.ORG //// |
//// //// |
//// 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: not supported by cvs2svn $ |
// Revision 1.17 2004/05/05 08:21:00 andreje |
// Bugfixes when GPIO_RGPIO_ECLK/GPIO_RGPIO_NEC disabled, gpio oe name change and set to active-high according to spec |
// |
// Revision 1.16 2003/12/17 13:00:52 gorand |
// added ECLK and NEC registers, all tests passed. |
// |
// Revision 1.15 2003/11/10 23:21:22 gorand |
// bug fixed. all tests passed. |
// |
// Revision 1.14 2003/11/06 13:59:07 gorand |
// added support for 8-bit access to registers. |
// |
// Revision 1.13 2002/11/18 22:35:18 lampret |
// Bug fix. Interrupts were also asserted when condition was not met. |
// |
// Revision 1.12 2002/11/11 21:36:28 lampret |
// Added ifdef to remove mux from clk_pad_i if mux is not allowed. This also removes RGPIO_CTRL[NEC]. |
// |
// Revision 1.11 2002/03/13 20:56:28 lampret |
// Removed zero padding as per Avi Shamli suggestion. |
// |
// Revision 1.10 2002/03/13 20:47:57 lampret |
// Ports changed per Ran Aviram suggestions. |
// |
// Revision 1.9 2002/03/09 03:43:27 lampret |
// Interrupt is asserted only when an input changes (code patch by Jacob Gorban) |
// |
// Revision 1.8 2002/01/14 19:06:28 lampret |
// Changed registered WISHBONE outputs wb_ack_o/wb_err_o to follow WB specification. |
// |
// Revision 1.7 2001/12/25 17:21:21 lampret |
// Fixed two typos. |
// |
// Revision 1.6 2001/12/25 17:12:35 lampret |
// Added RGPIO_INTS. |
// |
// Revision 1.5 2001/12/12 20:35:53 lampret |
// Fixing style. |
// |
// Revision 1.4 2001/12/12 07:12:58 lampret |
// Fixed bug when wb_inta_o is registered (GPIO_WB_REGISTERED_OUTPUTS) |
// |
// Revision 1.3 2001/11/15 02:24:37 lampret |
// Added GPIO_REGISTERED_WB_OUTPUTS, GPIO_REGISTERED_IO_OUTPUTS and GPIO_NO_NEGEDGE_FLOPS. |
// |
// Revision 1.2 2001/10/31 02:26:51 lampret |
// Fixed wb_err_o. |
// |
// Revision 1.1 2001/09/18 18:49:07 lampret |
// Changed top level ptc into gpio_top. Changed defines.v into gpio_defines.v. |
// |
// Revision 1.1 2001/08/21 21:39:28 lampret |
// Changed directory structure, port names and drfines. |
// |
// 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.v" |
// synopsys translate_on |
`include "gpio_defines.v" |
|
module gpio_top( |
// WISHBONE Interface |
wb_clk_i, wb_rst_i, wb_cyc_i, wb_adr_i, wb_dat_i, wb_sel_i, wb_we_i, wb_stb_i, |
wb_dat_o, wb_ack_o, wb_err_o, wb_inta_o, |
|
`ifdef GPIO_AUX_IMPLEMENT |
// Auxiliary inputs interface |
aux_i, |
`endif // GPIO_AUX_IMPLEMENT |
|
// External GPIO Interface |
ext_pad_i, ext_pad_o, ext_padoe_o |
`ifdef GPIO_CLKPAD |
, clk_pad_i |
`endif |
); |
|
parameter dw = 32; |
parameter aw = `GPIO_ADDRHH+1; |
parameter gw = `GPIO_IOS; |
// |
// WISHBONE Interface |
// |
input wb_clk_i; // Clock |
input wb_rst_i; // Reset |
input wb_cyc_i; // cycle valid input |
input [aw-1:0] wb_adr_i; // address bus inputs |
input [dw-1:0] wb_dat_i; // input data bus |
input [3:0] wb_sel_i; // byte select inputs |
input wb_we_i; // indicates write transfer |
input wb_stb_i; // strobe input |
output [dw-1:0] wb_dat_o; // output data bus |
output wb_ack_o; // normal termination |
output wb_err_o; // termination w/ error |
output wb_inta_o; // Interrupt request output |
|
`ifdef GPIO_AUX_IMPLEMENT |
// Auxiliary Inputs Interface |
input [gw-1:0] aux_i; // Auxiliary inputs |
`endif // GPIO_AUX_IMPLEMENT |
|
// |
// External GPIO Interface |
// |
input [gw-1:0] ext_pad_i; // GPIO Inputs |
`ifdef GPIO_CLKPAD |
input clk_pad_i; // GPIO Eclk |
`endif // GPIO_CLKPAD |
output [gw-1:0] ext_pad_o; // GPIO Outputs |
output [gw-1:0] ext_padoe_o; // GPIO output drivers enables |
|
`ifdef GPIO_IMPLEMENTED |
|
// |
// GPIO Input Register (or no register) |
// |
`ifdef GPIO_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 GPIO_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 GPIO_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 GPIO_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 GPIO_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 GPIO_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 GPIO_RGPIO_CTRL |
reg [1:0] rgpio_ctrl; // RGPIO_CTRL register |
`else |
wire [1:0] rgpio_ctrl; // No register |
`endif |
|
// |
// GPIO Interrupt Status Register (or no register) |
// |
`ifdef GPIO_RGPIO_INTS |
reg [gw-1:0] rgpio_ints; // RGPIO_INTS register |
`else |
wire [gw-1:0] rgpio_ints; // No register |
`endif |
|
// |
// GPIO Enable Clock Register (or no register) |
// |
`ifdef GPIO_RGPIO_ECLK |
reg [gw-1:0] rgpio_eclk; // RGPIO_ECLK register |
`else |
wire [gw-1:0] rgpio_eclk; // No register |
`endif |
|
// |
// GPIO Active Negative Edge Register (or no register) |
// |
`ifdef GPIO_RGPIO_NEC |
reg [gw-1:0] rgpio_nec; // RGPIO_NEC register |
`else |
wire [gw-1:0] rgpio_nec; // No register |
`endif |
|
|
// |
// Synchronization flops for input signals |
// |
`ifdef GPIO_SYNC_IN_WB |
reg [gw-1:0] sync , |
ext_pad_s ; |
`else |
wire [gw-1:0] ext_pad_s ; |
`endif |
|
|
|
// |
// Internal wires & regs |
// |
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 rgpio_ints_sel; // RGPIO_INTS select |
wire rgpio_eclk_sel ; |
wire rgpio_nec_sel ; |
wire full_decoding; // Full address decoding qualification |
wire [gw-1:0] in_muxed; // Muxed inputs |
wire wb_ack; // WB Acknowledge |
wire wb_err; // WB Error |
wire wb_inta; // WB Interrupt |
reg [dw-1:0] wb_dat; // WB Data out |
`ifdef GPIO_REGISTERED_WB_OUTPUTS |
reg wb_ack_o; // WB Acknowledge |
reg wb_err_o; // WB Error |
reg wb_inta_o; // WB Interrupt |
reg [dw-1:0] wb_dat_o; // WB Data out |
`endif |
wire [gw-1:0] out_pad; // GPIO Outputs |
`ifdef GPIO_REGISTERED_IO_OUTPUTS |
reg [gw-1:0] ext_pad_o; // GPIO Outputs |
`endif |
`ifdef GPIO_CLKPAD |
wire [gw-1:0] extc_in; // Muxed inputs sampled by external clock |
wire [gw-1:0] pext_clk; // External clock for posedge flops |
reg [gw-1:0] pextc_sampled; // Posedge external clock sampled inputs |
`ifdef GPIO_NO_NEGEDGE_FLOPS |
`ifdef GPIO_NO_CLKPAD_LOGIC |
`else |
reg [gw-1:0] nextc_sampled; // Negedge external clock sampled inputs |
`endif // GPIO_NO_CLKPAD_LOGIC |
`else |
reg [gw-1:0] nextc_sampled; // Negedge external clock sampled inputs |
`endif |
`endif // GPIO_CLKPAD |
|
|
// |
// 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) wb_sel_i evaluation is enabled and one of the wb_sel_i inputs is zero |
// |
|
// |
// WB Acknowledge |
// |
assign wb_ack = wb_cyc_i & wb_stb_i & !wb_err_o; |
|
// |
// Optional registration of WB Ack |
// |
`ifdef GPIO_REGISTERED_WB_OUTPUTS |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
wb_ack_o <= #1 1'b0; |
else |
wb_ack_o <= #1 wb_ack & ~wb_ack_o & (!wb_err) ; |
`else |
assign wb_ack_o = wb_ack; |
`endif |
|
// |
// WB Error |
// |
`ifdef GPIO_FULL_DECODE |
`ifdef GPIO_STRICT_32BIT_ACCESS |
assign wb_err = wb_cyc_i & wb_stb_i & (!full_decoding | (wb_sel_i != 4'b1111)); |
`else |
assign wb_err = wb_cyc_i & wb_stb_i & !full_decoding; |
`endif |
`else |
`ifdef GPIO_STRICT_32BIT_ACCESS |
assign wb_err = wb_cyc_i & wb_stb_i & (wb_sel_i != 4'b1111); |
`else |
assign wb_err = 1'b0; |
`endif |
`endif |
|
// |
// Optional registration of WB error |
// |
`ifdef GPIO_REGISTERED_WB_OUTPUTS |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
wb_err_o <= #1 1'b0; |
else |
wb_err_o <= #1 wb_err & ~wb_err_o; |
`else |
assign wb_err_o = wb_err; |
`endif |
|
// |
// Full address decoder |
// |
`ifdef GPIO_FULL_DECODE |
assign full_decoding = (wb_adr_i[`GPIO_ADDRHH:`GPIO_ADDRHL] == {`GPIO_ADDRHH-`GPIO_ADDRHL+1{1'b0}}) & |
(wb_adr_i[`GPIO_ADDRLH:`GPIO_ADDRLL] == {`GPIO_ADDRLH-`GPIO_ADDRLL+1{1'b0}}); |
`else |
assign full_decoding = 1'b1; |
`endif |
|
// |
// GPIO registers address decoder |
// |
`ifdef GPIO_RGPIO_OUT |
assign rgpio_out_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_OUT) & full_decoding; |
`endif |
`ifdef GPIO_RGPIO_OE |
assign rgpio_oe_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_OE) & full_decoding; |
`endif |
`ifdef GPIO_RGPIO_INTE |
assign rgpio_inte_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_INTE) & full_decoding; |
`endif |
`ifdef GPIO_RGPIO_PTRIG |
assign rgpio_ptrig_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_PTRIG) & full_decoding; |
`endif |
`ifdef GPIO_RGPIO_AUX |
assign rgpio_aux_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_AUX) & full_decoding; |
`endif |
`ifdef GPIO_RGPIO_CTRL |
assign rgpio_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_CTRL) & full_decoding; |
`endif |
`ifdef GPIO_RGPIO_INTS |
assign rgpio_ints_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_INTS) & full_decoding; |
`endif |
`ifdef GPIO_RGPIO_ECLK |
assign rgpio_eclk_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_ECLK) & full_decoding; |
`endif |
`ifdef GPIO_RGPIO_NEC |
assign rgpio_nec_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_NEC) & full_decoding; |
`endif |
|
|
// |
// Write to RGPIO_CTRL or update of RGPIO_CTRL[INT] bit |
// |
`ifdef GPIO_RGPIO_CTRL |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rgpio_ctrl <= #1 2'b0; |
else if (rgpio_ctrl_sel && wb_we_i) |
rgpio_ctrl <= #1 wb_dat_i[1:0]; |
else if (rgpio_ctrl[`GPIO_RGPIO_CTRL_INTE]) |
rgpio_ctrl[`GPIO_RGPIO_CTRL_INTS] <= #1 rgpio_ctrl[`GPIO_RGPIO_CTRL_INTS] | wb_inta_o; |
`else |
assign rgpio_ctrl = 2'h01; // RGPIO_CTRL[EN] = 1 |
`endif |
|
// |
// Write to RGPIO_OUT |
// |
`ifdef GPIO_RGPIO_OUT |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rgpio_out <= #1 {gw{1'b0}}; |
else if (rgpio_out_sel && wb_we_i) |
begin |
`ifdef GPIO_STRICT_32BIT_ACCESS |
rgpio_out <= #1 wb_dat_i[gw-1:0]; |
`endif |
|
`ifdef GPIO_WB_BYTES4 |
if ( wb_sel_i [3] == 1'b1 ) |
rgpio_out [gw-1:24] <= #1 wb_dat_i [gw-1:24] ; |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_out [23:16] <= #1 wb_dat_i [23:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_out [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_out [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES3 |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_out [gw-1:16] <= #1 wb_dat_i [gw-1:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_out [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_out [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES2 |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_out [gw-1:8] <= #1 wb_dat_i [gw-1:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_out [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES1 |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_out [gw-1:0] <= #1 wb_dat_i [gw-1:0] ; |
`endif |
end |
|
`else |
assign rgpio_out = `GPIO_DEF_RGPIO_OUT; // RGPIO_OUT = 0x0 |
`endif |
|
// |
// Write to RGPIO_OE. |
// |
`ifdef GPIO_RGPIO_OE |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rgpio_oe <= #1 {gw{1'b0}}; |
else if (rgpio_oe_sel && wb_we_i) |
begin |
`ifdef GPIO_STRICT_32BIT_ACCESS |
rgpio_oe <= #1 wb_dat_i[gw-1:0]; |
`endif |
|
`ifdef GPIO_WB_BYTES4 |
if ( wb_sel_i [3] == 1'b1 ) |
rgpio_oe [gw-1:24] <= #1 wb_dat_i [gw-1:24] ; |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_oe [23:16] <= #1 wb_dat_i [23:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_oe [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_oe [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES3 |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_oe [gw-1:16] <= #1 wb_dat_i [gw-1:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_oe [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_oe [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES2 |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_oe [gw-1:8] <= #1 wb_dat_i [gw-1:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_oe [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES1 |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_oe [gw-1:0] <= #1 wb_dat_i [gw-1:0] ; |
`endif |
end |
|
`else |
assign rgpio_oe = `GPIO_DEF_RGPIO_OE; // RGPIO_OE = 0x0 |
`endif |
|
// |
// Write to RGPIO_INTE |
// |
`ifdef GPIO_RGPIO_INTE |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rgpio_inte <= #1 {gw{1'b0}}; |
else if (rgpio_inte_sel && wb_we_i) |
begin |
`ifdef GPIO_STRICT_32BIT_ACCESS |
rgpio_inte <= #1 wb_dat_i[gw-1:0]; |
`endif |
|
`ifdef GPIO_WB_BYTES4 |
if ( wb_sel_i [3] == 1'b1 ) |
rgpio_inte [gw-1:24] <= #1 wb_dat_i [gw-1:24] ; |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_inte [23:16] <= #1 wb_dat_i [23:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_inte [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_inte [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES3 |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_inte [gw-1:16] <= #1 wb_dat_i [gw-1:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_inte [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_inte [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES2 |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_inte [gw-1:8] <= #1 wb_dat_i [gw-1:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_inte [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES1 |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_inte [gw-1:0] <= #1 wb_dat_i [gw-1:0] ; |
`endif |
end |
|
|
`else |
assign rgpio_inte = `GPIO_DEF_RGPIO_INTE; // RGPIO_INTE = 0x0 |
`endif |
|
// |
// Write to RGPIO_PTRIG |
// |
`ifdef GPIO_RGPIO_PTRIG |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rgpio_ptrig <= #1 {gw{1'b0}}; |
else if (rgpio_ptrig_sel && wb_we_i) |
begin |
`ifdef GPIO_STRICT_32BIT_ACCESS |
rgpio_ptrig <= #1 wb_dat_i[gw-1:0]; |
`endif |
|
`ifdef GPIO_WB_BYTES4 |
if ( wb_sel_i [3] == 1'b1 ) |
rgpio_ptrig [gw-1:24] <= #1 wb_dat_i [gw-1:24] ; |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_ptrig [23:16] <= #1 wb_dat_i [23:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_ptrig [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_ptrig [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES3 |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_ptrig [gw-1:16] <= #1 wb_dat_i [gw-1:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_ptrig [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_ptrig [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES2 |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_ptrig [gw-1:8] <= #1 wb_dat_i [gw-1:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_ptrig [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES1 |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_ptrig [gw-1:0] <= #1 wb_dat_i [gw-1:0] ; |
`endif |
end |
|
`else |
assign rgpio_ptrig = `GPIO_DEF_RGPIO_PTRIG; // RGPIO_PTRIG = 0x0 |
`endif |
|
// |
// Write to RGPIO_AUX |
// |
`ifdef GPIO_RGPIO_AUX |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rgpio_aux <= #1 {gw{1'b0}}; |
else if (rgpio_aux_sel && wb_we_i) |
begin |
`ifdef GPIO_STRICT_32BIT_ACCESS |
rgpio_aux <= #1 wb_dat_i[gw-1:0]; |
`endif |
|
`ifdef GPIO_WB_BYTES4 |
if ( wb_sel_i [3] == 1'b1 ) |
rgpio_aux [gw-1:24] <= #1 wb_dat_i [gw-1:24] ; |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_aux [23:16] <= #1 wb_dat_i [23:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_aux [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_aux [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES3 |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_aux [gw-1:16] <= #1 wb_dat_i [gw-1:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_aux [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_aux [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES2 |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_aux [gw-1:8] <= #1 wb_dat_i [gw-1:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_aux [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES1 |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_aux [gw-1:0] <= #1 wb_dat_i [gw-1:0] ; |
`endif |
end |
|
`else |
assign rgpio_aux = `GPIO_DEF_RGPIO_AUX; // RGPIO_AUX = 0x0 |
`endif |
|
|
// |
// Write to RGPIO_ECLK |
// |
`ifdef GPIO_RGPIO_ECLK |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rgpio_eclk <= #1 {gw{1'b0}}; |
else if (rgpio_eclk_sel && wb_we_i) |
begin |
`ifdef GPIO_STRICT_32BIT_ACCESS |
rgpio_eclk <= #1 wb_dat_i[gw-1:0]; |
`endif |
|
`ifdef GPIO_WB_BYTES4 |
if ( wb_sel_i [3] == 1'b1 ) |
rgpio_eclk [gw-1:24] <= #1 wb_dat_i [gw-1:24] ; |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_eclk [23:16] <= #1 wb_dat_i [23:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_eclk [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_eclk [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES3 |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_eclk [gw-1:16] <= #1 wb_dat_i [gw-1:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_eclk [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_eclk [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES2 |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_eclk [gw-1:8] <= #1 wb_dat_i [gw-1:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_eclk [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES1 |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_eclk [gw-1:0] <= #1 wb_dat_i [gw-1:0] ; |
`endif |
end |
|
|
`else |
assign rgpio_eclk = `GPIO_DEF_RGPIO_ECLK; // RGPIO_ECLK = 0x0 |
`endif |
|
|
|
// |
// Write to RGPIO_NEC |
// |
`ifdef GPIO_RGPIO_NEC |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rgpio_nec <= #1 {gw{1'b0}}; |
else if (rgpio_nec_sel && wb_we_i) |
begin |
`ifdef GPIO_STRICT_32BIT_ACCESS |
rgpio_nec <= #1 wb_dat_i[gw-1:0]; |
`endif |
|
`ifdef GPIO_WB_BYTES4 |
if ( wb_sel_i [3] == 1'b1 ) |
rgpio_nec [gw-1:24] <= #1 wb_dat_i [gw-1:24] ; |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_nec [23:16] <= #1 wb_dat_i [23:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_nec [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_nec [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES3 |
if ( wb_sel_i [2] == 1'b1 ) |
rgpio_nec [gw-1:16] <= #1 wb_dat_i [gw-1:16] ; |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_nec [15:8] <= #1 wb_dat_i [15:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_nec [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES2 |
if ( wb_sel_i [1] == 1'b1 ) |
rgpio_nec [gw-1:8] <= #1 wb_dat_i [gw-1:8] ; |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_nec [7:0] <= #1 wb_dat_i [7:0] ; |
`endif |
`ifdef GPIO_WB_BYTES1 |
if ( wb_sel_i [0] == 1'b1 ) |
rgpio_nec [gw-1:0] <= #1 wb_dat_i [gw-1:0] ; |
`endif |
end |
|
|
`else |
assign rgpio_nec = `GPIO_DEF_RGPIO_NEC; // RGPIO_NEC = 0x0 |
`endif |
|
// |
// synchronize inputs to systam clock |
// |
`ifdef GPIO_SYNC_IN_WB |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) begin |
sync <= #1 {gw{1'b0}} ; |
ext_pad_s <= #1 {gw{1'b0}} ; |
end else begin |
sync <= #1 ext_pad_i ; |
ext_pad_s <= #1 sync ; |
end |
`else |
assign ext_pad_s = ext_pad_i; |
`endif // GPIO_SYNC_IN_WB |
|
// |
// Latch into RGPIO_IN |
// |
`ifdef GPIO_RGPIO_IN |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rgpio_in <= #1 {gw{1'b0}}; |
else |
rgpio_in <= #1 in_muxed; |
`else |
assign rgpio_in = in_muxed; |
`endif |
|
`ifdef GPIO_CLKPAD |
|
`ifdef GPIO_SYNC_CLK_WB |
// |
// external clock enabled |
// synchronized to system clock |
// (one clock domain) |
// |
|
reg sync_clk, |
clk_s , |
clk_r ; |
wire pedge , |
nedge ; |
wire [gw-1:0] pedge_vec , |
nedge_vec ; |
wire [gw-1:0] in_lach ; |
|
assign pedge = clk_s & !clk_r ; |
assign nedge = !clk_s & clk_r ; |
assign pedge_vec = {gw{pedge}} ; |
assign nedge_vec = {gw{nedge}} ; |
|
assign in_lach = (~rgpio_nec & pedge_vec) | (rgpio_nec & nedge_vec) ; |
assign extc_in = (in_lach & ext_pad_s) | (~in_lach & pextc_sampled) ; |
|
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) begin |
sync_clk <= #1 1'b0 ; |
clk_s <= #1 1'b0 ; |
clk_r <= #1 1'b0 ; |
end else begin |
sync_clk <= #1 clk_pad_i ; |
clk_s <= #1 sync_clk ; |
clk_r <= #1 clk_s ; |
end |
|
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) begin |
pextc_sampled <= #1 {gw{1'b0}}; |
end else begin |
pextc_sampled <= #1 extc_in ; |
end |
|
assign in_muxed = (rgpio_eclk & pextc_sampled) | (~rgpio_eclk & ext_pad_s) ; |
|
`else |
// |
// external clock enabled |
// not synchronized to system clock |
// (two clock domains) |
// |
|
`ifdef GPIO_SYNC_IN_CLK_WB |
|
reg [gw-1:0] syn_extc , |
extc_s ; |
|
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) begin |
syn_extc <= #1 {gw{1'b0}}; |
extc_s <= #1 {gw{1'b0}}; |
end else begin |
syn_extc <= #1 extc_in ; |
extc_s <= #1 syn_extc; |
end |
|
`else |
|
wire [gw-1:0] extc_s ; |
assign extc_s = syn_extc ; |
|
`endif // GPIO_SYNC_IN_CLK_WB |
|
`ifdef GPIO_SYNC_IN_CLK |
reg [gw-1:0] syn_pclk , |
ext_pad_spc ; |
|
always @(posedge clk_pad_i or posedge wb_rst_i) |
if (wb_rst_i) begin |
syn_pclk <= #1 {gw{1'b0}} ; |
ext_pad_spc <= #1 {gw{1'b0}} ; |
end else begin |
syn_pclk <= #1 ext_pad_i ; |
ext_pad_spc <= #1 syn_pclk ; |
end |
|
`else |
|
wire [gw-1:0] ext_pad_spc ; |
assign ext_pad_spc = ext_pad_i ; |
|
`endif // GPIO_SYNC_IN_CLK |
|
always @(posedge clk_pad_i or posedge wb_rst_i) |
if (wb_rst_i) begin |
pextc_sampled <= #1 {gw{1'b0}}; |
end else begin |
pextc_sampled <= #1 ext_pad_spc ; |
end |
|
|
`ifdef GPIO_NO_NEGEDGE_FLOPS |
|
`ifdef GPIO_NO_CLKPAD_LOGIC |
|
assign extc_in = pextc_sampled; |
|
`else |
|
wire clk_n; |
assign clk_n = !clk_pad_i; |
|
`ifdef GPIO_SYNC_IN_CLK |
reg [gw-1:0] syn_nclk , |
ext_pad_snc ; |
|
always @(posedge clk_n or posedge wb_rst_i) |
if (wb_rst_i) begin |
syn_nclk <= #1 {gw{1'b0}} ; |
ext_pad_snc <= #1 {gw{1'b0}} ; |
end else begin |
syn_nclk <= #1 ext_pad_i ; |
ext_pad_snc <= #1 syn_nclk ; |
end |
|
`else |
|
wire [gw-1:0] ext_pad_snc ; |
assign ext_pad_snc = ext_pad_i ; |
|
`endif // GPIO_SYNC_IN_CLK |
|
always @(posedge clk_n or posedge wb_rst_i) |
if (wb_rst_i) begin |
nextc_sampled <= #1 {gw{1'b0}}; |
end else begin |
nextc_sampled <= #1 ext_pad_snc ; |
end |
|
assign extc_in = (~rgpio_nec & pextc_sampled) | (rgpio_nec & nextc_sampled) ; |
|
`endif // GPIO_NO_CLKPAD_LOGIC |
|
|
`else |
|
`ifdef GPIO_SYNC_IN_CLK |
reg [gw-1:0] syn_nclk , |
ext_pad_snc ; |
|
always @(negedge clk_n or posedge wb_rst_i) |
if (wb_rst_i) begin |
syn_nclk <= #1 {gw{1'b0}} ; |
ext_pad_snc <= #1 {gw{1'b0}} ; |
end else begin |
syn_nclk <= #1 ext_pad_i ; |
ext_pad_snc <= #1 syn_nclk ; |
end |
|
`else |
|
wire [gw-1:0] ext_pad_snc ; |
assign ext_pad_snc = ext_pad_i ; |
|
`endif // GPIO_SYNC_IN_CLK |
|
always @(negedge clk_pad_i or posedge wb_rst_i) |
if (wb_rst_i) begin |
nextc_sampled <= #1 {gw{1'b0}}; |
end else begin |
nextc_sampled <= #1 ext_pad_snc ; |
end |
|
assign extc_in = (~rgpio_nec & pextc_sampled) | (rgpio_nec & nextc_sampled) ; |
|
`endif // GPIO_NO_NEGEDGE_FLOPS |
|
assign in_muxed = (rgpio_eclk & extc_s) | (~rgpio_eclk & ext_pad_s) ; |
|
|
`endif // GPIO_SYNC_CLK_WB |
|
|
`else |
|
assign in_muxed = ext_pad_s ; |
|
`endif // GPIO_CLKPAD |
|
|
|
// |
// Mux all registers when doing a read of GPIO registers |
// |
always @(wb_adr_i or rgpio_in or rgpio_out or rgpio_oe or rgpio_inte or |
rgpio_ptrig or rgpio_aux or rgpio_ctrl or rgpio_ints or rgpio_eclk or rgpio_nec) |
case (wb_adr_i[`GPIO_OFS_BITS]) // synopsys full_case parallel_case |
`ifdef GPIO_READREGS |
`ifdef GPIO_RGPIO_OUT |
`GPIO_RGPIO_OUT: begin |
wb_dat[dw-1:0] = rgpio_out; |
end |
`endif |
`ifdef GPIO_RGPIO_OE |
`GPIO_RGPIO_OE: begin |
wb_dat[dw-1:0] = rgpio_oe; |
end |
`endif |
`ifdef GPIO_RGPIO_INTE |
`GPIO_RGPIO_INTE: begin |
wb_dat[dw-1:0] = rgpio_inte; |
end |
`endif |
`ifdef GPIO_RGPIO_PTRIG |
`GPIO_RGPIO_PTRIG: begin |
wb_dat[dw-1:0] = rgpio_ptrig; |
end |
`endif |
`ifdef GPIO_RGPIO_NEC |
`GPIO_RGPIO_NEC: begin |
wb_dat[dw-1:0] = rgpio_nec; |
end |
`endif |
`ifdef GPIO_RGPIO_ECLK |
`GPIO_RGPIO_ECLK: begin |
wb_dat[dw-1:0] = rgpio_eclk; |
end |
`endif |
`ifdef GPIO_RGPIO_AUX |
`GPIO_RGPIO_AUX: begin |
wb_dat[dw-1:0] = rgpio_aux; |
end |
`endif |
`ifdef GPIO_RGPIO_CTRL |
`GPIO_RGPIO_CTRL: begin |
wb_dat[1:0] = rgpio_ctrl; |
wb_dat[dw-1:2] = {dw-2{1'b0}}; |
end |
`endif |
`endif |
`ifdef GPIO_RGPIO_INTS |
`GPIO_RGPIO_INTS: begin |
wb_dat[dw-1:0] = rgpio_ints; |
end |
`endif |
default: begin |
wb_dat[dw-1:0] = rgpio_in; |
end |
endcase |
|
// |
// WB data output |
// |
`ifdef GPIO_REGISTERED_WB_OUTPUTS |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
wb_dat_o <= #1 {dw{1'b0}}; |
else |
wb_dat_o <= #1 wb_dat; |
`else |
assign wb_dat_o = wb_dat; |
`endif |
|
// |
// RGPIO_INTS |
// |
`ifdef GPIO_RGPIO_INTS |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
rgpio_ints <= #1 {gw{1'b0}}; |
else if (rgpio_ints_sel && wb_we_i) |
rgpio_ints <= #1 wb_dat_i[gw-1:0]; |
else if (rgpio_ctrl[`GPIO_RGPIO_CTRL_INTE]) |
rgpio_ints <= #1 (rgpio_ints | ((in_muxed ^ rgpio_in) & ~(in_muxed ^ rgpio_ptrig)) & rgpio_inte); |
`else |
assign rgpio_ints = (rgpio_ints | ((in_muxed ^ rgpio_in) & ~(in_muxed ^ rgpio_ptrig)) & rgpio_inte); |
`endif |
|
// |
// Generate interrupt request |
// |
assign wb_inta = |rgpio_ints ? rgpio_ctrl[`GPIO_RGPIO_CTRL_INTE] : 1'b0; |
|
// |
// Optional registration of WB interrupt |
// |
`ifdef GPIO_REGISTERED_WB_OUTPUTS |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
wb_inta_o <= #1 1'b0; |
else |
wb_inta_o <= #1 wb_inta; |
`else |
assign wb_inta_o = wb_inta; |
`endif // GPIO_REGISTERED_WB_OUTPUTS |
|
// |
// Output enables are RGPIO_OE bits |
// |
assign ext_padoe_o = rgpio_oe; |
|
// |
// Generate GPIO outputs |
// |
`ifdef GPIO_AUX_IMPLEMENT |
assign out_pad = rgpio_out & ~rgpio_aux | aux_i & rgpio_aux; |
`else |
assign out_pad = rgpio_out ; |
`endif // GPIO_AUX_IMPLEMENT |
|
// |
// Optional registration of GPIO outputs |
// |
`ifdef GPIO_REGISTERED_IO_OUTPUTS |
always @(posedge wb_clk_i or posedge wb_rst_i) |
if (wb_rst_i) |
ext_pad_o <= #1 {gw{1'b0}}; |
else |
ext_pad_o <= #1 out_pad; |
`else |
assign ext_pad_o = out_pad; |
`endif // GPIO_REGISTERED_IO_OUTPUTS |
|
|
`else |
|
// |
// When GPIO is not implemented, drive all outputs as would when RGPIO_CTRL |
// is cleared and WISHBONE transfers complete with errors |
// |
assign wb_inta_o = 1'b0; |
assign wb_ack_o = 1'b0; |
assign wb_err_o = wb_cyc_i & wb_stb_i; |
assign ext_padoe_o = {gw{1'b1}}; |
assign ext_pad_o = {gw{1'b0}}; |
|
// |
// Read GPIO registers |
// |
assign wb_dat_o = {dw{1'b0}}; |
|
`endif // GPIO_IMPLEMENTED |
|
endmodule |
|
/rtl/minsoc_top.ucf
0,0 → 1,36
|
NET "clk" LOC = E12; # 50 MHz on-board clock oscillator |
NET "reset" LOC = T14; # Push Button BTN_NORTH |
|
# UART Peripheral |
NET "uart_stx" LOC = E15; # RS232 Serial port ( DTE Connector ) |
NET "uart_srx" LOC = F16; # |
|
# GPIO |
NET "io_pins<0>" LOC = R20; |
NET "io_pins<1>" LOC = T19; |
NET "io_pins<2>" LOC = U20; |
NET "io_pins<3>" LOC = U19; |
NET "io_pins<4>" LOC = V19; |
NET "io_pins<5>" LOC = V20; |
NET "io_pins<6>" LOC = Y22; |
NET "io_pins<7>" LOC = W21; |
|
NET "i_pins<0>" LOC = V8; |
NET "i_pins<1>" LOC = U10; |
NET "i_pins<2>" LOC = U8; |
NET "i_pins<3>" LOC = T9; |
NET "i_pins<4>" LOC = T16; |
NET "i_pins<5>" LOC = U15; |
#NET "i_pins<6>" LOC = ; |
NET "i_pins<7>" LOC = T15; |
|
################################################################################# |
# Pin constraints including the IOSTANDARD and DRIVE |
# Reference : Spartan-3A/3AN FPGA Starter Kit Board User Guide ( UG334 v1.1 ) |
################################################################################# |
|
#NET "clk" LOC = E12 | IOSTANDARD = LVCMOS33; |
#NET "uart_stx" LOC = E15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; |
#NET "uart_srx" LOC = F16 | IOSTANDARD = LVCMOS33; |
#NET "reset" LOC = T14 | IOSTANDARD = LVCMOS33 | PULLDOWN ; |
/rtl/minsoc_defines.v
0,0 → 1,130
// |
// Define FPGA manufacturer |
// |
//`define GENERIC_FPGA |
//`define ALTERA_FPGA |
`define XILINX_FPGA |
|
// |
// Define FPGA Model (comment all out for ALTERA) |
// |
//`define SPARTAN2 |
//`define SPARTAN3 |
//`define SPARTAN3E |
`define SPARTAN3A |
//`define VIRTEX |
//`define VIRTEX2 |
//`define VIRTEX4 |
//`define VIRTEX5 |
|
|
// |
// Memory |
// |
`define MEMORY_ADR_WIDTH 13 //MEMORY_ADR_WIDTH IS NOT ALLOWED TO BE LESS THAN 12, memory is composed by blocks of address width 11 |
//Address width of memory -> select memory depth, 2 powers MEMORY_ADR_WIDTH defines the memory depth |
//the memory data width is 32 bit, memory amount in Bytes = 4*memory depth |
|
// |
// Memory type (uncomment something if ASIC or generic memory) |
// |
//`define GENERIC_MEMORY |
//`define AVANT_ATP |
//`define VIRAGE_SSP |
//`define VIRTUALSILICON_SSP |
|
|
// |
// TAP selection |
// |
//`define GENERIC_TAP |
`define FPGA_TAP |
|
// |
// Clock Division selection |
// |
//`define NO_CLOCK_DIVISION |
//`define GENERIC_CLOCK_DIVISION |
`define FPGA_CLOCK_DIVISION //Altera ALTPLL is not implemented, didn't find the code for its verilog instantiation |
//if you selected altera and this, the GENERIC_CLOCK_DIVISION will be automatically taken |
|
// |
// Define division |
// |
`define CLOCK_DIVISOR 5 //in case of GENERIC_CLOCK_DIVISION the real value will be rounded down to an even value |
//in FPGA case, check minsoc_clock_manager for allowed divisors |
//DO NOT USE CLOCK_DIVISOR = 1 COMMENT THE CLOCK DIVISION SELECTION INSTEAD |
|
// |
// Reset polarity |
// |
//`define NEGATIVE_RESET; //rstn |
`define POSITIVE_RESET; //rst |
|
// |
// Start-up circuit (only necessary later to load firmware automatically from SPI memory) |
// |
//`define START_UP |
|
// |
// Connected modules |
// |
`define UART |
//`define ETHERNET |
`define GPIO |
|
// |
// Ethernet reset |
// |
//`define ETH_RESET 1'b0 |
`define ETH_RESET 1'b1 |
|
// |
// GPIO Pins |
// |
`define GPIO_HAS_INPUT_PINS |
//`define GPIO_HAS_OUTPUT_PINS |
`define GPIO_HAS_BIDIR_PINS |
|
`define GPIO_NUM_INPUT 4'd8 |
`define GPIO_NUM_OUTPUT 4'd0 |
`define GPIO_NUM_BIDIR 4'd8 |
|
// |
// Interrupts |
// |
`define APP_INT_RES1 1:0 |
`define APP_INT_UART 2 |
`define APP_INT_RES2 3 |
`define APP_INT_ETH 4 |
`define APP_INT_PS2 5 |
`define APP_INT_GPIO 6 |
`define APP_INT_RES3 19:7 |
|
// |
// Address map |
// |
`define APP_ADDR_DEC_W 8 |
`define APP_ADDR_SRAM `APP_ADDR_DEC_W'h00 |
`define APP_ADDR_FLASH `APP_ADDR_DEC_W'h04 |
`define APP_ADDR_DECP_W 4 |
`define APP_ADDR_PERIP `APP_ADDR_DECP_W'h9 |
`define APP_ADDR_SPI `APP_ADDR_DEC_W'h97 |
`define APP_ADDR_ETH `APP_ADDR_DEC_W'h92 |
`define APP_ADDR_AUDIO `APP_ADDR_DEC_W'h9d |
`define APP_ADDR_UART `APP_ADDR_DEC_W'h90 |
`define APP_ADDR_PS2 `APP_ADDR_DEC_W'h94 |
`define APP_ADDR_GPIO `APP_ADDR_DEC_W'h9e |
`define APP_ADDR_RES2 `APP_ADDR_DEC_W'h9f |
|
// |
// Set-up GENERIC_TAP, GENERIC_MEMORY if GENERIC_FPGA was chosen |
// and GENERIC_CLOCK_DIVISION if NO_CLOCK_DIVISION was not set |
// |
`ifdef GENERIC_FPGA |
`define GENERIC_TAP |
`define GENERIC_MEMORY |
`ifndef NO_CLOCK_DIVISION |
`define GENERIC_CLOCK_DIVISION |
`endif |
`endif |
/rtl/minsoc_spartan_3a_starter_kit_ios.v
0,0 → 1,224
////////////////////////////////////////////////////////////////////////////////// |
// Company: |
// Engineer: |
// |
// Create Date: 11:51:27 10/29/2009 |
// Design Name: |
// Module Name: minsoc_spartan_3a_starter_kit_ios |
// Project Name: |
// Target Devices: |
// Tool versions: |
// Description: |
// |
// Dependencies: |
// |
// Revision: |
// Revision 0.01 - File Created |
// Additional Comments: |
// |
////////////////////////////////////////////////////////////////////////////////// |
|
module minsoc_spartan_3a_starter_kit_ios |
( |
// Signals from GPIO Core |
ext_pad_o, |
ext_pad_oe, |
ext_pad_i, |
|
// Signals driving external pins |
i_pins, |
o_pins, |
io_pins |
); |
parameter gpio_num = 32; |
parameter i_line_num = 8; |
parameter o_line_num = 8; |
parameter io_line_num= 8; |
|
input [gpio_num-1:0] ext_pad_o; |
input [gpio_num-1:0] ext_pad_oe; |
output [gpio_num-1:0] ext_pad_i; |
|
input [i_line_num-1:0] i_pins; |
output [o_line_num-1:0] o_pins; |
inout [io_line_num-1:0] io_pins; |
|
IOBUF #( |
.DRIVE(12), // Specify the output drive strength |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for the buffer, "0"-"16" (Spartan-3E only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only) |
.IOSTANDARD("DEFAULT"), // Specify the I/O standard |
.SLEW("SLOW") // Specify the output slew rate |
) IOBUF_inst_0 ( |
.O(ext_pad_i[0]), // Buffer output |
.IO(io_pins[0]), // Buffer inout port (connect directly to top-level port) |
.I(ext_pad_o[0]), // Buffer input |
.T(~ext_pad_oe[0]) // 3-state enable input |
); |
|
IOBUF #( |
.DRIVE(12), // Specify the output drive strength |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for the buffer, "0"-"16" (Spartan-3E only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only) |
.IOSTANDARD("DEFAULT"), // Specify the I/O standard |
.SLEW("SLOW") // Specify the output slew rate |
) IOBUF_inst_1 ( |
.O(ext_pad_i[1]), // Buffer output |
.IO(io_pins[1]), // Buffer inout port (connect directly to top-level port) |
.I(ext_pad_o[1]), // Buffer input |
.T(~ext_pad_oe[1]) // 3-state enable input |
); |
|
IOBUF #( |
.DRIVE(12), // Specify the output drive strength |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for the buffer, "0"-"16" (Spartan-3E only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only) |
.IOSTANDARD("DEFAULT"), // Specify the I/O standard |
.SLEW("SLOW") // Specify the output slew rate |
) IOBUF_inst_2 ( |
.O(ext_pad_i[2]), // Buffer output |
.IO(io_pins[2]), // Buffer inout port (connect directly to top-level port) |
.I(ext_pad_o[2]), // Buffer input |
.T(~ext_pad_oe[2]) // 3-state enable input |
); |
|
IOBUF #( |
.DRIVE(12), // Specify the output drive strength |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for the buffer, "0"-"16" (Spartan-3E only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only) |
.IOSTANDARD("DEFAULT"), // Specify the I/O standard |
.SLEW("SLOW") // Specify the output slew rate |
) IOBUF_inst_3 ( |
.O(ext_pad_i[3]), // Buffer output |
.IO(io_pins[3]), // Buffer inout port (connect directly to top-level port) |
.I(ext_pad_o[3]), // Buffer input |
.T(~ext_pad_oe[3]) // 3-state enable input |
); |
|
IOBUF #( |
.DRIVE(12), // Specify the output drive strength |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for the buffer, "0"-"16" (Spartan-3E only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only) |
.IOSTANDARD("DEFAULT"), // Specify the I/O standard |
.SLEW("SLOW") // Specify the output slew rate |
) IOBUF_inst_4 ( |
.O(ext_pad_i[4]), // Buffer output |
.IO(io_pins[4]), // Buffer inout port (connect directly to top-level port) |
.I(ext_pad_o[4]), // Buffer input |
.T(~ext_pad_oe[4]) // 3-state enable input |
); |
|
IOBUF #( |
.DRIVE(12), // Specify the output drive strength |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for the buffer, "0"-"16" (Spartan-3E only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only) |
.IOSTANDARD("DEFAULT"), // Specify the I/O standard |
.SLEW("SLOW") // Specify the output slew rate |
) IOBUF_inst_5 ( |
.O(ext_pad_i[5]), // Buffer output |
.IO(io_pins[5]), // Buffer inout port (connect directly to top-level port) |
.I(ext_pad_o[5]), // Buffer input |
.T(~ext_pad_oe[5]) // 3-state enable input |
); |
|
IOBUF #( |
.DRIVE(12), // Specify the output drive strength |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for the buffer, "0"-"16" (Spartan-3E only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only) |
.IOSTANDARD("DEFAULT"), // Specify the I/O standard |
.SLEW("SLOW") // Specify the output slew rate |
) IOBUF_inst_6 ( |
.O(ext_pad_i[6]), // Buffer output |
.IO(io_pins[6]), // Buffer inout port (connect directly to top-level port) |
.I(ext_pad_o[6]), // Buffer input |
.T(~ext_pad_oe[6]) // 3-state enable input |
); |
|
IOBUF #( |
.DRIVE(12), // Specify the output drive strength |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for the buffer, "0"-"16" (Spartan-3E only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only) |
.IOSTANDARD("DEFAULT"), // Specify the I/O standard |
.SLEW("SLOW") // Specify the output slew rate |
) IOBUF_inst_7 ( |
.O(ext_pad_i[7]), // Buffer output |
.IO(io_pins[7]), // Buffer inout port (connect directly to top-level port) |
.I(ext_pad_o[7]), // Buffer input |
.T(~ext_pad_oe[7]) // 3-state enable input |
); |
|
|
IBUF #( |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for // the buffer, "0"-"16" (Spartan-3E/3A only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input // register, "AUTO", "0"-"8" (Spartan-3E/3A only) |
.IOSTANDARD("DEFAULT") // Specify the input I/O standard |
)IBUF_inst_0 ( |
.O(ext_pad_i[8]), // Buffer output |
.I(i_pins[0]) // Buffer input (connect directly to top-level port) |
); |
|
IBUF #( |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for // the buffer, "0"-"16" (Spartan-3E/3A only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input // register, "AUTO", "0"-"8" (Spartan-3E/3A only) |
.IOSTANDARD("DEFAULT") // Specify the input I/O standard |
)IBUF_inst_1 ( |
.O(ext_pad_i[9]), // Buffer output |
.I(i_pins[1]) // Buffer input (connect directly to top-level port) |
); |
|
IBUF #( |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for // the buffer, "0"-"16" (Spartan-3E/3A only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input // register, "AUTO", "0"-"8" (Spartan-3E/3A only) |
.IOSTANDARD("DEFAULT") // Specify the input I/O standard |
)IBUF_inst_2 ( |
.O(ext_pad_i[10]), // Buffer output |
.I(i_pins[2]) // Buffer input (connect directly to top-level port) |
); |
|
IBUF #( |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for // the buffer, "0"-"16" (Spartan-3E/3A only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input // register, "AUTO", "0"-"8" (Spartan-3E/3A only) |
.IOSTANDARD("DEFAULT") // Specify the input I/O standard |
)IBUF_inst_3 ( |
.O(ext_pad_i[11]), // Buffer output |
.I(i_pins[3]) // Buffer input (connect directly to top-level port) |
); |
|
IBUF #( |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for // the buffer, "0"-"16" (Spartan-3E/3A only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input // register, "AUTO", "0"-"8" (Spartan-3E/3A only) |
.IOSTANDARD("DEFAULT") // Specify the input I/O standard |
)IBUF_inst_4 ( |
.O(ext_pad_i[12]), // Buffer output |
.I(i_pins[4]) // Buffer input (connect directly to top-level port) |
); |
|
IBUF #( |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for // the buffer, "0"-"16" (Spartan-3E/3A only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input // register, "AUTO", "0"-"8" (Spartan-3E/3A only) |
.IOSTANDARD("DEFAULT") // Specify the input I/O standard |
)IBUF_inst_5 ( |
.O(ext_pad_i[13]), // Buffer output |
.I(i_pins[5]) // Buffer input (connect directly to top-level port) |
); |
|
/* PUSH Button NORTH is RESET. |
IBUF #( |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for // the buffer, "0"-"16" (Spartan-3E/3A only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input // register, "AUTO", "0"-"8" (Spartan-3E/3A only) |
.IOSTANDARD("DEFAULT") // Specify the input I/O standard |
)IBUF_inst_6 ( |
.O(ext_pad_i[14]), // Buffer output |
.I(i_pins[6]) // Buffer input (connect directly to top-level port) |
); |
*/ |
|
IBUF #( |
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for // the buffer, "0"-"16" (Spartan-3E/3A only) |
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input // register, "AUTO", "0"-"8" (Spartan-3E/3A only) |
.IOSTANDARD("DEFAULT") // Specify the input I/O standard |
)IBUF_inst_7 ( |
.O(ext_pad_i[15]), // Buffer output |
.I(i_pins[7]) // Buffer input (connect directly to top-level port) |
); |
endmodule |
/rtl/minsoc_top.v
0,0 → 1,1105
`include "minsoc_defines.v" |
`include "or1200_defines.v" |
|
`include "gpio_defines.v" |
|
module minsoc_top ( |
clk,reset |
|
//JTAG ports |
`ifdef GENERIC_TAP |
, jtag_tdi,jtag_tms,jtag_tck, |
jtag_tdo,jtag_vref,jtag_gnd |
`endif |
|
//SPI ports |
`ifdef START_UP |
, spi_flash_mosi, spi_flash_miso, spi_flash_sclk, spi_flash_ss |
`endif |
|
//UART ports |
`ifdef UART |
, uart_stx,uart_srx |
`endif |
|
// Ethernet ports |
`ifdef ETHERNET |
, eth_col, eth_crs, eth_trste, eth_tx_clk, |
eth_tx_en, eth_tx_er, eth_txd, eth_rx_clk, |
eth_rx_dv, eth_rx_er, eth_rxd, eth_fds_mdint, |
eth_mdc, eth_mdio |
`endif |
|
// GPIO ports |
`ifdef GPIO |
`ifdef GPIO_HAS_INPUT_PINS |
,i_pins |
`endif |
`ifdef GPIO_HAS_OUTPUT_PINS |
,o_pins |
`endif |
`ifdef GPIO_HAS_BIDIR_PINS |
,io_pins |
`endif |
`endif |
); |
|
// |
// I/O Ports |
// |
|
input clk; |
input reset; |
|
// |
// SPI controller external i/f wires |
// |
`ifdef START_UP |
output spi_flash_mosi; |
input spi_flash_miso; |
output spi_flash_sclk; |
output [1:0] spi_flash_ss; |
`endif |
|
// |
// UART |
// |
`ifdef UART |
output uart_stx; |
input uart_srx; |
`endif |
|
// |
// Ethernet |
// |
`ifdef ETHERNET |
output eth_tx_er; |
input eth_tx_clk; |
output eth_tx_en; |
output [3:0] eth_txd; |
input eth_rx_er; |
input eth_rx_clk; |
input eth_rx_dv; |
input [3:0] eth_rxd; |
input eth_col; |
input eth_crs; |
output eth_trste; |
input eth_fds_mdint; |
inout eth_mdio; |
output eth_mdc; |
`endif |
|
// |
// GPIO |
// |
`ifdef GPIO |
`ifdef GPIO_HAS_INPUT_PINS |
input [`GPIO_NUM_INPUT-1:0] i_pins; |
`endif |
`ifdef GPIO_HAS_OUTPUT_PINS |
output [`GPIO_NUM_OUTPUT-1:0] o_pins; |
`endif |
`ifdef GPIO_HAS_BIDIR_PINS |
inout [`GPIO_NUM_BIDIR-1:0] io_pins; |
`endif |
`endif |
|
// |
// JTAG |
// |
`ifdef GENERIC_TAP |
input jtag_tdi; |
input jtag_tms; |
input jtag_tck; |
output jtag_tdo; |
output jtag_vref; |
output jtag_gnd; |
|
|
assign jtag_vref = 1'b1; |
assign jtag_gnd = 1'b0; |
`endif |
|
wire rstn; |
|
`ifdef POSITIVE_RESET |
assign rstn = ~reset; |
`elsif NEGATIVE_RESET |
assign rstn = reset; |
`endif |
|
// |
// Internal wires |
// |
|
// |
// Debug core master i/f wires |
// |
wire [31:0] wb_dm_adr_o; |
wire [31:0] wb_dm_dat_i; |
wire [31:0] wb_dm_dat_o; |
wire [3:0] wb_dm_sel_o; |
wire wb_dm_we_o; |
wire wb_dm_stb_o; |
wire wb_dm_cyc_o; |
wire wb_dm_ack_i; |
wire wb_dm_err_i; |
|
// |
// Debug <-> RISC wires |
// |
wire [3:0] dbg_lss; |
wire [1:0] dbg_is; |
wire [10:0] dbg_wp; |
wire dbg_bp; |
wire [31:0] dbg_dat_dbg; |
wire [31:0] dbg_dat_risc; |
wire [31:0] dbg_adr; |
wire dbg_ewt; |
wire dbg_stall; |
wire [2:0] dbg_op; //dbg_op[0] = dbg_we //dbg_op[2] = dbg_stb (didn't change for backward compatibility with DBG_IF_MODEL |
wire dbg_ack; |
|
// |
// RISC instruction master i/f wires |
// |
wire [31:0] wb_rim_adr_o; |
wire wb_rim_cyc_o; |
wire [31:0] wb_rim_dat_i; |
wire [31:0] wb_rim_dat_o; |
wire [3:0] wb_rim_sel_o; |
wire wb_rim_ack_i; |
wire wb_rim_err_i; |
wire wb_rim_rty_i = 1'b0; |
wire wb_rim_we_o; |
wire wb_rim_stb_o; |
wire [31:0] wb_rif_dat_i; |
wire wb_rif_ack_i; |
|
// |
// RISC data master i/f wires |
// |
wire [31:0] wb_rdm_adr_o; |
wire wb_rdm_cyc_o; |
wire [31:0] wb_rdm_dat_i; |
wire [31:0] wb_rdm_dat_o; |
wire [3:0] wb_rdm_sel_o; |
wire wb_rdm_ack_i; |
wire wb_rdm_err_i; |
wire wb_rdm_rty_i = 1'b0; |
wire wb_rdm_we_o; |
wire wb_rdm_stb_o; |
|
// |
// RISC misc |
// |
wire [19:0] pic_ints; |
|
// |
// Flash controller slave i/f wires |
// |
wire [31:0] wb_fs_dat_i; |
wire [31:0] wb_fs_dat_o; |
wire [31:0] wb_fs_adr_i; |
wire [3:0] wb_fs_sel_i; |
wire wb_fs_we_i; |
wire wb_fs_cyc_i; |
wire wb_fs_stb_i; |
wire wb_fs_ack_o; |
wire wb_fs_err_o; |
|
// |
// SPI controller slave i/f wires |
// |
wire [31:0] wb_sp_dat_i; |
wire [31:0] wb_sp_dat_o; |
wire [31:0] wb_sp_adr_i; |
wire [3:0] wb_sp_sel_i; |
wire wb_sp_we_i; |
wire wb_sp_cyc_i; |
wire wb_sp_stb_i; |
wire wb_sp_ack_o; |
wire wb_sp_err_o; |
|
// |
// SPI controller external i/f wires |
// |
wire spi_flash_mosi; |
wire spi_flash_miso; |
wire spi_flash_sclk; |
wire [1:0] spi_flash_ss; |
|
// |
// SRAM controller slave i/f wires |
// |
wire [31:0] wb_ss_dat_i; |
wire [31:0] wb_ss_dat_o; |
wire [31:0] wb_ss_adr_i; |
wire [3:0] wb_ss_sel_i; |
wire wb_ss_we_i; |
wire wb_ss_cyc_i; |
wire wb_ss_stb_i; |
wire wb_ss_ack_o; |
wire wb_ss_err_o; |
|
// |
// Ethernet core master i/f wires |
// |
wire [31:0] wb_em_adr_o; |
wire [31:0] wb_em_dat_i; |
wire [31:0] wb_em_dat_o; |
wire [3:0] wb_em_sel_o; |
wire wb_em_we_o; |
wire wb_em_stb_o; |
wire wb_em_cyc_o; |
wire wb_em_ack_i; |
wire wb_em_err_i; |
|
// |
// Ethernet core slave i/f wires |
// |
wire [31:0] wb_es_dat_i; |
wire [31:0] wb_es_dat_o; |
wire [31:0] wb_es_adr_i; |
wire [3:0] wb_es_sel_i; |
wire wb_es_we_i; |
wire wb_es_cyc_i; |
wire wb_es_stb_i; |
wire wb_es_ack_o; |
wire wb_es_err_o; |
|
// |
// Ethernet external i/f wires |
// |
wire eth_mdo; |
wire eth_mdoe; |
|
// |
// UART16550 core slave i/f wires |
// |
wire [31:0] wb_us_dat_i; |
wire [31:0] wb_us_dat_o; |
wire [31:0] wb_us_adr_i; |
wire [3:0] wb_us_sel_i; |
wire wb_us_we_i; |
wire wb_us_cyc_i; |
wire wb_us_stb_i; |
wire wb_us_ack_o; |
wire wb_us_err_o; |
|
// |
// UART external i/f wires |
// |
wire uart_stx; |
wire uart_srx; |
|
// |
// GPIO core slave i/f wires |
// |
wire [31:0] wb_gpio_dat_i; |
wire [31:0] wb_gpio_dat_o; |
wire [31:0] wb_gpio_adr_i; |
wire [3:0] wb_gpio_sel_i; |
wire wb_gpio_we_i; |
wire wb_gpio_cyc_i; |
wire wb_gpio_stb_i; |
wire wb_gpio_ack_o; |
wire wb_gpio_err_o; |
|
// |
// Interface to GPIO core - Device specific core |
// |
wire [`GPIO_IOS:0] ext_pad_o; |
wire [`GPIO_IOS:0] ext_pad_i; |
wire [`GPIO_IOS:0] ext_pad_oe_o; |
|
// |
// Reset debounce |
// |
reg rst_r; |
reg wb_rst; |
|
// |
// Global clock |
// |
wire wb_clk; |
|
// |
// Reset debounce |
// |
always @(posedge wb_clk or negedge rstn) |
if (~rstn) |
rst_r <= 1'b1; |
else |
rst_r <= #1 1'b0; |
|
// |
// Reset debounce |
// |
always @(posedge wb_clk) |
wb_rst <= #1 rst_r; |
|
// |
// Clock Divider |
// |
minsoc_clock_manager # |
( |
.divisor(`CLOCK_DIVISOR) |
) |
clk_adjust ( |
.clk_i(clk), |
.clk_o(wb_clk) |
); |
|
// |
// Unused WISHBONE signals |
// |
assign wb_us_err_o = 1'b0; |
assign wb_fs_err_o = 1'b0; |
assign wb_sp_err_o = 1'b0; |
|
// |
// Unused interrupts |
// |
assign pic_ints[`APP_INT_RES1] = 'b0; |
assign pic_ints[`APP_INT_RES2] = 'b0; |
assign pic_ints[`APP_INT_RES3] = 'b0; |
assign pic_ints[`APP_INT_PS2] = 'b0; |
|
// |
// Ethernet tri-state |
// |
`ifdef ETHERNET |
assign eth_mdio = eth_mdoe ? eth_mdo : 1'bz; |
assign eth_trste = `ETH_RESET; |
`endif |
|
|
// |
// RISC Instruction address for Flash |
// |
// Until first access to real Flash area, |
// CPU instruction is fixed to jump to the Flash area. |
// After Flash area is accessed, CPU instructions |
// come from the tc_top (wishbone "switch"). |
// |
`ifdef START_UP |
reg jump_flash; |
reg [3:0] rif_counter; |
reg [31:0] rif_dat_int; |
reg rif_ack_int; |
|
always @(posedge wb_clk or negedge rstn) |
begin |
if (!rstn) begin |
jump_flash <= #1 1'b1; |
rif_counter <= 4'h0; |
rif_ack_int <= 1'b0; |
end |
else begin |
rif_ack_int <= 1'b0; |
|
if (wb_rim_cyc_o && (wb_rim_adr_o[31:32-`APP_ADDR_DEC_W] == `APP_ADDR_FLASH)) |
jump_flash <= #1 1'b0; |
|
if ( jump_flash == 1'b1 ) begin |
if ( wb_rim_cyc_o && wb_rim_stb_o && ~wb_rim_we_o ) begin |
rif_counter <= rif_counter + 1'b1; |
rif_ack_int <= 1'b1; |
end |
end |
end |
end |
|
always @ (rif_counter) |
begin |
case ( rif_counter ) |
4'h0: rif_dat_int = { `OR1200_OR32_MOVHI , 5'h01 , 4'h0 , 1'b0 , `APP_ADDR_FLASH , 8'h00 }; |
4'h1: rif_dat_int = { `OR1200_OR32_ORI , 5'h01 , 5'h01 , 16'h0000 }; |
4'h2: rif_dat_int = { `OR1200_OR32_JR , 10'h000 , 5'h01 , 11'h000 }; |
4'h3: rif_dat_int = { `OR1200_OR32_NOP , 10'h000 , 16'h0000 }; |
default: rif_dat_int = 32'h0000_0000; |
endcase |
end |
|
assign wb_rif_dat_i = jump_flash ? rif_dat_int : wb_rim_dat_i; |
|
assign wb_rif_ack_i = jump_flash ? rif_ack_int : wb_rim_ack_i; |
|
`else |
assign wb_rif_dat_i = wb_rim_dat_i; |
assign wb_rif_ack_i = wb_rim_ack_i; |
`endif |
|
|
// |
// TAP<->dbg_interface |
// |
wire jtag_tck; |
wire debug_tdi; |
wire debug_tdo; |
wire capture_dr; |
wire shift_dr; |
wire pause_dr; |
wire update_dr; |
|
wire debug_select; |
wire test_logic_reset; |
|
// |
// Instantiation of the development i/f |
// |
adbg_top dbg_top ( |
|
// JTAG pins |
.tck_i ( jtag_tck ), |
.tdi_i ( debug_tdi ), |
.tdo_o ( debug_tdo ), |
.rst_i ( test_logic_reset ), //cable without rst |
|
// Boundary Scan signals |
.capture_dr_i ( capture_dr ), |
.shift_dr_i ( shift_dr ), |
.pause_dr_i ( pause_dr ), |
.update_dr_i ( update_dr ), |
|
.debug_select_i( debug_select ), |
// WISHBONE common |
.wb_clk_i ( wb_clk ), |
|
// WISHBONE master interface |
.wb_adr_o ( wb_dm_adr_o ), |
.wb_dat_i ( wb_dm_dat_i ), |
.wb_dat_o ( wb_dm_dat_o ), |
.wb_sel_o ( wb_dm_sel_o ), |
.wb_we_o ( wb_dm_we_o ), |
.wb_stb_o ( wb_dm_stb_o ), |
.wb_cyc_o ( wb_dm_cyc_o ), |
.wb_ack_i ( wb_dm_ack_i ), |
.wb_err_i ( wb_dm_err_i ), |
.wb_cti_o ( ), |
.wb_bte_o ( ), |
|
// RISC signals |
.cpu0_clk_i ( wb_clk ), |
.cpu0_addr_o ( dbg_adr ), |
.cpu0_data_i ( dbg_dat_risc ), |
.cpu0_data_o ( dbg_dat_dbg ), |
.cpu0_bp_i ( dbg_bp ), |
.cpu0_stall_o( dbg_stall ), |
.cpu0_stb_o ( dbg_op[2] ), |
.cpu0_we_o ( dbg_op[0] ), |
.cpu0_ack_i ( dbg_ack ), |
.cpu0_rst_o ( ) |
|
); |
|
// |
// JTAG TAP controller instantiation |
// |
`ifdef GENERIC_TAP |
tap_top tap_top( |
// JTAG pads |
.tms_pad_i(jtag_tms), |
.tck_pad_i(jtag_tck), |
.trstn_pad_i(rstn), |
.tdi_pad_i(jtag_tdi), |
.tdo_pad_o(jtag_tdo), |
.tdo_padoe_o( ), |
|
// TAP states |
.test_logic_reset_o( test_logic_reset ), |
.run_test_idle_o(), |
.shift_dr_o(shift_dr), |
.pause_dr_o(pause_dr), |
.update_dr_o(update_dr), |
.capture_dr_o(capture_dr), |
|
// Select signals for boundary scan or mbist |
.extest_select_o(), |
.sample_preload_select_o(), |
.mbist_select_o(), |
.debug_select_o(debug_select), |
|
// TDO signal that is connected to TDI of sub-modules. |
.tdi_o(debug_tdi), |
|
// TDI signals from sub-modules |
.debug_tdo_i(debug_tdo), // from debug module |
.bs_chain_tdo_i(1'b0), // from Boundary Scan Chain |
.mbist_tdo_i(1'b0) // from Mbist Chain |
); |
`elsif FPGA_TAP |
`ifdef ALTERA_FPGA |
altera_virtual_jtag tap_top( |
.tck_o(jtag_tck), |
.debug_tdo_o(debug_tdo), |
.tdi_o(debug_tdi), |
.test_logic_reset_o(test_logic_reset), |
.run_test_idle_o(), |
.shift_dr_o(shift_dr), |
.capture_dr_o(capture_dr), |
.pause_dr_o(pause_dr), |
.update_dr_o(update_dr), |
.debug_select_o(debug_select) |
); |
`elsif XILINX_FPGA |
minsoc_xilinx_internal_jtag tap_top( |
.tck_o( jtag_tck ), |
.debug_tdo_i( debug_tdo ), |
.tdi_o( debug_tdi ), |
|
.test_logic_reset_o( test_logic_reset ), |
.run_test_idle_o( ), |
|
.shift_dr_o( shift_dr ), |
.capture_dr_o( capture_dr ), |
.pause_dr_o( pause_dr ), |
.update_dr_o( update_dr ), |
.debug_select_o( debug_select ) |
); |
`endif // !FPGA_TAP |
|
`endif // !GENERIC_TAP |
|
// |
// Instantiation of the OR1200 RISC |
// |
or1200_top or1200_top ( |
|
// Common |
.rst_i ( wb_rst ), |
.clk_i ( wb_clk ), |
`ifdef OR1200_CLMODE_1TO2 |
.clmode_i ( 2'b01 ), |
`else |
`ifdef OR1200_CLMODE_1TO4 |
.clmode_i ( 2'b11 ), |
`else |
.clmode_i ( 2'b00 ), |
`endif |
`endif |
|
// WISHBONE Instruction Master |
.iwb_clk_i ( wb_clk ), |
.iwb_rst_i ( wb_rst ), |
.iwb_cyc_o ( wb_rim_cyc_o ), |
.iwb_adr_o ( wb_rim_adr_o ), |
.iwb_dat_i ( wb_rif_dat_i ), |
.iwb_dat_o ( wb_rim_dat_o ), |
.iwb_sel_o ( wb_rim_sel_o ), |
.iwb_ack_i ( wb_rif_ack_i ), |
.iwb_err_i ( wb_rim_err_i ), |
.iwb_rty_i ( wb_rim_rty_i ), |
.iwb_we_o ( wb_rim_we_o ), |
.iwb_stb_o ( wb_rim_stb_o ), |
|
// WISHBONE Data Master |
.dwb_clk_i ( wb_clk ), |
.dwb_rst_i ( wb_rst ), |
.dwb_cyc_o ( wb_rdm_cyc_o ), |
.dwb_adr_o ( wb_rdm_adr_o ), |
.dwb_dat_i ( wb_rdm_dat_i ), |
.dwb_dat_o ( wb_rdm_dat_o ), |
.dwb_sel_o ( wb_rdm_sel_o ), |
.dwb_ack_i ( wb_rdm_ack_i ), |
.dwb_err_i ( wb_rdm_err_i ), |
.dwb_rty_i ( wb_rdm_rty_i ), |
.dwb_we_o ( wb_rdm_we_o ), |
.dwb_stb_o ( wb_rdm_stb_o ), |
|
// Debug |
.dbg_stall_i ( dbg_stall ), |
.dbg_dat_i ( dbg_dat_dbg ), |
.dbg_adr_i ( dbg_adr ), |
.dbg_ewt_i ( 1'b0 ), |
.dbg_lss_o ( dbg_lss ), |
.dbg_is_o ( dbg_is ), |
.dbg_wp_o ( dbg_wp ), |
.dbg_bp_o ( dbg_bp ), |
.dbg_dat_o ( dbg_dat_risc ), |
.dbg_ack_o ( dbg_ack ), |
.dbg_stb_i ( dbg_op[2] ), |
.dbg_we_i ( dbg_op[0] ), |
|
// Power Management |
.pm_clksd_o ( ), |
.pm_cpustall_i ( 1'b0 ), |
.pm_dc_gate_o ( ), |
.pm_ic_gate_o ( ), |
.pm_dmmu_gate_o ( ), |
.pm_immu_gate_o ( ), |
.pm_tt_gate_o ( ), |
.pm_cpu_gate_o ( ), |
.pm_wakeup_o ( ), |
.pm_lvolt_o ( ), |
|
// Interrupts |
.pic_ints_i ( pic_ints ) |
); |
|
// |
// Startup OR1k |
// |
`ifdef START_UP |
OR1K_startup OR1K_startup0 |
( |
.wb_adr_i(wb_fs_adr_i[6:2]), |
.wb_stb_i(wb_fs_stb_i), |
.wb_cyc_i(wb_fs_cyc_i), |
.wb_dat_o(wb_fs_dat_o), |
.wb_ack_o(wb_fs_ack_o), |
.wb_clk(wb_clk), |
.wb_rst(wb_rst) |
); |
|
spi_flash_top # |
( |
.divider(0), |
.divider_len(2) |
) |
spi_flash_top0 |
( |
.wb_clk_i(wb_clk), |
.wb_rst_i(wb_rst), |
.wb_adr_i(wb_sp_adr_i[4:2]), |
.wb_dat_i(wb_sp_dat_i), |
.wb_dat_o(wb_sp_dat_o), |
.wb_sel_i(wb_sp_sel_i), |
.wb_we_i(wb_sp_we_i), |
.wb_stb_i(wb_sp_stb_i), |
.wb_cyc_i(wb_sp_cyc_i), |
.wb_ack_o(wb_sp_ack_o), |
|
.mosi_pad_o(spi_flash_mosi), |
.miso_pad_i(spi_flash_miso), |
.sclk_pad_o(spi_flash_sclk), |
.ss_pad_o(spi_flash_ss) |
); |
`else |
assign wb_fs_dat_o = 32'h0000_0000; |
assign wb_fs_ack_o = 1'b0; |
assign wb_sp_dat_o = 32'h0000_0000; |
assign wb_sp_ack_o = 1'b0; |
`endif |
|
// |
// Instantiation of the SRAM controller |
// |
minsoc_onchip_ram_top # |
( |
.adr_width(`MEMORY_ADR_WIDTH) //16 blocks of 2048 bytes memory 32768 |
) |
onchip_ram_top ( |
|
// WISHBONE common |
.wb_clk_i ( wb_clk ), |
.wb_rst_i ( wb_rst ), |
|
// WISHBONE slave |
.wb_dat_i ( wb_ss_dat_i ), |
.wb_dat_o ( wb_ss_dat_o ), |
.wb_adr_i ( wb_ss_adr_i ), |
.wb_sel_i ( wb_ss_sel_i ), |
.wb_we_i ( wb_ss_we_i ), |
.wb_cyc_i ( wb_ss_cyc_i ), |
.wb_stb_i ( wb_ss_stb_i ), |
.wb_ack_o ( wb_ss_ack_o ), |
.wb_err_o ( wb_ss_err_o ) |
); |
|
// |
// Instantiation of the UART16550 |
// |
`ifdef UART |
uart_top uart_top ( |
|
// WISHBONE common |
.wb_clk_i ( wb_clk ), |
.wb_rst_i ( wb_rst ), |
|
// WISHBONE slave |
.wb_adr_i ( wb_us_adr_i[4:0] ), |
.wb_dat_i ( wb_us_dat_i ), |
.wb_dat_o ( wb_us_dat_o ), |
.wb_we_i ( wb_us_we_i ), |
.wb_stb_i ( wb_us_stb_i ), |
.wb_cyc_i ( wb_us_cyc_i ), |
.wb_ack_o ( wb_us_ack_o ), |
.wb_sel_i ( wb_us_sel_i ), |
|
// Interrupt request |
.int_o ( pic_ints[`APP_INT_UART] ), |
|
// UART signals |
// serial input/output |
.stx_pad_o ( uart_stx ), |
.srx_pad_i ( uart_srx ), |
|
// modem signals |
.rts_pad_o ( ), |
.cts_pad_i ( 1'b0 ), |
.dtr_pad_o ( ), |
.dsr_pad_i ( 1'b0 ), |
.ri_pad_i ( 1'b0 ), |
.dcd_pad_i ( 1'b0 ) |
); |
`else |
assign wb_us_dat_o = 32'h0000_0000; |
assign wb_us_ack_o = 1'b0; |
`endif |
|
|
// |
// Instantiation of the GPIO |
// |
`ifdef GPIO |
gpio_top #( .gw(`GPIO_IOS + 1) ) |
gpio_top_inst ( |
|
// WISHBONE common |
.wb_clk_i ( wb_clk ), |
.wb_rst_i ( wb_rst ), |
|
// WISHBONE slave |
.wb_adr_i ( wb_gpio_adr_i[4:0] ), |
.wb_dat_i ( wb_gpio_dat_i ), |
.wb_dat_o ( wb_gpio_dat_o ), |
.wb_we_i ( wb_gpio_we_i ), |
.wb_stb_i ( wb_gpio_stb_i ), |
.wb_cyc_i ( wb_gpio_cyc_i ), |
.wb_ack_o ( wb_gpio_ack_o ), |
.wb_sel_i ( wb_gpio_sel_i ), |
|
// Interrupt request |
.wb_inta_o ( pic_ints[`APP_INT_GPIO] ), |
|
// GPIO external signals |
.ext_pad_o ( ext_pad_o ), |
.ext_pad_i ( ext_pad_i ), |
.ext_padoe_o( ext_pad_oe_o ) |
|
); |
|
minsoc_spartan_3a_starter_kit_ios #( .gpio_num(`GPIO_IOS + 1), |
`ifdef GPIO_HAS_INPUT_PINS |
.i_line_num(`GPIO_NUM_INPUT), |
`endif |
`ifdef GPIO_HAS_OUTPUT_PINS |
.o_line_num(`GPIO_NUM_OUTPUT), |
`endif |
`ifdef GPIO_HAS_BIDIR_PINS |
.io_line_num(`GPIO_NUM_BIDIR) |
`endif |
) minsoc_spartan_3a_starter_kit_ios_inst_0 ( |
.ext_pad_o( ext_pad_o ), |
.ext_pad_oe( ext_pad_oe_o ), |
.ext_pad_i( ext_pad_i ), |
`ifdef GPIO_HAS_INPUT_PINS |
.i_pins( i_pins ), |
`else |
.i_pins( ), |
`endif |
`ifdef GPIO_HAS_OUTPUT_PINS |
.o_pins( o_pins ), |
`else |
.o_pins( ), |
`endif |
`ifdef GPIO_HAS_BIDIR_PINS |
.io_pins( io_pins ) |
`else |
.io_pins( ) |
`endif |
); |
|
`else |
assign wb_gpio_dat_o = 32'h0000_0000; |
assign wb_gpio_ack_o = 1'b0; |
`endif |
|
|
|
// |
// Instantiation of the Ethernet 10/100 MAC |
// |
`ifdef ETHERNET |
eth_top eth_top ( |
|
// WISHBONE common |
.wb_clk_i ( wb_clk ), |
.wb_rst_i ( wb_rst ), |
|
// WISHBONE slave |
.wb_dat_i ( wb_es_dat_i ), |
.wb_dat_o ( wb_es_dat_o ), |
.wb_adr_i ( wb_es_adr_i[11:2] ), |
.wb_sel_i ( wb_es_sel_i ), |
.wb_we_i ( wb_es_we_i ), |
.wb_cyc_i ( wb_es_cyc_i ), |
.wb_stb_i ( wb_es_stb_i ), |
.wb_ack_o ( wb_es_ack_o ), |
.wb_err_o ( wb_es_err_o ), |
|
// WISHBONE master |
.m_wb_adr_o ( wb_em_adr_o ), |
.m_wb_sel_o ( wb_em_sel_o ), |
.m_wb_we_o ( wb_em_we_o ), |
.m_wb_dat_o ( wb_em_dat_o ), |
.m_wb_dat_i ( wb_em_dat_i ), |
.m_wb_cyc_o ( wb_em_cyc_o ), |
.m_wb_stb_o ( wb_em_stb_o ), |
.m_wb_ack_i ( wb_em_ack_i ), |
.m_wb_err_i ( wb_em_err_i ), |
|
// TX |
.mtx_clk_pad_i ( eth_tx_clk ), |
.mtxd_pad_o ( eth_txd ), |
.mtxen_pad_o ( eth_tx_en ), |
.mtxerr_pad_o ( eth_tx_er ), |
|
// RX |
.mrx_clk_pad_i ( eth_rx_clk ), |
.mrxd_pad_i ( eth_rxd ), |
.mrxdv_pad_i ( eth_rx_dv ), |
.mrxerr_pad_i ( eth_rx_er ), |
.mcoll_pad_i ( eth_col ), |
.mcrs_pad_i ( eth_crs ), |
|
// MIIM |
.mdc_pad_o ( eth_mdc ), |
.md_pad_i ( eth_mdio ), |
.md_pad_o ( eth_mdo ), |
.md_padoe_o ( eth_mdoe ), |
|
// Interrupt |
.int_o ( pic_ints[`APP_INT_ETH] ) |
); |
`else |
assign wb_es_dat_o = 32'h0000_0000; |
assign wb_es_ack_o = 1'b0; |
|
assign wb_em_adr_o = 32'h0000_0000; |
assign wb_em_sel_o = 4'h0; |
assign wb_em_we_o = 1'b0; |
assign wb_em_dat_o = 32'h0000_0000; |
assign wb_em_cyc_o = 1'b0; |
assign wb_em_stb_o = 1'b0; |
`endif |
|
// |
// Instantiation of the Traffic COP |
// |
minsoc_tc_top #(`APP_ADDR_DEC_W, |
`APP_ADDR_SRAM, |
`APP_ADDR_DEC_W, |
`APP_ADDR_FLASH, |
`APP_ADDR_DECP_W, |
`APP_ADDR_PERIP, |
`APP_ADDR_DEC_W, |
`APP_ADDR_SPI, |
`APP_ADDR_ETH, |
`APP_ADDR_AUDIO, |
`APP_ADDR_UART, |
`APP_ADDR_PS2, |
`APP_ADDR_GPIO, |
`APP_ADDR_RES2 |
) tc_top ( |
|
// WISHBONE common |
.wb_clk_i ( wb_clk ), |
.wb_rst_i ( wb_rst ), |
|
// WISHBONE Initiator 0 |
.i0_wb_cyc_i ( 1'b0 ), |
.i0_wb_stb_i ( 1'b0 ), |
.i0_wb_adr_i ( 32'h0000_0000 ), |
.i0_wb_sel_i ( 4'b0000 ), |
.i0_wb_we_i ( 1'b0 ), |
.i0_wb_dat_i ( 32'h0000_0000 ), |
.i0_wb_dat_o ( ), |
.i0_wb_ack_o ( ), |
.i0_wb_err_o ( ), |
|
// WISHBONE Initiator 1 |
.i1_wb_cyc_i ( wb_em_cyc_o ), |
.i1_wb_stb_i ( wb_em_stb_o ), |
.i1_wb_adr_i ( wb_em_adr_o ), |
.i1_wb_sel_i ( wb_em_sel_o ), |
.i1_wb_we_i ( wb_em_we_o ), |
.i1_wb_dat_i ( wb_em_dat_o ), |
.i1_wb_dat_o ( wb_em_dat_i ), |
.i1_wb_ack_o ( wb_em_ack_i ), |
.i1_wb_err_o ( wb_em_err_i ), |
|
// WISHBONE Initiator 2 |
.i2_wb_cyc_i ( 1'b0 ), |
.i2_wb_stb_i ( 1'b0 ), |
.i2_wb_adr_i ( 32'h0000_0000 ), |
.i2_wb_sel_i ( 4'b0000 ), |
.i2_wb_we_i ( 1'b0 ), |
.i2_wb_dat_i ( 32'h0000_0000 ), |
.i2_wb_dat_o ( ), |
.i2_wb_ack_o ( ), |
.i2_wb_err_o ( ), |
|
// WISHBONE Initiator 3 |
.i3_wb_cyc_i ( wb_dm_cyc_o ), |
.i3_wb_stb_i ( wb_dm_stb_o ), |
.i3_wb_adr_i ( wb_dm_adr_o ), |
.i3_wb_sel_i ( wb_dm_sel_o ), |
.i3_wb_we_i ( wb_dm_we_o ), |
.i3_wb_dat_i ( wb_dm_dat_o ), |
.i3_wb_dat_o ( wb_dm_dat_i ), |
.i3_wb_ack_o ( wb_dm_ack_i ), |
.i3_wb_err_o ( wb_dm_err_i ), |
|
// WISHBONE Initiator 4 |
.i4_wb_cyc_i ( wb_rdm_cyc_o ), |
.i4_wb_stb_i ( wb_rdm_stb_o ), |
.i4_wb_adr_i ( wb_rdm_adr_o ), |
.i4_wb_sel_i ( wb_rdm_sel_o ), |
.i4_wb_we_i ( wb_rdm_we_o ), |
.i4_wb_dat_i ( wb_rdm_dat_o ), |
.i4_wb_dat_o ( wb_rdm_dat_i ), |
.i4_wb_ack_o ( wb_rdm_ack_i ), |
.i4_wb_err_o ( wb_rdm_err_i ), |
|
// WISHBONE Initiator 5 |
.i5_wb_cyc_i ( wb_rim_cyc_o ), |
.i5_wb_stb_i ( wb_rim_stb_o ), |
.i5_wb_adr_i ( wb_rim_adr_o ), |
.i5_wb_sel_i ( wb_rim_sel_o ), |
.i5_wb_we_i ( wb_rim_we_o ), |
.i5_wb_dat_i ( wb_rim_dat_o ), |
.i5_wb_dat_o ( wb_rim_dat_i ), |
.i5_wb_ack_o ( wb_rim_ack_i ), |
.i5_wb_err_o ( wb_rim_err_i ), |
|
// WISHBONE Initiator 6 |
.i6_wb_cyc_i ( 1'b0 ), |
.i6_wb_stb_i ( 1'b0 ), |
.i6_wb_adr_i ( 32'h0000_0000 ), |
.i6_wb_sel_i ( 4'b0000 ), |
.i6_wb_we_i ( 1'b0 ), |
.i6_wb_dat_i ( 32'h0000_0000 ), |
.i6_wb_dat_o ( ), |
.i6_wb_ack_o ( ), |
.i6_wb_err_o ( ), |
|
// WISHBONE Initiator 7 |
.i7_wb_cyc_i ( 1'b0 ), |
.i7_wb_stb_i ( 1'b0 ), |
.i7_wb_adr_i ( 32'h0000_0000 ), |
.i7_wb_sel_i ( 4'b0000 ), |
.i7_wb_we_i ( 1'b0 ), |
.i7_wb_dat_i ( 32'h0000_0000 ), |
.i7_wb_dat_o ( ), |
.i7_wb_ack_o ( ), |
.i7_wb_err_o ( ), |
|
// WISHBONE Target 0 |
.t0_wb_cyc_o ( wb_ss_cyc_i ), |
.t0_wb_stb_o ( wb_ss_stb_i ), |
.t0_wb_adr_o ( wb_ss_adr_i ), |
.t0_wb_sel_o ( wb_ss_sel_i ), |
.t0_wb_we_o ( wb_ss_we_i ), |
.t0_wb_dat_o ( wb_ss_dat_i ), |
.t0_wb_dat_i ( wb_ss_dat_o ), |
.t0_wb_ack_i ( wb_ss_ack_o ), |
.t0_wb_err_i ( wb_ss_err_o ), |
|
// WISHBONE Target 1 |
.t1_wb_cyc_o ( wb_fs_cyc_i ), |
.t1_wb_stb_o ( wb_fs_stb_i ), |
.t1_wb_adr_o ( wb_fs_adr_i ), |
.t1_wb_sel_o ( wb_fs_sel_i ), |
.t1_wb_we_o ( wb_fs_we_i ), |
.t1_wb_dat_o ( wb_fs_dat_i ), |
.t1_wb_dat_i ( wb_fs_dat_o ), |
.t1_wb_ack_i ( wb_fs_ack_o ), |
.t1_wb_err_i ( wb_fs_err_o ), |
|
// WISHBONE Target 2 |
.t2_wb_cyc_o ( wb_sp_cyc_i ), |
.t2_wb_stb_o ( wb_sp_stb_i ), |
.t2_wb_adr_o ( wb_sp_adr_i ), |
.t2_wb_sel_o ( wb_sp_sel_i ), |
.t2_wb_we_o ( wb_sp_we_i ), |
.t2_wb_dat_o ( wb_sp_dat_i ), |
.t2_wb_dat_i ( wb_sp_dat_o ), |
.t2_wb_ack_i ( wb_sp_ack_o ), |
.t2_wb_err_i ( wb_sp_err_o ), |
|
// WISHBONE Target 3 |
.t3_wb_cyc_o ( wb_es_cyc_i ), |
.t3_wb_stb_o ( wb_es_stb_i ), |
.t3_wb_adr_o ( wb_es_adr_i ), |
.t3_wb_sel_o ( wb_es_sel_i ), |
.t3_wb_we_o ( wb_es_we_i ), |
.t3_wb_dat_o ( wb_es_dat_i ), |
.t3_wb_dat_i ( wb_es_dat_o ), |
.t3_wb_ack_i ( wb_es_ack_o ), |
.t3_wb_err_i ( wb_es_err_o ), |
|
// WISHBONE Target 4 |
.t4_wb_cyc_o ( ), |
.t4_wb_stb_o ( ), |
.t4_wb_adr_o ( ), |
.t4_wb_sel_o ( ), |
.t4_wb_we_o ( ), |
.t4_wb_dat_o ( ), |
.t4_wb_dat_i ( 32'h0000_0000 ), |
.t4_wb_ack_i ( 1'b0 ), |
.t4_wb_err_i ( 1'b1 ), |
|
// WISHBONE Target 5 |
.t5_wb_cyc_o ( wb_us_cyc_i ), |
.t5_wb_stb_o ( wb_us_stb_i ), |
.t5_wb_adr_o ( wb_us_adr_i ), |
.t5_wb_sel_o ( wb_us_sel_i ), |
.t5_wb_we_o ( wb_us_we_i ), |
.t5_wb_dat_o ( wb_us_dat_i ), |
.t5_wb_dat_i ( wb_us_dat_o ), |
.t5_wb_ack_i ( wb_us_ack_o ), |
.t5_wb_err_i ( wb_us_err_o ), |
|
// WISHBONE Target 6 |
.t6_wb_cyc_o ( ), |
.t6_wb_stb_o ( ), |
.t6_wb_adr_o ( ), |
.t6_wb_sel_o ( ), |
.t6_wb_we_o ( ), |
.t6_wb_dat_o ( ), |
.t6_wb_dat_i ( 32'h0000_0000 ), |
.t6_wb_ack_i ( 1'b0 ), |
.t6_wb_err_i ( 1'b1 ), |
|
// WISHBONE Target 7 |
.t7_wb_cyc_o ( wb_gpio_cyc_i ), |
.t7_wb_stb_o ( wb_gpio_stb_i ), |
.t7_wb_adr_o ( wb_gpio_adr_i ), |
.t7_wb_sel_o ( wb_gpio_sel_i ), |
.t7_wb_we_o ( wb_gpio_we_i ), |
.t7_wb_dat_o ( wb_gpio_dat_i ), |
.t7_wb_dat_i ( wb_gpio_dat_o ), |
.t7_wb_ack_i ( wb_gpio_ack_o ), |
.t7_wb_err_i ( wb_gpio_err_o ), |
|
// WISHBONE Target 8 |
.t8_wb_cyc_o ( ), |
.t8_wb_stb_o ( ), |
.t8_wb_adr_o ( ), |
.t8_wb_sel_o ( ), |
.t8_wb_we_o ( ), |
.t8_wb_dat_o ( ), |
.t8_wb_dat_i ( 32'h0000_0000 ), |
.t8_wb_ack_i ( 1'b0 ), |
.t8_wb_err_i ( 1'b1 ) |
); |
|
//initial begin |
// $dumpvars(0); |
// $dumpfile("dump.vcd"); |
//end |
|
endmodule |
/sw/gpio.c
0,0 → 1,225
#include "../support/support.h" |
#include "../support/board.h" |
|
#include "../support/spr_defs.h" |
|
#include "../drivers/uart.h" |
|
#include "gpio.h" |
|
void gpio_init(gpio_t *gpio, long instance_num, unsigned long base_addr) |
{ |
int i = MIN_GPIO_BIT; |
|
if ( gpio != NULL ) { |
gpio->instance_num = instance_num; |
gpio->base_addr = (unsigned char*)base_addr; |
for ( ;i<=MAX_GPIO_BIT;i++) |
gpio->vectors[i].vec = NULL; |
return; |
} else { |
// Print the error msgs here |
// |
uart_print_str("gpio inst in NULL.\n"); |
return; |
} |
} |
|
void gpio_config_bit(gpio_t *gpio, unsigned long bit, iotype_t io) |
{ |
if ( gpio != NULL ) { |
if ( io == IO_INPUT ) { |
gpio->io_config |= (1 << bit); |
*(unsigned long*)(gpio->base_addr + OE_REG_OFFSET) &= (~(1 << bit)); |
} else { |
gpio->io_config &= (~(1 << bit)); |
*(unsigned long*)(gpio->base_addr + OE_REG_OFFSET) |= (1 << bit); |
} |
return; |
} else { |
// Print the error msgs here |
// |
uart_print_str("gpio inst in NULL.\n"); |
return; |
} |
} |
|
void gpio_set_bit(gpio_t *gpio, unsigned long bit, unsigned long val) |
{ |
if ( gpio != NULL ) { |
if ( val != 0 ) |
*(unsigned long*)(gpio->base_addr + OUT_REG_OFFSET) |= (1 << bit); |
else |
*(unsigned long*)(gpio->base_addr + OUT_REG_OFFSET) &= (~(1 << bit)); |
return; |
} else { |
// Print the error msgs here |
// |
uart_print_str("gpio inst in NULL.\n"); |
return; |
} |
} |
|
void gpio_get_bit(gpio_t *gpio, unsigned long bit, unsigned long *val) |
{ |
unsigned long temp; |
|
if ( gpio != NULL ) { |
temp = *(unsigned long*)(gpio->base_addr + IN_REG_OFFSET); |
*val = (temp & (1 << bit))? 1 : 0; |
return; |
} else { |
// Print the error msgs here |
// |
uart_print_str("gpio inst in NULL.\n"); |
return; |
} |
} |
|
|
void gpio_add_interrupt(gpio_t *gpio, unsigned int bit, edge_t edge,void (*func)() ) |
{ |
if ( gpio != NULL ) { |
if ( ( gpio->io_config &(1 << bit)) != 0 ) { // Port bit is configured as IO_INPUT |
// |
// Disable the interrupts |
// |
*(unsigned long*)(gpio->base_addr + CTRL_REG_OFFSET) &= (~0x01); |
|
// Enable the interrupt bit |
// |
*(unsigned long*)(gpio->base_addr + INTE_REG_OFFSET) |= (1 << bit); |
|
// Enable the edge type |
// |
if ( edge == POS_EDGE ) |
*(unsigned long*)(gpio->base_addr + PTRIG_REG_OFFSET) |= (1 << bit); |
else |
*(unsigned long*)(gpio->base_addr + PTRIG_REG_OFFSET) &= (~(1 << bit)); |
|
// Set the function vector |
// |
gpio->vectors[bit].vec = func; |
|
int_add( 6, gpio_interrupt, gpio ); |
|
// Re-enable the global control bit |
// |
*(unsigned long*)(gpio->base_addr + CTRL_REG_OFFSET) |= 0x01; |
} else { |
// Port is configured as IO_OUTPUT |
uart_print_str("gpio pin is not an input pin.\n"); |
return; |
} |
|
} else { |
// Print the error msgs here |
// |
uart_print_str("gpio inst in NULL.\n"); |
return; |
} |
|
} |
|
void gpio_interrupt(gpio_t *gpio) |
{ |
int i; |
unsigned long int interrupt_status; |
|
if ( (*(unsigned long*)(gpio->base_addr + CTRL_REG_OFFSET)) & 0x02 ) |
{ |
// Interrupt is pending here |
// |
interrupt_status = *(unsigned long*)(gpio->base_addr + INTS_REG_OFFSET); |
|
// Prioritize from lower bits(0) to higher ones(31) |
// |
|
for ( i=MIN_GPIO_BIT; i<=MAX_GPIO_BIT; i++ ) { |
if ( (interrupt_status & (1<<i)) ) { |
*(unsigned long*)(gpio->base_addr + INTS_REG_OFFSET) &= (~( 1 << i )); |
(gpio->vectors[i].vec)(); |
} |
} |
|
*(unsigned long*)(gpio->base_addr + CTRL_REG_OFFSET) &= (~0x02); |
|
} |
} |
|
void hello_east() |
{ |
uart_print_str("Hello from PUSH Button EAST.\n"); |
} |
|
|
void hello_west() |
{ |
uart_print_str("Hello from PUSH Button WEST.\n"); |
} |
|
|
void hello_south() |
{ |
uart_print_str("Hello from PUSH Button SOUTH.\n"); |
} |
|
|
|
|
#define MAX_COUNT 10 |
|
int main() |
{ |
gpio_t gpio_1; |
unsigned long t0, t1, t2, t3; |
unsigned long count = 0; |
|
tick_init(); |
uart_init(); |
int_init(); |
int_add(2,&uart_interrupt); |
|
gpio_init( &gpio_1, 1, GPIO_BASE ); |
|
gpio_config_bit( &gpio_1, LED_0, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_1, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_2, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_3, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_4, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_5, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_6, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_7, IO_OUTPUT); |
|
while ( count++ < MAX_COUNT ) { |
gpio_set_bit( &gpio_1, LED_7, 0 ); |
gpio_set_bit( &gpio_1, LED_0, 1 ); |
udelay(); |
gpio_set_bit( &gpio_1, LED_0, 0 ); |
gpio_set_bit( &gpio_1, LED_1, 1 ); |
udelay(); |
gpio_set_bit( &gpio_1, LED_1, 0 ); |
gpio_set_bit( &gpio_1, LED_2, 1 ); |
udelay(); |
gpio_set_bit( &gpio_1, LED_2, 0 ); |
gpio_set_bit( &gpio_1, LED_3, 1 ); |
udelay(); |
gpio_set_bit( &gpio_1, LED_3, 0 ); |
gpio_set_bit( &gpio_1, LED_4, 1 ); |
udelay(); |
gpio_set_bit( &gpio_1, LED_4, 0 ); |
gpio_set_bit( &gpio_1, LED_5, 1 ); |
udelay(); |
gpio_set_bit( &gpio_1, LED_5, 0 ); |
gpio_set_bit( &gpio_1, LED_6, 1 ); |
udelay(); |
gpio_set_bit( &gpio_1, LED_6, 0 ); |
gpio_set_bit( &gpio_1, LED_7, 1 ); |
udelay(); |
} |
|
gpio_set_bit( &gpio_1, LED_7, 0 ); |
|
report(0xdeaddead); |
or32_exit(0); |
} |
/sw/udelay.c
0,0 → 1,13
#include "../support/support.h" |
#include "../support/board.h" |
|
#include "../drivers/tick.h" |
|
extern int tick_int; |
|
void udelay(void) |
{ |
while (!tick_int); |
tick_ack(); |
} |
|
/sw/gpio.h
0,0 → 1,76
#ifndef __GPIO_H__ |
|
#define __GPIO_H__ |
|
#define MIN_GPIO_BIT 0 |
#define MAX_GPIO_BIT 31 |
|
#define TOTAL_GPIO_BITS ((MAX_GPIO_BIT-MIN_GPIO_BIT+1)) |
|
|
#define IN_REG_OFFSET 0x00 |
#define OUT_REG_OFFSET 0x04 |
#define OE_REG_OFFSET 0x08 |
#define INTE_REG_OFFSET 0x0C |
#define PTRIG_REG_OFFSET 0x10 |
#define AUX_REG_OFFSET 0x14 |
#define CTRL_REG_OFFSET 0x18 |
#define INTS_REG_OFFSET 0x1C |
#define ECLK_REG_OFFSET 0x20 |
#define NEC_REG_OFFSET 0x24 |
|
|
typedef struct vector_t_ |
{ |
void (*vec)(); |
} vector_t; |
|
typedef struct gpio_t_ |
{ |
volatile unsigned char *base_addr; |
unsigned int instance_num; |
unsigned int io_config; |
vector_t vectors[TOTAL_GPIO_BITS]; |
} gpio_t; |
|
typedef enum iotype_t_ |
{ |
IO_OUTPUT = 0, |
IO_INPUT = 1 |
} iotype_t; |
|
typedef enum edge_t_ |
{ |
NEG_EDGE = 0, |
POS_EDGE = 1 |
} edge_t; |
|
|
#define LED_0 0x00 |
#define LED_1 0x01 |
#define LED_2 0x02 |
#define LED_3 0x03 |
#define LED_4 0x04 |
#define LED_5 0x05 |
#define LED_6 0x06 |
#define LED_7 0x07 |
|
#define DIP_0 0x08 |
#define DIP_1 0x09 |
#define DIP_2 0x0A |
#define DIP_3 0x0B |
|
#define PUSH_EAST 0x0C |
#define PUSH_WEST 0x0D |
#define PUSH_NORTH 0x0E |
#define PUSH_SOUTH 0x0F |
|
|
void gpio_init(gpio_t *, long, unsigned long); |
void gpio_config_bit(gpio_t *, unsigned long, iotype_t); |
void gpio_set_bit(gpio_t *, unsigned long, unsigned long); |
void gpio_get_bit(gpio_t *, unsigned long, unsigned long *); |
void gpio_add_interrupt(gpio_t *, unsigned int, edge_t,void (*func)() ); |
void gpio_interrupt(gpio_t *gpio); |
|
#endif |
/sw/Makefile
0,0 → 1,26
include ../support/Makefile.inc |
drivers = ../drivers/libdrivers.a |
cases = gpio-nocache gpio-icdc |
common = ../support/libsupport.a ../support/except.o |
|
all: $(cases) |
|
gpio-nocache: gpio.o udelay.o ../support/reset-nocache.o $(common) $(drivers) |
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $(GCC_LIB_OPTS) -T ../support/orp.ld $? -o $@.or32 |
$(OR32_TOOL_PREFIX)-objcopy -O binary $@.or32 $@.bin |
../utils/bin2hex $@.bin 1 -size_word > $@$(FLASH_MEM_HEX_FILE_SUFFIX).hex |
../utils/bin2vmem $@.bin > $@.vmem |
|
|
gpio-icdc: gpio.o udelay.o ../support/reset-icdc.o $(common) $(drivers) |
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $(GCC_LIB_OPTS) -T ../support/orp.ld $? -o $@.or32 |
$(OR32_TOOL_PREFIX)-objcopy -O binary $@.or32 $@.bin |
../utils/bin2hex $@.bin 1 -size_word > $@$(FLASH_MEM_HEX_FILE_SUFFIX).hex |
../utils/bin2vmem $@.bin > $@.vmem |
|
|
gpio.o: gpio.c |
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $? -c -o $@ |
|
udelay.o: udelay.c |
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $? -c -o $@ |
/sw/old/gpio.c
0,0 → 1,351
#include "../support/support.h" |
#include "../support/board.h" |
#include "../support/uart.h" |
|
#include "../support/spr_defs.h" |
|
#include "gpio.h" |
|
|
void uart_print_str(char *); |
void uart_print_long(unsigned long); |
|
// Dummy or32 except vectors |
void buserr_except(){} |
void dpf_except(){} |
void ipf_except(){} |
void lpint_except(){} |
void align_except(){} |
void illegal_except(){} |
/*void hpint_except(){ |
|
}*/ |
void dtlbmiss_except(){} |
void itlbmiss_except(){} |
void range_except(){} |
void syscall_except(){} |
void res1_except(){} |
void trap_except(){} |
void res2_except(){} |
|
|
void uart_interrupt() |
{ |
char lala; |
unsigned char interrupt_id; |
interrupt_id = REG8(UART_BASE + UART_IIR); |
if ( interrupt_id & UART_IIR_RDI ) |
{ |
lala = uart_getc(); |
uart_putc(lala+1); |
} |
} |
|
|
void uart_print_str(char *p) |
{ |
while(*p != 0) { |
uart_putc(*p); |
p++; |
} |
} |
|
void uart_print_long(unsigned long ul) |
{ |
int i; |
char c; |
|
|
uart_print_str("0x"); |
for(i=0; i<8; i++) { |
|
c = (char) (ul>>((7-i)*4)) & 0xf; |
if(c >= 0x0 && c<=0x9) |
c += '0'; |
else |
c += 'a' - 10; |
uart_putc(c); |
} |
|
} |
|
void uart_print_short(unsigned long ul) |
{ |
int i; |
char c; |
char flag=0; |
|
|
uart_print_str("0x"); |
for(i=0; i<8; i++) { |
|
c = (char) (ul>>((7-i)*4)) & 0xf; |
if(c >= 0x0 && c<=0x9) |
c += '0'; |
else |
c += 'a' - 10; |
if ((c != '0') || (i==7)) |
flag=1; |
if(flag) |
uart_putc(c); |
} |
|
} |
|
/* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
*/ |
|
void gpio_init(gpio_t *gpio, long instance_num, unsigned long base_addr) |
{ |
int i = MIN_GPIO_BIT; |
|
if ( gpio != NULL ) { |
gpio->instance_num = instance_num; |
gpio->base_addr = (unsigned char*)base_addr; |
for ( ;i<=MAX_GPIO_BIT;i++) |
gpio->vectors[i].vec = NULL; |
return; |
} else { |
// Print the error msgs here |
// |
uart_print_str("gpio inst in NULL.\n"); |
return; |
} |
} |
|
void gpio_config_bit(gpio_t *gpio, unsigned long bit, iotype_t io) |
{ |
if ( gpio != NULL ) { |
if ( io == IO_INPUT ) { |
gpio->io_config |= (1 << bit); |
*(unsigned long*)(gpio->base_addr + OE_REG_OFFSET) &= (~(1 << bit)); |
} else { |
gpio->io_config &= (~(1 << bit)); |
*(unsigned long*)(gpio->base_addr + OE_REG_OFFSET) |= (1 << bit); |
} |
return; |
} else { |
// Print the error msgs here |
// |
uart_print_str("gpio inst in NULL.\n"); |
return; |
} |
} |
|
void gpio_set_bit(gpio_t *gpio, unsigned long bit, unsigned long val) |
{ |
if ( gpio != NULL ) { |
if ( val != 0 ) |
*(unsigned long*)(gpio->base_addr + OUT_REG_OFFSET) |= (1 << bit); |
else |
*(unsigned long*)(gpio->base_addr + OUT_REG_OFFSET) &= (~(1 << bit)); |
return; |
} else { |
// Print the error msgs here |
// |
uart_print_str("gpio inst in NULL.\n"); |
return; |
} |
} |
|
void gpio_get_bit(gpio_t *gpio, unsigned long bit, unsigned long *val) |
{ |
unsigned long temp; |
|
if ( gpio != NULL ) { |
temp = *(unsigned long*)(gpio->base_addr + IN_REG_OFFSET); |
*val = (temp & (1 << bit))? 1 : 0; |
return; |
} else { |
// Print the error msgs here |
// |
uart_print_str("gpio inst in NULL.\n"); |
return; |
} |
} |
|
|
void gpio_add_interrupt(gpio_t *gpio, unsigned int bit, edge_t edge,void (*func)() ) |
{ |
if ( gpio != NULL ) { |
if ( ( gpio->io_config &(1 << bit)) != 0 ) { // Port bit is configured as IO_INPUT |
// |
// Disable the interrupts |
// |
*(unsigned long*)(gpio->base_addr + CTRL_REG_OFFSET) &= (~0x01); |
|
// Enable the interrupt bit |
// |
*(unsigned long*)(gpio->base_addr + INTE_REG_OFFSET) |= (1 << bit); |
|
// Enable the edge type |
// |
if ( edge == POS_EDGE ) |
*(unsigned long*)(gpio->base_addr + PTRIG_REG_OFFSET) |= (1 << bit); |
else |
*(unsigned long*)(gpio->base_addr + PTRIG_REG_OFFSET) &= (~(1 << bit)); |
|
// Set the function vector |
// |
gpio->vectors[bit].vec = func; |
|
int_add( 6, gpio_interrupt, gpio ); |
|
// Re-enable the global control bit |
// |
*(unsigned long*)(gpio->base_addr + CTRL_REG_OFFSET) |= 0x01; |
} else { |
// Port is configured as IO_OUTPUT |
uart_print_str("gpio pin is not an input pin.\n"); |
return; |
} |
|
} else { |
// Print the error msgs here |
// |
uart_print_str("gpio inst in NULL.\n"); |
return; |
} |
|
} |
|
void gpio_interrupt(gpio_t *gpio) |
{ |
int i; |
unsigned long int interrupt_status; |
|
if ( (*(unsigned long*)(gpio->base_addr + CTRL_REG_OFFSET)) & 0x02 ) |
{ |
// Interrupt is pending here |
// |
interrupt_status = *(unsigned long*)(gpio->base_addr + INTS_REG_OFFSET); |
|
// Prioritize from lower bits(0) to higher ones(31) |
// |
|
for ( i=MIN_GPIO_BIT; i<=MAX_GPIO_BIT; i++ ) { |
if ( (interrupt_status & (1<<i)) ) { |
*(unsigned long*)(gpio->base_addr + INTS_REG_OFFSET) &= (~( 1 << i )); |
(gpio->vectors[i].vec)(); |
} |
} |
|
*(unsigned long*)(gpio->base_addr + CTRL_REG_OFFSET) &= (~0x02); |
|
} |
} |
|
void hello_east() |
{ |
uart_print_str("Hello from PUSH Button EAST.\n"); |
} |
|
|
void hello_west() |
{ |
uart_print_str("Hello from PUSH Button WEST.\n"); |
} |
|
|
void hello_south() |
{ |
uart_print_str("Hello from PUSH Button SOUTH.\n"); |
} |
|
|
|
|
#define MAX_COUNT 10 |
|
int main() |
{ |
gpio_t gpio_1; |
unsigned long t0, t1, t2, t3; |
unsigned long count = 0; |
|
uart_init(); |
int_init(); |
int_add(2,&uart_interrupt); |
|
gpio_init( &gpio_1, 1, GPIO_BASE ); |
|
gpio_config_bit( &gpio_1, LED_0, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_1, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_2, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_3, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_4, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_5, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_6, IO_OUTPUT); |
gpio_config_bit( &gpio_1, LED_7, IO_OUTPUT); |
|
gpio_config_bit( &gpio_1, DIP_0, IO_INPUT); |
gpio_config_bit( &gpio_1, DIP_1, IO_INPUT); |
gpio_config_bit( &gpio_1, DIP_2, IO_INPUT); |
gpio_config_bit( &gpio_1, DIP_3, IO_INPUT); |
|
uart_print_str("Demo 1 : Check for running LED patterns on board ...\n"); |
|
while ( count++ < MAX_COUNT ) { |
gpio_set_bit( &gpio_1, LED_7, 0 ); |
gpio_set_bit( &gpio_1, LED_0, 1 ); |
udelay( 100000 ); |
gpio_set_bit( &gpio_1, LED_0, 0 ); |
gpio_set_bit( &gpio_1, LED_1, 1 ); |
udelay( 100000 ); |
gpio_set_bit( &gpio_1, LED_1, 0 ); |
gpio_set_bit( &gpio_1, LED_2, 1 ); |
udelay( 100000 ); |
gpio_set_bit( &gpio_1, LED_2, 0 ); |
gpio_set_bit( &gpio_1, LED_3, 1 ); |
udelay( 100000 ); |
gpio_set_bit( &gpio_1, LED_3, 0 ); |
gpio_set_bit( &gpio_1, LED_4, 1 ); |
udelay( 100000 ); |
gpio_set_bit( &gpio_1, LED_4, 0 ); |
gpio_set_bit( &gpio_1, LED_5, 1 ); |
udelay( 100000 ); |
gpio_set_bit( &gpio_1, LED_5, 0 ); |
gpio_set_bit( &gpio_1, LED_6, 1 ); |
udelay( 100000 ); |
gpio_set_bit( &gpio_1, LED_6, 0 ); |
gpio_set_bit( &gpio_1, LED_7, 1 ); |
udelay( 100000 ); |
} |
|
gpio_set_bit( &gpio_1, LED_7, 0 ); |
|
gpio_config_bit( &gpio_1, PUSH_EAST, IO_INPUT); |
gpio_add_interrupt( &gpio_1, PUSH_EAST, POS_EDGE, hello_east ); |
gpio_config_bit( &gpio_1, PUSH_WEST, IO_INPUT); |
gpio_add_interrupt( &gpio_1, PUSH_WEST, POS_EDGE, hello_west ); |
gpio_config_bit( &gpio_1, PUSH_SOUTH, IO_INPUT); |
gpio_add_interrupt( &gpio_1, PUSH_SOUTH, POS_EDGE, hello_south ); |
|
uart_print_str("Demo 2 : Press the DIP switches and watch corresponding LED glow ...\n"); |
|
|
while (1) { |
gpio_get_bit( &gpio_1, DIP_0, &t0 ); |
gpio_get_bit( &gpio_1, DIP_1, &t1 ); |
gpio_get_bit( &gpio_1, DIP_2, &t2 ); |
gpio_get_bit( &gpio_1, DIP_3, &t3 ); |
// |
gpio_set_bit( &gpio_1, LED_0, t0 ); |
gpio_set_bit( &gpio_1, LED_1, t1 ); |
gpio_set_bit( &gpio_1, LED_2, t2 ); |
gpio_set_bit( &gpio_1, LED_3, t3 ); |
} |
|
|
report(0xdeaddead); |
or32_exit(0); |
} |
/sw/old/udelay.c
0,0 → 1,17
#include "../support/support.h" |
#include "../support/board.h" |
|
|
void udelay(unsigned long); |
|
void udelay(unsigned long usecs) |
{ |
unsigned long i; |
unsigned long cycles = usecs / (IN_CLK / 1000000 ); |
unsigned long mem_dummy; |
volatile unsigned long* ptr = &mem_dummy; |
|
for ( i=0; i< cycles; i++) |
*ptr = 0xABCD; |
} |
|
/sw/old/gpio.h
0,0 → 1,76
#ifndef __GPIO_H__ |
|
#define __GPIO_H__ |
|
#define MIN_GPIO_BIT 0 |
#define MAX_GPIO_BIT 31 |
|
#define TOTAL_GPIO_BITS ((MAX_GPIO_BIT-MIN_GPIO_BIT+1)) |
|
|
#define IN_REG_OFFSET 0x00 |
#define OUT_REG_OFFSET 0x04 |
#define OE_REG_OFFSET 0x08 |
#define INTE_REG_OFFSET 0x0C |
#define PTRIG_REG_OFFSET 0x10 |
#define AUX_REG_OFFSET 0x14 |
#define CTRL_REG_OFFSET 0x18 |
#define INTS_REG_OFFSET 0x1C |
#define ECLK_REG_OFFSET 0x20 |
#define NEC_REG_OFFSET 0x24 |
|
|
typedef struct vector_t_ |
{ |
void (*vec)(); |
} vector_t; |
|
typedef struct gpio_t_ |
{ |
volatile unsigned char *base_addr; |
unsigned int instance_num; |
unsigned int io_config; |
vector_t vectors[TOTAL_GPIO_BITS]; |
} gpio_t; |
|
typedef enum iotype_t_ |
{ |
IO_OUTPUT = 0, |
IO_INPUT = 1 |
} iotype_t; |
|
typedef enum edge_t_ |
{ |
NEG_EDGE = 0, |
POS_EDGE = 1 |
} edge_t; |
|
|
#define LED_0 0x00 |
#define LED_1 0x01 |
#define LED_2 0x02 |
#define LED_3 0x03 |
#define LED_4 0x04 |
#define LED_5 0x05 |
#define LED_6 0x06 |
#define LED_7 0x07 |
|
#define DIP_0 0x08 |
#define DIP_1 0x09 |
#define DIP_2 0x0A |
#define DIP_3 0x0B |
|
#define PUSH_EAST 0x0C |
#define PUSH_WEST 0x0D |
#define PUSH_NORTH 0x0E |
#define PUSH_SOUTH 0x0F |
|
|
void gpio_init(gpio_t *, long, unsigned long); |
void gpio_config_bit(gpio_t *, unsigned long, iotype_t); |
void gpio_set_bit(gpio_t *, unsigned long, unsigned long); |
void gpio_get_bit(gpio_t *, unsigned long, unsigned long *); |
void gpio_add_interrupt(gpio_t *, unsigned int, edge_t,void (*func)() ); |
void gpio_interrupt(gpio_t *gpio); |
|
#endif |
/sw/old/Makefile
0,0 → 1,26
include ../support/Makefile.inc |
cases = gpio-nocache gpio-icdc |
common = ../support/libsupport.a ../support/except.o |
|
all: $(cases) |
|
gpio-nocache: gpio.o udelay.o ../support/reset-nocache.o $(common) |
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $(GCC_LIB_OPTS) -T ../support/orp.ld $? -o $@.or32 |
$(OR32_TOOL_PREFIX)-objcopy -O binary $@.or32 $@.bin |
../utils/bin2hex $@.bin 1 -size_word > $@$(FLASH_MEM_HEX_FILE_SUFFIX).hex |
../utils/bin2vmem $@.bin > $@.vmem |
|
|
gpio-icdc: gpio.o udelay.o ../support/reset-icdc.o |
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $(GCC_LIB_OPTS) -T ../support/orp.ld $? -o $@.or32 $(common) |
$(OR32_TOOL_PREFIX)-objcopy -O binary $@.or32 $@.bin |
../utils/bin2hex $@.bin 1 -size_word > $@$(FLASH_MEM_HEX_FILE_SUFFIX).hex |
../utils/bin2vmem $@.bin > $@.vmem |
|
|
gpio.o: gpio.c |
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $? -c -o $@ |
|
udelay.o: udelay.c |
$(OR32_TOOL_PREFIX)-gcc $(GCC_OPT) $? -c -o $@ |
|