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 |
|
|