OpenCores
URL https://opencores.org/ocsvn/attiny_atmega_xmega_core/attiny_atmega_xmega_core/trunk

Subversion Repositories attiny_atmega_xmega_core

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /attiny_atmega_xmega_core
    from Rev 14 to Rev 15
    Reverse comparison

Rev 14 → Rev 15

/trunk/sim_uc.v File deleted \ No newline at end of file
/trunk/io/uart_s.v File deleted
/trunk/io/spi_s.v File deleted
/trunk/io/io_s_h.v File deleted
/trunk/io/twi_s.v File deleted
/trunk/io/pio_s.v File deleted
/trunk/io/rtc_s.v File deleted
/trunk/sim_i2c.v File deleted
/trunk/mega_core_opt.v File deleted
/trunk/rtl/io/io_s_h.v
0,0 → 1,733
/*
* This IP is the simplifyed IO headerfile definition.
*
* Copyright (C) 2017 Iulian Gheorghiu
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
 
`timescale 1ns / 1ps
 
/*
--------------------------------------------------------------------------
RTC - Real time counter interface
--------------------------------------------------------------------------
*/
 
`define RTC_CNT_BYTE0 'h00
`define RTC_CNT_BYTE1 'h01
`define RTC_CNT_BYTE2 'h02
`define RTC_CNT_BYTE3 'h03
`define RTC_PERIOD_BYTE0 'h04
`define RTC_PERIOD_BYTE1 'h05
`define RTC_PERIOD_BYTE2 'h06
`define RTC_PERIOD_BYTE3 'h07
 
/*
--------------------------------------------------------------------------
PORT - I/O Port Configuration
--------------------------------------------------------------------------
*/
 
/* PORT - I/O Ports */
`define PORT_DIR 'h00 /* I/O Port Data Direction */
`define PORT_DIRSET 'h01 /* I/O Port Data Direction Set */
`define PORT_DIRCLR 'h02 /* I/O Port Data Direction Clear */
`define PORT_DIRTGL 'h03 /* I/O Port Data Direction Toggle */
`define PORT_OUT 'h04 /* I/O Port Output */
`define PORT_OUTSET 'h05 /* I/O Port Output Set */
`define PORT_OUTCLR 'h06 /* I/O Port Output Clear */
`define PORT_OUTTGL 'h07 /* I/O Port Output Toggle */
`define PORT_IN 'h08 /* I/O port Input */
`define PORT_INTCTRL 'h09 /* Interrupt Control Register */
`define PORT_INT0MASK 'h0A /* Port Interrupt Mask */
`define PORT_INT1MASK 'h0B
`define PORT_INTFLAGS 'h0C /* Interrupt Flag Register */
`define PORT_reserved_0x0D 'h0D
`define PORT_REMAP 'h0E /* Pin Remap Register */
`define PORT_reserved_0x0F 'h0F
`define PORT_PIN0CTRL 'h10 /* Pin 0 Control Register */
`define PORT_PIN1CTRL 'h11 /* Pin 1 Control Register */
`define PORT_PIN2CTRL 'h12 /* Pin 2 Control Register */
`define PORT_PIN3CTRL 'h13 /* Pin 3 Control Register */
`define PORT_PIN4CTRL 'h14 /* Pin 4 Control Register */
`define PORT_PIN5CTRL 'h15 /* Pin 5 Control Register */
`define PORT_PIN6CTRL 'h16 /* Pin 6 Control Register */
`define PORT_PIN7CTRL 'h17 /* Pin 7 Control Register */
 
 
/* Port Interrupt 0 Level */
//`define PORT_INT0LVL_OFF_gc (8'h00<<0) /* Interrupt Disabled */
//`define PORT_INT0LVL_LO_gc (8'h01<<0) /* Low Level */
//`define PORT_INT0LVL_MED_gc (8'h02<<0) /* Medium Level */
//`define PORT_INT0LVL_HI_gc (8'h03<<0) /* High Level */
 
/* Port Interrupt 1 Level */
//`define PORT_INT1LVL_OFF_gc (8'h00<<2) /* Interrupt Disabled */
//`define PORT_INT1LVL_LO_gc (8'h01<<2) /* Low Level */
//`define PORT_INT1LVL_MED_gc (8'h02<<2) /* Medium Level */
//`define PORT_INT1LVL_HI_gc (8'h03<<2) /* High Level */
 
/* Output/Pull Configuration */
//`define PORT_OPC_TOTEM_gc (8'h00<<3) /* Totempole */
//`define PORT_OPC_BUSKEEPER_gc (8'h01<<3) /* Totempole w/ Bus keeper on Input and Output */
//`define PORT_OPC_PULLDOWN_gc (8'h02<<3) /* Totempole w/ Pull-down on Input */
//`define PORT_OPC_PULLUP_gc (8'h03<<3) /* Totempole w/ Pull-up on Input */
//`define PORT_OPC_WIREDOR_gc (8'h04<<3) /* Wired OR */
//`define PORT_OPC_WIREDAND_gc (8'h05<<3) /* Wired AND */
//`define PORT_OPC_WIREDORPULL_gc (8'h06<<3) /* Wired OR w/ Pull-down */
//`define PORT_OPC_WIREDANDPULL_gc (8'h07<<3) /* Wired AND w/ Pull-up */
 
`define PORT_ISC_BOTHEDGES_gc 'h00 /* Sense Both Edges */
`define PORT_ISC_RISING_gc 'h01 /* Sense Rising Edge */
`define PORT_ISC_FALLING_gc 'h02 /* Sense Falling Edge */
`define PORT_ISC_LEVEL_gc 'h03 /* Sense Level (Transparent For Events) */
`define PORT_ISC_FORCE_ENABLE_gc 'h06 /* Digital Input Buffer Forced Enable */
`define PORT_ISC_INPUT_DISABLE_gc 'h07 /* Disable Digital Input Buffer */
 
/* PORT - I/O Port Configuration */
/* PORT.INTCTRL bit masks and bit positions */
//`define PORT_INT1LVL_gm 8'h0C /* Port Interrupt 1 Level group mask. */
//`define PORT_INT1LVL_gp 2 /* Port Interrupt 1 Level group position. */
//`define PORT_INT1LVL0_bm (1<<2) /* Port Interrupt 1 Level bit 0 mask. */
//`define PORT_INT1LVL0_bp 2 /* Port Interrupt 1 Level bit 0 position. */
//`define PORT_INT1LVL1_bm (1<<3) /* Port Interrupt 1 Level bit 1 mask. */
//`define PORT_INT1LVL1_bp 3 /* Port Interrupt 1 Level bit 1 position. */
 
//`define PORT_INT0LVL_gm 8'h03 /* Port Interrupt 0 Level group mask. */
//`define PORT_INT0LVL_gp 0 /* Port Interrupt 0 Level group position. */
//`define PORT_INT0LVL0_bm (1<<0) /* Port Interrupt 0 Level bit 0 mask. */
//`define PORT_INT0LVL0_bp 0 /* Port Interrupt 0 Level bit 0 position. */
//`define PORT_INT0LVL1_bm (1<<1) /* Port Interrupt 0 Level bit 1 mask. */
//`define PORT_INT0LVL1_bp 1 /* Port Interrupt 0 Level bit 1 position. */
 
/* PORT.INTFLAGS bit masks and bit positions */
//`define PORT_INT1IF_bm 8'h02 /* Port Interrupt 1 Flag bit mask. */
//`define PORT_INT1IF_bp 1 /* Port Interrupt 1 Flag bit position. */
 
`define PORT_INT0IF_bm 8'h01 /* Port Interrupt 0 Flag bit mask. */
`define PORT_INT0IF_bp 0 /* Port Interrupt 0 Flag bit position. */
 
/* PORT.PIN0CTRL bit masks and bit positions */
`define PORT_SRLEN_bm 8'h80 /* Slew Rate Enable bit mask. */
`define PORT_SRLEN_bp 7 /* Slew Rate Enable bit position. */
 
`define PORT_INVEN_bm 8'h40 /* Inverted I/O Enable bit mask. */
`define PORT_INVEN_bp 6 /* Inverted I/O Enable bit position. */
 
`define PORT_OPC_gm 8'h38 /* Output/Pull Configuration group mask. */
`define PORT_OPC_gp 3 /* Output/Pull Configuration group position. */
`define PORT_OPC0_bm (1<<3) /* Output/Pull Configuration bit 0 mask. */
`define PORT_OPC0_bp 3 /* Output/Pull Configuration bit 0 position. */
`define PORT_OPC1_bm (1<<4) /* Output/Pull Configuration bit 1 mask. */
`define PORT_OPC1_bp 4 /* Output/Pull Configuration bit 1 position. */
`define PORT_OPC2_bm (1<<5) /* Output/Pull Configuration bit 2 mask. */
`define PORT_OPC2_bp 5 /* Output/Pull Configuration bit 2 position. */
 
`define PORT_ISC_gm 8'h07 /* Input/Sense Configuration group mask. */
`define PORT_ISC_gp 0 /* Input/Sense Configuration group position. */
`define PORT_ISC0_bm (1<<0) /* Input/Sense Configuration bit 0 mask. */
`define PORT_ISC0_bp 0 /* Input/Sense Configuration bit 0 position. */
`define PORT_ISC1_bm (1<<1) /* Input/Sense Configuration bit 1 mask. */
`define PORT_ISC1_bp 1 /* Input/Sense Configuration bit 1 position. */
`define PORT_ISC2_bm (1<<2) /* Input/Sense Configuration bit 2 mask. */
`define PORT_ISC2_bp 2 /* Input/Sense Configuration bit 2 position. */
 
/*
--------------------------------------------------------------------------
USART - Universal Asynchronous Receiver-Transmitter
--------------------------------------------------------------------------
*/
 
/* USART - Universal Synchronous/Asynchronous Receiver/Transmitter */
`define USART_DATA 0
`define USART_STATUS 1
`define USART_CTRLA 2
`define USART_CTRLB 3
`define USART_CTRLC 4
`define USART_CTRLD 5
`define USART_BAUDCTRLA 6
`define USART_BAUDCTRLB 7
 
/* USART.CTRLA bit masks and bit positions */
/* Receive Complete Interrupt level */
`define USART_RXCINTLVL_OFF_gc (8'h00<<4) /* Interrupt Disabled */
`define USART_RXCINTLVL_LO_gc (8'h01<<4) /* Low Level */
`define USART_RXCINTLVL_MED_gc (8'h02<<4) /* Medium Level */
`define USART_RXCINTLVL_HI_gc (8'h03<<4) /* High Level */
 
/* Transmit Complete Interrupt level */
`define USART_TXCINTLVL_OFF_gc (8'h00<<2) /* Interrupt Disabled */
`define USART_TXCINTLVL_LO_gc (8'h01<<2) /* Low Level */
`define USART_TXCINTLVL_MED_gc (8'h02<<2) /* Medium Level */
`define USART_TXCINTLVL_HI_gc (8'h03<<2) /* High Level */
 
/* Data Register Empty Interrupt level */
`define USART_DREINTLVL_OFF_gc (8'h00<<0) /* Interrupt Disabled */
`define USART_DREINTLVL_LO_gc (8'h01<<0) /* Low Level */
`define USART_DREINTLVL_MED_gc (8'h02<<0) /* Medium Level */
`define USART_DREINTLVL_HI_gc (8'h03<<0) /* High Level */
`define USART_DREINTLVL_gc (0) /* High Level */
 
/* USART.CTRLC bit masks and bit positions */
/* Character Size */
`define USART_CHSIZE_5BIT_gc (8'h00<<0) /* Character size: 5 bit */
`define USART_CHSIZE_6BIT_gc (8'h01<<0) /* Character size: 6 bit */
`define USART_CHSIZE_7BIT_gc (8'h02<<0) /* Character size: 7 bit */
`define USART_CHSIZE_8BIT_gc (8'h03<<0) /* Character size: 8 bit */
`define USART_CHSIZE_9BIT_gc (8'h07<<0) /* Character size: 9 bit */
 
/* Communication Mode */
`define USART_CMODE_ASYNCHRONOUS_gc (8'h00<<6) /* Asynchronous Mode */
`define USART_CMODE_SYNCHRONOUS_gc (8'h01<<6) /* Synchronous Mode */
`define USART_CMODE_IRDA_gc (8'h02<<6) /* IrDA Mode */
`define USART_CMODE_MSPI_gc (8'h03<<6) /* Master SPI Mode */
 
/* Parity Mode */
`define USART_PMODE_DISABLED_gc (8'h00<<4) /* No Parity */
`define USART_PMODE_EVEN_gc (8'h02<<4) /* Even Parity */
`define USART_PMODE_ODD_gc (8'h03<<4) /* Odd Parity */
 
 
/* USART - Universal Asynchronous Receiver-Transmitter */
/* USART.STATUS bit masks and bit positions */
`define USART_RXCIF_bm 8'h80 /* Receive Interrupt Flag bit mask. */
`define USART_RXCIF_bp 7 /* Receive Interrupt Flag bit position. */
 
`define USART_TXCIF_bm 8'h40 /* Transmit Interrupt Flag bit mask. */
`define USART_TXCIF_bp 6 /* Transmit Interrupt Flag bit position. */
 
`define USART_DREIF_bm 8'h20 /* Data Register Empty Flag bit mask. */
`define USART_DREIF_bp 5 /* Data Register Empty Flag bit position. */
 
`define USART_FERR_bm 8'h10 /* Frame Error bit mask. */
`define USART_FERR_bp 4 /* Frame Error bit position. */
 
`define USART_BUFOVF_bm 8'h08 /* Buffer Overflow bit mask. */
`define USART_BUFOVF_bp 3 /* Buffer Overflow bit position. */
 
`define USART_PERR_bm 8'h04 /* Parity Error bit mask. */
`define USART_PERR_bp 2 /* Parity Error bit position. */
 
`define USART_RXB8_bm 8'h01 /* Receive Bit 8 bit mask. */
`define USART_RXB8_bp 0 /* Receive Bit 8 bit position. */
 
/* USART.CTRLA bit masks and bit positions */
`define USART_RXCINTLVL_gm 8'h30 /* Receive Interrupt Level group mask. */
`define USART_RXCINTLVL_gp 4 /* Receive Interrupt Level group position. */
`define USART_RXCINTLVL0_bm (1<<4) /* Receive Interrupt Level bit 0 mask. */
`define USART_RXCINTLVL0_bp 4 /* Receive Interrupt Level bit 0 position. */
`define USART_RXCINTLVL1_bm (1<<5) /* Receive Interrupt Level bit 1 mask. */
`define USART_RXCINTLVL1_bp 5 /* Receive Interrupt Level bit 1 position. */
 
`define USART_TXCINTLVL_gm 8'h0C /* Transmit Interrupt Level group mask. */
`define USART_TXCINTLVL_gp 2 /* Transmit Interrupt Level group position. */
`define USART_TXCINTLVL0_bm (1<<2) /* Transmit Interrupt Level bit 0 mask. */
`define USART_TXCINTLVL0_bp 2 /* Transmit Interrupt Level bit 0 position. */
`define USART_TXCINTLVL1_bm (1<<3) /* Transmit Interrupt Level bit 1 mask. */
`define USART_TXCINTLVL1_bp 3 /* Transmit Interrupt Level bit 1 position. */
 
`define USART_DREINTLVL_gm 8'h03 /* Data Register Empty Interrupt Level group mask. */
`define USART_DREINTLVL_gp 0 /* Data Register Empty Interrupt Level group position. */
`define USART_DREINTLVL0_bm (1<<0) /* Data Register Empty Interrupt Level bit 0 mask. */
`define USART_DREINTLVL0_bp 0 /* Data Register Empty Interrupt Level bit 0 position. */
`define USART_DREINTLVL1_bm (1<<1) /* Data Register Empty Interrupt Level bit 1 mask. */
`define USART_DREINTLVL1_bp 1 /* Data Register Empty Interrupt Level bit 1 position. */
 
/* USART.CTRLB bit masks and bit positions */
`define USART_RXEN_bm 8'h10 /* Receiver Enable bit mask. */
`define USART_RXEN_bp 4 /* Receiver Enable bit position. */
 
`define USART_TXEN_bm 8'h08 /* Transmitter Enable bit mask. */
`define USART_TXEN_bp 3 /* Transmitter Enable bit position. */
 
`define USART_CLK2X_bm 8'h04 /* Double transmission speed bit mask. */
`define USART_CLK2X_bp 2 /* Double transmission speed bit position. */
 
`define USART_MPCM_bm 8'h02 /* Multi-processor Communication Mode bit mask. */
`define USART_MPCM_bp 1 /* Multi-processor Communication Mode bit position. */
 
`define USART_TXB8_bm 8'h01 /* Transmit bit 8 bit mask. */
`define USART_TXB8_bp 0 /* Transmit bit 8 bit position. */
 
/* USART.CTRLC bit masks and bit positions */
`define USART_CMODE_gm 8'hC0 /* Communication Mode group mask. */
`define USART_CMODE_gp 6 /* Communication Mode group position. */
`define USART_CMODE0_bm (1<<6) /* Communication Mode bit 0 mask. */
`define USART_CMODE0_bp 6 /* Communication Mode bit 0 position. */
`define USART_CMODE1_bm (1<<7) /* Communication Mode bit 1 mask. */
`define USART_CMODE1_bp 7 /* Communication Mode bit 1 position. */
 
`define USART_PMODE_gm 8'h30 /* Parity Mode group mask. */
`define USART_PMODE_gp 4 /* Parity Mode group position. */
`define USART_PMODE0_bm (1<<4) /* Parity Mode bit 0 mask. */
`define USART_PMODE0_bp 4 /* Parity Mode bit 0 position. */
`define USART_PMODE1_bm (1<<5) /* Parity Mode bit 1 mask. */
`define USART_PMODE1_bp 5 /* Parity Mode bit 1 position. */
 
`define USART_SBMODE_bm 8'h08 /* Stop Bit Mode bit mask. */
`define USART_SBMODE_bp 3 /* Stop Bit Mode bit position. */
 
`define USART_CHSIZE_gm 8'h07 /* Character Size group mask. */
`define USART_CHSIZE_gp 0 /* Character Size group position. */
`define USART_CHSIZE0_bm (1<<0) /* Character Size bit 0 mask. */
`define USART_CHSIZE0_bp 0 /* Character Size bit 0 position. */
`define USART_CHSIZE1_bm (1<<1) /* Character Size bit 1 mask. */
`define USART_CHSIZE1_bp 1 /* Character Size bit 1 position. */
`define USART_CHSIZE2_bm (1<<2) /* Character Size bit 2 mask. */
`define USART_CHSIZE2_bp 2 /* Character Size bit 2 position. */
 
/* USART.BAUDCTRLA bit masks and bit positions */
`define USART_BSEL_gm 8'hFF /* Baud Rate Selection Bits [7:0] group mask. */
`define USART_BSEL_gp 0 /* Baud Rate Selection Bits [7:0] group position. */
`define USART_BSEL0_bm (1<<0) /* Baud Rate Selection Bits [7:0] bit 0 mask. */
`define USART_BSEL0_bp 0 /* Baud Rate Selection Bits [7:0] bit 0 position. */
`define USART_BSEL1_bm (1<<1) /* Baud Rate Selection Bits [7:0] bit 1 mask. */
`define USART_BSEL1_bp 1 /* Baud Rate Selection Bits [7:0] bit 1 position. */
`define USART_BSEL2_bm (1<<2) /* Baud Rate Selection Bits [7:0] bit 2 mask. */
`define USART_BSEL2_bp 2 /* Baud Rate Selection Bits [7:0] bit 2 position. */
`define USART_BSEL3_bm (1<<3) /* Baud Rate Selection Bits [7:0] bit 3 mask. */
`define USART_BSEL3_bp 3 /* Baud Rate Selection Bits [7:0] bit 3 position. */
`define USART_BSEL4_bm (1<<4) /* Baud Rate Selection Bits [7:0] bit 4 mask. */
`define USART_BSEL4_bp 4 /* Baud Rate Selection Bits [7:0] bit 4 position. */
`define USART_BSEL5_bm (1<<5) /* Baud Rate Selection Bits [7:0] bit 5 mask. */
`define USART_BSEL5_bp 5 /* Baud Rate Selection Bits [7:0] bit 5 position. */
`define USART_BSEL6_bm (1<<6) /* Baud Rate Selection Bits [7:0] bit 6 mask. */
`define USART_BSEL6_bp 6 /* Baud Rate Selection Bits [7:0] bit 6 position. */
`define USART_BSEL7_bm (1<<7) /* Baud Rate Selection Bits [7:0] bit 7 mask. */
`define USART_BSEL7_bp 7 /* Baud Rate Selection Bits [7:0] bit 7 position. */
 
/* USART.BAUDCTRLB bit masks and bit positions */
`define USART_BSCALE_gm 8'hF0 /* Baud Rate Scale group mask. */
`define USART_BSCALE_gp 4 /* Baud Rate Scale group position. */
`define USART_BSCALE0_bm (1<<4) /* Baud Rate Scale bit 0 mask. */
`define USART_BSCALE0_bp 4 /* Baud Rate Scale bit 0 position. */
`define USART_BSCALE1_bm (1<<5) /* Baud Rate Scale bit 1 mask. */
`define USART_BSCALE1_bp 5 /* Baud Rate Scale bit 1 position. */
`define USART_BSCALE2_bm (1<<6) /* Baud Rate Scale bit 2 mask. */
`define USART_BSCALE2_bp 6 /* Baud Rate Scale bit 2 position. */
`define USART_BSCALE3_bm (1<<7) /* Baud Rate Scale bit 3 mask. */
`define USART_BSCALE3_bp 7 /* Baud Rate Scale bit 3 position. */
 
/* USART_BSEL Predefined. */
/* USART_BSEL Predefined. */
 
/*
--------------------------------------------------------------------------
TWI - Two-Wire Interface
--------------------------------------------------------------------------
*/
 
/* TWI - Two-Wire Interface */
`define TWI_CTRL 0
 
`define TWI_MASTER_CTRLA 1 /* Control Register A */
`define TWI_MASTER_CTRLB 2 /* Control Register B */
`define TWI_MASTER_CTRLC 3 /* Control Register C */
`define TWI_MASTER_STATUS 4 /* Status Register */
`define TWI_MASTER_BAUD 5 /* Baurd Rate Control Register */
`define TWI_MASTER_ADDR 6 /* Address Register */
`define TWI_MASTER_DATA 7 /* Data Register */
 
`define TWI_SLAVE_CTRLA 8 /* Control Register A */
`define TWI_SLAVE_CTRLB 9 /* Control Register B */
`define TWI_SLAVE_STATUS 10 /* Status Register */
`define TWI_SLAVE_ADDR 11 /* Address Register */
`define TWI_SLAVE_DATA 12 /* Data Register */
`define TWI_SLAVE_ADDRMASK 13 /* Address Mask Register */
 
`define TOS 14 /* Timeout Status Register */
`define TOCONF 15/* Timeout Configuration Register */
 
 
/* TWI - Two-Wire Interface */
/* TWI.CTRL bit masks and bit positions */
/* SDA Hold Time */
`define TWI_SDAHOLD_OFF_gc (8'h00<<1) /* SDA Hold Time off */
`define TWI_SDAHOLD_50NS_gc (8'h01<<1) /* SDA Hold Time 50 ns */
`define TWI_SDAHOLD_300NS_gc (8'h02<<1) /* SDA Hold Time 300 ns */
`define TWI_SDAHOLD_400NS_gc (8'h03<<1) /* SDA Hold Time 400 ns */
 
/* TWI_MASTER.CTRLA bit masks and bit positions */
/* Master Interrupt Level */
`define TWI_MASTER_INTLVL_OFF_gc (8'h00<<6) /* Interrupt Disabled */
`define TWI_MASTER_INTLVL_LO_gc (8'h01<<6) /* Low Level */
`define TWI_MASTER_INTLVL_MED_gc (8'h02<<6) /* Medium Level */
`define TWI_MASTER_INTLVL_HI_gc (8'h03<<6) /* High Level */
 
/* TWI_MASTER.CTRLB bit masks and bit positions */
/* Inactive Timeout */
`define TWI_MASTER_TIMEOUT_DISABLED_gc (8'h00<<2) /* Bus Timeout Disabled */
`define TWI_MASTER_TIMEOUT_50US_gc (8'h01<<2) /* 50 Microseconds */
`define TWI_MASTER_TIMEOUT_100US_gc (8'h02<<2) /* 100 Microseconds */
`define TWI_MASTER_TIMEOUT_200US_gc (8'h03<<2) /* 200 Microseconds */
 
/* TWI_MASTER.CTRLC bit masks and bit positions */
/* Master Command */
`define TWI_MASTER_CMD_NOACT_gc (8'h00<<0) /* No Action */
`define TWI_MASTER_CMD_REPSTART_gc (8'h01<<0) /* Issue Repeated Start Condition */
`define TWI_MASTER_CMD_RECVTRANS_gc (8'h02<<0) /* Receive or Transmit Data */
`define TWI_MASTER_CMD_STOP_gc (8'h03<<0) /* Issue Stop Condition */
 
/* TWI_MASTER.STATUS bit masks and bit positions */
/* Master Bus State */
`define TWI_MASTER_BUSSTATE_UNKNOWN_gc (8'h00<<0) /* Unknown Bus State */
`define TWI_MASTER_BUSSTATE_IDLE_gc (8'h01<<0) /* Bus is Idle */
`define TWI_MASTER_BUSSTATE_OWNER_gc (8'h02<<0) /* This Module Controls The Bus */
`define TWI_MASTER_BUSSTATE_BUSY_gc (8'h03<<0) /* The Bus is Busy */
 
/* TWI_SLAVE.CTRLA bit masks and bit positions */
/* Slave Interrupt Level */
`define TWI_SLAVE_INTLVL_OFF_gc (8'h00<<6) /* Interrupt Disabled */
`define TWI_SLAVE_INTLVL_LO_gc (8'h01<<6) /* Low Level */
`define TWI_SLAVE_INTLVL_MED_gc (8'h02<<6) /* Medium Level */
`define TWI_SLAVE_INTLVL_HI_gc (8'h03<<6) /* High Level */
 
/* TWI_SLAVE.CTRLB bit masks and bit positions */
/* Slave Command */
`define TWI_SLAVE_CMD_NOACT_gc (8'h00<<0) /* No Action */
`define TWI_SLAVE_CMD_COMPTRANS_gc (8'h02<<0) /* Used To Complete a Transaction */
`define TWI_SLAVE_CMD_RESPONSE_gc (8'h03<<0) /* Used in Response to Address/Data Interrupt */
 
 
/* TWI_MASTER.CTRLA bit masks and bit positions */
`define TWI_MASTER_INTLVL_gm 8'hC0 /* Interrupt Level group mask. */
`define TWI_MASTER_INTLVL_gp 6 /* Interrupt Level group position. */
`define TWI_MASTER_INTLVL0_bm (1<<6) /* Interrupt Level bit 0 mask. */
`define TWI_MASTER_INTLVL0_bpv6 /* Interrupt Level bit 0 position. */
`define TWI_MASTER_INTLVL1_bm (1<<7) /* Interrupt Level bit 1 mask. */
`define TWI_MASTER_INTLVL1_bp 7 /* Interrupt Level bit 1 position. */
 
`define TWI_MASTER_RIEN_bm 8'h20 /* Read Interrupt Enable bit mask. */
`define TWI_MASTER_RIEN_bp 5 /* Read Interrupt Enable bit position. */
 
`define TWI_MASTER_WIEN_bm 8'h10 /* Write Interrupt Enable bit mask. */
`define TWI_MASTER_WIEN_bp 4 /* Write Interrupt Enable bit position. */
 
`define TWI_MASTER_ENABLE_bm 8'h08 /* Enable TWI Master bit mask. */
`define TWI_MASTER_ENABLE_bp 3 /* Enable TWI Master bit position. */
 
/* TWI_MASTER.CTRLB bit masks and bit positions */
`define TWI_MASTER_TIMEOUT_gm 8'h0C /* Inactive Bus Timeout group mask. */
`define TWI_MASTER_TIMEOUT_gp 2 /* Inactive Bus Timeout group position. */
`define TWI_MASTER_TIMEOUT0_bm (1<<2) /* Inactive Bus Timeout bit 0 mask. */
`define TWI_MASTER_TIMEOUT0_bp 2 /* Inactive Bus Timeout bit 0 position. */
`define TWI_MASTER_TIMEOUT1_bm (1<<3) /* Inactive Bus Timeout bit 1 mask. */
`define TWI_MASTER_TIMEOUT1_bp 3 /* Inactive Bus Timeout bit 1 position. */
 
`define TWI_MASTER_QCEN_bm 8'h02 /* Quick Command Enable bit mask. */
`define TWI_MASTER_QCEN_bp 1 /* Quick Command Enable bit position. */
 
`define TWI_MASTER_SMEN_bm 8'h01 /* Smart Mode Enable bit mask. */
`define TWI_MASTER_SMEN_bp 0 /* Smart Mode Enable bit position. */
 
/* TWI_MASTER.CTRLC bit masks and bit positions */
`define TWI_MASTER_ACKACT_bm 8'h04 /* Acknowledge Action bit mask. */
`define TWI_MASTER_ACKACT_bp 2 /* Acknowledge Action bit position. */
 
`define TWI_MASTER_CMD_gm 8'h03 /* Command group mask. */
`define TWI_MASTER_CMD_gp 0 /* Command group position. */
`define TWI_MASTER_CMD0_bm (1<<0) /* Command bit 0 mask. */
`define TWI_MASTER_CMD0_bp 0 /* Command bit 0 position. */
`define TWI_MASTER_CMD1_bm (1<<1) /* Command bit 1 mask. */
`define TWI_MASTER_CMD1_bp 1 /* Command bit 1 position. */
 
/* TWI_MASTER.STATUS bit masks and bit positions */
`define TWI_MASTER_RIF_bm 8'h80 /* Read Interrupt Flag bit mask. */
`define TWI_MASTER_RIF_bp 7 /* Read Interrupt Flag bit position. */
 
`define TWI_MASTER_WIF_bm 8'h40 /* Write Interrupt Flag bit mask. */
`define TWI_MASTER_WIF_bp 6 /* Write Interrupt Flag bit position. */
 
`define TWI_MASTER_CLKHOLD_bm 8'h20 /* Clock Hold bit mask. */
`define TWI_MASTER_CLKHOLD_bp 5 /* Clock Hold bit position. */
 
`define TWI_MASTER_RXACK_bm 8'h10 /* Received Acknowledge bit mask. */
`define TWI_MASTER_RXACK_bp 4 /* Received Acknowledge bit position. */
 
`define TWI_MASTER_ARBLOST_bm 8'h08 /* Arbitration Lost bit mask. */
`define TWI_MASTER_ARBLOST_bp 3 /* Arbitration Lost bit position. */
 
`define TWI_MASTER_BUSERR_bm 8'h04 /* Bus Error bit mask. */
`define TWI_MASTER_BUSERR_bp 2 /* Bus Error bit position. */
 
`define TWI_MASTER_BUSSTATE_gm 8'h03 /* Bus State group mask. */
`define TWI_MASTER_BUSSTATE_gp 0 /* Bus State group position. */
`define TWI_MASTER_BUSSTATE0_bm (1<<0) /* Bus State bit 0 mask. */
`define TWI_MASTER_BUSSTATE0_bp 0 /* Bus State bit 0 position. */
`define TWI_MASTER_BUSSTATE1_bm (1<<1) /* Bus State bit 1 mask. */
`define TWI_MASTER_BUSSTATE1_bp 1 /* Bus State bit 1 position. */
 
/* TWI_SLAVE.CTRLA bit masks and bit positions */
`define TWI_SLAVE_INTLVL_gm 8'hC0 /* Interrupt Level group mask. */
`define TWI_SLAVE_INTLVL_gp 6 /* Interrupt Level group position. */
`define TWI_SLAVE_INTLVL0_bm (1<<6) /* Interrupt Level bit 0 mask. */
`define TWI_SLAVE_INTLVL0_bp 6 /* Interrupt Level bit 0 position. */
`define TWI_SLAVE_INTLVL1_bm (1<<7) /* Interrupt Level bit 1 mask. */
`define TWI_SLAVE_INTLVL1_bp 7 /* Interrupt Level bit 1 position. */
 
`define TWI_SLAVE_DIEN_bm 8'h20 /* Data Interrupt Enable bit mask. */
`define TWI_SLAVE_DIEN_bp 5 /* Data Interrupt Enable bit position. */
 
`define TWI_SLAVE_APIEN_bm 8'h10 /* Address/Stop Interrupt Enable bit mask. */
`define TWI_SLAVE_APIEN_bp 4 /* Address/Stop Interrupt Enable bit position. */
 
`define TWI_SLAVE_ENABLE_bm 8'h08 /* Enable TWI Slave bit mask. */
`define TWI_SLAVE_ENABLE_bp 3 /* Enable TWI Slave bit position. */
 
`define TWI_SLAVE_PIEN_bm 8'h04 /* Stop Interrupt Enable bit mask. */
`define TWI_SLAVE_PIEN_bp 2 /* Stop Interrupt Enable bit position. */
 
`define TWI_SLAVE_PMEN_bm 8'h02 /* Promiscuous Mode Enable bit mask. */
`define TWI_SLAVE_PMEN_bp 1 /* Promiscuous Mode Enable bit position. */
 
`define TWI_SLAVE_SMEN_bm 8'h01 /* Smart Mode Enable bit mask. */
`define TWI_SLAVE_SMEN_bp 0 /* Smart Mode Enable bit position. */
 
/* TWI_SLAVE.CTRLB bit masks and bit positions */
`define TWI_SLAVE_ACKACT_bm 8'h04 /* Acknowledge Action bit mask. */
`define TWI_SLAVE_ACKACT_bp 2 /* Acknowledge Action bit position. */
 
`define TWI_SLAVE_CMD_gm 8'h03 /* Command group mask. */
`define TWI_SLAVE_CMD_gp 0 /* Command group position. */
`define TWI_SLAVE_CMD0_bm (1<<0) /* Command bit 0 mask. */
`define TWI_SLAVE_CMD0_bp 0 /* Command bit 0 position. */
`define TWI_SLAVE_CMD1_bm (1<<1) /* Command bit 1 mask. */
`define TWI_SLAVE_CMD1_bp 1 /* Command bit 1 position. */
 
/* TWI_SLAVE.STATUS bit masks and bit positions */
`define TWI_SLAVE_DIF_bm 8'h80 /* Data Interrupt Flag bit mask. */
`define TWI_SLAVE_DIF_bp 7 /* Data Interrupt Flag bit position. */
 
`define TWI_SLAVE_APIF_bm 8'h40 /* Address/Stop Interrupt Flag bit mask. */
`define TWI_SLAVE_APIF_bp 6 /* Address/Stop Interrupt Flag bit position. */
 
`define TWI_SLAVE_CLKHOLD_bm 8'h20 /* Clock Hold bit mask. */
`define TWI_SLAVE_CLKHOLD_bp 5 /* Clock Hold bit position. */
 
`define TWI_SLAVE_RXACK_bm 8'h10 /* Received Acknowledge bit mask. */
`define TWI_SLAVE_RXACK_bp 4 /* Received Acknowledge bit position. */
 
`define TWI_SLAVE_COLL_bm 8'h08 /* Collision bit mask. */
`define TWI_SLAVE_COLL_bp 3 /* Collision bit position. */
 
`define TWI_SLAVE_BUSERR_bm 8'h04 /* Bus Error bit mask. */
`define TWI_SLAVE_BUSERR_bp 2 /* Bus Error bit position. */
 
`define TWI_SLAVE_DIR_bm 8'h02 /* Read/Write Direction bit mask. */
`define TWI_SLAVE_DIR_bp 1 /* Read/Write Direction bit position. */
 
`define TWI_SLAVE_AP_bm 8'h01 /* Slave Address or Stop bit mask. */
`define TWI_SLAVE_AP_bp 0 /* Slave Address or Stop bit position. */
 
/* TWI_SLAVE.ADDRMASK bit masks and bit positions */
`define TWI_SLAVE_ADDRMASK_gm 8'hFE /* Address Mask group mask. */
`define TWI_SLAVE_ADDRMASK_gp 1 /* Address Mask group position. */
`define TWI_SLAVE_ADDRMASK0_bm (1<<1) /* Address Mask bit 0 mask. */
`define TWI_SLAVE_ADDRMASK0_bp 1 /* Address Mask bit 0 position. */
`define TWI_SLAVE_ADDRMASK1_bm (1<<2) /* Address Mask bit 1 mask. */
`define TWI_SLAVE_ADDRMASK1_bp 2 /* Address Mask bit 1 position. */
`define TWI_SLAVE_ADDRMASK2_bm (1<<3) /* Address Mask bit 2 mask. */
`define TWI_SLAVE_ADDRMASK2_bp 3 /* Address Mask bit 2 position. */
`define TWI_SLAVE_ADDRMASK3_bm (1<<4) /* Address Mask bit 3 mask. */
`define TWI_SLAVE_ADDRMASK3_bp 4 /* Address Mask bit 3 position. */
`define TWI_SLAVE_ADDRMASK4_bm (1<<5) /* Address Mask bit 4 mask. */
`define TWI_SLAVE_ADDRMASK4_bp 5 /* Address Mask bit 4 position. */
`define TWI_SLAVE_ADDRMASK5_bm (1<<6) /* Address Mask bit 5 mask. */
`define TWI_SLAVE_ADDRMASK5_bp 6 /* Address Mask bit 5 position. */
`define TWI_SLAVE_ADDRMASK6_bm (1<<7) /* Address Mask bit 6 mask. */
`define TWI_SLAVE_ADDRMASK6_bp 7 /* Address Mask bit 6 position. */
 
`define TWI_SLAVE_ADDREN_bm 8'h01 /* Address Enable bit mask. */
`define TWI_SLAVE_ADDREN_bp 0 /* Address Enable bit position. */
 
/* TWI.CTRL bit masks and bit positions */
`define TWI_SDAHOLD_gm 8'h06 /* SDA Hold Time Enable group mask. */
`define TWI_SDAHOLD_gp 1 /* SDA Hold Time Enable group position. */
`define TWI_SDAHOLD0_bm (1<<1) /* SDA Hold Time Enable bit 0 mask. */
`define TWI_SDAHOLD0_bp 1 /* SDA Hold Time Enable bit 0 position. */
`define TWI_SDAHOLD1_bm (1<<2) /* SDA Hold Time Enable bit 1 mask. */
`define TWI_SDAHOLD1_bp 2 /* SDA Hold Time Enable bit 1 position. */
 
`define TWI_EDIEN_bm 8'h01 /* External Driver Interface Enable bit mask. */
`define TWI_EDIEN_bp 0 /* External Driver Interface Enable bit position. */
 
/*
--------------------------------------------------------------------------
SPI - Serial Peripheral Interface
--------------------------------------------------------------------------
*/
 
/* SPI - Serial Peripheral Interface */
`define SPI_CTRL 0 /* Control Register */
`define SPI_INTCTRL 1 /* Interrupt Control Register */
`define SPI_STATUS 2 /* Status Register */
`define SPI_DATA 3 /* Data Register */
`define CTRLB 4 /* Control Register B */
 
/* SPI Mode */
`define SPI_MODE_0_gc = (0x00<<2) /* SPI Mode 0, base clock at "0", sampling on leading edge (rising) & set-up on trailling edge (falling). */
`define SPI_MODE_1_gc = (0x01<<2) /* SPI Mode 1, base clock at "0", set-up on leading edge (rising) & sampling on trailling edge (falling). */
`define SPI_MODE_2_gc = (0x02<<2) /* SPI Mode 2, base clock at "1", sampling on leading edge (falling) & set-up on trailling edge (rising). */
`define SPI_MODE_3_gc = (0x03<<2) /* SPI Mode 3, base clock at "1", set-up on leading edge (falling) & sampling on trailling edge (rising). */
 
/* Prescaler setting */
`define SPI_PRESCALER_DIV4_gc = (0x00<<0) /* If CLK2X=1 CLKper/2, else (CLK2X=0) CLKper/4. */
`define SPI_PRESCALER_DIV16_gc = (0x01<<0) /* If CLK2X=1 CLKper/8, else (CLK2X=0) CLKper/16. */
`define SPI_PRESCALER_DIV64_gc = (0x02<<0) /* If CLK2X=1 CLKper/32, else (CLK2X=0) CLKper/64. */
`define SPI_PRESCALER_DIV128_gc = (0x03<<0) /* If CLK2X=1 CLKper/64, else (CLK2X=0) CLKper/128. */
 
/* Interrupt level */
`define SPI_INTLVL_OFF_gc = (0x00<<0) /* Interrupt Disabled */
`define SPI_INTLVL_LO_gc = (0x01<<0) /* Low Level */
`define SPI_INTLVL_MED_gc = (0x02<<0) /* Medium Level */
`define SPI_INTLVL_HI_gc = (0x03<<0) /* High Level */
 
/* Buffer Modes */
`define SPI_BUFMODE_OFF_gc = (0x00<<6) /* SPI Unbuffered Mode */
`define SPI_BUFMODE_BUFMODE1_gc = (0x02<<6) /* Buffer Mode 1 (with dummy byte) */
`define SPI_BUFMODE_BUFMODE2_gc = (0x03<<6) /* Buffer Mode 2 (no dummy byte) */
 
/* SPI - Serial Peripheral Interface */
/* SPI.CTRL bit masks and bit positions */
`define SPI_CLK2X_bm 0x80 /* Enable Double Speed bit mask. */
`define SPI_CLK2X_bp 7 /* Enable Double Speed bit position. */
 
`define SPI_ENABLE_bm 0x40 /* Enable SPI Module bit mask. */
`define SPI_ENABLE_bp 6 /* Enable SPI Module bit position. */
 
`define SPI_DORD_bm 0x20 /* Data Order Setting bit mask. */
`define SPI_DORD_bp 5 /* Data Order Setting bit position. */
 
`define SPI_MASTER_bm 0x10 /* Master Operation Enable bit mask. */
`define SPI_MASTER_bp 4 /* Master Operation Enable bit position. */
 
`define SPI_MODE_gm 0x0C /* SPI Mode group mask. */
`define SPI_MODE_gp 2 /* SPI Mode group position. */
`define SPI_MODE0_bm (1<<2) /* SPI Mode bit 0 mask. */
`define SPI_MODE0_bp 2 /* SPI Mode bit 0 position. */
`define FPGA_SPI_MODE1_bm (1<<3) /* SPI Mode bit 1 mask. */
`define MODE1_bp 3 /* SPI Mode bit 1 position. */
 
`define SPI_PRESCALER_gm 0x03 /* Prescaler group mask. */
`define SPI_PRESCALER_gp 0 /* Prescaler group position. */
`define SPI_PRESCALER0_bm (1<<0) /* Prescaler bit 0 mask. */
`define SPI_PRESCALER0_bp 0 /* Prescaler bit 0 position. */
`define SPI_PRESCALER1_bm (1<<1) /* Prescaler bit 1 mask. */
`define SPI_PRESCALER1_bp 1 /* Prescaler bit 1 position. */
 
/* SPI.INTCTRL bit masks and bit positions */
`define SPI_RXCIE_bm 0x80 /* Receive Complete Interrupt Enable (In Buffer Modes Only). bit mask. */
`define SPI_RXCIE_bp 7 /* Receive Complete Interrupt Enable (In Buffer Modes Only). bit position. */
 
`define SPI_TXCIE_bm 0x40 /* Transmit Complete Interrupt Enable (In Buffer Modes Only). bit mask. */
`define SPI_TXCIE_bp 6 /* Transmit Complete Interrupt Enable (In Buffer Modes Only). bit position. */
 
`define SPI_DREIE_bm 0x20 /* Data Register Empty Interrupt Enable (In Buffer Modes Only). bit mask. */
`define SPI_DREIE_bp 5 /* Data Register Empty Interrupt Enable (In Buffer Modes Only). bit position. */
 
`define SPI_SSIE_bm 0x10 /* Slave Select Trigger Interrupt Enable (In Buffer Modes Only). bit mask. */
`define SPI_SSIE_bp 4 /* Slave Select Trigger Interrupt Enable (In Buffer Modes Only). bit position. */
 
`define SPI_INTLVL_gm 0x03 /* Interrupt level group mask. */
`define SPI_INTLVL_gp 0 /* Interrupt level group position. */
`define SPI_INTLVL0_bm (1<<0) /* Interrupt level bit 0 mask. */
`define SPI_INTLVL0_bp 0 /* Interrupt level bit 0 position. */
`define SPI_INTLVL1_bm (1<<1) /* Interrupt level bit 1 mask. */
`define SPI_INTLVL1_bp 1 /* Interrupt level bit 1 position. */
 
/* SPI.STATUS bit masks and bit positions */
`define SPI_IF_bm 0x80 /* Interrupt Flag (In Standard Mode Only). bit mask. */
`define SPI_IF_bp 7 /* Interrupt Flag (In Standard Mode Only). bit position. */
 
`define SPI_RXCIF_bm 0x80 /* Receive Complete Interrupt Flag (In Buffer Modes Only). bit mask. */
`define SPI_RXCIF_bp 7 /* Receive Complete Interrupt Flag (In Buffer Modes Only). bit position. */
 
`define SPI_WRCOL_bm 0x40 /* Write Collision Flag (In Standard Mode Only). bit mask. */
`define SPI_WRCOL_bp 6 /* Write Collision Flag (In Standard Mode Only). bit position. */
 
`define SPI_TXCIF_bm 0x40 /* Transmit Complete Interrupt Flag (In Buffer Modes Only). bit mask. */
`define SPI_TXCIF_bp 6 /* Transmit Complete Interrupt Flag (In Buffer Modes Only). bit position. */
 
`define SPI_DREIF_bm 0x20 /* Data Register Empty Interrupt Flag (In Buffer Modes Only). bit mask. */
`define SPI_DREIF_bp 5 /* Data Register Empty Interrupt Flag (In Buffer Modes Only). bit position. */
 
`define SPI_SSIF_bm 0x10 /* Slave Select Trigger Interrupt Flag (In Buffer Modes Only). bit mask. */
`define SPI_SSIF_bp 4 /* Slave Select Trigger Interrupt Flag (In Buffer Modes Only). bit position. */
 
`define SPI_BUFOVF_bm 0x01 /* Buffer Overflow (In Buffer Modes Only). bit mask. */
`define SPI_BUFOVF_bp 0 /* Buffer Overflow (In Buffer Modes Only). bit position. */
 
/* SPI.CTRLB bit masks and bit positions */
`define SPI_BUFMODE_gm 0xC0 /* Buffer Modes group mask. */
`define SPI_BUFMODE_gp 6 /* Buffer Modes group position. */
`define SPI_BUFMODE0_bm (1<<6) /* Buffer Modes bit 0 mask. */
`define SPI_BUFMODE0_bp 6 /* Buffer Modes bit 0 position. */
`define SPI_BUFMODE1_bm (1<<7) /* Buffer Modes bit 1 mask. */
`define SPI_BUFMODE1_bp 7 /* Buffer Modes bit 1 position. */
 
`define SPI_SSD_bm 0x04 /* Slave Select Disable bit mask. */
`define SPI_SSD_bp 2 /* Slave Select Disable bit position. */
 
/*
--------------------------------------------------------------------------
LCD - LCD display Interface
--------------------------------------------------------------------------
*/
 
`define LCD_CTRL 0
`define LCD_H_RES_LOW 1
`define LCD_H_RES_HIGH 2
`define LCD_H_PULSE_WIDTH 3
`define LCD_H_BACK_PORCH 4
`define LCD_H_FRONT_PORCH 5
`define LCD_V_RES_LOW 6
`define LCD_V_RES_HIGH 7
`define LCD_V_PULSE_WIDTH 8
`define LCD_V_BACK_PORCH 9
`define LCD_V_FRONT_PORCH 10
`define LCD_PIXEL_SIZE 11
`define LCD_BASE_ADDR_BYTE0 12
`define LCD_BASE_ADDR_BYTE1 13
`define LCD_BASE_ADDR_BYTE2 14
`define LCD_BASE_ADDR_BYTE3 15
 
/*
--------------------------------------------------------------------------
GFX_ACCEL - GFX_ACCEL LCD display 2D accelerator interface
--------------------------------------------------------------------------
*/
 
`define GFX_ACCEL_CMD 16
`define GFX_ACCEL_CLIP_X_MIN_L 18
`define GFX_ACCEL_CLIP_X_MIN_H 19
`define GFX_ACCEL_CLIP_X_MAX_L 20
`define GFX_ACCEL_CLIP_X_MAX_H 21
`define GFX_ACCEL_CLIP_Y_MIN_L 22
`define GFX_ACCEL_CLIP_Y_MIN_H 23
`define GFX_ACCEL_CLIP_Y_MAX_L 24
`define GFX_ACCEL_CLIP_Y_MAX_H 25
`define GFX_ACCEL_BYTE_0 26
`define GFX_ACCEL_BYTE_1 27
`define GFX_ACCEL_BYTE_2 28
`define GFX_ACCEL_BYTE_3 29
 
`define GFX_ACCEL_CMD_IDLE 0
`define GFX_ACCEL_CMD_VRAM_ACCESS 1
`define GFX_ACCEL_CMD_PIXEL_LOAD 2
`define GFX_ACCEL_CMD_PIXEL 3
`define GFX_ACCEL_CMD_CTRL_ACCESS 4
`define GFX_ACCEL_CMD_FILL_RECT 5
 
/trunk/rtl/io/pio_s.v
0,0 → 1,242
/*----------------------------------------------------------------------------/
/ This IP is an PIO interface. /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2018 Iulian Gheorghiu (morgoth.creator@gmail.com), all right reserved.
/
/ This IP file is an open source software. Redistribution and use of this IP in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
 
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/----------------------------------------------------------------------------*/
 
`timescale 1ns / 1ps
 
`include "io_s_h.v"
 
module pio_s #(
parameter DINAMIC_IN_OUT_CONFIG = "FALSE",
parameter IN_OUT_MASK_CONFIG = 8'h00,
parameter USE_INTERRUPTS = "FALSE",
parameter DINAMIC_INTERRUPT_CONFIG = "FALSE",
parameter INTERRUPT_MASK_CONFIG = 8'h00,
parameter INTERRUPT_UP_DN_EDGE_DETECT = 8'h00,
parameter INTERRUPT_BOTH_EDGES_DETECT_MASK = 8'h00,
parameter BUS_KEPPER_EN_MASK = 0,
parameter BUS_PULL_UP_EN_MASK = 0,
parameter BUS_PULL_DN_EN_MASK = 0,
parameter ADDRESS = 0,
parameter BUS_ADDR_DATA_LEN = 16
)(
input rst,
input clk,
input [BUS_ADDR_DATA_LEN-1:0]addr,
input wr,
input rd,
input [7:0]bus_in,
output reg[7:0]bus_out,
output int,
input int_rst,
inout [7:0]io
);
 
 
reg [7:0]IO_DIR;
reg [7:0]IO_OUT;
reg [7:0]INTMASK;
reg [7:0]INTFLAGS;
reg [7:0]PINCTRL[0:7];
 
 
reg [7:0]INT_DETECT_POSEDGE;
reg [7:0]INT_DETECT_POSEDGE_n;
reg [7:0]INT_DETECT_NEGEDGE;
reg [7:0]INT_DETECT_NEGEDGE_n;
 
wire cs_int = addr >= ADDRESS && addr < (ADDRESS + 32);
wire rd_int = cs_int && rd;
wire wr_int = cs_int && wr;
 
integer cnt_detect;
 
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
IO_DIR <= 'h00;
IO_OUT <= 'h00;
INTMASK <= 'h00;
INTFLAGS <= 'h00;
INT_DETECT_POSEDGE_n <= 'h00;
INT_DETECT_NEGEDGE_n <= 'h00;
end
else
begin
if(wr_int)
begin
case(addr[4:0])
`PORT_DIR: IO_DIR <= bus_in;
`PORT_DIRSET: IO_DIR <= IO_DIR | bus_in;
`PORT_DIRCLR: IO_DIR <= IO_DIR & (~bus_in);
`PORT_DIRTGL: IO_DIR <= IO_DIR ^ (~bus_in);
`PORT_OUT: IO_OUT <= bus_in;
`PORT_OUTSET: IO_OUT <= IO_OUT | bus_in;
`PORT_OUTCLR: IO_OUT <= IO_OUT & (~bus_in);
`PORT_OUTTGL: IO_OUT <= IO_OUT ^ (~bus_in);
`PORT_INT0MASK: INTMASK <= bus_in;
`PORT_INTFLAGS: INTFLAGS <= INTFLAGS & (~bus_in);
`PORT_PIN0CTRL, `PORT_PIN1CTRL,
`PORT_PIN2CTRL, `PORT_PIN3CTRL,
`PORT_PIN4CTRL, `PORT_PIN5CTRL,
`PORT_PIN6CTRL, `PORT_PIN7CTRL: PINCTRL[addr[2:0]] <= bus_in;
endcase
end
else
begin
if(USE_INTERRUPTS == "TRUE")
begin
for (cnt_detect = 0; cnt_detect < 8; cnt_detect = cnt_detect + 1)
begin
if(INT_DETECT_POSEDGE_n[cnt_detect] != INT_DETECT_POSEDGE[cnt_detect])
begin
INTFLAGS[cnt_detect] <= 1'b1;
INT_DETECT_POSEDGE_n[cnt_detect] <= ~INT_DETECT_POSEDGE_n[cnt_detect];
end
else if(INT_DETECT_NEGEDGE_n[cnt_detect] != INT_DETECT_NEGEDGE[cnt_detect])
begin
INTFLAGS[cnt_detect] <= 1'b1;
INT_DETECT_NEGEDGE_n[cnt_detect] <= ~INT_DETECT_NEGEDGE_n[cnt_detect];
end
end
end
end
end
end
 
always @ (*)
begin
bus_out <= 8'hz;
if(rd_int)
begin
case(addr[4:0])
`PORT_DIR,
`PORT_DIRSET: bus_out <= DINAMIC_IN_OUT_CONFIG == "TRUE" ? IO_DIR : 'h00;
`PORT_DIRCLR: bus_out <= DINAMIC_IN_OUT_CONFIG == "TRUE" ? ~IO_DIR : 'h00;
`PORT_OUT,
`PORT_OUTSET: bus_out <= IO_OUT;
`PORT_OUTCLR: bus_out <= ~IO_OUT;
`PORT_IN: bus_out <= io;
`PORT_INT0MASK: bus_out <= USE_INTERRUPTS == "TRUE" ? (DINAMIC_INTERRUPT_CONFIG == "TRUE" ? INTMASK : INTERRUPT_MASK_CONFIG) : 0;
`PORT_INTFLAGS: bus_out <= USE_INTERRUPTS == "TRUE" ? INTFLAGS : 0;
`PORT_PIN0CTRL, `PORT_PIN1CTRL,
`PORT_PIN2CTRL, `PORT_PIN3CTRL,
`PORT_PIN4CTRL, `PORT_PIN5CTRL,
`PORT_PIN6CTRL, `PORT_PIN7CTRL: bus_out <= USE_INTERRUPTS == "TRUE" ? PINCTRL[addr[2:0]] : 'h0;
default: bus_out <= 'h00;
endcase
end
end
wire out_0 = DINAMIC_IN_OUT_CONFIG == "TRUE" ? (IO_DIR[0] ? IO_OUT[0] : 1'bz) : (IN_OUT_MASK_CONFIG[0] ? IO_OUT[0] : 1'bz);
wire out_1 = DINAMIC_IN_OUT_CONFIG == "TRUE" ? (IO_DIR[1] ? IO_OUT[1] : 1'bz) : (IN_OUT_MASK_CONFIG[1] ? IO_OUT[1] : 1'bz);
wire out_2 = DINAMIC_IN_OUT_CONFIG == "TRUE" ? (IO_DIR[2] ? IO_OUT[2] : 1'bz) : (IN_OUT_MASK_CONFIG[2] ? IO_OUT[2] : 1'bz);
wire out_3 = DINAMIC_IN_OUT_CONFIG == "TRUE" ? (IO_DIR[3] ? IO_OUT[3] : 1'bz) : (IN_OUT_MASK_CONFIG[3] ? IO_OUT[3] : 1'bz);
wire out_4 = DINAMIC_IN_OUT_CONFIG == "TRUE" ? (IO_DIR[4] ? IO_OUT[4] : 1'bz) : (IN_OUT_MASK_CONFIG[4] ? IO_OUT[4] : 1'bz);
wire out_5 = DINAMIC_IN_OUT_CONFIG == "TRUE" ? (IO_DIR[5] ? IO_OUT[5] : 1'bz) : (IN_OUT_MASK_CONFIG[5] ? IO_OUT[5] : 1'bz);
wire out_6 = DINAMIC_IN_OUT_CONFIG == "TRUE" ? (IO_DIR[6] ? IO_OUT[6] : 1'bz) : (IN_OUT_MASK_CONFIG[6] ? IO_OUT[6] : 1'bz);
wire out_7 = DINAMIC_IN_OUT_CONFIG == "TRUE" ? (IO_DIR[7] ? IO_OUT[7] : 1'bz) : (IN_OUT_MASK_CONFIG[7] ? IO_OUT[7] : 1'bz);
assign io = {out_7, out_6, out_5, out_4, out_3, out_2, out_1, out_0};
 
assign int = USE_INTERRUPTS == "TRUE" ?|INTFLAGS : 'h00;
 
wire _int_mode_up_edge0 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[0] ? (PINCTRL[0][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[0][3:0] == `PORT_ISC_RISING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[0] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[0] : INTERRUPT_UP_DN_EDGE_DETECT[0]);
wire _int_mode_up_edge1 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[1] ? (PINCTRL[1][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[1][3:0] == `PORT_ISC_RISING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[1] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[1] : INTERRUPT_UP_DN_EDGE_DETECT[1]);
wire _int_mode_up_edge2 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[2] ? (PINCTRL[2][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[2][3:0] == `PORT_ISC_RISING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[2] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[2] : INTERRUPT_UP_DN_EDGE_DETECT[2]);
wire _int_mode_up_edge3 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[3] ? (PINCTRL[3][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[3][3:0] == `PORT_ISC_RISING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[3] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[3] : INTERRUPT_UP_DN_EDGE_DETECT[3]);
wire _int_mode_up_edge4 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[4] ? (PINCTRL[4][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[4][3:0] == `PORT_ISC_RISING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[4] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[4] : INTERRUPT_UP_DN_EDGE_DETECT[4]);
wire _int_mode_up_edge5 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[5] ? (PINCTRL[5][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[5][3:0] == `PORT_ISC_RISING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[5] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[5] : INTERRUPT_UP_DN_EDGE_DETECT[5]);
wire _int_mode_up_edge6 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[6] ? (PINCTRL[6][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[6][3:0] == `PORT_ISC_RISING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[6] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[6] : INTERRUPT_UP_DN_EDGE_DETECT[6]);
wire _int_mode_up_edge7 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[7] ? (PINCTRL[7][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[7][3:0] == `PORT_ISC_RISING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[7] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[7] : INTERRUPT_UP_DN_EDGE_DETECT[7]);
wire [7:0]int_mode_up_edge = {_int_mode_up_edge7, _int_mode_up_edge6, _int_mode_up_edge5, _int_mode_up_edge4, _int_mode_up_edge3, _int_mode_up_edge2, _int_mode_up_edge1, _int_mode_up_edge0};
 
wire _int_mode_dn_edge0 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[0] ? (PINCTRL[0][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[0][3:0] == `PORT_ISC_FALLING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[0] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[0] : ~INTERRUPT_UP_DN_EDGE_DETECT[0]);
wire _int_mode_dn_edge1 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[1] ? (PINCTRL[1][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[1][3:0] == `PORT_ISC_FALLING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[1] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[1] : ~INTERRUPT_UP_DN_EDGE_DETECT[1]);
wire _int_mode_dn_edge2 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[2] ? (PINCTRL[2][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[2][3:0] == `PORT_ISC_FALLING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[2] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[2] : ~INTERRUPT_UP_DN_EDGE_DETECT[2]);
wire _int_mode_dn_edge3 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[3] ? (PINCTRL[3][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[3][3:0] == `PORT_ISC_FALLING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[3] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[3] : ~INTERRUPT_UP_DN_EDGE_DETECT[3]);
wire _int_mode_dn_edge4 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[4] ? (PINCTRL[4][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[4][3:0] == `PORT_ISC_FALLING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[4] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[4] : ~INTERRUPT_UP_DN_EDGE_DETECT[4]);
wire _int_mode_dn_edge5 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[5] ? (PINCTRL[5][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[5][3:0] == `PORT_ISC_FALLING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[5] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[5] : ~INTERRUPT_UP_DN_EDGE_DETECT[5]);
wire _int_mode_dn_edge6 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[6] ? (PINCTRL[6][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[6][3:0] == `PORT_ISC_FALLING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[6] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[6] : ~INTERRUPT_UP_DN_EDGE_DETECT[6]);
wire _int_mode_dn_edge7 = DINAMIC_INTERRUPT_CONFIG == "TRUE" ? (INTMASK[7] ? (PINCTRL[7][3:0] == `PORT_ISC_BOTHEDGES_gc) || (PINCTRL[7][3:0] == `PORT_ISC_FALLING_gc) : 1'b0) : (INTERRUPT_MASK_CONFIG[7] ? INTERRUPT_BOTH_EDGES_DETECT_MASK[7] : ~INTERRUPT_UP_DN_EDGE_DETECT[7]);
wire [7:0]int_mode_dn_edge = {_int_mode_dn_edge7, _int_mode_dn_edge6, _int_mode_dn_edge5, _int_mode_dn_edge4, _int_mode_dn_edge3, _int_mode_dn_edge2, _int_mode_dn_edge1, _int_mode_dn_edge0};
 
genvar cnt;
generate
 
for (cnt = 0; cnt < 8; cnt = cnt + 1)
begin:POSEDGE
always @ (posedge io[cnt] or posedge rst)
begin
if(USE_INTERRUPTS == "TRUE")
begin
if(rst)
INT_DETECT_POSEDGE[cnt] <= 'h00;
else if(INT_DETECT_POSEDGE_n[cnt] == INT_DETECT_POSEDGE[cnt] && int_mode_up_edge)
INT_DETECT_POSEDGE[cnt] <= ~INT_DETECT_POSEDGE[cnt];
end
end
end
 
for (cnt = 0; cnt < 8; cnt = cnt + 1)
begin:NEGEDGE
always @ (negedge io[cnt] or posedge rst)
begin
if(USE_INTERRUPTS == "TRUE")
begin
if(rst)
INT_DETECT_NEGEDGE[cnt] <= 'h00;
else if(INT_DETECT_NEGEDGE_n[cnt] == INT_DETECT_NEGEDGE[cnt] && int_mode_dn_edge)
INT_DETECT_NEGEDGE[cnt] <= ~INT_DETECT_NEGEDGE[cnt];
end
end
end
 
for (cnt = 0; cnt < 8; cnt = cnt + 1)
begin:KEPPERS
if (BUS_KEPPER_EN_MASK[cnt])
begin
KEEPER KEEPER_inst (
.O(io[cnt]) // Keeper output (connect directly to top-level port)
);
end
end
 
for (cnt = 0; cnt < 8; cnt = cnt + 1)
begin:PULLUPS
if (BUS_PULL_UP_EN_MASK[cnt])
begin
PULLUP PULLUP_inst (
.O(io[cnt]) // PullUp output (connect directly to top-level port)
);
end
end
 
for (cnt = 0; cnt < 8; cnt = cnt + 1)
begin:PULLDOWNS
if (BUS_PULL_DN_EN_MASK[cnt])
begin
PULLDOWN PULLDOWN_inst (
.O(io[cnt]) // PullDown output (connect directly to top-level port)
);
end
end
 
endgenerate
 
endmodule
/trunk/rtl/io/rtc_s.v
0,0 → 1,300
`timescale 1ns / 1ps
/*
* This IP is a simple RTC timmer implementation.
*
* Copyright (C) 2018 Iulian Gheorghiu
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
 
`include "io_s_h.v"
 
module rtc_s #(
parameter ADDRESS = 0,
parameter BUS_ADDR_DATA_LEN = 16,
parameter CNT_SIZE = 10
)(
input rst,
input clk,
input [BUS_ADDR_DATA_LEN-1:0]addr,
input wr,
input rd,
input [7:0]bus_in,
output reg[7:0]bus_out,
output reg int,
input int_rst
);
 
wire cs_int = addr >= ADDRESS && addr < (ADDRESS + 8);
wire rd_int = cs_int && rd;
wire wr_int = cs_int && wr;
reg int_rst_int;
reg int_rst_int_n;
 
reg [CNT_SIZE > 8 ? (CNT_SIZE-1-8) : 0:0]CNT_IO;
reg [CNT_SIZE-1:0]cnt;
reg [CNT_SIZE > 8 ? (CNT_SIZE-1-8) : 0:0]PERIOD_IO;
reg [CNT_SIZE-1:0]PERIOD;
 
always @ (posedge int_rst or posedge rst)
begin
if(rst)
int_rst_int <= 'h0;
else if(int_rst_int == int_rst_int_n)
int_rst_int <= ~int_rst_int;
end
 
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
cnt <= 'h00;
CNT_IO <= 'h00;
PERIOD <= 'h00;
PERIOD_IO <= 'h00;
int <= 1'b0;
int_rst_int_n <= 'h0;
end
else
begin
if(cnt >= PERIOD - 1)
begin
cnt <= 'h0;
if(PERIOD)
int <= 1'b1;
end
else if(PERIOD)
begin
cnt <= cnt + 1;
end
if(int_rst_int_n != int_rst_int)
begin
int_rst_int_n <= ~int_rst_int_n;
int <= 1'b0;
end
if(wr_int)
begin
case(addr[2:0])
`RTC_CNT_BYTE0:
begin
cnt[(CNT_SIZE >= 8 ? 7 : CNT_SIZE):0] <= bus_in;
if(CNT_SIZE > 8)
begin
cnt[CNT_SIZE-1:8] <= CNT_IO;
end
end
`RTC_CNT_BYTE1:
begin
if(CNT_SIZE > 8)
begin
CNT_IO[(CNT_SIZE >= 16 ? 7 : (CNT_SIZE-1-8)):0] <= bus_in;
end
end
`RTC_CNT_BYTE2:
begin
if(CNT_SIZE > 16)
begin
CNT_IO[(CNT_SIZE >= 24 ? 15 : (CNT_SIZE-1-8)):8] <= bus_in;
end
end
`RTC_CNT_BYTE3:
begin
if(CNT_SIZE > 24)
begin
CNT_IO[CNT_SIZE-1-8:16] <= bus_in;
end
end
`RTC_PERIOD_BYTE0:
begin
PERIOD[(CNT_SIZE >= 8 ? 7 : (CNT_SIZE-1)):0] <= bus_in;
if(CNT_SIZE > 8)
begin
PERIOD[CNT_SIZE-1:8] <= PERIOD_IO;
end
end
`RTC_PERIOD_BYTE1:
begin
if(CNT_SIZE > 8)
begin
PERIOD_IO[(CNT_SIZE >= 16 ? 7 : (CNT_SIZE-1-8)):0] <= bus_in;
end
end
`RTC_PERIOD_BYTE2:
begin
if(CNT_SIZE > 16)
begin
PERIOD_IO[(CNT_SIZE >= 24 ? 15 : (CNT_SIZE-1-8)):8] <= bus_in;
end
end
`RTC_PERIOD_BYTE3:
begin
if(CNT_SIZE > 24)
begin
PERIOD_IO[(CNT_SIZE-1-8):16] <= bus_in;
end
end
endcase
end
else if(rd_int)
begin
case(addr[2:0])
`RTC_CNT_BYTE0:
begin
//int <= 1'b0;
if(CNT_SIZE > 8)
begin
CNT_IO <= cnt[CNT_SIZE-1:8];
end
end
`RTC_PERIOD_BYTE0:
begin
if(CNT_SIZE > 8)
begin
PERIOD_IO <= PERIOD[CNT_SIZE-1:8];
end
end
endcase
end
end
end
always @ (*)
begin
bus_out <= 8'hz;
if(rd_int)
begin
case(addr[2:0])
`RTC_CNT_BYTE0:
begin
if(CNT_SIZE >= 8)
begin
bus_out <= cnt[7:0];
end
else
begin
bus_out <= {{8-CNT_SIZE{1'b0}}, cnt[CNT_SIZE-1-8:0]};
end
end
`RTC_CNT_BYTE1:
begin
if(CNT_SIZE > 8)
begin
if(CNT_SIZE >=16)
begin
bus_out <= CNT_IO[15:8];
end
else
begin
bus_out <= {{16-CNT_SIZE{1'b0}}, CNT_IO[CNT_SIZE-1-8:0]};
end
end
else
begin
bus_out <= 0;
end
end
`RTC_CNT_BYTE2:
begin
if(CNT_SIZE > 16)
begin
if(CNT_SIZE >=24)
begin
bus_out <= CNT_IO[23:16];
end
else
begin
bus_out <= {{24-CNT_SIZE{1'b0}}, CNT_IO[CNT_SIZE-1-8:8]};
end
end
else
begin
bus_out <= 0;
end
end
`RTC_CNT_BYTE3:
begin
if(CNT_SIZE > 24)
begin
bus_out <= {{32-CNT_SIZE{1'b0}}, CNT_IO[CNT_SIZE-1-8:16]};
end
else
begin
bus_out <= 0;
end
end
`RTC_PERIOD_BYTE0:
begin
if(CNT_SIZE >= 8)
begin
bus_out <= PERIOD[7:0];
end
else
begin
bus_out <= {{8-CNT_SIZE{1'b0}}, PERIOD[CNT_SIZE-1:0]};
end
end
`RTC_PERIOD_BYTE1:
begin
if(CNT_SIZE > 8)
begin
if(CNT_SIZE >=16)
begin
bus_out <= PERIOD_IO[15:8];
end
else
begin
bus_out <= {{16-CNT_SIZE{1'b0}}, PERIOD_IO[CNT_SIZE-1-8:0]};
end
end
else
begin
bus_out <= 0;
end
end
`RTC_PERIOD_BYTE2:
begin
if(CNT_SIZE > 16)
begin
if(CNT_SIZE >=24)
begin
bus_out <= PERIOD_IO[23:16];
end
else
begin
bus_out <= {{24-CNT_SIZE{1'b0}}, PERIOD_IO[CNT_SIZE-1-8:8]};
end
end
else
begin
bus_out <= 0;
end
end
`RTC_PERIOD_BYTE3:
begin
if(CNT_SIZE > 24)
begin
bus_out <= {{32-CNT_SIZE{1'b0}}, PERIOD_IO[CNT_SIZE-1-8:16]};
end
else
begin
bus_out <= 0;
end
end
endcase
end
end
 
endmodule
/trunk/rtl/io/spi_s.v
0,0 → 1,292
/*
* This IP is a SPI IO adapter implementation.
*
* Copyright (C) 2018 Iulian Gheorghiu
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
 
`timescale 1ns / 1ps
 
`include "io_s_h.v"
 
module spi_s #(
parameter DINAMIC_BAUDRATE = "TRUE",
parameter BAUDRATE_DIVIDER = 3,
parameter ADDRESS = 0,
parameter BUS_ADDR_DATA_LEN = 16
)(
input rst,
input clk,
input [BUS_ADDR_DATA_LEN-1:0]addr,
input wr,
input rd,
input [7:0]bus_in,
output reg[7:0]bus_out,
output int,
 
output sck,/* SPI 'sck' signal (output) */
output mosi,/* SPI 'mosi' signal (output) */
input miso,/* SPI 'miso' signal (input) */
output reg ss/* SPI 'ss' signal (if send buffer is maintained full the ss signal will not go high between between transmit chars)(output) */
);
 
//reg [7:0]CTRL;
//reg [7:0]BAUD;
 
wire cs_int = addr >= ADDRESS && addr < (ADDRESS + 8);
wire rd_int = cs_int && rd;
wire wr_int = cs_int && wr;
 
reg [7:0]baud_cnt;
 
wire buffempty;
 
reg [7:0]CTRL;
reg [7:0]INTCTRL;
reg [7:0]STATUS;
 
localparam WORD_LEN = 8;
localparam PRESCALLER_SIZE = 8;
 
reg _mosi;
 
reg charreceivedp;
reg charreceivedn;
 
reg inbufffullp = 1'b0;
reg inbufffulln = 1'b0;
 
reg [WORD_LEN - 1:0]input_buffer;
reg [WORD_LEN - 1:0]output_buffer;
 
assign buffempty = ~(inbufffullp ^ inbufffulln);
reg [2:0]prescallerbuff;
 
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
inbufffullp <= 1'b0;
prescallerbuff <= 3'b000;
CTRL <= 0;
INTCTRL <= 0;
input_buffer <= 0;
end
else
begin
if(wr_int)
begin
case(addr[2:0])
`SPI_CTRL: CTRL <= bus_in;
`SPI_INTCTRL: INTCTRL <= bus_in;
`SPI_DATA:
begin
if(inbufffullp == inbufffulln && buffempty && CTRL[`SPI_ENABLE_bp])
begin
inbufffullp <= ~inbufffullp;
prescallerbuff <= {CTRL[`SPI_CLK2X_bp], CTRL[`SPI_PRESCALER_gp + 1:`SPI_PRESCALER_gp]};
input_buffer <= bus_in;
end
end
endcase
end
end
end
 
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
STATUS <= 8'h00;
charreceivedn <= 1'b0;
end
else if(rd_int)
begin
case(addr[2:0])
`SPI_DATA: STATUS[`SPI_IF_bp] <= 1'b0;
endcase
end
else if(charreceivedp != charreceivedn)
begin
STATUS[`SPI_IF_bp] <= 1'b1;
charreceivedn <= ~charreceivedn;
end
 
end
 
always @ (*)
begin
bus_out <= 8'bz;
if(rd_int)
begin
case(addr[2:0])
`SPI_CTRL: bus_out <= CTRL;
`SPI_INTCTRL: bus_out <= INTCTRL;
`SPI_STATUS: bus_out <= STATUS;
`SPI_DATA: bus_out <= output_buffer;
endcase
end
end
 
assign int = INTCTRL[`SPI_INTLVL_gp + 1: `SPI_INTLVL_gp] ? STATUS[`SPI_IF_bp] : 1'b0;
 
/***********************************************/
/************ !Asynchronus send ****************/
/***********************************************/
localparam state_idle = 1'b0;
localparam state_busy = 1'b1;
reg state;
 
 
reg [PRESCALLER_SIZE - 1:0]prescaller_cnt;
reg [WORD_LEN - 1:0]shift_reg_out;
reg [WORD_LEN - 1:0]shift_reg_in;
reg [4:0]sckint;
//reg sckintn;
reg [2:0]prescallerint;
reg [7:0]prescdemux;
 
 
always @ (*)
begin
case(prescallerint)
3'b000: prescdemux <= 3;
3'b001: prescdemux <= 15;
3'b010: prescdemux <= 63;
3'b011: prescdemux <= 127;
3'b100: prescdemux <= 1;
3'b101: prescdemux <= 7;
3'b110: prescdemux <= 31;
3'b111: prescdemux <= 63;
endcase
end
 
reg lsbfirstint;
reg [1:0]modeint;
 
 
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
baud_cnt = 'h00;
inbufffulln <= 1'b0;
ss <= 1'b1;
state <= state_idle;
prescaller_cnt <= {PRESCALLER_SIZE{1'b0}};
prescallerint <= {PRESCALLER_SIZE{3'b0}};
shift_reg_out <= {WORD_LEN{1'b0}};
shift_reg_in <= {WORD_LEN{1'b0}};
sckint <= {5{1'b0}};
_mosi <= 1'b1;
output_buffer <= {WORD_LEN{1'b0}};
charreceivedp <= 1'b0;
lsbfirstint <= 1'b0;
modeint <= 2'b00;
end
else
begin
if(CTRL[`SPI_ENABLE_bp])
begin
if(DINAMIC_BAUDRATE == "TRUE" ? baud_cnt == prescdemux : baud_cnt == {BAUDRATE_DIVIDER})
begin
baud_cnt <= 'h00;
case(state)
state_idle:
begin
if(inbufffullp != inbufffulln)
begin
inbufffulln <= ~inbufffulln;
ss <= 1'b0;
prescaller_cnt <= {PRESCALLER_SIZE{1'b0}};
prescallerint <= prescallerbuff;
lsbfirstint <= CTRL[`SPI_DORD_bp];
modeint <= CTRL[`SPI_MODE_gp + 1:`SPI_MODE_gp];
shift_reg_out <= input_buffer;
state <= state_busy;
if(!CTRL[`SPI_MODE_gp])
begin
if(!CTRL[`SPI_DORD_bp])
_mosi <= input_buffer[WORD_LEN - 1];
else
_mosi <= input_buffer[0];
end
end
end
state_busy:
begin
if(prescaller_cnt != prescdemux)
begin
prescaller_cnt <= prescaller_cnt + 1;
end
else
begin
prescaller_cnt <= {PRESCALLER_SIZE{1'b0}};
sckint <= sckint + 1;
if(sckint[0] == modeint[0])
begin
if(!lsbfirstint)
begin
shift_reg_in <= {miso, shift_reg_in[7:1]};
shift_reg_out <= {shift_reg_out[6:0], 1'b1};
end
else
begin
shift_reg_in <= {shift_reg_in[6:0], miso};
shift_reg_out <= {1'b1, shift_reg_out[7:1]};
end
end
else
begin
if(sckint[4:1] == WORD_LEN - 1)
begin
sckint <= {5{1'b0}};
if(inbufffullp == inbufffulln)
begin
ss <= 1'b1;
end
output_buffer <= shift_reg_in;
if(charreceivedp == charreceivedn)
begin
charreceivedp <= ~charreceivedp;
end
state <= state_idle;
end
else
begin
if(!lsbfirstint)
_mosi <= shift_reg_out[WORD_LEN - 1];
else
_mosi <= shift_reg_out[0];
end
end
end
end
endcase
end
else
begin
baud_cnt <= baud_cnt + 1;
end
end
end
end
 
assign sck = (modeint[1])? ~sckint : sckint;
assign mosi = (ss) ? 1'b1:_mosi;
 
endmodule
/trunk/rtl/io/twi_s.v
0,0 → 1,333
/*
* This IP is a TWI IO adapter implementation.
*
* Copyright (C) 2018 Iulian Gheorghiu
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
 
`timescale 1ns / 1ps
 
`include "io_s_h.v"
 
module twi_s #(
parameter DINAMIC_BAUDRATE = "TRUE",
parameter BAUDRATE_DIVIDER = 255,
parameter ADDRESS = 0,
parameter BUS_ADDR_DATA_LEN = 16
)(
input rst,
input clk,
input [BUS_ADDR_DATA_LEN-1:0]addr,
input wr,
input rd,
input [7:0]bus_in,
output reg[7:0]bus_out,
output int_tx_cmpl,
output int_rx_cmpl,
input int_tx_rst,
input int_rx_rst,
inout scl,
inout sda
);
 
reg [7:0]CTRLA;
reg [7:0]CTRLB;
reg [7:0]CTRLC;
reg [7:0]STATUS;
reg [7:0]BAUD;
reg [7:0]DATA;
 
wire cs_int = addr >= ADDRESS && addr < (ADDRESS + 16);
wire rd_int = cs_int && rd;
wire wr_int = cs_int && wr;
 
reg [7:0]baud_cnt;
reg [1:0]cmd;
reg tx_mode;
reg start_sent;
reg rcv_ack;
reg send_ack;
reg send_ack_st2;
reg [1:0]stage;
reg [2:0]bit_count;
reg scl_int;
reg sda_int;
reg send_ack_int;
 
localparam [2:0]CMD_NOP = {1'b1, 2'b00};
localparam [2:0]CMD_RESTART = {1'b0, 2'b01};
localparam [2:0]CMD_RECEIVE = {1'b0, 2'b10};
localparam [2:0]CMD_STOP = {1'b0, 2'b11};
 
always @ (*)
begin
bus_out <= 'hz;
if(rd_int)
begin
case(addr[3:0])
`TWI_MASTER_CTRLA: bus_out <= CTRLA;
`TWI_MASTER_CTRLB: bus_out <= CTRLB;
`TWI_MASTER_CTRLC: bus_out <= CTRLC;
`TWI_MASTER_STATUS: bus_out <= STATUS;
`TWI_MASTER_BAUD: bus_out <= BAUD;
`TWI_MASTER_DATA: bus_out <= DATA;
endcase
end
end
 
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
CTRLA <= 'h0;
CTRLB <= 'h0;
CTRLC <= 'h0;
STATUS <= 'h0;
BAUD <= 'h0;
DATA <= 'h0;
baud_cnt <= 'h00;
cmd <= 'h00;
tx_mode <= 1'b0;
start_sent <= 1'b0;
scl_int <= 1'b1;
sda_int <= 1'b1;
rcv_ack <= 1'b0;
send_ack <= 1'b0;
send_ack_st2 <= 1'b0;
stage <= 'h00;
send_ack_int <= 1'b1;
end
else
begin
if(DINAMIC_BAUDRATE == "TRUE" ? baud_cnt == BAUD : baud_cnt == {BAUDRATE_DIVIDER})
begin
baud_cnt <= 'h00;
if(CTRLA[`TWI_MASTER_ENABLE_bp])
begin
case({tx_mode, cmd})
CMD_NOP:
begin
if(~start_sent)
begin/* Send the start sequence */
stage <= stage + 1;
case(stage)
'h0:
begin
scl_int <= 1'b1;
sda_int <= 1'b0;
end
'h1:
begin
scl_int <= 1'b0;
bit_count <= 'hF;
start_sent <= 1'b1;
stage <= 'h0;
end
endcase
end
else
begin/* Send bits */
stage <= stage + 1;
case(stage)
'h0:
begin
case(rcv_ack)
1'b0:
begin
sda_int <= DATA[bit_count];
end
1'b1:
sda_int <= 1'b1;
endcase
end
'h1:
begin
scl_int <= 1'b1;
end
'h2:
begin
if(rcv_ack)
STATUS[`TWI_MASTER_RXACK_bp] <= sda;
end
'h3:
begin
stage <= 'h0;
scl_int <= 1'b0;
case(rcv_ack)
1'b0:
begin
if(~|bit_count)
rcv_ack <= 1'b1;
bit_count <= bit_count - 1;
end
1'b1:
begin
tx_mode <= 1'b0;
STATUS[`TWI_MASTER_WIF_bp] <= 1'b1;
rcv_ack <= 1'b0;
end
endcase
end
endcase
end
end
CMD_RESTART:
begin/* Send restart */
stage <= stage + 1;
case(stage)
'h0:
begin
sda_int <= 1'b1;
end
'h1:
begin
scl_int <= 1'b1;
end
'h2:
begin
sda_int <= 1'b0;
end
'h3:
begin
scl_int <= 1'b0;
bit_count <= 'hF;
start_sent <= 1'b1;
stage <= 'h0;
cmd <= 'h0;
CTRLC[`TWI_MASTER_CMD_gp + 1:`TWI_MASTER_CMD_gp] <= 'h0;
end
endcase
end
CMD_RECEIVE:
begin/* Receive bits */
stage <= stage + 1;
case(stage)
'h0:
begin
if(send_ack && ~send_ack_st2)
sda_int <= send_ack_int;
else if(send_ack_st2)
begin
STATUS[`TWI_MASTER_RIF_bp] <= 1'b1;
cmd <= 'h0;
CTRLC[`TWI_MASTER_CMD_gp + 1:`TWI_MASTER_CMD_gp] <= 'h0;
sda_int <= 1'b1;
end
end
'h1:
begin
scl_int <= 1'b1;
end
'h2:
begin
if(~send_ack)
DATA[bit_count] <= sda;
end
'h3:
begin
scl_int <= 1'b0;
stage <= 'h0;
case(send_ack)
1'b0:
begin
if(~|bit_count)
send_ack <= 1'b1;
bit_count <= bit_count - 1;
end
1'b1: send_ack_st2 <= 1'b1;
endcase
end
endcase
end
CMD_STOP:
begin/* Send stop */
stage <= stage + 1;
case(stage)
'h0: sda_int <= 1'b0;
'h1: scl_int <= 1'b1;
'h2:
begin
sda_int <= 1'b1;
start_sent <= 1'b0;
stage <= 'h0;
cmd <= 'h0;
CTRLC[`TWI_MASTER_CMD_gp + 1:`TWI_MASTER_CMD_gp] <= 'h0;
end
endcase
end
endcase
end
end
else
begin
baud_cnt <= baud_cnt + 1;
end
if(CTRLA[`TWI_MASTER_ENABLE_bp])
begin
if(CTRLC[`TWI_MASTER_CMD_gp + 1:`TWI_MASTER_CMD_gp] && ~|cmd && ~tx_mode)
begin
cmd <= CTRLC[`TWI_MASTER_CMD_gp + 1:`TWI_MASTER_CMD_gp];
stage <= 'h0;
send_ack <= 1'b0;
send_ack_st2 <= 1'b0;
send_ack_int <= CTRLC[`TWI_SLAVE_ACKACT_bp];
end
end
if(wr_int)
begin
case(addr[3:0])
`TWI_MASTER_CTRLA: CTRLA <= bus_in;
`TWI_MASTER_CTRLB: CTRLB <= bus_in;
`TWI_MASTER_CTRLC: CTRLC <= bus_in;
`TWI_MASTER_STATUS: STATUS <= STATUS ^ bus_in;
`TWI_MASTER_BAUD: BAUD <= bus_in;
//`TWI_MASTER_ADDR: ADDR <= bus_in;
`TWI_MASTER_DATA:
begin
if(~|CTRLC[`TWI_MASTER_CMD_gp + 1:`TWI_MASTER_CMD_gp])
begin
DATA <= bus_in;
tx_mode <= 1'b1;
STATUS[`TWI_MASTER_WIF_bp] <= 1'b0;
end
end
endcase
end
if(rd_int)
begin
case(addr[3:0])
`TWI_MASTER_DATA:
begin
STATUS[`TWI_MASTER_RIF_bp] <= 1'b0;
end
endcase
end
end
end
 
PULLUP PULLUP_scl_inst (
.O(scl) // 1-bit output: Pullup output (connect directly to top-level port)
);
PULLUP PULLUP_sda_inst (
.O(sda) // 1-bit output: Pullup output (connect directly to top-level port)
);
 
 
assign scl = scl_int ? 1'bz : scl_int;
assign sda = sda_int ? 1'bz : sda_int;
 
endmodule
/trunk/rtl/io/uart_s.v
0,0 → 1,476
/*
* This IP is a simple paralel IO adapter implementation.
*
* Copyright (C) 2018 Iulian Gheorghiu
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
 
`timescale 1ns / 1ps
 
`include "io_s_h.v"
 
module uart_s #(
parameter BAUDRATE_COUNTER_LENGTH = 12,
parameter DINAMIC_BAUDRATE = "TRUE",
parameter BAUDRATE_DIVIDER = 19200,
parameter ADDRESS = 0,
parameter BUS_ADDR_DATA_LEN = 16
)(
input rst,
input clk,
input [BUS_ADDR_DATA_LEN-1:0]addr,
input wr,
input rd,
input [7:0]bus_in,
output reg[7:0]bus_out,
output int_rx_rcv,
output int_tx_compl,
output int_tx_buff_empty,
inout int_rst,
inout rtx_clk,
output reg tx,
input rx
);
 
localparam [6:0]MAX_WORD_LEN = 9;
 
localparam state_idle = 1'b0;
localparam state_busy = 1'b1;
 
reg [7:0]DATA_in;
reg [7:0]DATA_out;
reg [7:0]STATUS;
reg [7:0]CTRLA;
reg [7:0]CTRLB;
reg [7:0]CTRLC;
reg [7:0]BAUDCTRLA;
reg [7:0]BAUDCTRLB;
reg [7:0]BAUDCTRLB_tmp_read;
reg [7:0]BAUDCTRLB_tmp_write;
 
wire cs_int = addr >= ADDRESS && addr < (ADDRESS + 16);
wire rd_int = cs_int && rd;
wire wr_int = cs_int && wr;
 
reg [BAUDRATE_COUNTER_LENGTH == 0 ? 0 : BAUDRATE_COUNTER_LENGTH - 1:0]baud_cnt;
 
reg receiveoverrunp;
reg receiveoverrunn;
wire receiveoverrunpn;
 
reg [2:0]rxbitcntstate;
 
reg charreceivedp;
reg charreceivedn;
 
reg state_rx;
reg state_tx;
reg [(MAX_WORD_LEN - 1) + 4:0]shift_reg_in;
reg [(MAX_WORD_LEN - 1) + 4:0]shift_reg_out;
//reg [MAX_WORD_LEN - 1:0]temp_output_buffer;
reg [7:0]sckint_rx;
//reg [3:0]bitcount_rx;
reg [3:0]total_word_len_rx;
 
wire _chk_int;
wire chk_int;
reg [(MAX_WORD_LEN - 1) + 4:0]parity_mask;
wire [(MAX_WORD_LEN - 1) + 4:0]valid_data;
wire parity_bit;
reg [3:0]wordlen;
 
reg inbufffullp;
reg inbufffulln;
 
reg last_state_rxp;
reg last_state_rxn;
wire rx_start_detected;
 
reg [3:0]sckint_tx;
reg [3:0]bitcount_tx;
reg [3:0]total_word_len_tx;
 
wire buffempty = ~(inbufffullp ^ inbufffulln);
reg [11:0]prescallerbuff;
 
reg int_tx_compl_int;
reg int_tx_buff_empty_int;
assign int_tx_compl = CTRLB[`USART_TXEN_bp] ? int_tx_compl_int : 1'b0;
assign int_tx_buff_empty = CTRLB[`USART_TXEN_bp] ? int_tx_buff_empty_int : 1'b0;
reg int_rx_rcv_int;
assign int_rx_rcv = CTRLB[`USART_RXEN_bp] ? int_rx_rcv_int : 1'b0;
 
wire [15:0]static_baudrate = {BAUDCTRLB, BAUDCTRLA};
 
always @ (posedge rd_int or posedge rst)
begin
if(rst)
begin
charreceivedn <= 1'b0;
receiveoverrunp <= 1'b0;
end
else if(rd_int)
begin
case(addr[3:0])
`USART_DATA:
begin
if(charreceivedp != charreceivedn)
charreceivedn <= ~charreceivedn;
if(receiveoverrunn != receiveoverrunp)
receiveoverrunp <= ~receiveoverrunp;
end
endcase
end
end
 
always @ (*)
begin
if(rst)
begin
BAUDCTRLB_tmp_read <= 'h0;
end
else if(rd_int)
begin
case(addr[3:0])
`USART_DATA: bus_out <= DATA_out;
`USART_STATUS: bus_out <= STATUS;
`USART_CTRLA: bus_out <= CTRLA;
`USART_CTRLB: bus_out <= CTRLB;
`USART_CTRLC: bus_out <= CTRLC;
`USART_BAUDCTRLA:
begin
if(DINAMIC_BAUDRATE == "TRUE")
begin
bus_out <= BAUDCTRLA;
BAUDCTRLB_tmp_read <= BAUDCTRLB;
end
else
begin
bus_out <= static_baudrate[7:0];
end
end
`USART_BAUDCTRLB:
begin
if(DINAMIC_BAUDRATE == "TRUE")
bus_out <= BAUDCTRLB_tmp_read;
else
bus_out <= static_baudrate[15:8];
end
default: bus_out <= 8'bz;
endcase
end
else
begin
bus_out <= 8'bz;
end
end
 
 
always @ (*)
begin
case(CTRLC[`USART_CHSIZE_gp + 2:`USART_CHSIZE_gp])
3'h00: wordlen <= 12'd5;
3'h01: wordlen <= 12'd6;
3'h02: wordlen <= 12'd7;
3'h03: wordlen <= 12'd8;
3'h07: wordlen <= 12'd9;
default: wordlen <= 12'd8;
endcase
end
 
always @ (*)
begin
case(wordlen)
4'h05: parity_mask <= 12'b000000111110;
4'h06: parity_mask <= 12'b000001111110;
4'h07: parity_mask <= 12'b000011111110;
4'h09: parity_mask <= 12'b001111111110;
default: parity_mask <= 12'b000111111110;
endcase
end
assign valid_data = shift_reg_in & parity_mask;
assign _chk_int = ^valid_data;
assign chk_int = (CTRLC[`USART_CMODE_gp + 1:`USART_CMODE_gp] == 2'b10) ? ~_chk_int:_chk_int;
assign parity_bit = (shift_reg_in & (1 << wordlen + 1)) ? 1:0;
 
always @ (negedge rx or posedge rst)
begin
if(rst)
last_state_rxn <= 0;
else
begin
if(last_state_rxn == last_state_rxp)
begin
last_state_rxn <= ~last_state_rxp;
end
end
end
 
assign rx_start_detected = (last_state_rxn ^ last_state_rxp);
 
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
baud_cnt = 'h00;
charreceivedn <= 1'b0;
inbufffullp <= 1'b0;
inbufffulln <= 1'b0;
DATA_in <= 'h0;
STATUS <= 'h0;
CTRLA <= 'h0;
CTRLB <= 'h0;
CTRLC <= `USART_CHSIZE_8BIT_gc;
BAUDCTRLA <= 'h0;
BAUDCTRLB <= 'h0;
BAUDCTRLB_tmp_write <= 'h0;
last_state_rxp <= 'h0;
state_rx <= state_idle;
state_tx <= state_idle;
shift_reg_in <= 'h0;
sckint_rx <= 'h0;
charreceivedp <= 'h0;
receiveoverrunn <= 'h0;
rxbitcntstate <= 'h0;
total_word_len_rx <= 'h0;
int_rx_rcv_int <= 'h0;
int_tx_compl_int <= 'h0;
int_tx_buff_empty_int <= 'h0;
tx <= 1'b1;
end
else
begin
STATUS[`USART_DREIF_bp] <= buffempty;
/*
* Read from IO logic
*/
if(wr_int)
begin
case(addr[3:0])
`USART_STATUS: STATUS <= STATUS ^ bus_in;
`USART_CTRLA: CTRLA <= bus_in;
`USART_CTRLB: CTRLB <= bus_in;
`USART_CTRLC: CTRLC <= bus_in;
`USART_BAUDCTRLA:
begin
if(DINAMIC_BAUDRATE == "TRUE")
begin
BAUDCTRLA <= bus_in;
BAUDCTRLB <= BAUDCTRLB_tmp_write;
end
end
`USART_BAUDCTRLB:
begin
if(DINAMIC_BAUDRATE == "TRUE")
begin
BAUDCTRLB_tmp_write <= bus_in;
end
end
`USART_DATA:
begin
if(inbufffullp == inbufffulln && buffempty && CTRLB[`USART_TXEN_bp])
begin
inbufffullp <= ~inbufffullp;
prescallerbuff <= {BAUDCTRLB[3:0], BAUDCTRLA};
DATA_in <= bus_in;
int_tx_compl_int <= 1'b0;
int_tx_buff_empty_int <= 'h0;
end
end
endcase
end
if(rd_int)
begin
case(addr[3:0])
`USART_DATA: int_rx_rcv_int <= 1'b0;
endcase
end
if(DINAMIC_BAUDRATE == "TRUE" ? baud_cnt == prescallerbuff : baud_cnt == {BAUDRATE_DIVIDER})
begin
baud_cnt <= 'h00;
if(CTRLB[`USART_RXEN_bp])
begin
/*
* Rx logic
*/
if(state_rx == state_idle)
begin
// Wait for a transition from hi to low that indicate a start condition.
if(rx_start_detected)
begin
shift_reg_in <= 0;
sckint_rx <= 0;
rxbitcntstate <= 7;
// Calculate the total number of bits to receive including end.
total_word_len_rx <= CTRLC[`USART_CMODE_gp + 1:`USART_CMODE_gp] ? 1 : 0 + 1 + CTRLC[`USART_SBMODE_bp] + wordlen;
state_rx <= state_busy;
end
end
else
begin
case(sckint_rx[3:0])
7,8,9:
begin
rxbitcntstate <= rxbitcntstate + (rx ? 3'd7 : 3'd1);
sckint_rx <= sckint_rx + 1;
end
10:
begin
if(sckint_rx[7:4] == total_word_len_rx)// If is stop bit check-it and out the received data.
begin
// Verify stop bit to be valid, else report a frame error.
STATUS[`USART_FERR_bp] <= ~rxbitcntstate[2];
// Verify the parity bit
if(CTRLC[`USART_CMODE_gp + 1:`USART_CMODE_gp])
STATUS[`USART_PERR_bp] <= parity_bit ^ chk_int;
else
STATUS[`USART_PERR_bp] <= 'h0;
// Put data from shift register to output data register.
{STATUS[`USART_RXB8_bp], DATA_out} <= valid_data[9:1];
// Check if the previous received data has been read from output register, if not report a overrun situation..
if(charreceivedn == charreceivedp)
charreceivedp <= ~charreceivedp;
else
begin
if(receiveoverrunn == receiveoverrunp)
receiveoverrunn <= ~receiveoverrunn;
end
if(CTRLA[`USART_RXCINTLVL_gp + 1 : `USART_RXCINTLVL_gp])
begin
int_rx_rcv_int <= 1'b1;
end
state_rx <= state_idle;
sckint_rx <= 0;
last_state_rxp <= last_state_rxn;
end
else
begin
shift_reg_in[sckint_rx[7:4]] <= rxbitcntstate[2];
sckint_rx <= sckint_rx + 1;
end
end
15:
begin
rxbitcntstate <= 7;
sckint_rx <= sckint_rx + 1;
end
default:
begin
sckint_rx <= sckint_rx + 1;
end
endcase
end
end
else
begin
int_rx_rcv_int <= 'h0;
end
/*
* Tx logic
*/
if(CTRLB[`USART_TXEN_bp])
begin
case(state_tx)
state_idle:
begin
if(inbufffullp != inbufffulln)
begin
inbufffulln <= ~inbufffulln;
sckint_tx <= 5'h01;
int_tx_compl_int <= 1'b0;
if(CTRLA[`USART_DREINTLVL_gc + 1 : `USART_DREINTLVL_gc])
begin
int_tx_buff_empty_int <= 'h1;
end
case({CTRLC[`USART_PMODE_gp + 1 : `USART_PMODE_gp], CTRLC[`USART_SBMODE_bp], wordlen})
{2'b00, 4'h05}: shift_reg_out <= {1'b1, DATA_in[4:0], 1'h0};
{2'b00, 4'h06}: shift_reg_out <= {1'b1, DATA_in[5:0], 1'h0};
{2'b00, 4'h07}: shift_reg_out <= {1'b1, DATA_in[6:0], 1'h0};
{2'b00, 4'h08}: shift_reg_out <= {1'b1, DATA_in, 1'h0};
{2'b00, 4'h09}: shift_reg_out <= {1'b1, CTRLB[`USART_TXB8_bp], DATA_in, 1'h0};
{2'b01, 4'h05}: shift_reg_out <= {2'b11, DATA_in[4:0], 1'h0};
{2'b01, 4'h06}: shift_reg_out <= {2'b11, DATA_in[5:0], 1'h0};
{2'b01, 4'h07}: shift_reg_out <= {2'b11, DATA_in[6:0], 1'h0};
{2'b01, 4'h08}: shift_reg_out <= {2'b11, DATA_in, 1'h0};
{2'b01, 4'h09}: shift_reg_out <= {2'b11, CTRLB[`USART_TXB8_bp], DATA_in, 1'h0};
{2'b10, 4'h05}: shift_reg_out <= {1'b1, chk_int, DATA_in[4:0], 1'h0};
{2'b10, 4'h06}: shift_reg_out <= {1'b1, chk_int, DATA_in[5:0], 1'h0};
{2'b10, 4'h07}: shift_reg_out <= {1'b1, chk_int, DATA_in[6:0], 1'h0};
{2'b10, 4'h08}: shift_reg_out <= {1'b1, chk_int, DATA_in, 1'h0};
{2'b10, 4'h09}: shift_reg_out <= {1'b1, chk_int, CTRLB[`USART_TXB8_bp], DATA_in, 1'h0};
{2'b11, 4'h05}:shift_reg_out <= {2'b11, chk_int, DATA_in[4:0], 1'h0};
{2'b11, 4'h06}:shift_reg_out <= {2'b11, chk_int, DATA_in[5:0], 1'h0};
{2'b11, 4'h07}:shift_reg_out <= {2'b11, chk_int, DATA_in[6:0], 1'h0};
{2'b11, 4'h08}:shift_reg_out <= {2'b11, chk_int, DATA_in, 1'h0};
{2'b11, 4'h09}:shift_reg_out <= {2'b11, chk_int, CTRLB[`USART_TXB8_bp], DATA_in, 1'h0};
default: shift_reg_out <= {1'b1, DATA_in[7:0], 1'h0};
endcase
bitcount_tx <= 4'b0000;
total_word_len_tx <= CTRLC[`USART_PMODE_gp + 1:`USART_PMODE_gp] ? 1 : 0 + 1 + CTRLC[`USART_SBMODE_bp] + wordlen + 1;
state_tx <= state_busy;
/*Put start, first bit from shift_reg_out*/
tx <= 1'b0;
end
end
state_busy:
begin
case(sckint_tx)
4'h0D:
begin
sckint_tx <= sckint_tx + 1;
bitcount_tx <= bitcount_tx + 'b0001;
end
4'h0E:
begin
if(bitcount_tx == total_word_len_tx)
begin
state_tx <= state_idle;
if(CTRLA[`USART_TXCINTLVL_gp + 1 : `USART_TXCINTLVL_gp])
begin
int_tx_compl_int <= 1'b1;
end
end
sckint_tx <= sckint_tx + 1;
end
4'h0F:
begin
sckint_tx <= sckint_tx + 1;
tx <= shift_reg_out[bitcount_tx];
end
default:
begin
sckint_tx <= sckint_tx + 1;
end
endcase
end
endcase
end
else
begin
int_tx_compl_int <= 'h0;
int_tx_buff_empty_int <= 'h0;
end
end
else
begin
baud_cnt <= baud_cnt + 1;
end
end
end
 
 
endmodule
/trunk/rtl/mega_core_opt.v
0,0 → 1,3352
/*----------------------------------------------------------------------------/
/ This IP is the Atmel ATTINY-ATMEGA-ATXMEGA CPU implementation. /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2017 Iulian Gheorghiu (morgoth.creator@gmail.com), all right reserved.
/
/ This IP file is an open source software. Redistribution and use of this IP in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
 
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/----------------------------------------------------------------------------*/
 
`timescale 1ns / 1ps
 
/*
* Define modes.
*/
 
`define USE_RAM_READ_DELAY 1// For now let it undefined because is not fully implemented( uncommenting this line will result in unnexpected behavior ).
 
//`define USE_EXTENDED_RAMP_REGS// For future usage.
//`define USE_CCP_REG// For future usage.
`define USE_LPM
 
/*
* Core configurations:
* "REDUCED" // (not working)
* "MINIMAL"
* "CLASSIC_8K"
* "CLASSIC_128K"
* "ENHANCED_8K"
* "ENHANCED_128K"
* "ENHANCED_4M" //Not implemented
* "XMEGA"
*/
 
/*
* Watchdog.
*/
module watchdog # (
parameter CNT_WIDTH = 0
)(
input rst,
input clk,
input wdt_clk,
input wdt_rst_in,
output reg wdt_rst_out);
reg [CNT_WIDTH:0]wdt_cnt;
reg reset;
reg reset_n;
reg wdt_reset;
reg wdt_reset_n;
 
always @ (posedge rst or posedge wdt_rst_in)
begin
if(rst)
reset <= 1'b0;
else
reset <= ~reset_n;
end
 
always @ (posedge rst or posedge wdt_clk)
begin
if(rst)
begin
reset_n <= 1'b0;
wdt_reset <=1'b0;
wdt_cnt <= 'h0000;
end
else if(reset != reset_n)
begin
reset_n <= reset;
wdt_cnt <= 'h0000;
end
else if(wdt_clk)
begin
if(wdt_cnt[CNT_WIDTH])
begin
wdt_reset <= ~wdt_reset_n;
wdt_cnt <= 'h0000;
end
else
begin
wdt_cnt <= wdt_cnt + 1;
end
end
end
 
always @ (posedge rst or posedge clk)
begin
wdt_rst_out <= 1'b0;
if(rst)
wdt_reset_n <= 1'b1;
else if(wdt_reset != wdt_reset_n)
begin
wdt_reset_n <= wdt_reset;
wdt_rst_out <= 1'b1;
end
end
 
endmodule
/*
* !Watchdog.
*/
/*
* !Define modes.
*/
 
/*
* Instruction set.
*/
 
`define INSTRUCTION_NOP 16'b0000000000000000
`define INSTRUCTION_MOVW 16'b00000001xxxxxxxx//00000001DDDDRRRR
`define INSTRUCTION_MULS 16'b00000010xxxxxxxx//00000010ddddrrrr
`define INSTRUCTION_MULSU 16'b000000110xxx0xxx//000000110ddd0rrr
`define INSTRUCTION_FMUL 16'b000000110xxx1xxx//000000110ddd1rrr
`define INSTRUCTION_FMULS 16'b000000111xxx0xxx//000000111dddurrr
`define INSTRUCTION_FMULSU 16'b000000111xxx1xxx//000000111dddurrr
`define INSTRUCTION_CPC 16'b000001xxxxxxxxxx//000001rdddddrrrr
`define INSTRUCTION_CP 16'b000101xxxxxxxxxx//000101rdddddrrrr
`define INSTRUCTION_SBC 16'b000010xxxxxxxxxx//000010rdddddrrrr
`define INSTRUCTION_SUB 16'b000110xxxxxxxxxx//000110rdddddrrrr
`define INSTRUCTION_ADD 16'b000011xxxxxxxxxx//000011rdddddrrrr
`define INSTRUCTION_ADC 16'b000111xxxxxxxxxx//000111rdddddrrrr
`define INSTRUCTION_CPSE 16'b000100xxxxxxxxxx//000100rdddddrrrr
`define INSTRUCTION_AND 16'b001000xxxxxxxxxx//001000rdddddrrrr
`define INSTRUCTION_EOR 16'b001001xxxxxxxxxx//001001rdddddrrrr
`define INSTRUCTION_OR 16'b001010xxxxxxxxxx//001010rdddddrrrr
`define INSTRUCTION_MOV 16'b001011xxxxxxxxxx//001011rdddddrrrr
`define INSTRUCTION_CPI 16'b0011xxxxxxxxxxxx//0011kkkkddddkkkk
`define INSTRUCTION_SUBI 16'b0101xxxxxxxxxxxx//0101kkkkddddkkkk
`define INSTRUCTION_SBCI 16'b0100xxxxxxxxxxxx//0100kkkkddddkkkk
`define INSTRUCTION_ORI_SBR 16'b0110xxxxxxxxxxxx//0110kkkkddddkkkk
`define INSTRUCTION_ANDI_CBR 16'b0111xxxxxxxxxxxx//0111kkkkddddkkkk
 
`define INSTRUCTION_LDD_STD 16'b10x0xxxxxxxxxxxx//10k0kksdddddykkk
`define INSTRUCTION_LDS_STS 16'b100100xxxxxx0000//100100sddddd0000
`define INSTRUCTION_LD_ST_YZP 16'b100100xxxxxxx001//100100sdddddy001
`define INSTRUCTION_LD_ST_YZN 16'b100100xxxxxxx010//100100sdddddy010
`define INSTRUCTION_LPM_R 16'b1001000xxxxx0100//1001000ddddd01q0
`define INSTRUCTION_LPM_R_P 16'b1001000xxxxx0101//1001000ddddd01q1
`define INSTRUCTION_XCH 16'b1001001xxxxx0100//1001001ddddd0100
`define INSTRUCTION_LAS 16'b1001001xxxxx0101//1001001ddddd0101
`define INSTRUCTION_LAC 16'b1001001xxxxx0110//1001001ddddd0110
`define INSTRUCTION_LAT 16'b1001001xxxxx0111//1001001ddddd0111
`define INSTRUCTION_LD_ST_X 16'b100100xxxxxx1100//100100sddddd1100
`define INSTRUCTION_LD_ST_XP 16'b100100xxxxxx1101//100100sddddd1101
`define INSTRUCTION_LD_ST_XN 16'b100100xxxxxx1110//100100sddddd1110
`define INSTRUCTION_POP_PUSH 16'b100100xxxxxx1111//100100sddddd1111
`define INSTRUCTION_COM 16'b1001010xxxxx0000//1001010ddddd0000
`define INSTRUCTION_NEG 16'b1001010xxxxx0001//1001010ddddd0001
`define INSTRUCTION_SWAP 16'b1001010xxxxx0010//1001010ddddd0010
`define INSTRUCTION_INC 16'b1001010xxxxx0011//1001010ddddd0011
`define INSTRUCTION_ASR 16'b1001010xxxxx0101//1001010ddddd0101
`define INSTRUCTION_LSR 16'b1001010xxxxx0110//1001010ddddd0110
`define INSTRUCTION_ROR 16'b1001010xxxxx0111//1001010ddddd0111
`define INSTRUCTION_SEx_CLx 16'b10010100xxxx1000//10010100Bbbb1000
`define INSTRUCTION_RET_RETI 16'b10010101000x1000//10010101000x1000
`define INSTRUCTION_RET 16'b1001010100001000//1001010100001000
`define INSTRUCTION_RETI 16'b1001010100011000//1001010100001000
`define INSTRUCTION_SLEEP 16'b1001010110000000//1001010100001000
`define INSTRUCTION_BREAK 16'b1001010110011000//1001010100011000
`define INSTRUCTION_WDR 16'b1001010110101000//1001010100101000
`define INSTRUCTION_LPM_ELPM 16'b10010101110x1000//10010101110q1000
`define INSTRUCTION_SPM 16'b1001010111101000//1001010111101000
`define INSTRUCTION_SPM_Z_P 16'b1001010111111000//1001010111111000
`define INSTRUCTION_IJMP 16'b1001010000001001//1001010c000e1001
`define INSTRUCTION_ICALL 16'b1001010100001001//1001010c000e1001
`define INSTRUCTION_DEC 16'b1001010xxxxx1010//1001010ddddd1010
`define INSTRUCTION_DES 16'b10010100xxxx1011//10010100kkkk1011
`define INSTRUCTION_JMP 16'b1001010xxxxx110x//1001010kkkkk110k
`define INSTRUCTION_CALL 16'b1001010xxxxx111x//1001010kkkkk111k
`define INSTRUCTION_ADIW 16'b10010110xxxxxxxx//10010110kkppkkkk
`define INSTRUCTION_SBIW 16'b10010111xxxxxxxx//10010111kkppkkkk
`define INSTRUCTION_CBI_SBI 16'b100110x0xxxxxxxx//100110B0aaaaabbb
`define INSTRUCTION_SBIC_SBIS 16'b100110x1xxxxxxxx//100110B1aaaaabbb
`define INSTRUCTION_MUL 16'b100111xxxxxxxxxx//100111rdddddrrrr
`define INSTRUCTION_IN_OUT 16'b1011xxxxxxxxxxxx//1011saadddddaaaa
`define INSTRUCTION_RJMP 16'b1100xxxxxxxxxxxx//1100xxxxxxxxxxxx
`define INSTRUCTION_RCALL 16'b1101xxxxxxxxxxxx//1101xxxxxxxxxxxx
`define INSTRUCTION_LDI 16'b1110xxxxxxxxxxxx//1110KKKKddddKKKK
`define INSTRUCTION_COND_BRANCH 16'b11110xxxxxxxxxxx//11110Bxxxxxxxbbb
`define INSTRUCTION_BLD_BST 16'b111110xxxxxx0xxx//111110sddddd0bbb
`define INSTRUCTION_SBRC_SBRS 16'b111111xxxxxx0xxx//111111Bddddd0bbb
/*
* !Instruction set.
*/
 
/*
* Instruction decoder.
*/
module inst_dec(
input [15:0]inst,
input INTERRUPT_IN_EXECUTION,
output reg SEL_INSTRUCTION_MOVW,
output reg SEL_INSTRUCTION_MULS,
output reg SEL_INSTRUCTION_MULSU,
output reg SEL_INSTRUCTION_FMUL,
output reg SEL_INSTRUCTION_FMULS,
output reg SEL_INSTRUCTION_FMULSU,
output reg SEL_INSTRUCTION_CPC,
output reg SEL_INSTRUCTION_CP,
output reg SEL_INSTRUCTION_SBC,
output reg SEL_INSTRUCTION_SUB,
output reg SEL_INSTRUCTION_ADD,
output reg SEL_INSTRUCTION_ADC,
output reg SEL_INSTRUCTION_CPSE,
output reg SEL_INSTRUCTION_AND,
output reg SEL_INSTRUCTION_EOR,
output reg SEL_INSTRUCTION_OR,
output reg SEL_INSTRUCTION_MOV,
output reg SEL_INSTRUCTION_CPI,
output reg SEL_INSTRUCTION_SUBI,
output reg SEL_INSTRUCTION_SBCI,
output reg SEL_INSTRUCTION_ORI_SBR,
output reg SEL_INSTRUCTION_ANDI_CBR,
output reg SEL_INSTRUCTION_LDD_STD,
output reg SEL_INSTRUCTION_LDS_STS,
output reg SEL_INSTRUCTION_LD_ST_YZP,
output reg SEL_INSTRUCTION_LD_ST_YZN,
output reg SEL_INSTRUCTION_LPM_R,
output reg SEL_INSTRUCTION_LPM_R_P,
output reg SEL_INSTRUCTION_XCH,
output reg SEL_INSTRUCTION_LAS,
output reg SEL_INSTRUCTION_LAC,
output reg SEL_INSTRUCTION_LAT,
output reg SEL_INSTRUCTION_LD_ST_X,
output reg SEL_INSTRUCTION_LD_ST_XP,
output reg SEL_INSTRUCTION_LD_ST_XN,
output reg SEL_INSTRUCTION_POP_PUSH,
output reg SEL_INSTRUCTION_COM,
output reg SEL_INSTRUCTION_NEG,
output reg SEL_INSTRUCTION_SWAP,
output reg SEL_INSTRUCTION_INC,
output reg SEL_INSTRUCTION_ASR,
output reg SEL_INSTRUCTION_LSR,
output reg SEL_INSTRUCTION_ROR,
output reg SEL_INSTRUCTION_SEx_CLx,
output reg SEL_INSTRUCTION_RET,
output reg SEL_INSTRUCTION_RETI,
output reg SEL_INSTRUCTION_SLEEP,
output reg SEL_INSTRUCTION_BREAK,
output reg SEL_INSTRUCTION_WDR,
output reg SEL_INSTRUCTION_LPM_ELPM,
output reg SEL_INSTRUCTION_SPM,
output reg SEL_INSTRUCTION_SPM_Z_P,
output reg SEL_INSTRUCTION_IJMP,
output reg SEL_INSTRUCTION_ICALL,
output reg SEL_INSTRUCTION_DEC,
output reg SEL_INSTRUCTION_DES,
output reg SEL_INSTRUCTION_JMP,
output reg SEL_INSTRUCTION_CALL,
output reg SEL_INSTRUCTION_ADIW,
output reg SEL_INSTRUCTION_SBIW,
output reg SEL_INSTRUCTION_CBI_SBI,
output reg SEL_INSTRUCTION_SBIC_SBIS,
output reg SEL_INSTRUCTION_MUL,
output reg SEL_INSTRUCTION_IN_OUT,
output reg SEL_INSTRUCTION_RJMP,
output reg SEL_INSTRUCTION_RCALL,
output reg SEL_INSTRUCTION_LDI,
output reg SEL_INSTRUCTION_COND_BRANCH,
output reg SEL_INSTRUCTION_BLD_BST,
output reg SEL_INSTRUCTION_SBRC_SBRS
);
 
always @ (*)
begin
SEL_INSTRUCTION_MOVW <= 1'b0;
SEL_INSTRUCTION_MULS <= 1'b0;
SEL_INSTRUCTION_MULSU <= 1'b0;
SEL_INSTRUCTION_FMUL <= 1'b0;
SEL_INSTRUCTION_FMULS <= 1'b0;
SEL_INSTRUCTION_FMULSU <= 1'b0;
SEL_INSTRUCTION_CPC <= 1'b0;
SEL_INSTRUCTION_CP <= 1'b0;
SEL_INSTRUCTION_SBC <= 1'b0;
SEL_INSTRUCTION_SUB <= 1'b0;
SEL_INSTRUCTION_ADD <= 1'b0;
SEL_INSTRUCTION_ADC <= 1'b0;
SEL_INSTRUCTION_CPSE <= 1'b0;
SEL_INSTRUCTION_AND <= 1'b0;
SEL_INSTRUCTION_EOR <= 1'b0;
SEL_INSTRUCTION_OR <= 1'b0;
SEL_INSTRUCTION_MOV <= 1'b0;
SEL_INSTRUCTION_CPI <= 1'b0;
SEL_INSTRUCTION_SUBI <= 1'b0;
SEL_INSTRUCTION_SBCI <= 1'b0;
SEL_INSTRUCTION_ORI_SBR <= 1'b0;
SEL_INSTRUCTION_ANDI_CBR <= 1'b0;
SEL_INSTRUCTION_LDD_STD <= 1'b0;
SEL_INSTRUCTION_LDS_STS <= 1'b0;
SEL_INSTRUCTION_LD_ST_YZP <= 1'b0;
SEL_INSTRUCTION_LD_ST_YZN <= 1'b0;
SEL_INSTRUCTION_LPM_R <= 1'b0;
SEL_INSTRUCTION_LPM_R_P <= 1'b0;
SEL_INSTRUCTION_XCH <= 1'b0;
SEL_INSTRUCTION_LAS <= 1'b0;
SEL_INSTRUCTION_LAC <= 1'b0;
SEL_INSTRUCTION_LAT <= 1'b0;
SEL_INSTRUCTION_LD_ST_X <= 1'b0;
SEL_INSTRUCTION_LD_ST_XP <= 1'b0;
SEL_INSTRUCTION_LD_ST_XN <= 1'b0;
SEL_INSTRUCTION_POP_PUSH <= 1'b0;
SEL_INSTRUCTION_COM <= 1'b0;
SEL_INSTRUCTION_NEG <= 1'b0;
SEL_INSTRUCTION_SWAP <= 1'b0;
SEL_INSTRUCTION_INC <= 1'b0;
SEL_INSTRUCTION_ASR <= 1'b0;
SEL_INSTRUCTION_LSR <= 1'b0;
SEL_INSTRUCTION_ROR <= 1'b0;
SEL_INSTRUCTION_SEx_CLx <= 1'b0;
SEL_INSTRUCTION_RET <= 1'b0;
SEL_INSTRUCTION_RETI <= 1'b0;
SEL_INSTRUCTION_SLEEP <= 1'b0;
SEL_INSTRUCTION_BREAK <= 1'b0;
SEL_INSTRUCTION_WDR <= 1'b0;
SEL_INSTRUCTION_LPM_ELPM <= 1'b0;
SEL_INSTRUCTION_SPM <= 1'b0;
SEL_INSTRUCTION_SPM_Z_P <= 1'b0;
SEL_INSTRUCTION_IJMP <= 1'b0;
SEL_INSTRUCTION_ICALL <= 1'b0;
SEL_INSTRUCTION_DEC <= 1'b0;
SEL_INSTRUCTION_DES <= 1'b0;
SEL_INSTRUCTION_JMP <= 1'b0;
SEL_INSTRUCTION_CALL <= 1'b0;
SEL_INSTRUCTION_ADIW <= 1'b0;
SEL_INSTRUCTION_SBIW <= 1'b0;
SEL_INSTRUCTION_CBI_SBI <= 1'b0;
SEL_INSTRUCTION_SBIC_SBIS <= 1'b0;
SEL_INSTRUCTION_MUL <= 1'b0;
SEL_INSTRUCTION_IN_OUT <= 1'b0;
SEL_INSTRUCTION_RJMP <= 1'b0;
SEL_INSTRUCTION_RCALL <= 1'b0;
SEL_INSTRUCTION_LDI <= 1'b0;
SEL_INSTRUCTION_COND_BRANCH <= 1'b0;
SEL_INSTRUCTION_BLD_BST <= 1'b0;
SEL_INSTRUCTION_SBRC_SBRS <= 1'b0;
casex({INTERRUPT_IN_EXECUTION, inst})
{1'b0, `INSTRUCTION_MOVW}: SEL_INSTRUCTION_MOVW <= 1'b1;
{1'b0, `INSTRUCTION_MULS}: SEL_INSTRUCTION_MULS <= 1'b1;
{1'b0, `INSTRUCTION_MULSU}: SEL_INSTRUCTION_MULSU <= 1'b1;
{1'b0, `INSTRUCTION_FMUL}: SEL_INSTRUCTION_FMUL <= 1'b1;
{1'b0, `INSTRUCTION_FMULS}: SEL_INSTRUCTION_FMULS <= 1'b1;
{1'b0, `INSTRUCTION_FMULSU}: SEL_INSTRUCTION_FMULSU <= 1'b1;
{1'b0, `INSTRUCTION_CPC}: SEL_INSTRUCTION_CPC <= 1'b1;
{1'b0, `INSTRUCTION_CP}: SEL_INSTRUCTION_CP <= 1'b1;
{1'b0, `INSTRUCTION_SBC}: SEL_INSTRUCTION_SBC <= 1'b1;
{1'b0, `INSTRUCTION_SUB}: SEL_INSTRUCTION_SUB <= 1'b1;
{1'b0, `INSTRUCTION_ADD}: SEL_INSTRUCTION_ADD <= 1'b1;
{1'b0, `INSTRUCTION_ADC}: SEL_INSTRUCTION_ADC <= 1'b1;
{1'b0, `INSTRUCTION_CPSE}: SEL_INSTRUCTION_CPSE <= 1'b1;
{1'b0, `INSTRUCTION_AND}: SEL_INSTRUCTION_AND <= 1'b1;
{1'b0, `INSTRUCTION_EOR}: SEL_INSTRUCTION_EOR <= 1'b1;
{1'b0, `INSTRUCTION_OR}: SEL_INSTRUCTION_OR <= 1'b1;
{1'b0, `INSTRUCTION_MOV}: SEL_INSTRUCTION_MOV <= 1'b1;
{1'b0, `INSTRUCTION_CPI}: SEL_INSTRUCTION_CPI <= 1'b1;
{1'b0, `INSTRUCTION_SUBI}: SEL_INSTRUCTION_SUBI <= 1'b1;
{1'b0, `INSTRUCTION_SBCI}: SEL_INSTRUCTION_SBCI <= 1'b1;
{1'b0, `INSTRUCTION_ORI_SBR}: SEL_INSTRUCTION_ORI_SBR <= 1'b1;
{1'b0, `INSTRUCTION_ANDI_CBR}: SEL_INSTRUCTION_ANDI_CBR <= 1'b1;
{1'b0, `INSTRUCTION_LDD_STD}: SEL_INSTRUCTION_LDD_STD <= 1'b1;
{1'b0, `INSTRUCTION_LDS_STS}: SEL_INSTRUCTION_LDS_STS <= 1'b1;
{1'b0, `INSTRUCTION_LD_ST_YZP}: SEL_INSTRUCTION_LD_ST_YZP <= 1'b1;
{1'b0, `INSTRUCTION_LD_ST_YZN}: SEL_INSTRUCTION_LD_ST_YZN <= 1'b1;
{1'b0, `INSTRUCTION_LPM_R}: SEL_INSTRUCTION_LPM_R <= 1'b1;
{1'b0, `INSTRUCTION_LPM_R_P}: SEL_INSTRUCTION_LPM_R_P <= 1'b1;
{1'b0, `INSTRUCTION_XCH}: SEL_INSTRUCTION_XCH <= 1'b1;
{1'b0, `INSTRUCTION_LAS}: SEL_INSTRUCTION_LAS <= 1'b1;
{1'b0, `INSTRUCTION_LAC}: SEL_INSTRUCTION_LAC <= 1'b1;
{1'b0, `INSTRUCTION_LAT}: SEL_INSTRUCTION_LAT <= 1'b1;
{1'b0, `INSTRUCTION_LD_ST_X}: SEL_INSTRUCTION_LD_ST_X <= 1'b1;
{1'b0, `INSTRUCTION_LD_ST_XP}: SEL_INSTRUCTION_LD_ST_XP <= 1'b1;
{1'b0, `INSTRUCTION_LD_ST_XN}: SEL_INSTRUCTION_LD_ST_XN <= 1'b1;
{1'b0, `INSTRUCTION_POP_PUSH}: SEL_INSTRUCTION_POP_PUSH <= 1'b1;
{1'b0, `INSTRUCTION_COM}: SEL_INSTRUCTION_COM <= 1'b1;
{1'b0, `INSTRUCTION_NEG}: SEL_INSTRUCTION_NEG <= 1'b1;
{1'b0, `INSTRUCTION_SWAP}: SEL_INSTRUCTION_SWAP <= 1'b1;
{1'b0, `INSTRUCTION_INC}: SEL_INSTRUCTION_INC <= 1'b1;
{1'b0, `INSTRUCTION_ASR}: SEL_INSTRUCTION_ASR <= 1'b1;
{1'b0, `INSTRUCTION_LSR}: SEL_INSTRUCTION_LSR <= 1'b1;
{1'b0, `INSTRUCTION_ROR}: SEL_INSTRUCTION_ROR <= 1'b1;
{1'b0, `INSTRUCTION_SEx_CLx}: SEL_INSTRUCTION_SEx_CLx <= 1'b1;
{1'b0, `INSTRUCTION_RET}: SEL_INSTRUCTION_RET <= 1'b1;
{1'b0, `INSTRUCTION_RETI}: SEL_INSTRUCTION_RETI <= 1'b1;
{1'b0, `INSTRUCTION_SLEEP}: SEL_INSTRUCTION_SLEEP <= 1'b1;
{1'b0, `INSTRUCTION_BREAK}: SEL_INSTRUCTION_BREAK <= 1'b1;
{1'b0, `INSTRUCTION_WDR}: SEL_INSTRUCTION_WDR <= 1'b1;
{1'b0, `INSTRUCTION_LPM_ELPM}: SEL_INSTRUCTION_LPM_ELPM <= 1'b1;
{1'b0, `INSTRUCTION_SPM}: SEL_INSTRUCTION_SPM <= 1'b1;
{1'b0, `INSTRUCTION_SPM_Z_P}: SEL_INSTRUCTION_SPM_Z_P <= 1'b1;
{1'b0, `INSTRUCTION_IJMP}: SEL_INSTRUCTION_IJMP <= 1'b1;
{1'b0, `INSTRUCTION_ICALL}: SEL_INSTRUCTION_ICALL <= 1'b1;
{1'b0, `INSTRUCTION_DEC}: SEL_INSTRUCTION_DEC <= 1'b1;
{1'b0, `INSTRUCTION_DES}: SEL_INSTRUCTION_DES <= 1'b1;
{1'b0, `INSTRUCTION_JMP}: SEL_INSTRUCTION_JMP <= 1'b1;
{1'b0, `INSTRUCTION_CALL}: SEL_INSTRUCTION_CALL <= 1'b1;
{1'b0, `INSTRUCTION_ADIW}: SEL_INSTRUCTION_ADIW <= 1'b1;
{1'b0, `INSTRUCTION_SBIW}: SEL_INSTRUCTION_SBIW <= 1'b1;
{1'b0, `INSTRUCTION_CBI_SBI}: SEL_INSTRUCTION_CBI_SBI <= 1'b1;
{1'b0, `INSTRUCTION_SBIC_SBIS}: SEL_INSTRUCTION_SBIC_SBIS <= 1'b1;
{1'b0, `INSTRUCTION_MUL}: SEL_INSTRUCTION_MUL <= 1'b1;
{1'b0, `INSTRUCTION_IN_OUT}: SEL_INSTRUCTION_IN_OUT <= 1'b1;
{1'b0, `INSTRUCTION_RJMP}: SEL_INSTRUCTION_RJMP <= 1'b1;
{1'b0, `INSTRUCTION_RCALL}: SEL_INSTRUCTION_RCALL <= 1'b1;
{1'b0, `INSTRUCTION_LDI}: SEL_INSTRUCTION_LDI <= 1'b1;
{1'b0, `INSTRUCTION_COND_BRANCH}: SEL_INSTRUCTION_COND_BRANCH <= 1'b1;
{1'b0, `INSTRUCTION_BLD_BST}: SEL_INSTRUCTION_BLD_BST <= 1'b1;
{1'b0, `INSTRUCTION_SBRC_SBRS}: SEL_INSTRUCTION_SBRC_SBRS <= 1'b1;
endcase
end
endmodule
/*
* !Instruction decoder.
*/
 
/*
* Registers memory.
*/
`define ALU_FLAG_C 0
`define ALU_FLAG_Z 1
`define ALU_FLAG_N 2
`define ALU_FLAG_V 3
`define ALU_FLAG_S 4
`define ALU_FLAG_H 5
`define ALU_FLAG_T 6
`define ALU_FLAG_I 7
 
module mega_regs #
(
parameter PLATFORM = "XILINX"
)(
input rst,
input clk,
input [4:0]rw_addr,
input [15:0]rw_data,
input rw_16bit,
input write,
input [4:0]rd_addr_d,
output [15:0]rd_data_d,
input rd_16bit_d,
input read_d,
input [4:0]rd_addr_r,
output [15:0]rd_data_r,
input rd_16bit_r,
input read_r
);
 
generate
if(PLATFORM == "XILINX")
begin
reg [7:0]REGL[0:15];
reg [7:0]REGH[0:15];
 
/*integer k;
 
initial
begin
for (k = 0; k < 16; k = k + 1)
begin
REGL[k] = 0;
REGH[k] = 0;
end
end*/
always @ (posedge clk)
begin
if(write)
begin
if(!rw_16bit & !rw_addr[0])
REGL[rw_addr[4:1]] <= rw_data[7:0];
else if(!rw_16bit & rw_addr[0])
REGH[rw_addr[4:1]] <= rw_data[7:0];
else
begin
REGL[rw_addr[4:1]] <= rw_data[7:0];
REGH[rw_addr[4:1]] <= rw_data[15:8];
end
end
end
 
assign rd_data_d = (read_d) ? (rd_16bit_d) ? {REGH[rd_addr_d[4:1]], REGL[rd_addr_d[4:1]]} : (rd_addr_d[0]) ? {8'h00, REGH[rd_addr_d[4:1]]} : {8'h00, REGL[rd_addr_d[4:1]]} : 16'bx;
assign rd_data_r = (read_r) ? (rd_16bit_r) ? {REGH[rd_addr_r[4:1]], REGL[rd_addr_r[4:1]]} : (rd_addr_r[0]) ? {8'h00, REGH[rd_addr_r[4:1]]} : {8'h00, REGL[rd_addr_r[4:1]]} : 16'bx;
end /* PLATFORM != "XILINX" */
else
if(PLATFORM == "LATTICE_ECP5" || PLATFORM == "LATTICE_ECP3" || PLATFORM == "LATTICE_LIFMD" || PLATFORM == "LATTICE_MARCHXO2" || PLATFORM == "LATTICE_MARCHXO3L")
begin/* Lattice Diamond does not know how to implement distributed RAM with true three ports, so I implement him from individual distributed RAM cells. */
wire [7:0]REGLD_out;
wire [7:0]REGHD_out;
wire [7:0]REGLR_out;
wire [7:0]REGHR_out;
wire write_to_L = write & ((!rw_16bit & !rw_addr[0]) || rw_16bit);
wire write_to_H = write &((!rw_16bit & rw_addr[0]) || rw_16bit);
wire write_to_HL = write &rw_16bit;
 
DPR16X4C REG_L_D_4_7(
.DI3(rw_data[7]),
.DI2(rw_data[6]),
.DI1(rw_data[5]),
.DI0(rw_data[4]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_L | write_to_HL),
.RAD3(rd_addr_d[4]),
.RAD2(rd_addr_d[3]),
.RAD1(rd_addr_d[2]),
.RAD0(rd_addr_d[1]),
.DO3(REGLD_out[7]),
.DO2(REGLD_out[6]),
.DO1(REGLD_out[5]),
.DO0(REGLD_out[4])
);
DPR16X4C REG_L_D_0_3(
.DI3(rw_data[3]),
.DI2(rw_data[2]),
.DI1(rw_data[1]),
.DI0(rw_data[0]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_L | write_to_HL),
.RAD3(rd_addr_d[4]),
.RAD2(rd_addr_d[3]),
.RAD1(rd_addr_d[2]),
.RAD0(rd_addr_d[1]),
.DO3(REGLD_out[3]),
.DO2(REGLD_out[2]),
.DO1(REGLD_out[1]),
.DO0(REGLD_out[0])
);
DPR16X4C REG_H_D_4_7(
.DI3(write_to_HL ? rw_data[15] : rw_data[7]),
.DI2(write_to_HL ? rw_data[14] : rw_data[6]),
.DI1(write_to_HL ? rw_data[13] : rw_data[5]),
.DI0(write_to_HL ? rw_data[12] : rw_data[4]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_H | write_to_HL),
.RAD3(rd_addr_d[4]),
.RAD2(rd_addr_d[3]),
.RAD1(rd_addr_d[2]),
.RAD0(rd_addr_d[1]),
.DO3(REGHD_out[7]),
.DO2(REGHD_out[6]),
.DO1(REGHD_out[5]),
.DO0(REGHD_out[4])
);
DPR16X4C REG_H_D_0_3(
.DI3(write_to_HL ? rw_data[11] : rw_data[3]),
.DI2(write_to_HL ? rw_data[10] : rw_data[2]),
.DI1(write_to_HL ? rw_data[9] : rw_data[1]),
.DI0(write_to_HL ? rw_data[8] : rw_data[0]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_H | write_to_HL),
.RAD3(rd_addr_d[4]),
.RAD2(rd_addr_d[3]),
.RAD1(rd_addr_d[2]),
.RAD0(rd_addr_d[1]),
.DO3(REGHD_out[3]),
.DO2(REGHD_out[2]),
.DO1(REGHD_out[1]),
.DO0(REGHD_out[0])
);
DPR16X4C REG_L_R_4_7(
.DI3(rw_data[7]),
.DI2(rw_data[6]),
.DI1(rw_data[5]),
.DI0(rw_data[4]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_L | write_to_HL),
.RAD3(rd_addr_r[4]),
.RAD2(rd_addr_r[3]),
.RAD1(rd_addr_r[2]),
.RAD0(rd_addr_r[1]),
.DO3(REGLR_out[7]),
.DO2(REGLR_out[6]),
.DO1(REGLR_out[5]),
.DO0(REGLR_out[4])
);
DPR16X4C REG_L_R_0_3(
.DI3(rw_data[3]),
.DI2(rw_data[2]),
.DI1(rw_data[1]),
.DI0(rw_data[0]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_L | write_to_HL),
.RAD3(rd_addr_r[4]),
.RAD2(rd_addr_r[3]),
.RAD1(rd_addr_r[2]),
.RAD0(rd_addr_r[1]),
.DO3(REGLR_out[3]),
.DO2(REGLR_out[2]),
.DO1(REGLR_out[1]),
.DO0(REGLR_out[0])
);
DPR16X4C REG_H_R_4_7(
.DI3(write_to_HL ? rw_data[15] : rw_data[7]),
.DI2(write_to_HL ? rw_data[14] : rw_data[6]),
.DI1(write_to_HL ? rw_data[13] : rw_data[5]),
.DI0(write_to_HL ? rw_data[12] : rw_data[4]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_H | write_to_HL),
.RAD3(rd_addr_r[4]),
.RAD2(rd_addr_r[3]),
.RAD1(rd_addr_r[2]),
.RAD0(rd_addr_r[1]),
.DO3(REGHR_out[7]),
.DO2(REGHR_out[6]),
.DO1(REGHR_out[5]),
.DO0(REGHR_out[4])
);
DPR16X4C REG_H_R_0_3(
.DI3(write_to_HL ? rw_data[11] : rw_data[3]),
.DI2(write_to_HL ? rw_data[10] : rw_data[2]),
.DI1(write_to_HL ? rw_data[9] : rw_data[1]),
.DI0(write_to_HL ? rw_data[8] : rw_data[0]),
.WAD3(rw_addr[4]),
.WAD2(rw_addr[3]),
.WAD1(rw_addr[2]),
.WAD0(rw_addr[1]),
.WCK(clk),
.WRE(write_to_H | write_to_HL),
.RAD3(rd_addr_r[4]),
.RAD2(rd_addr_r[3]),
.RAD1(rd_addr_r[2]),
.RAD0(rd_addr_r[1]),
.DO3(REGHR_out[3]),
.DO2(REGHR_out[2]),
.DO1(REGHR_out[1]),
.DO0(REGHR_out[0])
);
assign rd_data_d = (read_d) ? (rd_16bit_d) ? {REGHD_out, REGLD_out} : (rd_addr_d[0]) ? {8'h00, REGHD_out} : {8'h00, REGLD_out} : 16'bx;
assign rd_data_r = (read_r) ? (rd_16bit_r) ? {REGHR_out, REGLR_out} : (rd_addr_r[0]) ? {8'h00, REGHR_out} : {8'h00, REGLR_out} : 16'bx;
 
end/* PLATFORM != "LATTICE_ECP5" || PLATFORM != "LATTICE_ECP3" || PLATFORM != "LATTICE_LIFMD" || PLATFORM != "LATTICE_MARCHXO2" || PLATFORM != "LATTICE_MARCHXO3L" */
endgenerate
endmodule
/*
* !Registers memory.
*/
 
/*
* Asynchronous ALU.
*/
module mega_alu # (
parameter CORE_CONFIG = "XMEGA"
)(
input [3:0]inst,
input [4:0]in_addr_1,
input [4:0]in_addr_2,
input [15:0]in_1,
input [15:0]in_2,
output reg [15:0]out,
//output c_out,
input ALU_FLAG_C_IN, //Zero Flag
input ALU_FLAG_Z_IN, //Zero Flag
input ALU_FLAG_N_IN, //Negative Flag
input ALU_FLAG_V_IN, //Two's complement overflow indicator
input ALU_FLAG_S_IN, //N?V for signed tests
input ALU_FLAG_H_IN, //Half Carry Flag
input ALU_FLAG_T_IN, //Transfer bit used by BLD and BST instructions
input ALU_FLAG_I_IN, //Global Interrupt Enable/Disable Flag
output reg ALU_FLAG_C_OUT, //Carry Flag
output reg ALU_FLAG_Z_OUT, //Zero Flag
output reg ALU_FLAG_N_OUT, //Negative Flag
output reg ALU_FLAG_V_OUT, //Two's complement overflow indicator
output reg ALU_FLAG_S_OUT, //N?V for signed tests
output reg ALU_FLAG_H_OUT, //Half Carry Flag
output reg ALU_FLAG_T_OUT, //Transfer bit used by BLD and BST instructions
output reg ALU_FLAG_I_OUT, //Global Interrupt Enable/Disable Flag
input SEL_INSTRUCTION_MOVW,
input SEL_INSTRUCTION_MULS,
input SEL_INSTRUCTION_MULSU,
input SEL_INSTRUCTION_FMUL,
input SEL_INSTRUCTION_FMULS,
input SEL_INSTRUCTION_FMULSU,
input SEL_INSTRUCTION_CPC,
input SEL_INSTRUCTION_CP,
input SEL_INSTRUCTION_SBC,
input SEL_INSTRUCTION_SUB,
input SEL_INSTRUCTION_ADD,
input SEL_INSTRUCTION_ADC,
input SEL_INSTRUCTION_AND,
input SEL_INSTRUCTION_ANDI_CBR,
input SEL_INSTRUCTION_EOR,
input SEL_INSTRUCTION_OR,
input SEL_INSTRUCTION_ORI_SBR,
input SEL_INSTRUCTION_MOV,
input SEL_INSTRUCTION_CPI,
input SEL_INSTRUCTION_SUBI,
input SEL_INSTRUCTION_SBCI,
input SEL_INSTRUCTION_LPM_R_P,
input SEL_INSTRUCTION_COM,
input SEL_INSTRUCTION_NEG,
input SEL_INSTRUCTION_SWAP,
input SEL_INSTRUCTION_INC,
input SEL_INSTRUCTION_ASR,
input SEL_INSTRUCTION_LSR,
input SEL_INSTRUCTION_ROR,
input SEL_INSTRUCTION_SEx_CLx,
input SEL_INSTRUCTION_DEC,
input SEL_INSTRUCTION_ADIW,
input SEL_INSTRUCTION_SBIW,
input SEL_INSTRUCTION_MUL
);
 
reg in_addr_1_and_2_equal;
 
always @ (in_addr_1 or in_addr_2)
begin
in_addr_1_and_2_equal = in_addr_1 == in_addr_2;
end
 
reg [15:0]in_2_int;
reg cin_int;
 
always @ (*)
begin
in_2_int <= in_1;
cin_int <= ALU_FLAG_C_IN;
 
if(SEL_INSTRUCTION_ADD |
SEL_INSTRUCTION_ADC)
begin
if(!in_addr_1_and_2_equal)
in_2_int <= in_2;
end
if(
(SEL_INSTRUCTION_ADIW && CORE_CONFIG != "REDUCED") |
(SEL_INSTRUCTION_SBIW && CORE_CONFIG != "REDUCED") |
SEL_INSTRUCTION_SUB |
SEL_INSTRUCTION_SBC |
SEL_INSTRUCTION_SUBI |
SEL_INSTRUCTION_SBCI |
SEL_INSTRUCTION_INC |
SEL_INSTRUCTION_DEC |
SEL_INSTRUCTION_LPM_R_P |
SEL_INSTRUCTION_CP |
SEL_INSTRUCTION_CPI |
SEL_INSTRUCTION_CPC) in_2_int <= in_2;
 
if(SEL_INSTRUCTION_ADD |
(SEL_INSTRUCTION_ADIW && CORE_CONFIG != "REDUCED") |
(SEL_INSTRUCTION_SBIW && CORE_CONFIG != "REDUCED") |
SEL_INSTRUCTION_LSR |
SEL_INSTRUCTION_NEG |
SEL_INSTRUCTION_SUB |
SEL_INSTRUCTION_SUBI |
SEL_INSTRUCTION_INC |
SEL_INSTRUCTION_DEC |
SEL_INSTRUCTION_LPM_R_P |
SEL_INSTRUCTION_CP |
SEL_INSTRUCTION_CPI) cin_int <= 1'b0;
end
 
wire [17:0] add_result_int_w_c_tmp = {in_1, 1'b1} + {in_2_int, cin_int};
wire [16:0] add_result_int_w_c = add_result_int_w_c_tmp[17:1];
wire [17:0] sub_result_int_w_c_tmp = {in_1, 1'b0} - {in_2_int, cin_int};
wire [16:0] sub_result_int_w_c = sub_result_int_w_c_tmp[17:1];
 
/*
* Multiply Unit.
*/
 
reg [7:0]in_1_mul;
reg [7:0]in_2_mul;
wire [15:0]mul_result_int = in_1_mul * in_2_mul;
wire mul_sign_int = in_1[7] ^ in_2[7];
always @ (*)
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
begin
in_1_mul <= 0;
in_2_mul <= 0;
if(SEL_INSTRUCTION_MUL | SEL_INSTRUCTION_FMUL)
begin
in_1_mul <= in_1[7:0];
in_2_mul <= in_2[7:0];
end
if(SEL_INSTRUCTION_MULS | SEL_INSTRUCTION_FMULS)
begin
in_1_mul <= {1'b0, in_1[6:0]};
in_2_mul <= {1'b0, in_2[6:0]};
end
if(SEL_INSTRUCTION_MULSU | SEL_INSTRUCTION_FMULSU)
begin
in_1_mul <= {1'b0, in_1[6:0]};
in_2_mul <= in_2[7:0];
end
end
end
 
always @ (*)
begin
{ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, in_1};
if(SEL_INSTRUCTION_ADD)
begin
if(in_addr_1_and_2_equal)
{ALU_FLAG_C_OUT, out} <= {in_1[7], 8'h00, in_1[6:0], cin_int};//LSL
else
{ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]};
end
if(SEL_INSTRUCTION_ADC)
begin
if(in_addr_1_and_2_equal)
{ALU_FLAG_C_OUT, out} <= {in_1[7], 8'h00, in_1[6:0], cin_int};//ROL
else
{ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]};
end
if(SEL_INSTRUCTION_INC |
SEL_INSTRUCTION_DEC) {ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]};
if(SEL_INSTRUCTION_SUB |
SEL_INSTRUCTION_SBC |
SEL_INSTRUCTION_SUBI |
SEL_INSTRUCTION_SBCI) {ALU_FLAG_C_OUT, out} <= {sub_result_int_w_c[8], 8'h00, sub_result_int_w_c[7:0]};
if(SEL_INSTRUCTION_LSR |
SEL_INSTRUCTION_ROR) {ALU_FLAG_C_OUT, out} <= {in_1[0], 8'h00, cin_int, in_1[7:1]};
if(SEL_INSTRUCTION_AND |
SEL_INSTRUCTION_ANDI_CBR) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, (in_1[7:0] & in_2[7:0])};
if(SEL_INSTRUCTION_OR |
SEL_INSTRUCTION_ORI_SBR) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, (in_1[7:0] | in_2[7:0])};
if(SEL_INSTRUCTION_EOR) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, (in_1[7:0] ^ in_2[7:0])};
if(SEL_INSTRUCTION_MOV) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'h00, in_2[7:0]};
if(SEL_INSTRUCTION_MOVW) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, in_2};
if(SEL_INSTRUCTION_COM) {ALU_FLAG_C_OUT, out} <= {1'b1, 8'h00, (8'hFF - in_1[7:0])};
if(SEL_INSTRUCTION_NEG) {ALU_FLAG_C_OUT, out} <= {|in_1[7:0], 8'h00, (8'h00 - in_1[7:0])};
if(SEL_INSTRUCTION_ADIW && CORE_CONFIG != "REDUCED")
{ALU_FLAG_C_OUT, out} <= add_result_int_w_c;
if(SEL_INSTRUCTION_SBIW && CORE_CONFIG != "REDUCED")
{ALU_FLAG_C_OUT, out} <= sub_result_int_w_c;
if((SEL_INSTRUCTION_MUL) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {mul_result_int[15], mul_result_int};
if((SEL_INSTRUCTION_MULS) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {mul_sign_int, mul_sign_int, mul_result_int[14:0]};
if((SEL_INSTRUCTION_MULSU) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {in_1[7], in_1[7], mul_result_int};
if((SEL_INSTRUCTION_FMUL) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {mul_result_int[15], mul_result_int[14:0], 1'b0};
if((SEL_INSTRUCTION_FMULS) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {mul_sign_int, mul_result_int[14:0], 1'b0};
if((SEL_INSTRUCTION_FMULSU) && CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
{ALU_FLAG_C_OUT, out} <= {in_1[7], mul_result_int[14:0], 1'b0};
if(SEL_INSTRUCTION_ASR) {ALU_FLAG_C_OUT, out} <= {in_1[0], 8'h00, in_1[7], in_1[7:1]};
if(SEL_INSTRUCTION_CP |
SEL_INSTRUCTION_CPI |
SEL_INSTRUCTION_CPC) {ALU_FLAG_C_OUT, out} <= {sub_result_int_w_c[8], 8'h00, sub_result_int_w_c[7:0]};
if(SEL_INSTRUCTION_SWAP) {ALU_FLAG_C_OUT, out} <= {ALU_FLAG_C_IN, 8'b0, in_1[3:0], in_1[7:4]};
if(SEL_INSTRUCTION_SEx_CLx) {ALU_FLAG_C_OUT, out} <= inst[2:0] ? {ALU_FLAG_C_IN, {16{1'b0}}} : {~inst[3], {16{1'b0}}};
if(SEL_INSTRUCTION_LPM_R_P && CORE_CONFIG != "REDUCED")
{ALU_FLAG_C_OUT, out} <= add_result_int_w_c;
end
 
wire flag_h_adc_sub_cp = (~in_1[3] & in_2[3])|(in_2[3] & out[3])|(out[3] & ~in_1[3]);
wire flag_v_add_adc = (in_1[7] & in_2[7] & ~out[7])|(~in_1[7] & ~in_2[7] & out[7]);
wire flag_v_sub_sbc = (in_1[7] & ~in_2[7] & ~out[7])|(~in_1[7] & in_2[7] & out[7]);
/*
* ALU FLAG effect for each instruction.
*/
always @ (inst or out or in_1 or in_2 or
ALU_FLAG_Z_IN or ALU_FLAG_N_IN or ALU_FLAG_V_IN or
ALU_FLAG_S_IN or ALU_FLAG_H_IN or ALU_FLAG_T_IN or
ALU_FLAG_I_IN or ALU_FLAG_C_OUT or in_addr_1_and_2_equal or
flag_v_add_adc or flag_h_adc_sub_cp or
flag_v_sub_sbc or SEL_INSTRUCTION_ADD or
SEL_INSTRUCTION_ADC or SEL_INSTRUCTION_SUB or
SEL_INSTRUCTION_SUBI or SEL_INSTRUCTION_CP or
SEL_INSTRUCTION_CPI or SEL_INSTRUCTION_INC or
SEL_INSTRUCTION_DEC or SEL_INSTRUCTION_SBC or
SEL_INSTRUCTION_SBCI or SEL_INSTRUCTION_CPC or
SEL_INSTRUCTION_ADIW or SEL_INSTRUCTION_SBIW or
SEL_INSTRUCTION_AND or SEL_INSTRUCTION_OR or
SEL_INSTRUCTION_COM or SEL_INSTRUCTION_EOR or
SEL_INSTRUCTION_NEG or SEL_INSTRUCTION_ASR or
SEL_INSTRUCTION_LSR or SEL_INSTRUCTION_ROR or
SEL_INSTRUCTION_SEx_CLx or SEL_INSTRUCTION_MUL or
SEL_INSTRUCTION_FMUL or SEL_INSTRUCTION_MULS or
SEL_INSTRUCTION_MULSU or SEL_INSTRUCTION_FMULS or
SEL_INSTRUCTION_FMULSU)
begin
ALU_FLAG_Z_OUT <= ALU_FLAG_Z_IN;
ALU_FLAG_N_OUT <= ALU_FLAG_N_IN;
ALU_FLAG_V_OUT <= ALU_FLAG_V_IN;
ALU_FLAG_S_OUT <= ALU_FLAG_S_IN;
ALU_FLAG_H_OUT <= ALU_FLAG_H_IN;
ALU_FLAG_T_OUT <= ALU_FLAG_T_IN;
ALU_FLAG_I_OUT <= ALU_FLAG_I_IN;
if(SEL_INSTRUCTION_ADD)
begin
ALU_FLAG_N_OUT <= out[7];
if(in_addr_1_and_2_equal)
begin//LSL
ALU_FLAG_H_OUT <= in_1[3];
ALU_FLAG_V_OUT <= ALU_FLAG_N_OUT ^ ALU_FLAG_C_OUT;
ALU_FLAG_S_OUT <= out[7] != ALU_FLAG_V_OUT;
end
else
begin
ALU_FLAG_H_OUT <= (in_1[3] & in_2[3])|(in_2[3] & ~out[3])|(~out[3] & in_1[3]);
ALU_FLAG_V_OUT <= flag_v_add_adc;
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
end
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_ADC)
begin//ROL
ALU_FLAG_N_OUT <= out[7];
if(in_addr_1_and_2_equal)
begin
ALU_FLAG_H_OUT <= in_1[3];
ALU_FLAG_V_OUT <= ALU_FLAG_N_OUT ^ ALU_FLAG_C_OUT;
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_N_OUT ^ ALU_FLAG_C_OUT;
end
else
begin
ALU_FLAG_H_OUT <= (in_1[3] & in_2[3])|(in_2[3] & out[3])|(~out[3] & ~in_1[3]);
ALU_FLAG_V_OUT <= flag_v_add_adc;
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
end
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_SUB |
SEL_INSTRUCTION_SUBI |
SEL_INSTRUCTION_CP |
SEL_INSTRUCTION_CPI)
begin
ALU_FLAG_H_OUT <= flag_h_adc_sub_cp;
ALU_FLAG_V_OUT <= flag_v_sub_sbc;
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_INC |
SEL_INSTRUCTION_DEC)
begin
ALU_FLAG_V_OUT <= &{~out[7], out[6:0]};
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_SBC |
SEL_INSTRUCTION_SBCI |
SEL_INSTRUCTION_CPC)
begin
ALU_FLAG_H_OUT <= flag_h_adc_sub_cp;
ALU_FLAG_V_OUT <= flag_v_sub_sbc;
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &{~out[7:0], ALU_FLAG_Z_IN};
end
if(CORE_CONFIG != "REDUCED")
begin
if(SEL_INSTRUCTION_ADIW |
SEL_INSTRUCTION_SBIW)
begin
ALU_FLAG_V_OUT <= ALU_FLAG_C_OUT;
ALU_FLAG_N_OUT <= out[15];
ALU_FLAG_S_OUT <= out[15] ^ ALU_FLAG_C_OUT;
ALU_FLAG_Z_OUT <= &(~out[15:0]);
end
end
if(SEL_INSTRUCTION_ANDI_CBR |
SEL_INSTRUCTION_ORI_SBR |
SEL_INSTRUCTION_AND |
SEL_INSTRUCTION_OR |
SEL_INSTRUCTION_COM |
SEL_INSTRUCTION_EOR)
begin
ALU_FLAG_V_OUT <= 1'b0;
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_NEG)
begin
ALU_FLAG_H_OUT <= out[3] + ~in_1[3];
ALU_FLAG_V_OUT <= &{out[7], ~out[6:0]};
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_ASR)
begin
ALU_FLAG_V_OUT <= 1'b0;
ALU_FLAG_N_OUT <= out[7];
ALU_FLAG_S_OUT <= out[7] ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_LSR |
SEL_INSTRUCTION_ROR)
begin
ALU_FLAG_H_OUT <= in_1[3];
ALU_FLAG_N_OUT <= 0;
ALU_FLAG_V_OUT <= 0 ^ ALU_FLAG_C_OUT;
ALU_FLAG_S_OUT <= 0 ^ ALU_FLAG_V_OUT;
ALU_FLAG_Z_OUT <= &(~out[7:0]);
end
if(SEL_INSTRUCTION_SEx_CLx)
begin
case(inst[2:0])
3'd1: ALU_FLAG_Z_OUT <= ~inst[3];
3'd2: ALU_FLAG_N_OUT <= ~inst[3];
3'd3: ALU_FLAG_V_OUT <= ~inst[3];
3'd4: ALU_FLAG_S_OUT <= ~inst[3];
3'd5: ALU_FLAG_H_OUT <= ~inst[3];
3'd6: ALU_FLAG_T_OUT <= ~inst[3];
3'd7: ALU_FLAG_I_OUT <= ~inst[3];
endcase
end
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
begin
if(SEL_INSTRUCTION_MUL |
SEL_INSTRUCTION_FMUL)
ALU_FLAG_Z_OUT <= &(~out[15:0]);
if(SEL_INSTRUCTION_MULS |
SEL_INSTRUCTION_MULSU |
SEL_INSTRUCTION_FMULS |
SEL_INSTRUCTION_FMULSU)
ALU_FLAG_Z_OUT <= &(~out[15:0]);
end
end
 
endmodule
/*
* !Asynchronous ALU.
*/
/*
* Interrupt and priority encoder.
*/
module int_encoder # (
parameter VECTOR_INT_TABLE_SIZE = 0,
parameter STORE_INTERUPTS = "FALSE"
)(
input rst,
input [((VECTOR_INT_TABLE_SIZE == 0) ? 0 : VECTOR_INT_TABLE_SIZE-1):0]int_sig_in,
output int_request,
output reg[((VECTOR_INT_TABLE_SIZE > 127) ? 7 :
(VECTOR_INT_TABLE_SIZE > 63) ? 6 :
(VECTOR_INT_TABLE_SIZE > 31) ? 5 :
(VECTOR_INT_TABLE_SIZE > 15) ? 4 :
(VECTOR_INT_TABLE_SIZE > 7) ? 3 :
(VECTOR_INT_TABLE_SIZE > 3) ? 2 :
(VECTOR_INT_TABLE_SIZE > 1) ? 1 : 0) : 0]int_vect,
input executed
);
 
reg [VECTOR_INT_TABLE_SIZE : 0]int_sig_in_int;
reg [VECTOR_INT_TABLE_SIZE : 0]int_sig_in_int_n;
wire [VECTOR_INT_TABLE_SIZE : 0]int_sig_in_int_active = int_sig_in_int ^ int_sig_in_int_n;
 
genvar i;
generate
for (i = 0; i < VECTOR_INT_TABLE_SIZE;i = i + 1)
begin :int_sig_store
always @(posedge rst or posedge int_sig_in[i])
begin
if(STORE_INTERUPTS == "TRUE" && VECTOR_INT_TABLE_SIZE != 0)
begin
if(rst)
int_sig_in_int[i] <= 1'b0;
else
begin
if(int_sig_in_int_n[i] == int_sig_in_int[i])
int_sig_in_int[i] <= ~int_sig_in_int_n[i];
end
end
end
always @ (posedge rst or posedge executed)
begin
if(STORE_INTERUPTS == "TRUE" && VECTOR_INT_TABLE_SIZE != 0)
begin
if(rst)
int_sig_in_int_n[i] <= 1'b0;
else if(executed && int_vect == i)
int_sig_in_int_n[int_vect] <= int_sig_in_int[int_vect];
end
end
end
endgenerate
 
integer j;
always @*
begin
if(VECTOR_INT_TABLE_SIZE != 0)
begin
int_vect <= 0;
for (j=VECTOR_INT_TABLE_SIZE-1; j>=0; j=j-1)
if ((STORE_INTERUPTS == "TRUE") ? int_sig_in_int_active[j] : int_sig_in[j])
int_vect <= j+1;
end
end
 
assign int_request = (int_vect != 0 && VECTOR_INT_TABLE_SIZE != 'h0);
 
endmodule
/*
* !Interrupt and priority encoder.
*/
 
/*
* XMega core.
*/
 
`define STEP0 0
`define STEP1 1
`define STEP2 2
 
module mega_core # (
parameter PLATFORM = "XILINX",
parameter CORE_CONFIG = "XMEGA",// Supported: "REDUCED", "MINIMAL", "CLASSIC_8K", "CLASSIC_128K", "ENHANCED_8K", "ENHANCED_128K", "ENHANCED_4M", "XMEGA"
parameter BUS_ADDR_PGM_WIDTH = 14,
parameter BUS_ADDR_DATA_WIDTH = 13,
parameter USE_BRAM_ROM = "FALSE",
parameter WATCHDOG_CNT_WIDTH = 0,
parameter VECTOR_INT_TABLE_SIZE = 0,
parameter STORE_INTERUPTS = "FALSE",
parameter MAP_REGS_IN_TO_SRAM_SECTION = "FALSE"
 
)(
input rst,
output sys_rst,
input clk,
input clk_wdt,
output reg [BUS_ADDR_PGM_WIDTH-1:0]pgm_addr,
input [15:0]pgm_data,
output reg [BUS_ADDR_DATA_WIDTH-1:0]data_addr,
input [7:0]data_in,
output [7:0]data_out,
output data_we,
output data_re,
output [5:0]io_addr,
input [7:0]io_in,
output [7:0]io_out,
output io_we,
output io_re,
input [(VECTOR_INT_TABLE_SIZE == 0 ? 0 : VECTOR_INT_TABLE_SIZE - 1):0]int_sig,
output reg [(VECTOR_INT_TABLE_SIZE == 0 ? 0 : VECTOR_INT_TABLE_SIZE - 1):0]int_rst,
output reg wdt_rst_out
);
 
reg [7:0]ALU_FLAGS; //Carry Flag
wire ALU_FLAG_C_OUT; //Carry Flag
wire ALU_FLAG_Z_OUT; //Zero Flag
wire ALU_FLAG_N_OUT; //Negative Flag
wire ALU_FLAG_V_OUT; //Two's complement overflow indicator
wire ALU_FLAG_S_OUT; //N?V for signed tests
wire ALU_FLAG_H_OUT; //Half Carry Flag
wire ALU_FLAG_T_OUT; //Transfer bit used by BLD and BST instructions
wire ALU_FLAG_I_OUT; //Global Interrupt Enable/Disable Flag
reg [BUS_ADDR_PGM_WIDTH-1:0]PC;
reg [BUS_ADDR_PGM_WIDTH-1:0]pgm_indirect_addr;
wire [BUS_ADDR_PGM_WIDTH-1:0]PC_PLUS_ONE = PC + 1;
wire [BUS_ADDR_PGM_WIDTH-1:0]PC_PLUS_TWO = PC + 2;
wire [BUS_ADDR_PGM_WIDTH-1:0]PC_PLUS_THREE = PC + 3;
reg [BUS_ADDR_DATA_WIDTH-1:0]SP;
wire [BUS_ADDR_DATA_WIDTH-1:0]SP_PLUS_ONE = SP + 1;
wire [BUS_ADDR_DATA_WIDTH-1:0]SP_MINUS_ONE = SP - 1;
reg [1:0]step_cnt;
reg [15:0]tmp_pgm_data;
 
`ifdef USE_CCP_REG
reg [7:0]CCP; /* Configuration Change Protection */
`endif
`ifdef USE_EXTENDED_RAMP_REGS
reg [7:0]RAMPD; /* Ramp D */
reg [7:0]RAMPX; /* Ramp X */
reg [7:0]RAMPY; /* Ramp Y */
reg [7:0]RAMPZ; /* Ramp Z */
reg [7:0]EIND; /* Extended Indirect Jump */
`endif
 
wire core_rst;
assign sys_rst = (WATCHDOG_CNT_WIDTH != 'd0) ? core_rst : rst;
 
wire alu_rdy;
 
wire [7:0]data_in_int;
reg [7:0]data_out_int;
wire [7:0]io_in_int;
reg [7:0]io_out_int;
 
reg data_we_int;
reg data_re_int;
 
reg [BUS_ADDR_DATA_WIDTH - 1:0]data_addr_int;
reg [BUS_ADDR_DATA_WIDTH - 1:0]data_addr_int_tmp;
 
reg [5:0]io_addr_int;
 
reg io_we_int;
reg io_re_int;
 
assign io_we = io_we_int;
assign io_re = io_re_int;
assign io_addr = io_addr_int;
assign io_in_int = io_in;
assign io_out = io_out_int;
assign data_we = data_we_int;
assign data_re = data_re_int;
always @ (*) data_addr <= data_addr_int;
assign data_out = data_out_int;
assign data_in_int = data_in;
 
/*
* ! pgm_addr bus switcher
*/
 
// REG aditional
reg write_to_reg;
// REG wires
reg [4:0]rw_addr;
reg [15:0]rw_data;
reg rw_16bit;
//wire write;
reg [4:0]rd_addr_d;
wire [15:0]rd_data_d;
reg rd_16bit_d;
wire read_d;
reg [4:0]rd_addr_r;
wire [15:0]rd_data_r;
 
wire [BUS_ADDR_DATA_WIDTH-1:0]rd_data_r_PLUS_ONE = rd_data_r + 1;
wire [BUS_ADDR_DATA_WIDTH-1:0]rd_data_r_MINUS_ONE = rd_data_r - 1;
reg rd_16bit_r;
wire read_r;
 
// ALU wires
reg [15:0]alu_in_1;
reg [15:0]alu_in_2;
wire [15:0]alu_out;
//wire alu_c_out;
reg [BUS_ADDR_DATA_WIDTH-1:0]indirect_addr_offset;
wire [BUS_ADDR_DATA_WIDTH-1:0]indirect_addr_offset_res = rd_data_r + indirect_addr_offset;
 
reg [4:0]reg_clr_cnt;
assign alu_rdy = reg_clr_cnt == 16;
//`ifdef USE_RAM_READ_DELAY
reg rom_read_delay;
reg [1:0]ram_read_delay;
//`endif
 
reg [15:0]pgm_data_int;
 
 
always @ (*)
begin
pgm_data_int <= pgm_data;
end
 
localparam int_bus_size = (VECTOR_INT_TABLE_SIZE > 127) ? 8 :
(VECTOR_INT_TABLE_SIZE > 63) ? 7 :
(VECTOR_INT_TABLE_SIZE > 31) ? 6 :
(VECTOR_INT_TABLE_SIZE > 15) ? 5 :
(VECTOR_INT_TABLE_SIZE > 7) ? 4 :
(VECTOR_INT_TABLE_SIZE > 3) ? 3 :
(VECTOR_INT_TABLE_SIZE > 1) ? 2 : 1;
reg interrupt_registered;
reg current_int_executed;
wire [int_bus_size - 1 : 0]current_int_vect;
reg [int_bus_size - 1 : 0]current_int_vect_int;
wire int_request;
 
/*always @ (posedge interrupt_registered)
begin
current_int_vect_int <= current_int_vect;
end*/
 
int_encoder # (
.VECTOR_INT_TABLE_SIZE(VECTOR_INT_TABLE_SIZE),
.STORE_INTERUPTS(STORE_INTERUPTS)
)int_encoder_inst(
.rst(rst),
.int_sig_in(int_sig),
.int_vect(current_int_vect),
.int_request(int_request),
.executed(current_int_executed)
);
 
/*
* pgm_addr bus switcher
*/
always @ (*)
begin
if(CORE_CONFIG != "REDUCED")
begin
`ifdef USE_LPM
case(step_cnt)
`STEP2:
begin
casex(tmp_pgm_data)
`INSTRUCTION_LPM_R,
`INSTRUCTION_LPM_R_P: pgm_addr <= pgm_indirect_addr[{1'b0, BUS_ADDR_PGM_WIDTH-1}:1];
default: pgm_addr <= PC;
endcase
end
default: pgm_addr <= PC;
endcase
`endif
end
else
begin
pgm_addr <= PC;
end
end
 
 
wire SEL_S1_INSTRUCTION_MOVW;
wire SEL_S1_INSTRUCTION_MULS;
wire SEL_S1_INSTRUCTION_MULSU;
wire SEL_S1_INSTRUCTION_FMUL;
wire SEL_S1_INSTRUCTION_FMULS;
wire SEL_S1_INSTRUCTION_FMULSU;
wire SEL_S1_INSTRUCTION_CPC;
wire SEL_S1_INSTRUCTION_CP;
wire SEL_S1_INSTRUCTION_SBC;
wire SEL_S1_INSTRUCTION_SUB;
wire SEL_S1_INSTRUCTION_ADD;
wire SEL_S1_INSTRUCTION_ADC;
wire SEL_S1_INSTRUCTION_CPSE;
wire SEL_S1_INSTRUCTION_AND;
wire SEL_S1_INSTRUCTION_EOR;
wire SEL_S1_INSTRUCTION_OR;
wire SEL_S1_INSTRUCTION_MOV;
wire SEL_S1_INSTRUCTION_CPI;
wire SEL_S1_INSTRUCTION_SUBI;
wire SEL_S1_INSTRUCTION_SBCI;
wire SEL_S1_INSTRUCTION_ORI_SBR;
wire SEL_S1_INSTRUCTION_ANDI_CBR;
wire SEL_S1_INSTRUCTION_LDD_STD;
wire SEL_S1_INSTRUCTION_LDS_STS;
wire SEL_S1_INSTRUCTION_LD_ST_YZP;
wire SEL_S1_INSTRUCTION_LD_ST_YZN;
wire SEL_S1_INSTRUCTION_LPM_R;
wire SEL_S1_INSTRUCTION_LPM_R_P;
wire SEL_S1_INSTRUCTION_XCH;
wire SEL_S1_INSTRUCTION_LAS;
wire SEL_S1_INSTRUCTION_LAC;
wire SEL_S1_INSTRUCTION_LAT;
wire SEL_S1_INSTRUCTION_LD_ST_X;
wire SEL_S1_INSTRUCTION_LD_ST_XP;
wire SEL_S1_INSTRUCTION_LD_ST_XN;
wire SEL_S1_INSTRUCTION_POP_PUSH;
wire SEL_S1_INSTRUCTION_COM;
wire SEL_S1_INSTRUCTION_NEG;
wire SEL_S1_INSTRUCTION_SWAP;
wire SEL_S1_INSTRUCTION_INC;
wire SEL_S1_INSTRUCTION_ASR;
wire SEL_S1_INSTRUCTION_LSR;
wire SEL_S1_INSTRUCTION_ROR;
wire SEL_S1_INSTRUCTION_SEx_CLx;
wire SEL_S1_INSTRUCTION_RET;
wire SEL_S1_INSTRUCTION_RETI;
wire SEL_S1_INSTRUCTION_SLEEP;
wire SEL_S1_INSTRUCTION_BREAK;
wire SEL_S1_INSTRUCTION_WDR;
wire SEL_S1_INSTRUCTION_LPM_ELPM;
wire SEL_S1_INSTRUCTION_SPM;
wire SEL_S1_INSTRUCTION_SPM_Z_P;
wire SEL_S1_INSTRUCTION_IJMP;
wire SEL_S1_INSTRUCTION_ICALL;
wire SEL_S1_INSTRUCTION_DEC;
wire SEL_S1_INSTRUCTION_DES;
wire SEL_S1_INSTRUCTION_JMP;
wire SEL_S1_INSTRUCTION_CALL;
wire SEL_S1_INSTRUCTION_ADIW;
wire SEL_S1_INSTRUCTION_SBIW;
wire SEL_S1_INSTRUCTION_CBI_SBI;
wire SEL_S1_INSTRUCTION_SBIC_SBIS;
wire SEL_S1_INSTRUCTION_MUL;
wire SEL_S1_INSTRUCTION_IN_OUT;
wire SEL_S1_INSTRUCTION_RJMP;
wire SEL_S1_INSTRUCTION_RCALL;
wire SEL_S1_INSTRUCTION_LDI;
wire SEL_S1_INSTRUCTION_COND_BRANCH;
wire SEL_S1_INSTRUCTION_BLD_BST;
wire SEL_S1_INSTRUCTION_SBRC_SBRS;
 
inst_dec inst_dec_s1_inst(
.inst(
`ifdef USE_RAM_READ_DELAY
ram_read_delay != `USE_RAM_READ_DELAY || step_cnt != `STEP1 ? tmp_pgm_data :
`endif
pgm_data_int),
.INTERRUPT_IN_EXECUTION(interrupt_registered),
.SEL_INSTRUCTION_MOVW(SEL_S1_INSTRUCTION_MOVW),
.SEL_INSTRUCTION_MULS(SEL_S1_INSTRUCTION_MULS),
.SEL_INSTRUCTION_MULSU(SEL_S1_INSTRUCTION_MULSU),
.SEL_INSTRUCTION_FMUL(SEL_S1_INSTRUCTION_FMUL),
.SEL_INSTRUCTION_FMULS(SEL_S1_INSTRUCTION_FMULS),
.SEL_INSTRUCTION_FMULSU(SEL_S1_INSTRUCTION_FMULSU),
.SEL_INSTRUCTION_CPC(SEL_S1_INSTRUCTION_CPC),
.SEL_INSTRUCTION_CP(SEL_S1_INSTRUCTION_CP),
.SEL_INSTRUCTION_SBC(SEL_S1_INSTRUCTION_SBC),
.SEL_INSTRUCTION_SUB(SEL_S1_INSTRUCTION_SUB),
.SEL_INSTRUCTION_ADD(SEL_S1_INSTRUCTION_ADD),
.SEL_INSTRUCTION_ADC(SEL_S1_INSTRUCTION_ADC),
.SEL_INSTRUCTION_CPSE(SEL_S1_INSTRUCTION_CPSE),
.SEL_INSTRUCTION_AND(SEL_S1_INSTRUCTION_AND),
.SEL_INSTRUCTION_EOR(SEL_S1_INSTRUCTION_EOR),
.SEL_INSTRUCTION_OR(SEL_S1_INSTRUCTION_OR),
.SEL_INSTRUCTION_MOV(SEL_S1_INSTRUCTION_MOV),
.SEL_INSTRUCTION_CPI(SEL_S1_INSTRUCTION_CPI),
.SEL_INSTRUCTION_SUBI(SEL_S1_INSTRUCTION_SUBI),
.SEL_INSTRUCTION_SBCI(SEL_S1_INSTRUCTION_SBCI),
.SEL_INSTRUCTION_ORI_SBR(SEL_S1_INSTRUCTION_ORI_SBR),
.SEL_INSTRUCTION_ANDI_CBR(SEL_S1_INSTRUCTION_ANDI_CBR),
.SEL_INSTRUCTION_LDD_STD(SEL_S1_INSTRUCTION_LDD_STD),
.SEL_INSTRUCTION_LDS_STS(SEL_S1_INSTRUCTION_LDS_STS),
.SEL_INSTRUCTION_LD_ST_YZP(SEL_S1_INSTRUCTION_LD_ST_YZP),
.SEL_INSTRUCTION_LD_ST_YZN(SEL_S1_INSTRUCTION_LD_ST_YZN),
.SEL_INSTRUCTION_LPM_R(SEL_S1_INSTRUCTION_LPM_R),
.SEL_INSTRUCTION_LPM_R_P(SEL_S1_INSTRUCTION_LPM_R_P),
.SEL_INSTRUCTION_XCH(SEL_S1_INSTRUCTION_XCH),
.SEL_INSTRUCTION_LAS(SEL_S1_INSTRUCTION_LAS),
.SEL_INSTRUCTION_LAC(SEL_S1_INSTRUCTION_LAC),
.SEL_INSTRUCTION_LAT(SEL_S1_INSTRUCTION_LAT),
.SEL_INSTRUCTION_LD_ST_X(SEL_S1_INSTRUCTION_LD_ST_X),
.SEL_INSTRUCTION_LD_ST_XP(SEL_S1_INSTRUCTION_LD_ST_XP),
.SEL_INSTRUCTION_LD_ST_XN(SEL_S1_INSTRUCTION_LD_ST_XN),
.SEL_INSTRUCTION_POP_PUSH(SEL_S1_INSTRUCTION_POP_PUSH),
.SEL_INSTRUCTION_COM(SEL_S1_INSTRUCTION_COM),
.SEL_INSTRUCTION_NEG(SEL_S1_INSTRUCTION_NEG),
.SEL_INSTRUCTION_SWAP(SEL_S1_INSTRUCTION_SWAP),
.SEL_INSTRUCTION_INC(SEL_S1_INSTRUCTION_INC),
.SEL_INSTRUCTION_ASR(SEL_S1_INSTRUCTION_ASR),
.SEL_INSTRUCTION_LSR(SEL_S1_INSTRUCTION_LSR),
.SEL_INSTRUCTION_ROR(SEL_S1_INSTRUCTION_ROR),
.SEL_INSTRUCTION_SEx_CLx(SEL_S1_INSTRUCTION_SEx_CLx),
.SEL_INSTRUCTION_RET(SEL_S1_INSTRUCTION_RET),
.SEL_INSTRUCTION_RETI(SEL_S1_INSTRUCTION_RETI),
.SEL_INSTRUCTION_SLEEP(SEL_S1_INSTRUCTION_SLEEP),
.SEL_INSTRUCTION_BREAK(SEL_S1_INSTRUCTION_BREAK),
.SEL_INSTRUCTION_WDR(SEL_S1_INSTRUCTION_WDR),
.SEL_INSTRUCTION_LPM_ELPM(SEL_S1_INSTRUCTION_LPM_ELPM),
.SEL_INSTRUCTION_SPM(SEL_S1_INSTRUCTION_SPM),
.SEL_INSTRUCTION_SPM_Z_P(SEL_S1_INSTRUCTION_SPM_Z_P),
.SEL_INSTRUCTION_IJMP(SEL_S1_INSTRUCTION_IJMP),
.SEL_INSTRUCTION_ICALL(SEL_S1_INSTRUCTION_ICALL),
.SEL_INSTRUCTION_DEC(SEL_S1_INSTRUCTION_DEC),
.SEL_INSTRUCTION_DES(SEL_S1_INSTRUCTION_DES),
.SEL_INSTRUCTION_JMP(SEL_S1_INSTRUCTION_JMP),
.SEL_INSTRUCTION_CALL(SEL_S1_INSTRUCTION_CALL),
.SEL_INSTRUCTION_ADIW(SEL_S1_INSTRUCTION_ADIW),
.SEL_INSTRUCTION_SBIW(SEL_S1_INSTRUCTION_SBIW),
.SEL_INSTRUCTION_CBI_SBI(SEL_S1_INSTRUCTION_CBI_SBI),
.SEL_INSTRUCTION_SBIC_SBIS(SEL_S1_INSTRUCTION_SBIC_SBIS),
.SEL_INSTRUCTION_MUL(SEL_S1_INSTRUCTION_MUL),
.SEL_INSTRUCTION_IN_OUT(SEL_S1_INSTRUCTION_IN_OUT),
.SEL_INSTRUCTION_RJMP(SEL_S1_INSTRUCTION_RJMP),
.SEL_INSTRUCTION_RCALL(SEL_S1_INSTRUCTION_RCALL),
.SEL_INSTRUCTION_LDI(SEL_S1_INSTRUCTION_LDI),
.SEL_INSTRUCTION_COND_BRANCH(SEL_S1_INSTRUCTION_COND_BRANCH),
.SEL_INSTRUCTION_BLD_BST(SEL_S1_INSTRUCTION_BLD_BST),
.SEL_INSTRUCTION_SBRC_SBRS(SEL_S1_INSTRUCTION_SBRC_SBRS)
);
 
reg SEL_S2_INSTRUCTION_CPSE;
reg SEL_S2_INSTRUCTION_LDS_STS;
reg SEL_S2_INSTRUCTION_LD_ST_YZP;
reg SEL_S2_INSTRUCTION_LD_ST_YZN;
reg SEL_S2_INSTRUCTION_LPM_ELPM;
reg SEL_S2_INSTRUCTION_LPM_R;
reg SEL_S2_INSTRUCTION_LPM_R_P;
reg SEL_S2_INSTRUCTION_LD_ST_X;
reg SEL_S2_INSTRUCTION_LD_ST_XP;
reg SEL_S2_INSTRUCTION_LD_ST_XN;
reg SEL_S2_INSTRUCTION_RET;
reg SEL_S2_INSTRUCTION_RETI;
reg SEL_S2_INSTRUCTION_ICALL;
reg SEL_S2_INSTRUCTION_JMP;
reg SEL_S2_INSTRUCTION_CALL;
reg SEL_S2_INSTRUCTION_SBIC_SBIS;
reg SEL_S2_INSTRUCTION_MUL;
reg SEL_S2_INSTRUCTION_MULS;
reg SEL_S2_INSTRUCTION_MULSU;
reg SEL_S2_INSTRUCTION_FMUL;
reg SEL_S2_INSTRUCTION_FMULS;
reg SEL_S2_INSTRUCTION_FMULSU;
reg SEL_S2_INSTRUCTION_RCALL;
reg SEL_S2_INSTRUCTION_SBRC_SBRS;
 
reg select_io_in_stam;
integer io_ports_displacement;
 
/*
* IO maping switch
*/
always @*
begin
if(CORE_CONFIG == "XMEGA")
begin
if(ram_read_delay == 0)
select_io_in_stam = data_addr_int_tmp < 'h40;
else
select_io_in_stam = pgm_data_int < 'h40;
io_ports_displacement = 'h0000;
end
else
begin
if(ram_read_delay == 0)
select_io_in_stam = data_addr_int_tmp < 'h60;
else
select_io_in_stam = pgm_data_int < 'h60;
io_ports_displacement = 'h0020;
end
end
/*
* !IO maping switch
*/
 
`ifdef USE_RAM_READ_DELAY
wire [15:0]tmp_pgm_data_switched = ram_read_delay == `USE_RAM_READ_DELAY ? pgm_data_int : tmp_pgm_data;
`else
wire [15:0]tmp_pgm_data_switched = pgm_data_int;
`endif
 
/*
* Busses switch.
*/
reg skip_execution;
always @ (*)
begin
rw_addr <= 5'h0;
rw_16bit <= 1'b0;
rd_addr_d <= 5'h0;
rd_16bit_d <= 1'b0;
rd_addr_r <= 5'h0;
rd_16bit_r <= 1'b0;
// Connect busses
rw_data <= 16'h0;
alu_in_1 <= 16'h0;
alu_in_2 <= 16'h0;
write_to_reg <= 1'b0;
io_we_int <= 1'b0;
io_re_int <= 1'b0;
io_addr_int <= 16'h0;
io_out_int <= 'h0;
data_addr_int <= 'hz;
data_out_int <= 'hz;
data_re_int <= 1'b0;
indirect_addr_offset <= 16'h0;
data_we_int <= 1'b0;
 
if(~alu_rdy)
begin
rw_addr <= reg_clr_cnt;
rw_16bit <= 1'b1;
rw_data <= 16'h0;
write_to_reg <= 1'b1;
end
else
begin
/*
* Data address switch.
*/
if(!skip_execution | USE_BRAM_ROM != "TRUE")
begin
case(step_cnt)
`STEP1:
begin
if(CORE_CONFIG != "REDUCED")
begin
if(SEL_S1_INSTRUCTION_LDD_STD)
data_addr_int <= indirect_addr_offset_res;
if(SEL_S1_INSTRUCTION_POP_PUSH)
begin
if(pgm_data_int[9])
data_addr_int <= SP;
else
data_addr_int <= SP_PLUS_ONE;
end
end
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
if(SEL_S1_INSTRUCTION_LD_ST_X |
SEL_S1_INSTRUCTION_LD_ST_XP |
SEL_S1_INSTRUCTION_LD_ST_YZP)
data_addr_int <= rd_data_r;
if(SEL_S1_INSTRUCTION_LD_ST_XN |
SEL_S1_INSTRUCTION_LD_ST_YZN)
data_addr_int <= rd_data_r_MINUS_ONE;
end
if((SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) |
(SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
SEL_S1_INSTRUCTION_RCALL |
(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0))
data_addr_int <= SP;
if(SEL_S1_INSTRUCTION_RET |
SEL_S1_INSTRUCTION_RETI)
data_addr_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, SP_PLUS_ONE};
if (SEL_S1_INSTRUCTION_XCH |
SEL_S1_INSTRUCTION_LAS |
SEL_S1_INSTRUCTION_LAC |
SEL_S1_INSTRUCTION_LAT)
data_addr_int <= rd_data_r;
end
`STEP2:
begin
if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
data_addr_int <= SP;
else
begin
casex(tmp_pgm_data)
`INSTRUCTION_ICALL:
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
data_addr_int <= SP;
end
end
`INSTRUCTION_CALL:
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")
begin
data_addr_int <= SP;
end
end
`INSTRUCTION_RCALL: data_addr_int <= SP;
`INSTRUCTION_RET_RETI: data_addr_int <= SP_PLUS_ONE;
`INSTRUCTION_LDS_STS:
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
`endif
data_addr_int <= pgm_data_int[BUS_ADDR_DATA_WIDTH-1:0];
`ifdef USE_RAM_READ_DELAY
else
data_addr_int <= data_addr_int_tmp;
`endif
end
endcase
end
end
endcase
/*
* Instruction decode.
*/
rd_addr_d <= 'h0;
rd_addr_r <= 'h0;
case(step_cnt)
`STEP1:
begin
if(SEL_S1_INSTRUCTION_MOVW)
begin
rw_addr <= {pgm_data_int[7:4], 1'b0};
rw_16bit <= 1'b1;
rd_addr_d <= {pgm_data_int[7:4], 1'b0};
rd_16bit_d <= 1'b1;
rd_addr_r <= {pgm_data_int[3:0], 1'b0};
rd_16bit_r <= 1'b1;
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= rd_data_r;
rw_data <= alu_out;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
/*if(SEL_S1_INSTRUCTION_CPSE)
begin
end*/
if(SEL_S1_INSTRUCTION_CPI)
begin
rd_addr_d <= {1'b1, pgm_data_int[7:4]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= {pgm_data_int[11:8], pgm_data_int[3:0]};
end
if(SEL_S1_INSTRUCTION_CPC |
SEL_S1_INSTRUCTION_CP)
begin
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= rd_data_r;
end
if(SEL_S1_INSTRUCTION_SBC |
SEL_S1_INSTRUCTION_SUB |
SEL_S1_INSTRUCTION_ADD |
SEL_S1_INSTRUCTION_ADC |
SEL_S1_INSTRUCTION_AND |
SEL_S1_INSTRUCTION_EOR |
SEL_S1_INSTRUCTION_OR |
SEL_S1_INSTRUCTION_MOV)
begin
rw_addr <= pgm_data_int[8:4];
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= rd_data_r;
rw_data <= alu_out;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(SEL_S1_INSTRUCTION_SUBI |
SEL_S1_INSTRUCTION_SBCI |
SEL_S1_INSTRUCTION_ORI_SBR |
SEL_S1_INSTRUCTION_ANDI_CBR)
begin
rw_addr <= {1'b1, pgm_data_int[7:4]};
rd_addr_d <= {1'b1, pgm_data_int[7:4]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= {8'h00, pgm_data_int[11:8], pgm_data_int[3:0]};
rw_data <= alu_out;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(SEL_S1_INSTRUCTION_COM |
SEL_S1_INSTRUCTION_NEG |
SEL_S1_INSTRUCTION_SWAP |
SEL_S1_INSTRUCTION_INC |
SEL_S1_INSTRUCTION_DEC |
SEL_S1_INSTRUCTION_ASR |
SEL_S1_INSTRUCTION_LSR |
SEL_S1_INSTRUCTION_ROR)
begin
rw_addr <= pgm_data_int[8:4];
rd_addr_d <= pgm_data_int[8:4];
// Connect busses
alu_in_1 <= rd_data_d;
if(SEL_S1_INSTRUCTION_INC) alu_in_2 <= 16'h0001;
if(SEL_S1_INSTRUCTION_DEC) alu_in_2 <= 16'hFFFF;
rw_data <= alu_out;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(CORE_CONFIG != "REDUCED")
begin
if(SEL_S1_INSTRUCTION_LDD_STD)
begin
rd_addr_r <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
rd_16bit_r <= 1'b1;
indirect_addr_offset <= {{10{1'b0}}, tmp_pgm_data_switched[13], tmp_pgm_data_switched[11:10], tmp_pgm_data_switched[2:0]};
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
else
begin
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
`ifdef USE_LPM
if(SEL_S1_INSTRUCTION_LPM_R |
SEL_S1_INSTRUCTION_LPM_R_P |
SEL_S1_INSTRUCTION_LPM_ELPM)
begin
rd_addr_d <= 'h1E;//pgm_data_int[8:4];
rd_16bit_d <= 1'b1;
if(pgm_data_int[0])
begin
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= 1;
rw_addr <= 'h1E;//pgm_data_int[8:4];
rw_data <= alu_out;
rw_16bit <= 1'b1;
write_to_reg <= 1'b1;
end
end
`endif
end/*!CORE_CONFIG != "REDUCED"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
/*if(SEL_S1_INSTRUCTION_LD_ST_X)
begin
rd_addr_r <= 5'd26;
rd_16bit_r <= 1'b1;
if(pgm_data_int[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
else
begin
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end*/
if(SEL_S1_INSTRUCTION_LD_ST_YZP |
SEL_S1_INSTRUCTION_LD_ST_YZN)
begin
rd_addr_r <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
rd_16bit_r <= 1'b1;
rw_addr <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
//rw_16bit <= 1'b1;
//rw_16bit <= 1'b1;
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
else
begin
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
if(SEL_S1_INSTRUCTION_LD_ST_X |
SEL_S1_INSTRUCTION_LD_ST_XP |
SEL_S1_INSTRUCTION_LD_ST_XN)
begin
rd_addr_r <= 5'd26;
rd_16bit_r <= 1'b1;
rw_addr <= 5'd26;
//rw_16bit <= 1'b1;
//rw_16bit <= 1'b1;
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
else
begin
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
if(SEL_S1_INSTRUCTION_ADIW |
SEL_S1_INSTRUCTION_SBIW)
begin
rw_addr <= {2'b11, pgm_data_int[5:4], 1'b0};
rw_16bit <= 1'b1;
rd_addr_d <= {2'b11, pgm_data_int[5:4], 1'b0};
rd_16bit_d <= 1'b1;
//rd_addr_r <= {5{1'b00}};
rd_16bit_r <= 1'b1;
// Connect busses
rw_data <= alu_out;
alu_in_1 <= rd_data_d;
alu_in_2 <= {10'h000, pgm_data_int[7:6], pgm_data_int[3:0]};
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(SEL_S1_INSTRUCTION_POP_PUSH)
begin
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1; // Put "data_we" to high to store the selected register.
end
else
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
if(SEL_S1_INSTRUCTION_IJMP)
begin
rd_addr_d <= 5'h1e;
rd_16bit_d <= 1'b1;
end
end/*!CORE_CONFIG != "REDUCED" || CORE_CONFIG != "MINIMAL"*/
if(SEL_S1_INSTRUCTION_IN_OUT)
begin
rw_addr <= pgm_data_int[8:4];
rd_addr_d <= pgm_data_int[8:4];
if(!pgm_data_int[11])
begin
case({pgm_data_int[10:9], pgm_data_int[3:0]})
`ifdef USE_CCP_REG
6'h34:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= CCP;
end
end
`endif
`ifdef USE_EXTENDED_RAMP_REGS
6'h38:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= RAMPD;
end
end
6'h39:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= RAMPX;
end
end
6'h3A:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= RAMPY;
end
end
6'h3B:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= RAMPZ;
end
end
6'h3C:
begin
if(CORE_CONFIG == "XMEGA")
begin
rw_data <= EIND;
end
end
`endif
6'h3D: //SPL
begin
if(CORE_CONFIG != "REDUCED")
begin
rw_data <= SP[7:0];
end
end
6'h3E: //SPH
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
begin
rw_data <= {{BUS_ADDR_DATA_WIDTH-1-8{1'b0}}, SP[BUS_ADDR_DATA_WIDTH-1:8]};
end
end
6'h3F: rw_data <= ALU_FLAGS;
default:
begin
io_addr_int <= {pgm_data_int[10:9], pgm_data_int[3:0]};
io_re_int <= 1'b1;
rw_data <= io_in_int;
end
endcase
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
else
begin
case({pgm_data_int[10:9], pgm_data_int[3:0]})
`ifdef USE_CCP_REG
6'h34,
`endif
`ifdef USE_EXTENDED_RAMP_REGS
6'h38,
6'h39,
6'h3A,
6'h3B,
6'h3C,
`endif
6'h3D,// SPL
6'h3E,// SPH
6'h3F:;//SREG
default:
begin
io_addr_int <= {pgm_data_int[10:9], pgm_data_int[3:0]};
io_out_int <= rd_data_d;
io_we_int <= 1'b1; // Put "data_we" to high to store the selected register.
end
endcase
end
end
if(CORE_CONFIG == "XMEGA")
begin
if(SEL_S1_INSTRUCTION_XCH |
SEL_S1_INSTRUCTION_LAS |
SEL_S1_INSTRUCTION_LAC |
SEL_S1_INSTRUCTION_LAT)
begin
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= 5'h1e;
rw_addr <= pgm_data_int[8:4];
data_re_int <= 1'b1;
if(SEL_S1_INSTRUCTION_XCH) data_out_int <= rd_data_d;
else if(SEL_S1_INSTRUCTION_LAS) data_out_int <= data_in_int | rd_data_d;
else if(SEL_S1_INSTRUCTION_LAC) data_out_int <= data_in_int & ~rd_data_d;
else if(SEL_S1_INSTRUCTION_LAT) data_out_int <= data_in_int ^ rd_data_d;
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
end
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
begin
if((SEL_S1_INSTRUCTION_MUL |
SEL_S1_INSTRUCTION_MULS |
SEL_S1_INSTRUCTION_MULSU |
SEL_S1_INSTRUCTION_FMUL |
SEL_S1_INSTRUCTION_FMULS |
SEL_S1_INSTRUCTION_FMULSU))
begin
rw_16bit <= 1'b1;
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= rd_data_r;
rw_data <= alu_out;
// Signalize write_to_reg;
//write_to_reg <= 1'b1;
// Because the multiply unit has more latency, we will add an extra clock.
end
end
if(SEL_S1_INSTRUCTION_LDI)
begin
rw_addr <= {1'b1, pgm_data_int[7:4]};
// Connect busses
rw_data <= {8'h00, pgm_data_int[11:8], pgm_data_int[3:0]};
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(SEL_S1_INSTRUCTION_CBI_SBI)
begin
io_addr_int <= {{11{1'b0}}, pgm_data_int[7:3]};
case(pgm_data_int[2:0])
3'h0: io_out_int <= {io_in_int[7:1], pgm_data_int[9]};
3'h1: io_out_int <= {io_in_int[7:2], pgm_data_int[9], io_in_int[0]};
3'h2: io_out_int <= {io_in_int[7:3], pgm_data_int[9], io_in_int[1:0]};
3'h3: io_out_int <= {io_in_int[7:4], pgm_data_int[9], io_in_int[2:0]};
3'h4: io_out_int <= {io_in_int[7:5], pgm_data_int[9], io_in_int[3:0]};
3'h5: io_out_int <= {io_in_int[7:6], pgm_data_int[9], io_in_int[4:0]};
3'h6: io_out_int <= {io_in_int[7], pgm_data_int[9], io_in_int[5:0]};
3'h7: io_out_int <= {pgm_data_int[9], io_in_int[6:0]};
endcase
io_re_int <= 1'b1;
io_we_int <= 1'b1;
end
if(SEL_S1_INSTRUCTION_BLD_BST)
begin
rd_addr_d <= pgm_data_int[8:4];
if(~pgm_data_int[9])
begin
rw_addr <= pgm_data_int[8:4];
// Signalize write_to_reg;
write_to_reg <= 1'b1;
case(pgm_data_int[2:0])
3'h0: rw_data <= {rd_data_d[7:1], ALU_FLAGS[`ALU_FLAG_T]};
3'h1: rw_data <= {rd_data_d[7:2], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[0]};
3'h2: rw_data <= {rd_data_d[7:3], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[1:0]};
3'h3: rw_data <= {rd_data_d[7:4], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[2:0]};
3'h4: rw_data <= {rd_data_d[7:5], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[3:0]};
3'h5: rw_data <= {rd_data_d[7:6], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[4:0]};
3'h6: rw_data <= {rd_data_d[7], ALU_FLAGS[`ALU_FLAG_T], rd_data_d[5:0]};
3'h7: rw_data <= {ALU_FLAGS[`ALU_FLAG_T], rd_data_d[6:0]};
endcase
end
end
if(SEL_S1_INSTRUCTION_RCALL)
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= PC[7:0];// Put low byte of the PC.
default : data_out_int <= PC_PLUS_ONE[7:0];// Put low byte of the PC.
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if(SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"))
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= PC[7:0];// Put low byte of the PC.
default : data_out_int <= PC_PLUS_ONE[7:0];// Put low byte of the PC.
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= PC_PLUS_ONE[7:0];
default : data_out_int <= PC[7:0];
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")))
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= PC_PLUS_ONE[7:0];
default : data_out_int <= PC_PLUS_TWO[7:0];
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if(SEL_S1_INSTRUCTION_RET |
SEL_S1_INSTRUCTION_RETI)
begin
data_re_int <= 1'b1;
end
if(SEL_S1_INSTRUCTION_CPSE)
begin
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
end
if(SEL_S1_INSTRUCTION_SBRC_SBRS)
begin
rd_addr_d <= pgm_data_int[8:4];
end
if(SEL_S1_INSTRUCTION_SBIC_SBIS)
begin
io_addr_int <= {{11{1'b0}}, pgm_data_int[7:3]};
io_re_int <= 1'b1;
end
end
`STEP2:
begin
`ifdef USE_LPM
if(CORE_CONFIG != "REDUCED")
begin
if(SEL_S2_INSTRUCTION_LPM_R |
SEL_S2_INSTRUCTION_LPM_R_P |
SEL_S2_INSTRUCTION_LPM_ELPM)
begin
if(~rom_read_delay || USE_BRAM_ROM == "FALSE")
begin
if(SEL_S2_INSTRUCTION_LPM_ELPM)
rw_addr <= 0;
else
rw_addr <= tmp_pgm_data[8:4];
rw_data <= pgm_indirect_addr[0] ? pgm_data_int[15:8] : pgm_data_int[7:0];
rw_16bit <= 1'b0;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
end
end
`endif
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
if(SEL_S2_INSTRUCTION_ICALL)
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
endcase
rd_addr_d <= 5'h1e;
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
rd_16bit_d <= 1'b1;
end
if(SEL_S2_INSTRUCTION_LDS_STS)
begin
if(tmp_pgm_data[9])
begin
rd_addr_d <= tmp_pgm_data[8:4];
if(select_io_in_stam)
begin
case(pgm_data_int[(CORE_CONFIG == "XMEGA" ? 5 : 6):0])
`ifdef USE_CCP_REG
'h34 + io_ports_displacement,
`endif
`ifdef USE_EXTENDED_RAMP_REGS
'h38 + io_ports_displacement,
'h39 + io_ports_displacement,
'h3A + io_ports_displacement,
'h3B + io_ports_displacement,
'h3C + io_ports_displacement,
`endif
'h00, 'h01, 'h02, 'h03, 'h04, 'h05, 'h06, 'h07, 'h08, 'h09, 'h0A, 'h0B, 'h0C, 'h0D, 'h0E, 'h0F,
'h10, 'h11, 'h12, 'h13, 'h14, 'h15, 'h16, 'h17, 'h18, 'h19, 'h1A, 'h1B, 'h1C, 'h1D, 'h1E, 'h1F:
begin
if(CORE_CONFIG != "XMEGA")
begin
if(MAP_REGS_IN_TO_SRAM_SECTION == "TRUE")
begin
rw_addr <= tmp_pgm_data[4:0];
rw_data <= rd_data_d;
end
end
end
'h3D + io_ports_displacement,// SPL
'h3E + io_ports_displacement,// SPH
'h3F + io_ports_displacement:;//SREG
default:
begin
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
endcase
end
else
begin
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
end
else
begin
rw_addr <= tmp_pgm_data[8:4];
// Signalize write_to_reg;
//write_to_reg <= 1'b1;
if(select_io_in_stam)
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
`endif
write_to_reg <= 1'b1;
case(pgm_data_int[(CORE_CONFIG == "XMEGA" ? 5 : 6):0])
`ifdef USE_CCP_REG
'h34 + io_ports_displacement: rw_data <= CCP;
`endif
`ifdef USE_EXTENDED_RAMP_REGS
'h38 + io_ports_displacement: rw_data <= RAMPD;
'h39 + io_ports_displacement: rw_data <= RAMPX;
'h3A + io_ports_displacement: rw_data <= RAMPY;
'h3B + io_ports_displacement: rw_data <= RAMPZ;
'h3C + io_ports_displacement: rw_data <= EIND;
`endif
'h00, 'h01, 'h02, 'h03, 'h04, 'h05, 'h06, 'h07, 'h08, 'h09, 'h0A, 'h0B, 'h0C, 'h0D, 'h0E, 'h0F,
'h10, 'h11, 'h12, 'h13, 'h14, 'h15, 'h16, 'h17, 'h18, 'h19, 'h1A, 'h1B, 'h1C, 'h1D, 'h1E, 'h1F:
begin
if(CORE_CONFIG != "XMEGA")
begin
if(MAP_REGS_IN_TO_SRAM_SECTION == "TRUE")
begin
rd_addr_d <= tmp_pgm_data[4:0];
rw_data <= rd_data_d;
end
end
end
'h3D + io_ports_displacement: //SPL
begin
if(CORE_CONFIG != "REDUCED")
begin
rw_data <= SP[7:0];
end
end
'h3E + io_ports_displacement: //SPH
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
begin
rw_data <= {{BUS_ADDR_DATA_WIDTH-1-8{1'b0}}, SP[BUS_ADDR_DATA_WIDTH-1:8]};
end
end
'h3F + io_ports_displacement: rw_data <= ALU_FLAGS;//SREG
default:
begin
// Connect busses
rw_data <= data_in_int;
data_re_int <= 1'b1;
end
endcase
end
else
begin
//rd_addr_d <= tmp_pgm_data[4:0];
//rw_data <= rd_data_d;
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == 0)
`endif
write_to_reg <= 1'b1;
rw_data <= data_in_int;
data_re_int <= 1'b1;
end
end
end
if(SEL_S2_INSTRUCTION_LD_ST_X |
SEL_S2_INSTRUCTION_LD_ST_XP |
SEL_S2_INSTRUCTION_LD_ST_XN)
begin
rd_addr_r <= 5'd26;
rd_16bit_r <= 1'b1;
rw_addr <= 5'd26;
rw_16bit <= 1'b1;
case(tmp_pgm_data[1:0])
2'b00: rw_data <= rd_data_r;
2'b01: rw_data <= rd_data_r_PLUS_ONE;
2'b10: rw_data <= rd_data_r_MINUS_ONE;
endcase
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
if(SEL_S2_INSTRUCTION_LD_ST_YZP |
SEL_S2_INSTRUCTION_LD_ST_YZN)
begin
rd_addr_r <= {{3{1'b1}}, ~tmp_pgm_data[3], 1'b0};
rd_16bit_r <= 1'b1;
rw_addr <= {{3{1'b1}}, ~tmp_pgm_data[3], 1'b0};
rw_16bit <= 1'b1;
case(tmp_pgm_data[1:0])
2'b01: rw_data <= rd_data_r_PLUS_ONE;
2'b10: rw_data <= rd_data_r_MINUS_ONE;
endcase
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
end/*!CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")
begin
if((SEL_S2_INSTRUCTION_MUL |
SEL_S2_INSTRUCTION_MULS |
SEL_S2_INSTRUCTION_MULSU |
SEL_S2_INSTRUCTION_FMUL |
SEL_S2_INSTRUCTION_FMULS |
SEL_S2_INSTRUCTION_FMULSU))
begin
rw_16bit <= 1'b1;
rd_addr_d <= pgm_data_int[8:4];
rd_addr_r <= {pgm_data_int[9], pgm_data_int[3:0]};
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= rd_data_r;
rw_data <= alu_out;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
end
if(SEL_S2_INSTRUCTION_RET |
SEL_S2_INSTRUCTION_RETI)
begin
data_re_int <= 1'b1;
end
if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if(SEL_S2_INSTRUCTION_RCALL)
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if((SEL_S2_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")))
begin
case(USE_BRAM_ROM)
"TRUE" : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
default : data_out_int <= {{BUS_ADDR_PGM_WIDTH-1-8{1'b0}}, PC_PLUS_ONE[BUS_ADDR_PGM_WIDTH-1:8]};// Put high byte of the PC.
endcase
data_we_int <= 1'b1; // Put "data_we" to high to store low byte of the PC.
end
if(SEL_S2_INSTRUCTION_CPSE)
begin
rd_addr_d <= tmp_pgm_data[8:4];
rd_addr_r <= {tmp_pgm_data[9], tmp_pgm_data[3:0]};
end
if(SEL_S2_INSTRUCTION_SBRC_SBRS)
begin
rd_addr_d <= tmp_pgm_data[8:4];
end
if(SEL_S2_INSTRUCTION_SBIC_SBIS)
begin
io_addr_int <= {{11{1'b0}}, tmp_pgm_data[7:3]};
io_re_int <= 1'b1;
end
end
endcase
end
end
end
/*
* !Busses switch.
*/
 
wire [15:0]relative_offset = (USE_BRAM_ROM == "TRUE") ? PC + {{5{tmp_pgm_data[11]}}, tmp_pgm_data[10:0]} : PC_PLUS_ONE + {{5{pgm_data_int[11]}}, pgm_data_int[10:0]};
wire [15:0]relative_offset_rjmp = PC + {{5{pgm_data_int[11]}}, pgm_data_int[10:0]};
 
reg [BUS_ADDR_PGM_WIDTH-1-8:0]PGM_HI_TMP;
 
 
/*
* Instruction execution sequencer.
*/
always @ (posedge clk)
begin
if((WATCHDOG_CNT_WIDTH != 'd0) ? core_rst : rst)
begin
reg_clr_cnt <= 0;
end
else
if(~alu_rdy)
begin
ALU_FLAGS[0] <= 1'b0; //Carry Flag
ALU_FLAGS[1] <= 1'b0; //Zero Flag
ALU_FLAGS[2] <= 1'b0; //Negative Flag
ALU_FLAGS[3] <= 1'b0; //Two's complement overflow indicator
ALU_FLAGS[4] <= 1'b0; //N?V for signed tests
ALU_FLAGS[5] <= 1'b0; //Half Carry Flag
ALU_FLAGS[6] <= 1'b0; //Transfer bit used by BLD and BST instructions
ALU_FLAGS[7] <= 1'b0; //Global Interrupt Enable/Disable Flag
SEL_S2_INSTRUCTION_CPSE <= 'h0;
SEL_S2_INSTRUCTION_LDS_STS <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_YZP <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_YZN <= 'h0;
SEL_S2_INSTRUCTION_LPM_ELPM <= 'h0;
SEL_S2_INSTRUCTION_LPM_R <= 'h0;
SEL_S2_INSTRUCTION_LPM_R_P <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_X <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_XP <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_XN <='h0 ;
SEL_S2_INSTRUCTION_RET <= 'h0;
SEL_S2_INSTRUCTION_RETI <= 'h0;
SEL_S2_INSTRUCTION_ICALL <= 'h0;
SEL_S2_INSTRUCTION_JMP <= 'h0;
SEL_S2_INSTRUCTION_CALL <= 'h0;
SEL_S2_INSTRUCTION_SBIC_SBIS <= 'h0;
SEL_S2_INSTRUCTION_MUL <= 'h0;
SEL_S2_INSTRUCTION_MULS <= 'h0;
SEL_S2_INSTRUCTION_MULSU <= 'h0;
SEL_S2_INSTRUCTION_FMUL <= 'h0;
SEL_S2_INSTRUCTION_FMULS <= 'h0;
SEL_S2_INSTRUCTION_FMULSU <= 'h0;
SEL_S2_INSTRUCTION_RCALL <= 'h0;
SEL_S2_INSTRUCTION_SBRC_SBRS <= 'h0;
PC <= 'h0000;
SP <= 'h0000;
current_int_executed <= 1'b0;
if (USE_BRAM_ROM == "TRUE")
skip_execution <= 1'b0;
if(CORE_CONFIG == "XMEGA")
begin
`ifdef USE_CCP_REG
CCP <= 8'h0;
`endif //!USE_CCP_REG
`ifdef USE_EXTENDED_RAMP_REGS
RAMPD <= 8'h0;
RAMPX <= 8'h0;
RAMPY <= 8'h0;
RAMPZ <= 8'h0;
EIND <= 8'h0;
`endif //!USE_EXTENDED_RAMP_REGS
end/*!CORE_CONFIG == "XMEGA"*/
step_cnt <= `STEP1;
`ifdef USE_RAM_READ_DELAY
ram_read_delay <= `USE_RAM_READ_DELAY;
`endif
rom_read_delay <= 1'b1;
reg_clr_cnt <= reg_clr_cnt + 1;
wdt_rst_out <= 1'b0;
interrupt_registered <= 1'b0;
end
else
begin
/*
* Preserve flags until otervice specified.
*/
ALU_FLAGS[0] <= ALU_FLAG_C_OUT; //Carry Flag
ALU_FLAGS[1] <= ALU_FLAG_Z_OUT; //Zero Flag
ALU_FLAGS[2] <= ALU_FLAG_N_OUT; //Negative Flag
ALU_FLAGS[3] <= ALU_FLAG_V_OUT; //Two's complement overflow indicator
ALU_FLAGS[4] <= ALU_FLAG_S_OUT; //N?V for signed tests
ALU_FLAGS[5] <= ALU_FLAG_H_OUT; //Half Carry Flag
ALU_FLAGS[6] <= ALU_FLAG_T_OUT; //Transfer bit used by BLD and BST instructions
ALU_FLAGS[7] <= ALU_FLAG_I_OUT; //Global Interrupt Enable/Disable Flag
step_cnt <= `STEP1;
PC <= PC_PLUS_ONE;// Increment PC by 1 if not specified otherwise.
wdt_rst_out <= 1'b0;
current_int_executed <= 1'b0;
int_rst <= 'h00;
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
begin
`endif
SEL_S2_INSTRUCTION_CPSE <= SEL_S1_INSTRUCTION_CPSE;
SEL_S2_INSTRUCTION_LDS_STS <= SEL_S1_INSTRUCTION_LDS_STS;
SEL_S2_INSTRUCTION_LD_ST_YZP <= SEL_S1_INSTRUCTION_LD_ST_YZP;
SEL_S2_INSTRUCTION_LD_ST_YZN <= SEL_S1_INSTRUCTION_LD_ST_YZN;
SEL_S2_INSTRUCTION_LPM_R <= SEL_S1_INSTRUCTION_LPM_R;
SEL_S2_INSTRUCTION_LPM_R_P <= SEL_S1_INSTRUCTION_LPM_R_P;
SEL_S2_INSTRUCTION_LPM_ELPM <= SEL_S1_INSTRUCTION_LPM_ELPM;
SEL_S2_INSTRUCTION_LD_ST_X <= SEL_S1_INSTRUCTION_LD_ST_X;
SEL_S2_INSTRUCTION_LD_ST_XP <= SEL_S1_INSTRUCTION_LD_ST_XP;
SEL_S2_INSTRUCTION_LD_ST_XN <=SEL_S1_INSTRUCTION_LD_ST_XN ;
SEL_S2_INSTRUCTION_RET <= SEL_S1_INSTRUCTION_RET;
SEL_S2_INSTRUCTION_RETI <= SEL_S1_INSTRUCTION_RETI;
SEL_S2_INSTRUCTION_ICALL <= SEL_S1_INSTRUCTION_ICALL;
SEL_S2_INSTRUCTION_JMP <= SEL_S1_INSTRUCTION_JMP;
SEL_S2_INSTRUCTION_CALL <= SEL_S1_INSTRUCTION_CALL;
SEL_S2_INSTRUCTION_SBIC_SBIS <= SEL_S1_INSTRUCTION_SBIC_SBIS;
SEL_S2_INSTRUCTION_MUL <= SEL_S1_INSTRUCTION_MUL;
SEL_S2_INSTRUCTION_MULS <= SEL_S1_INSTRUCTION_MULS;
SEL_S2_INSTRUCTION_MULSU <= SEL_S1_INSTRUCTION_MULSU;
SEL_S2_INSTRUCTION_FMUL <= SEL_S1_INSTRUCTION_FMUL;
SEL_S2_INSTRUCTION_FMULS <= SEL_S1_INSTRUCTION_FMULS;
SEL_S2_INSTRUCTION_FMULSU <= SEL_S1_INSTRUCTION_FMULSU;
SEL_S2_INSTRUCTION_RCALL <= SEL_S1_INSTRUCTION_RCALL;
SEL_S2_INSTRUCTION_SBRC_SBRS <= SEL_S1_INSTRUCTION_SBRC_SBRS;
`ifdef USE_RAM_READ_DELAY
end
`endif
`ifdef USE_RAM_READ_DELAY
//if(int_request && step_cnt == `STEP1 && ram_read_delay == `USE_RAM_READ_DELAY && ALU_FLAGS[7] && VECTOR_INT_TABLE_SIZE != 0)
if(int_request && ALU_FLAGS[7] && VECTOR_INT_TABLE_SIZE != 0)
begin
case(step_cnt)
/*`STEP1:
begin
if(ram_read_delay == 0 &&
//(SEL_S1_INSTRUCTION_LDD_STD && ~tmp_pgm_data_switched[9]) ||
(SEL_S1_INSTRUCTION_POP_PUSH && ~tmp_pgm_data_switched[9]))
begin
if(current_int_vect)
begin
interrupt_registered <= 1'b1;
current_int_vect_int <= current_int_vect;
PC <= PC_PLUS_ONE;
int_rst <= 1'b1 << (current_int_vect - 1);
end
end
end */
`STEP2:
begin
if(ram_read_delay == 0 &&
(SEL_S2_INSTRUCTION_LPM_R ||
SEL_S2_INSTRUCTION_LPM_R_P ||
SEL_S2_INSTRUCTION_LPM_ELPM ||
(SEL_S2_INSTRUCTION_LDS_STS && ~pgm_data_int[9]) ||
((SEL_S2_INSTRUCTION_MUL |
SEL_S2_INSTRUCTION_MULS |
SEL_S2_INSTRUCTION_MULSU |
SEL_S2_INSTRUCTION_FMUL |
SEL_S2_INSTRUCTION_FMULS |
SEL_S2_INSTRUCTION_FMULSU) && (CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")) ||
((SEL_S2_INSTRUCTION_LD_ST_YZP ||
SEL_S2_INSTRUCTION_LD_ST_YZN ||
SEL_S2_INSTRUCTION_LD_ST_X ||
SEL_S2_INSTRUCTION_LD_ST_XP ||
SEL_S2_INSTRUCTION_LD_ST_XN) && ~pgm_data_int[9]) ||
(SEL_S2_INSTRUCTION_JMP && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) ||
(SEL_S2_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) ||
(SEL_S2_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) ||
SEL_S2_INSTRUCTION_RCALL ||
SEL_S2_INSTRUCTION_RET ||
SEL_S2_INSTRUCTION_RETI ||
SEL_S2_INSTRUCTION_CPSE ||
SEL_S2_INSTRUCTION_SBRC_SBRS ||
SEL_S2_INSTRUCTION_SBIC_SBIS))
begin
if(current_int_vect)
begin
interrupt_registered <= 1'b1;
current_int_vect_int <= current_int_vect;
PC <= PC_PLUS_ONE;
int_rst <= 1'b1 << (current_int_vect - 1);
end
end
end
endcase
end
`else
if(int_request && step_cnt == `STEP1 && ALU_FLAGS[7] && VECTOR_INT_TABLE_SIZE != 0)
begin
interrupt_registered <= 1'b1;
current_int_vect_int <= current_int_vect;
PC <= PC - 1;
int_rst <= 1'b1 << (current_int_vect - 1);
end
`endif
if(skip_execution == 1'b0 || USE_BRAM_ROM != "TRUE")
begin
case(step_cnt)
`STEP1:
begin
if(SEL_S1_INSTRUCTION_WDR)
begin
case(WATCHDOG_CNT_WIDTH)
0:;
default: wdt_rst_out <= 1'b1;
endcase
end
if(SEL_S1_INSTRUCTION_IN_OUT)
begin
if(pgm_data_int[11])
begin
case({pgm_data_int[10:9], pgm_data_int[3:0]})
`ifdef USE_CCP_REG
6'h34:
begin
if(CORE_CONFIG == "XMEGA")
begin
CCP <= rd_data_d;
end
end
`endif
`ifdef USE_EXTENDED_RAMP_REGS
6'h38:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPD <= rd_data_d;
end
end
6'h39:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPX <= rd_data_d;
end
end
6'h3A:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPY <= rd_data_d;
end
end
6'h3B:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPZ <= rd_data_d;
end
end
6'h3C:
begin
if(CORE_CONFIG == "XMEGA")
begin
EIND <= rd_data_d;
end
end
`endif
6'h3D: //SPL
begin
if(CORE_CONFIG != "REDUCED")
begin
SP[7:0] <= rd_data_d;
end
end
6'h3E: //SPH
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
begin
SP[BUS_ADDR_DATA_WIDTH-1:8] <= rd_data_d[BUS_ADDR_DATA_WIDTH-1-8:0];
end
end
6'h3F: ALU_FLAGS <= rd_data_d;//SREG
endcase
end
end
if(CORE_CONFIG != "REDUCED")
begin
`ifdef USE_RAM_READ_DELAY
if(SEL_S1_INSTRUCTION_LDD_STD)
begin
if(~tmp_pgm_data_switched[9])
begin
if(ram_read_delay == `USE_RAM_READ_DELAY)
tmp_pgm_data <= pgm_data_int;
if(ram_read_delay)
begin
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
end
else
begin
ram_read_delay <= `USE_RAM_READ_DELAY;
end
end
end
`endif
`ifdef USE_LPM
if(SEL_S1_INSTRUCTION_LPM_R |
SEL_S1_INSTRUCTION_LPM_R_P |
SEL_S1_INSTRUCTION_LPM_ELPM)
begin
tmp_pgm_data <= pgm_data_int;
pgm_indirect_addr <= rd_data_d[BUS_ADDR_PGM_WIDTH-1:0];
case(USE_BRAM_ROM)
"TRUE" : PC <= PC;
endcase
step_cnt <= `STEP2;
end
`endif
if(SEL_S1_INSTRUCTION_POP_PUSH)
begin
if(tmp_pgm_data_switched[9])
SP <= SP_MINUS_ONE;
else
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
tmp_pgm_data <= pgm_data_int;
if(ram_read_delay)
begin
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
end
else
begin
ram_read_delay <= `USE_RAM_READ_DELAY;
SP <= SP_PLUS_ONE;
end
`else
SP <= SP_PLUS_ONE;
`endif
end
end
end/*!CORE_CONFIG == "REDUCED"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
if(SEL_S1_INSTRUCTION_IJMP)
begin
PC <= rd_data_d;
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
if(SEL_S1_INSTRUCTION_LDS_STS)
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
if((SEL_S1_INSTRUCTION_MUL |
SEL_S1_INSTRUCTION_MULS |
SEL_S1_INSTRUCTION_MULSU |
SEL_S1_INSTRUCTION_FMUL |
SEL_S1_INSTRUCTION_FMULS |
SEL_S1_INSTRUCTION_FMULSU) && (CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K"))
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
PC <= PC;
end
if(SEL_S1_INSTRUCTION_LD_ST_YZP |
SEL_S1_INSTRUCTION_LD_ST_YZN |
SEL_S1_INSTRUCTION_LD_ST_X |
SEL_S1_INSTRUCTION_LD_ST_XP |
SEL_S1_INSTRUCTION_LD_ST_XN)
begin
`ifdef USE_RAM_READ_DELAY
if((~pgm_data_int[9] && ram_read_delay == `USE_RAM_READ_DELAY) || (~tmp_pgm_data[9] && ram_read_delay != `USE_RAM_READ_DELAY))
begin
if(ram_read_delay)
begin
if(ram_read_delay == `USE_RAM_READ_DELAY)
tmp_pgm_data <= pgm_data_int;
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
end
else
begin
ram_read_delay <= `USE_RAM_READ_DELAY;
case(USE_BRAM_ROM)
"TRUE" :;
default: tmp_pgm_data <= pgm_data_int;
endcase
step_cnt <= `STEP2;
PC <= PC;
end
end
else
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
PC <= PC;
end
`else
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
PC <= PC;
`endif
end
end/*!CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")
begin
if(SEL_S1_INSTRUCTION_JMP)
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
end
if(SEL_S1_INSTRUCTION_RJMP)
begin
case(USE_BRAM_ROM)
"TRUE" :
begin
skip_execution <= 1'b1;
if(PC)
PC <= relative_offset_rjmp;
else
PC <= relative_offset_rjmp + 1;
end
default : PC <= relative_offset;
endcase
end
if((SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) |
(SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
SEL_S1_INSTRUCTION_RCALL |
interrupt_registered)
begin
step_cnt <= `STEP2;
tmp_pgm_data <= pgm_data_int;
SP <= SP_MINUS_ONE;
if((SEL_S1_INSTRUCTION_ICALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")) |
SEL_S1_INSTRUCTION_RCALL) PC <= PC;
else if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
begin
ALU_FLAGS[7] <= 1'b0;
PC <= PC;
end
end
if(SEL_S1_INSTRUCTION_RET |
SEL_S1_INSTRUCTION_RETI)
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
tmp_pgm_data <= pgm_data_int;
if(ram_read_delay)
begin
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
end
else
begin
step_cnt <= `STEP2;
SP <= SP_PLUS_ONE;
PGM_HI_TMP <= data_in_int;
ram_read_delay <= `USE_RAM_READ_DELAY;
end
`else
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
SP <= SP_PLUS_ONE;
PGM_HI_TMP <= data_in_int;
PC <= PC;
`endif
end
if(SEL_S1_INSTRUCTION_COND_BRANCH)
begin
if(~pgm_data_int[10] == ALU_FLAGS[pgm_data_int[2:0]])
begin
case(USE_BRAM_ROM)
"TRUE" :
begin
skip_execution <= 1'b1;
PC <= PC + {{10{pgm_data_int[9]}}, pgm_data_int[8:3]};
end
default : PC <= PC + {{10{pgm_data_int[9]}}, pgm_data_int[8:3]} + 16'h0001;
endcase
end
end
if(SEL_S1_INSTRUCTION_CPSE)
begin
case(USE_BRAM_ROM)
"TRUE" :
begin
if(rd_data_d != rd_data_r)
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
end
default:
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
endcase
end
if(SEL_S1_INSTRUCTION_SBRC_SBRS)
begin
case(USE_BRAM_ROM)
"TRUE" :
begin
if(rd_data_d[tmp_pgm_data[2:0]] != tmp_pgm_data[9])
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
end
default:
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
endcase
end
if(SEL_S1_INSTRUCTION_SBIC_SBIS)
begin
case(USE_BRAM_ROM)
"TRUE" :
begin
if(io_in_int[tmp_pgm_data[2:0]] != tmp_pgm_data[9])
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
end
default:
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
end
endcase
end
if(SEL_S1_INSTRUCTION_BLD_BST)
begin
if(pgm_data_int[9])
ALU_FLAGS[`ALU_FLAG_T] <= rd_data_d[pgm_data_int[2:0]];
end
end
`STEP2:
begin
if(CORE_CONFIG != "REDUCED")
begin
`ifdef USE_LPM
if(SEL_S2_INSTRUCTION_LPM_R |
SEL_S2_INSTRUCTION_LPM_R_P)
begin
case(USE_BRAM_ROM)
"TRUE":
begin
if(rom_read_delay)
begin
rom_read_delay <= 1'b0;
step_cnt <= `STEP2;
end
else
begin
rom_read_delay <= 1'b1;
skip_execution <= 1'b1;
end
end
endcase
PC <= PC;
end
`endif
end
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
if(SEL_S2_INSTRUCTION_LDS_STS)
begin
if(tmp_pgm_data[9])
begin
if(select_io_in_stam)
begin
case(pgm_data_int[(CORE_CONFIG == "XMEGA" ? 5 : 6):0])
`ifdef USE_CCP_REG
'h34 + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
CCP <= rd_data_d;
end
end
`endif
`ifdef USE_EXTENDED_RAMP_REGS
'h38 + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPD <= rd_data_d;
end
end
'h39 + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPX <= rd_data_d;
end
end
'h3A + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPY <= rd_data_d;
end
end
'h3B + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
RAMPZ <= rd_data_d;
end
end
'h3C + io_ports_displacement:
begin
if(CORE_CONFIG == "XMEGA")
begin
EIND <= rd_data_d;
end
end
`endif
'h3D + io_ports_displacement: //SPL
begin
if(CORE_CONFIG != "REDUCED")
begin
SP[7:0] <= rd_data_d;
end
end
'h3E + io_ports_displacement: //SPH
begin
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && BUS_ADDR_DATA_WIDTH > 8)
begin
SP[BUS_ADDR_DATA_WIDTH-1:8] <= rd_data_d[BUS_ADDR_DATA_WIDTH-1-8:0];
end
end
'h3F + io_ports_displacement: ALU_FLAGS <= rd_data_d;//SREG
endcase
end
end
else
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay)
begin
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
data_addr_int_tmp <= pgm_data_int;
end
else
begin
ram_read_delay <= `USE_RAM_READ_DELAY;
end
`endif
end
end
if(SEL_S2_INSTRUCTION_ICALL)
begin
SP <= SP_MINUS_ONE;
PC <= rd_data_d;// Backup the reg Z value to a 16bit temporary register because the reading section of REG's is asynchronous.
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
end/*!CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")
begin
if(SEL_S2_INSTRUCTION_JMP)
begin
PC <= pgm_data_int;
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
end
if((SEL_S2_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
interrupt_registered)
begin
SP <= SP_MINUS_ONE;
if(interrupt_registered && VECTOR_INT_TABLE_SIZE != 0)
begin
interrupt_registered <= 1'b0;
current_int_executed <= 1'b1;
if(CORE_CONFIG == "XMEGA")
begin
PC <= {current_int_vect_int, 1'b0};
end
else
begin
if(BUS_ADDR_PGM_WIDTH > 12)
PC <= {current_int_vect_int, 1'b0};
else
PC <= current_int_vect_int;
end
end
else
begin
PC <= pgm_data_int;
end
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
if(SEL_S2_INSTRUCTION_RCALL)
begin
SP <= SP_MINUS_ONE;
PC <= relative_offset;// If is a relative CALL load the offset to "TEMP16".
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
if(SEL_S2_INSTRUCTION_RET |
SEL_S2_INSTRUCTION_RETI)
begin
`ifdef USE_RAM_READ_DELAY
if(ram_read_delay == `USE_RAM_READ_DELAY)
tmp_pgm_data <= tmp_pgm_data;
if(ram_read_delay)
begin
ram_read_delay <= ram_read_delay - 1;
PC <= PC;
step_cnt <= step_cnt;
end
else
begin
`endif
SP <= SP_PLUS_ONE;
if(tmp_pgm_data[4])
ALU_FLAGS[7] <= 1'b1;
PC <= {PGM_HI_TMP, data_in_int};
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
`ifdef USE_RAM_READ_DELAY
ram_read_delay <= `USE_RAM_READ_DELAY;
end
`endif
end
if(SEL_S2_INSTRUCTION_CPSE)
begin
if(rd_data_d == rd_data_r)
begin
if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
SEL_S1_INSTRUCTION_LDS_STS |
SEL_S1_INSTRUCTION_JMP)
begin
PC <= PC_PLUS_TWO;
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
end
else
begin
case(USE_BRAM_ROM)
"TRUE" :;
default: PC <= PC;
endcase
end
end
if(SEL_S2_INSTRUCTION_SBRC_SBRS)
begin
if(rd_data_d[tmp_pgm_data[2:0]] == tmp_pgm_data[9])
begin
if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
SEL_S1_INSTRUCTION_LDS_STS |
SEL_S1_INSTRUCTION_JMP)
begin
PC <= PC_PLUS_TWO;
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
end
else
begin
case(USE_BRAM_ROM)
"TRUE" :;
default: PC <= PC;
endcase
end
end
if(SEL_S2_INSTRUCTION_SBIC_SBIS)
begin
if(io_in_int[tmp_pgm_data[2:0]] == tmp_pgm_data[9])
begin
if((SEL_S1_INSTRUCTION_CALL && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) |
SEL_S1_INSTRUCTION_LDS_STS |
SEL_S1_INSTRUCTION_JMP)
begin
PC <= PC_PLUS_TWO;
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b1;
endcase
end
end
else
begin
case(USE_BRAM_ROM)
"TRUE" :;
default: PC <= PC;
endcase
end
end
end
endcase
end
else
begin
case(USE_BRAM_ROM)
"TRUE" : skip_execution <= 1'b0;
endcase
end
end
end
 
mega_regs #(
.PLATFORM(PLATFORM)
)regs(
.rst(rst),
.clk(clk),
.rw_addr(rw_addr),
.rw_data(rw_data),
.rw_16bit(rw_16bit),
.write(write_to_reg),
.rd_addr_d(rd_addr_d),
.rd_data_d(rd_data_d),
.rd_16bit_d(rd_16bit_d),
.read_d(1'b1),
.rd_addr_r(rd_addr_r),
.rd_data_r(rd_data_r),
.rd_16bit_r(rd_16bit_r),
.read_r(1'b1)
);
 
mega_alu #(
.CORE_CONFIG(CORE_CONFIG)
)alu(
.inst(pgm_data_int[7:4]),
.in_addr_1(rd_addr_d),
.in_addr_2(rd_addr_r),
.in_1(alu_in_1),
.in_2(alu_in_2),
.out(alu_out),
.ALU_FLAG_C_IN(ALU_FLAGS[0]), //Carry Flag
.ALU_FLAG_Z_IN(ALU_FLAGS[1]), //Zero Flag
.ALU_FLAG_N_IN(ALU_FLAGS[2]), //Negative Flag
.ALU_FLAG_V_IN(ALU_FLAGS[3]), //Two's complement overflow indicator
.ALU_FLAG_S_IN(ALU_FLAGS[4]), //N?V for signed tests
.ALU_FLAG_H_IN(ALU_FLAGS[5]), //Half Carry Flag
.ALU_FLAG_T_IN(ALU_FLAGS[6]), //Transfer bit used by BLD and BST instructions
.ALU_FLAG_I_IN(ALU_FLAGS[7]), //Global Interrupt Enable/Disable Flag
 
.ALU_FLAG_C_OUT(ALU_FLAG_C_OUT), //Carry Flag
.ALU_FLAG_Z_OUT(ALU_FLAG_Z_OUT), //Zero Flag
.ALU_FLAG_N_OUT(ALU_FLAG_N_OUT), //Negative Flag
.ALU_FLAG_V_OUT(ALU_FLAG_V_OUT), //Two's complement overflow indicator
.ALU_FLAG_S_OUT(ALU_FLAG_S_OUT), //N?V for signed tests
.ALU_FLAG_H_OUT(ALU_FLAG_H_OUT), //Half Carry Flag
.ALU_FLAG_T_OUT(ALU_FLAG_T_OUT), //Transfer bit used by BLD and BST instructions
.ALU_FLAG_I_OUT(ALU_FLAG_I_OUT), //Global Interrupt Enable/Disable Flag
.SEL_INSTRUCTION_MOVW(SEL_S1_INSTRUCTION_MOVW),
.SEL_INSTRUCTION_MULS(SEL_S1_INSTRUCTION_MULS),
.SEL_INSTRUCTION_MULSU(SEL_S1_INSTRUCTION_MULSU),
.SEL_INSTRUCTION_FMUL(SEL_S1_INSTRUCTION_FMUL),
.SEL_INSTRUCTION_FMULS(SEL_S1_INSTRUCTION_FMULS),
.SEL_INSTRUCTION_FMULSU(SEL_S1_INSTRUCTION_FMULSU),
.SEL_INSTRUCTION_CPC(SEL_S1_INSTRUCTION_CPC),
.SEL_INSTRUCTION_CP(SEL_S1_INSTRUCTION_CP),
.SEL_INSTRUCTION_SBC(SEL_S1_INSTRUCTION_SBC),
.SEL_INSTRUCTION_SUB(SEL_S1_INSTRUCTION_SUB),
.SEL_INSTRUCTION_ADD(SEL_S1_INSTRUCTION_ADD),
.SEL_INSTRUCTION_ADC(SEL_S1_INSTRUCTION_ADC),
.SEL_INSTRUCTION_AND(SEL_S1_INSTRUCTION_AND),
.SEL_INSTRUCTION_ANDI_CBR(SEL_S1_INSTRUCTION_ANDI_CBR),
.SEL_INSTRUCTION_EOR(SEL_S1_INSTRUCTION_EOR),
.SEL_INSTRUCTION_OR(SEL_S1_INSTRUCTION_OR),
.SEL_INSTRUCTION_ORI_SBR(SEL_S1_INSTRUCTION_ORI_SBR),
.SEL_INSTRUCTION_MOV(SEL_S1_INSTRUCTION_MOV),
.SEL_INSTRUCTION_CPI(SEL_S1_INSTRUCTION_CPI),
.SEL_INSTRUCTION_SUBI(SEL_S1_INSTRUCTION_SUBI),
.SEL_INSTRUCTION_SBCI(SEL_S1_INSTRUCTION_SBCI),
.SEL_INSTRUCTION_LPM_R_P(SEL_S1_INSTRUCTION_LPM_R_P),
.SEL_INSTRUCTION_COM(SEL_S1_INSTRUCTION_COM),
.SEL_INSTRUCTION_NEG(SEL_S1_INSTRUCTION_NEG),
.SEL_INSTRUCTION_SWAP(SEL_S1_INSTRUCTION_SWAP),
.SEL_INSTRUCTION_INC(SEL_S1_INSTRUCTION_INC),
.SEL_INSTRUCTION_ASR(SEL_S1_INSTRUCTION_ASR),
.SEL_INSTRUCTION_LSR(SEL_S1_INSTRUCTION_LSR),
.SEL_INSTRUCTION_ROR(SEL_S1_INSTRUCTION_ROR),
.SEL_INSTRUCTION_SEx_CLx(SEL_S1_INSTRUCTION_SEx_CLx),
.SEL_INSTRUCTION_DEC(SEL_S1_INSTRUCTION_DEC),
.SEL_INSTRUCTION_ADIW(SEL_S1_INSTRUCTION_ADIW),
.SEL_INSTRUCTION_SBIW(SEL_S1_INSTRUCTION_SBIW),
.SEL_INSTRUCTION_MUL(SEL_S1_INSTRUCTION_MUL)
);
 
watchdog # (
.CNT_WIDTH(WATCHDOG_CNT_WIDTH)
)wdt_inst(
.rst(rst),
.clk(clk),
.wdt_clk(clk_wdt),
.wdt_rst_in(wdt_rst_out),
.wdt_rst_out(core_rst)
);
 
endmodule
/trunk/rtl/sim_i2c.v
0,0 → 1,147
/*
* This is the simulation file for TWI IP.
*
* Copyright (C) 2018 Iulian Gheorghiu
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
 
`timescale 1ns / 1ps
`include "io_s_h.v"
 
module sim_i2c(
output reg rst,
output reg clk,
output reg [15:0]addr,
output reg wr,
output reg rd,
output [7:0]bus_in,
output reg [7:0]bus_out,
output int_tx_cmpl,
output int_rx_cmpl,
output int_tx_rst,
output int_rx_rst,
inout scl,
inout sda
);
 
 
always #(1) clk <= ~clk; // clocking device
 
initial
begin
rst = 0;
clk = 1;
wr = 0;
rd = 0;
#2;
rst = 1;
#2;
rst = 0;
#4;
addr = `TWI_MASTER_BAUD;
bus_out = 'h1;
wr = 1;
#2;
addr = `TWI_MASTER_CTRLA;
bus_out = `TWI_MASTER_ENABLE_bm;
#2;
addr = `TWI_MASTER_DATA;
bus_out = 8'h55;
#2;
wr = 0;
bus_out = 'hz;
rd = 1;
addr = `TWI_MASTER_STATUS;
#2;
while(~bus_in[`TWI_MASTER_WIF_bp]) #2;
rd = 0;
#2;
wr = 1;
addr = `TWI_MASTER_DATA;
bus_out = 8'hAA;
#2;
wr = 0;
bus_out = 'hz;
rd = 1;
addr = `TWI_MASTER_STATUS;
#2;
while(~bus_in[`TWI_MASTER_WIF_bp]) #2;
rd = 0;
#2;
addr = `TWI_MASTER_CTRLC;
bus_out = `TWI_MASTER_CMD_REPSTART_gc;
#2;
wr = 1;
addr = `TWI_MASTER_CTRLC;
bus_out = `TWI_MASTER_CMD_RECVTRANS_gc;
#2;
wr = 0;
bus_out = 'hz;
rd = 1;
addr = `TWI_MASTER_STATUS;
#2;
while(~bus_in[`TWI_MASTER_RIF_bp]) #2;
addr = `TWI_MASTER_DATA;
#2;
rd = 0;
#2;
wr = 1;
addr = `TWI_MASTER_CTRLC;
bus_out = `TWI_MASTER_ACKACT_bm | `TWI_MASTER_CMD_RECVTRANS_gc;
#2;
wr = 0;
bus_out = 'hz;
rd = 1;
addr = `TWI_MASTER_STATUS;
#2;
while(~bus_in[`TWI_MASTER_RIF_bp]) #2;
addr = `TWI_MASTER_DATA;
#2;
rd = 0;
#2;
wr = 1;
addr = `TWI_MASTER_CTRLC;
bus_out = `TWI_MASTER_CMD_STOP_gc;
#2;
wr = 0;
bus_out = 'hz;
#10;
$finish;
end
 
twi_s #(
.DINAMIC_BAUDRATE("TRUE"),
.BAUDRATE_DIVIDER(19200),
.ADDRESS(0),
.BUS_ADDR_DATA_LEN(16)
)twi_inst(
.rst(rst),
.clk(clk),
.addr(addr),
.wr(wr),
.rd(rd),
.bus_in(bus_out),
.bus_out(bus_in),
.int_tx_cmpl(int_tx_cmpl),
.int_rx_cmpl(int_rx_cmpl),
.int_tx_rst(int_tx_rst),
.int_rx_rst(int_rx_rst),
.scl(scl),
.sda(sda)
);
endmodule
/trunk/rtl/sim_uc.v
0,0 → 1,456
/*
* This is the simulation file for Atmel XMEGA CPU IP.
*
* Copyright (C) 2017 Iulian Gheorghiu
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
 
`timescale 1ns / 1ps
//`include "ddr3_v.v"
/* For Attiny 26 */
//`define BUS_ADDR_PGM_LEN_SIM 11 /* < in address lines 2KWords */
//`define BUS_ADDR_DATA_LEN_SIM 8 /* < in address lines 256Bytes data address space */
//`define DATA_MEM_SIZE_LEN_SIM 7 /* < in address lines 128Bytes */
//`define DATA_ADDR_RESERVED_AT_BOTTOM_SIM 'd128 /* < in bytes ( 128 bytes to let space for IO usage )*/
 
/* For ATXmega */
`define BUS_ADDR_PGM_LEN_SIM 16 /* < in address lines 64KWords */
`define BUS_ADDR_DATA_LEN_SIM 16 /* < in address lines 64KBytes data address space */
`define DATA_MEM_SIZE_LEN_SIM 12 /* < in address lines 4KByte */
`define DATA_ADDR_RESERVED_AT_BOTTOM_SIM 'd8192 /* < in bytes ( 8192 bytes is the standard atxmega reserved address for IO usage )*/
 
`define USE_HDMI_OUTPUT
 
`define DDR3_ADDR_BUS_LEN 15
 
module sim_uc(
//`DDR3_TOP
);
 
//`DDR3_IO
 
reg rst = 0;
 
/*ddr3 ddr3_inst(
`DDR3_CONNECT
);*/
reg int1 = 0;
reg int2 = 0;
reg int3 = 0;
wire _int1 = int1;
wire _int2 = int2;
wire _int3 = int3;
wire [4:0]int = 0;
 
wire sys_rst;
 
wire [7:0]port_out;
wire [7:0]port_in = port_out;
wire UART_TXD;
wire UART_RXD = UART_TXD;
 
wire hdmi_tx_cec;
wire hdmi_tx_clk_n;
wire hdmi_tx_clk_p;
wire hdmi_tx_hpd;
wire hdmi_tx_rscl;
wire hdmi_tx_rsda;
wire [2:0]hdmi_tx_n;
wire [2:0]hdmi_tx_p;
 
 
 
reg core_clk = 0;
reg ram_clk = 0;
always #(1) ram_clk <= ~ram_clk; // clocking device
always @ (posedge ram_clk)
begin
core_clk <= ~core_clk;
end
 
wire lcd_clk = core_clk;
//wire pgm_re;
wire [`BUS_ADDR_PGM_LEN_SIM-1:0] pgm_addr;
wire [15:0] pgm_data;
wire data_re;
wire data_we;
wire [`BUS_ADDR_DATA_LEN_SIM-1:0] data_addr;
wire [7:0]data_in;
wire [7:0]data_out;
 
wire io_re;
wire io_we;
wire [5:0] io_addr;
wire [7:0] io_in;
wire [7:0] io_out;
 
//assign data_addr = data_re | data_we ? 'bz : 0;
wire ram_data_sel = data_addr >= `DATA_ADDR_RESERVED_AT_BOTTOM_SIM;
wire [`BUS_ADDR_DATA_LEN_SIM-1:0]ram_offset = `DATA_ADDR_RESERVED_AT_BOTTOM_SIM;
wire [`DATA_MEM_SIZE_LEN_SIM-1:0]ram_addr_bus = data_addr - ram_offset;
 
wire rtc_int;
wire int_pio_a;
wire int_pio_b;
wire int_pio_c;
wire int_pio_d;
wire int_pio_e;
wire int_pio_f;
wire int_uart_a_rx_rcv;
wire int_uart_a_tx_compl;
wire int_uart_a_tx_buff_empty;
wire int_spi_a;
wire [10:0]int_rst;
 
initial begin
rst = 0;
#1;
rst = 1;
#1;
rst = 0;
//port_out = 8'haa;
#110000;
int1 = 1;
//int2 = 1;
//int3 = 1;
#20;
int1 = 0;
int2 = 0;
int3 = 0;
#1200000;
$finish;
end
 
rtc_s # (
.ADDRESS('h40),
.BUS_ADDR_DATA_LEN(`BUS_ADDR_DATA_LEN_SIM),
.CNT_SIZE(32)
) rtc (
.rst(sys_rst),
.clk(core_clk),
.addr(data_addr),
.wr(data_we),
.rd(data_re),
.bus_in(data_out),
.bus_out(data_in),
.int(rtc_int),
.int_rst(int_rst[0])
);
 
pio_s # (
.DINAMIC_IN_OUT_CONFIG("TRUE"),
.IN_OUT_MASK_CONFIG(8'h00),
.USE_INTERRUPTS("TRUE"),
.DINAMIC_INTERRUPT_CONFIG("TRUE"),
.INTERRUPT_MASK_CONFIG(8'h07),
.INTERRUPT_UP_DN_EDGE_DETECT(8'h07),
.INTERRUPT_BOTH_EDGES_DETECT_MASK(8'h00),
.BUS_KEPPER_EN_MASK(8'b00000000),
.BUS_PULL_UP_EN_MASK(8'b00000000),
.BUS_PULL_DN_EN_MASK(8'b00000000),
.ADDRESS('h60),
.BUS_ADDR_DATA_LEN(`BUS_ADDR_DATA_LEN_SIM)
) pio_port_A (
.rst(sys_rst),
.clk(core_clk),
.addr(data_addr),
.wr(data_we),
.rd(data_re),
.bus_in(data_out),
.bus_out(data_in),
.io({int, _int3, _int2, _int1}),
.int(int_pio_a),
.int_rst(int_rst[1])
);
 
pio_s # (
.DINAMIC_IN_OUT_CONFIG("FALSE"),
.IN_OUT_MASK_CONFIG(8'h00),
.USE_INTERRUPTS("FALSE"),
.DINAMIC_INTERRUPT_CONFIG("FALSE"),
.INTERRUPT_MASK_CONFIG(8'h00),
.INTERRUPT_UP_DN_EDGE_DETECT(8'h00),
.INTERRUPT_BOTH_EDGES_DETECT_MASK(8'h00),
.BUS_KEPPER_EN_MASK(8'b00000000),
.BUS_PULL_UP_EN_MASK(8'b00000000),
.BUS_PULL_DN_EN_MASK(8'b00000000),
.ADDRESS('h80),
.BUS_ADDR_DATA_LEN(`BUS_ADDR_DATA_LEN_SIM)
) pio_port_B (
.rst(sys_rst),
.clk(core_clk),
.addr(data_addr),
.wr(data_we),
.rd(data_re),
.bus_in(data_out),
.bus_out(data_in),
.io(port_in),
.int(int_pio_b),
.int_rst(int_rst[2])
);
 
pio_s # (
.DINAMIC_IN_OUT_CONFIG("FALSE"),
.IN_OUT_MASK_CONFIG(8'hFF),
.USE_INTERRUPTS("FALSE"),
.DINAMIC_INTERRUPT_CONFIG("FALSE"),
.INTERRUPT_MASK_CONFIG(8'h00),
.INTERRUPT_UP_DN_EDGE_DETECT(8'h00),
.INTERRUPT_BOTH_EDGES_DETECT_MASK(8'h00),
.BUS_KEPPER_EN_MASK(8'b00000000),
.BUS_PULL_UP_EN_MASK(8'b00000000),
.BUS_PULL_DN_EN_MASK(8'b00000000),
.ADDRESS('hA0),
.BUS_ADDR_DATA_LEN(`BUS_ADDR_DATA_LEN_SIM)
) pio_port_C (
.rst(sys_rst),
.clk(core_clk),
.addr(data_addr),
.wr(data_we),
.rd(data_re),
.bus_in(data_out),
.bus_out(data_in),
.io(port_out),
.int(int_pio_c),
.int_rst(int_rst[3])
);
//`ifdef _0_
uart_s # (
.BAUDRATE_COUNTER_LENGTH(12),
.DINAMIC_BAUDRATE("TRUE"),
.BAUDRATE_DIVIDER((1000 / 24) / 16 / 19200),
.ADDRESS('hC0),
.BUS_ADDR_DATA_LEN(`BUS_ADDR_DATA_LEN_SIM)
) uart_A (
.rst(sys_rst),
.clk(core_clk),
.addr(data_addr),
.wr(data_we),
.rd(data_re),
.bus_in(data_out),
.bus_out(data_in),
.int_rx_rcv(int_uart_a_rx_rcv),
.int_tx_compl(int_uart_a_tx_compl),
.int_tx_buff_empty(int_uart_a_tx_buff_empty),
.tx(UART_TXD),
.rx(UART_RXD)
);
 
wire oled_sclk;
wire oled_sdin;
 
spi_s #(
.DINAMIC_BAUDRATE("TRUE"),
.BAUDRATE_DIVIDER(8),
.ADDRESS('h600),
.BUS_ADDR_DATA_LEN(`BUS_ADDR_DATA_LEN_SIM)
)spi_A(
.rst(sys_rst),
.clk(core_clk),
.addr(data_addr),
.wr(data_we),
.rd(data_re),
.bus_in(data_out),
.bus_out(data_in),
.int(int_spi_a),
 
.sck(oled_sclk),/* SPI 'sck' signal (output) */
.mosi(oled_sdin),/* SPI 'mosi' signal (output) */
.miso(1'b1),/* SPI 'miso' signal (input) */
.ss()/* SPI 'ss' signal (if send buffer is maintained full the ss signal will not go high between between transmit chars)(output) */
);
 
wire ja_scl;
wire ja_sda;
 
twi_s #(
.DINAMIC_BAUDRATE("TRUE"),
.BAUDRATE_DIVIDER(255),
.ADDRESS('h800),
.BUS_ADDR_DATA_LEN(`BUS_ADDR_DATA_LEN_SIM)
)twi_inst(
.rst(sys_rst),
.clk(core_clk),
.addr(data_addr),
.wr(data_we),
.rd(data_re),
.bus_in(data_out),
.bus_out(data_in),
.int_tx_cmpl(),
.int_rx_cmpl(),
.int_tx_rst(),
.int_rx_rst(),
.scl(ja_scl),
.sda(ja_sda)
);
wire lcd_h_int;
wire lcd_v_int;
wire lcd_de;
wire [7:0]ja_int;
wire [7:0]jb_int;
wire [7:0]jc_int;
wire lcd_clk_10;
`ifndef USE_HDMI_OUTPUT
assign ja = {ja_int[7:1], lcd_clk_10};
assign jb = {jb_int[7:1], lcd_h_int};
assign jc = {jc_int[7:1], lcd_v_int};
`endif
 
lcd # (
.MASTER("TRUE"),
.DEBUG(""),//"PATERN_RASTER"
.DISPLAY_CFG("1280_720_60_DISPLAY_74_25_Mhz"),
 
.ADDRESS('hE0),
.BUS_VRAM_ADDR_LEN(24),
.BUS_VRAM_DATA_LEN(8),
.BUS_ADDR_DATA_LEN(16),
.DINAMIC_CONFIG("FALSE"),
.VRAM_BASE_ADDRESS_CONF(0),
/* This timings are for AT070TN92 LCD display module but is not tacken in account because we will load a default setup with DISPLAY_CFG parameter.*/
.H_RES_CONF(720),
.H_BACK_PORCH_CONF(138),
.H_FRONT_PORCH_CONF(16),
.H_PULSE_WIDTH_CONF(62),
.V_RES_CONF(480),
.V_BACK_PORCH_CONF(45),
.V_FRONT_PORCH_CONF(9),
.V_PULSE_WIDTH_CONF(6),
.PIXEL_SIZE_CONF(16),
.HSYNK_INVERTED_CONF(1'b0),
.VSYNK_INVERTED_CONF(1'b0),
.DATA_ENABLE_INVERTED_CONF(1'b0),
.DEDICATED_VRAM_SIZE(800 * 480)
)lcd_inst(
.rst(sys_rst),
.ctrl_clk(core_clk),
.ctrl_addr(data_addr),
.ctrl_wr(data_we),
.ctrl_rd(data_re),
.ctrl_data_in(data_out),
.ctrl_data_out(data_in),
 
.vmem_addr(ram_addr_bus),
.vmem_in(data_out),
.vmem_out(data_in),
.vmem_rd(1'b0),
.vmem_wr(data_we & ram_data_sel),
`ifdef USE_HDMI_OUTPUT
.lcd_clk(lcd_clk_10),
`else
.lcd_clk(lcd_clk),
`endif
.lcd_h_synk(lcd_h_int),
.lcd_v_synk(lcd_v_int),
.lcd_r(ja_int),
.lcd_g(jb_int),
.lcd_b(jc_int),
.lcd_de(lcd_de)
);
 
`ifdef USE_HDMI_OUTPUT
hdmi_out # (
.PLATFORM("XILINX_ARTIX_7")
)hdmi_out_inst(
.rst(sys_rst),
.clk(lcd_clk),
.hdmi_tx_cec(hdmi_tx_cec),
.hdmi_tx_clk_n(hdmi_tx_clk_n),
.hdmi_tx_clk_p(hdmi_tx_clk_p),
.hdmi_tx_hpd(hdmi_tx_hpd),
.hdmi_tx_rscl(hdmi_tx_rscl),
.hdmi_tx_rsda(hdmi_tx_rsda),
.hdmi_tx_n(hdmi_tx_n),
.hdmi_tx_p(hdmi_tx_p),
.lcd_clk_out(lcd_clk_10),
.lcd_h_synk(lcd_h_int),
.lcd_v_synk(lcd_v_int),
.lcd_r('hAA),
.lcd_g('hDB),
.lcd_b('h24),
.lcd_de(lcd_de)
);
`endif
//`endif //!_0_
 
rom #(
.ADDR_ROM_BUS_WIDTH(`BUS_ADDR_PGM_LEN_SIM),
.ROM_PATH("core1ROM.mem"),
.SYNCHRONOUS("FALSE")
)rom(
.clk(core_clk),
.a(pgm_addr),
.d(pgm_data)
);
 
ram #(
.ADDR_BUS_WIDTH(`DATA_MEM_SIZE_LEN_SIM),
.RAM_PATH(""),
.SYNCHRONOUS("TRUE")
)ram(
.clk(core_clk),
.re(data_re & ram_data_sel),
.we(data_we & ram_data_sel),
.a(ram_addr_bus),
.d_in(data_out),
.d_out(data_in)
);
mega_core #(
.CORE_CONFIG("XMEGA"),// Supported: "REDUCED", "MINIMAL", "CLASSIC_8K", "CLASSIC_128K", "ENHANCED_8K", "ENHANCED_128K", "ENHANCED_4M", "XMEGA"
.BUS_ADDR_PGM_WIDTH(`BUS_ADDR_PGM_LEN_SIM),
.BUS_ADDR_DATA_WIDTH(`BUS_ADDR_DATA_LEN_SIM),
.USE_BRAM_ROM("FALSE"),
.WATCHDOG_CNT_WIDTH(21),/* If is 0 the watchdog is disabled */
.VECTOR_INT_TABLE_SIZE(10),
.STORE_INTERUPTS("FALSE"),
.MAP_REGS_IN_TO_SRAM_SECTION("FALSE")
)core(
.rst(rst),
.sys_rst(sys_rst),/* Output reset provided by core thru watchdog to the rest of the system */
.clk(core_clk),
.clk_wdt(core_clk),
.pgm_addr(pgm_addr),
.pgm_data(pgm_data),
.data_re(data_re),
.data_we(data_we),
.data_addr(data_addr),
.data_in(data_in),
.data_out(data_out),
.io_re(io_re),
.io_we(io_we),
.io_addr(io_addr),
.io_in(io_in),
.io_out(io_out),
.int_sig({int_uart_a_tx_buff_empty, int_uart_a_tx_compl, int_uart_a_rx_rcv, int_spi_a, int_pio_f, int_pio_e, int_pio_d, int_pio_c, int_pio_b, int_pio_a, rtc_int}),
.int_rst(int_rst),
.wdt_rst_out()
);
 
 
endmodule

powered by: WebSVN 2.1.0

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