URL
https://opencores.org/ocsvn/neo430/neo430/trunk
Subversion Repositories neo430
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 195 to Rev 194
- ↔ Reverse comparison
Rev 195 → Rev 194
/neo430/trunk/neo430/README.md
3,9 → 3,7
[![Build Status](https://travis-ci.com/stnolting/neo430.svg?branch=master)](https://travis-ci.com/stnolting/neo430) |
[![last commit](https://img.shields.io/github/last-commit/stnolting/neo430)](https://github.com/stnolting/neo430/commits/master) |
[![issues](https://img.shields.io/github/issues/stnolting/neo430)](https://github.com/stnolting/neo430/issues) |
[![release](https://img.shields.io/github/v/release/stnolting/neo430)](https://github.com/stnolting/neo430/releases) |
[![license](https://img.shields.io/github/license/stnolting/neo430)](https://github.com/stnolting/neo430/blob/master/LICENSE) |
[![documentary](https://img.shields.io/badge/datasheet-neo430.pdf-blue)](https://raw.githubusercontent.com/stnolting/neo430/master/doc/NEO430.pdf) |
|
## Table of Content |
|
13,10 → 11,9
* [Processor Features](#Processor-Features) |
* [Differences to the Original MSP430 Processors](#Differences-to-the-Original-MSP430-Processors) |
* [Top Entity](#Top-Entity) |
* [FPGA Implementation Results](#FPGA-Implementation-Results) |
* [HW-SW Ecosystem](#HW-SW-Ecosystem) |
* [Implementation Results](#Implementation-Results) |
* [Performance](#Performance) |
* [**Quick Start**](#Quick-Start) |
* [Quick Start](#Quick-Start) |
* [Change Log](#Change-Log) |
* [Contact](#Contact) |
* [Disclaimer, Proprietary and Legal Notice](#Disclaimer-Proprietary-and-Legal-Notice) |
63,7 → 60,7
- 16-bit open source soft-core microcontroller-like processor system |
- Full support of the original [MSP430 instruction set architecture](https://raw.githubusercontent.com/stnolting/neo430/master/doc/instruction_set.pdf) |
- Code-efficient CISC-like instruction capabilities |
- Tool chain based on free [TI msp430-gcc compiler](http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/latest/index_FDS.html "TI `msp430-gcc` compiler") (also available here [on github](https://github.com/stnolting/msp430-gcc)) |
- Tool chain based on free [TI msp430-gcc compiler](http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/latest/index_FDS.html "TI `msp430-gcc` compiler") |
- Application compilation scripts ([makefiles](https://github.com/stnolting/neo430/blob/master/sw/example/blink_led/Makefile)) for Windows Powershell / Windows Subsystem for Linux / native Linux |
- Software requirements (regardless of platform): |
- TI `msp430-gcc` compiler |
75,7 → 72,7
- Internal [DMEM](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_dmem.vhd) (RAM, for data) and [IMEM](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_imem.vhd) (RAM or ROM, for code), configurable sizes |
- Customizable processor hardware configuration: |
- Optional multiplier/divider unit ([MULDIV](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_muldiv.vhd)) |
- Optional high-precision timer ([TIMER](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_timer.vhd)) |
- Optional high-precision timer ([TIMER](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_timer.vhd)) with arbitrary frequency generator output |
- Optional universal asynchronous receiver and transmitter ([UART](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_uart.vhd)) |
- Optional serial peripheral interface ([SPI](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_spi.vhd)), 8 or 16 bit tansfer data size, 6 dedicated CS lines |
- Optional I2C-compatible two wire serial interface ([TWI](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_twi.vhd)) supporting clock stretching |
87,7 → 84,6
- Optional 4 channel PWM controller with 4 or 8 bit resolution ([PWM](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_pwm.vhd)) |
- Optional Galois Ring Oscillator (GARO) based true random number generator ([TRNG](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_trng.vhd)) with de-biasing and internal post-processing |
- Optional external interrupts controller with 8 independent channels ([EXIRQ](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_exirq.vhd)), can also be used for software-triggered interrupts (traps, breakpoints, etc.) |
- Optional NCO-based programmable frequency generator with 3 independent channels ([FREQ_GEN](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_freq_gen.vhd)) |
- Optional internal [bootloader](https://github.com/stnolting/neo430/blob/master/sw/bootloader/bootloader.c) (2kB ROM) with serial user console and automatic boot from external SPI flash (like the FPGA configuration storage) |
|
|
119,7 → 115,6
If you need a top entity with resolved signals, take a look at the [top_templates](https://github.com/stnolting/neo430/blob/master/rtl/top_templates) folder. |
These alternative top entities also support AXI or Avalon connectivity. |
|
|
### Generics |
|
| Generic Name | Type | Default Value | Function | |
128,147 → 123,114
| IMEM_SIZE | natural | 4*1024 | Size of internal instruction memory in bytes (max 48 kB) | |
| DMEM_SIZE | natural | 2*1024 | Size of internal data memory in bytes (max 12 kB) | |
| USER_CODE | std_ulogic_vector(15:0) | x"0000" | 16-bit custom user code, can be read by user software | |
| MULDIV_USE | boolean | true | Implement multiplier/divider unit (MULDIV) | |
| WB32_USE | boolean | true | Implement Wishbone interface adapter (WB32) | |
| WDT_USE | boolean | true | Implement watchdog timer (WDT) | |
| GPIO_USE | boolean | true | Implement general purpose parallel in/out port (GPIO) | |
| TIMER_USE | boolean | true | Implement high-precision timer (TIMER) | |
| UART_USE | boolean | true | Implement UART serial communication unit (UART) | |
| CRC_USE | boolean | true | Implement checksum computation unit (CRC16/32) | |
| CFU_USE | boolean | false | Implement custom functions unit (CFU) | |
| PWM_USE | boolean | true | Implement pulse width controller (PWM) | |
| TWI_USE | boolean | true | Implement two wire serial interface unit (TWI) | |
| SPI_USE | boolean | true | Implement serial peripheral interface unit (SPI) | |
| TRNG_USE | boolean | false | Implement true random number generator (TRNG) | |
| EXIRQ_USE | boolean | true | Implement external interrupts controller (EXIRQ) | |
| FREQ_GEN_USE | boolean | true | Implement programmable frequency generator (FREQ_GEN) | |
| MULDIV_USE | boolean | true | Implement multiplier/divider unit | |
| WB32_USE | boolean | true | Implement Wishbone interface adapter | |
| WDT_USE | boolean | true | Implement watchdog timer | |
| GPIO_USE | boolean | true | Implement general purpose parallel in/out port | |
| TIMER_USE | boolean | true | Implement high-precision timer | |
| UART_USE | boolean | true | Implement UART serial communication unit | |
| CRC_USE | boolean | true | Implement checksum computation unit | |
| CFU_USE | boolean | false | Implement custom functions unit | |
| PWM_USE | boolean | true | Implement pulse width controller | |
| TWI_USE | boolean | true | Implement two wire serial interface unit | |
| SPI_USE | boolean | true | Implement serial peripheral interface unit | |
| TRNG_USE | boolean | false | Implement true random number generator | |
| EXIRQ_USE | boolean | true | Implement external interrupts controller | |
| BOOTLD_USE | boolean | true | Implement and auto-start internal bootloader | |
| IMEM_AS_ROM | boolean | false | Implement internal instruction memory as read-only | |
|
|
### Signals |
|
Note regarding unused unit's IO: Connect all unused inputs to low and leave all unused outputs 'open'. |
Signal driections are seen from the processor. |
|
| Signal Name | Width | Direction | HW Unit | Function | |
|:-------------|:-----:|:---------:|:--------:|:---------------------------------------------------------| |
| clk_i | 1 | In | - | Global clock line; all FFs triggering on rising edge | |
| rst_i | 1 | In | - | Global reset, low-active | |
| gpio_o | 16 | Out | GPIO | General purpose parallel output | |
| gpio_i | 16 | In | GPIO | General purpose parallel input | |
| pwm_o | 4 | Out | PWM | Pulse width modulation channels | |
| timer_fg_o | 1 | Out | FREQ_GEN | Programmable frequency generator output | |
| uart_txd_o | 1 | Out | UART | UART serial transmitter | |
| uart_rxd_i | 1 | In | UART | UARt serial receiver | |
| spi_sclk_o | 1 | Out | SPI | SPI master clock | |
| spi_mosi_o | 1 | Out | SPI | SPI serial data output | |
| spi_miso_i | 1 | In | SPI | SPI serial data input | |
| spi_cs_o | 8 | Out | SPI | SPI chip select lines (active-low) | |
| twi_sda_io | 1 | InOut | TWI | TWI master serial data line (external pull-up required) | |
| twi_scl_io | 1 | InOut | TWI | TWI master serial clock line (external pull-up required) | |
| wb_adr_o | 32 | Out | WB32 | Wishbone slave address | |
| wb_dat_i | 32 | In | WB32 | Wishbone write data | |
| wb_dat_o | 32 | Out | WB32 | Wishbone read data | |
| wb_we_o | 1 | Out | WB32 | Wishbone write enable | |
| wb_sel_o | 1 | Out | WB32 | Wishbone byte enable | |
| wb_stb_o | 1 | Out | WB32 | Wishbone strobe | |
| wb_cyc_o | 1 | Out | WB32 | Wishbone valid cycle | |
| wb_ack_i | 1 | In | WB32 | Wishbone transfer acknowledge | |
| ext_irq_i | 8 | In | EXIRQ | Interrupt request lines, high-active | |
| ext_ack_o | 8 | Out | EXIRQ | Interrupt acknowledge, high-active, single-shot | |
| Signal Name | Width | Direction | HW Unit | Function | |
|:-------------|:-----:|:---------:|:-------:|:---------------------------------------------------------| |
| clk_i | 1 | In | - | Global clock line; all FFs triggering on rising edge | |
| rst_i | 1 | In | - | Global reset, low-active | |
| gpio_o | 16 | Out | GPIO | General purpose parallel output | |
| gpio_i | 16 | In | GPIO | General purpose parallel input | |
| pwm_o | 4 | Out | PWM | Pulse width modulation channels | |
| timer_fg_o | 1 | Out | TIMER | Arbitrar frequency generator output | |
| uart_txd_o | 1 | Out | UART | UART serial transmitter | |
| uart_rxd_i | 1 | In | UART | UARt serial receiver | |
| spi_sclk_o | 1 | Out | SPI | SPI master clock | |
| spi_mosi_o | 1 | Out | SPI | SPI serial data output | |
| spi_miso_i | 1 | In | SPI | SPI serial data input | |
| spi_cs_o | 8 | Out | SPI | SPI chip select lines (active-low) | |
| twi_sda_io | 1 | InOut | TWI | TWI master serial data line | |
| twi_scl_io | 1 | InOut | TWI | TWI master serial clock line | |
| wb_adr_o | 32 | Out | WB32 | Slave address | |
| wb_dat_i | 32 | In | WB32 | Write data | |
| wb_dat_o | 32 | Out | WB32 | Read data | |
| wb_we_o | 1 | Out | WB32 | Write enable | |
| wb_sel_o | 1 | Out | WB32 | Byte enable | |
| wb_stb_o | 1 | Out | WB32 | Strobe | |
| wb_cyc_o | 1 | Out | WB32 | Valid cycle | |
| wb_ack_i | 1 | In | WB32 | Transfer acknowledge | |
| ext_irq_i | 8 | In | EXIRQ | Interrupt request lines, high-active | |
| ext_ack_o | 8 | Out | EXIRQ | Interrupt acknowledge, high-active, single-shot | |
|
|
|
## FPGA Implementation Results |
## Implementation Results |
|
Mapping results generated for HW version 0x0406. The full (default) hardware configuration includes |
Mapping results generated for HW version 0x0320. The full (default) hardware configuration includes |
all optional processor modules (excluding the CFU and the TRNG), an IMEM size of 4kB and a DMEM |
size of 2kB. The minimal configuration only includes the CPU (including IMEM and DMEM) and the GPIO module. |
Results generated with Xilinx Vivado 2019.2, Intel Quartus Prime Lite 17.1 and Lattice Radiant 1.1 (Synplify) |
size of 2kB. The minimal configuration only includes the CPU and the GPIO module. Results generated with Xilinx Vivado 2017.3, |
Intel Quartus Prime Lite 17.1 and Lattice Radiant 1.1 (Synplify) |
|
| __Xilinx Artix-7 (XC7A35TICSG324-1L)__ | LUTs | FFs | BRAMs | DSPs | f_max* | |
|:---------------------------------------|:---------:|:------------:|:--------:|:------:|:-------:| |
| Full (default) configuration: | 1036 (5%) | 1144 (2.75%) | 2.5 (5%) | 0 (0%) | 100 MHz | |
| Minimal configuration (CPU + GPIO): | 576 (3%) | 266 (0.6%) | 1 (2%) | 0 (0%) | 100 MHz | |
| __Xilinx Artix-7 (XC7A35TICSG324-1L)__ | LUTs | FFs | BRAMs | DSPs | f_max* | |
|:----------------------------------------|:----------:|:-----------:|:--------:|:------:|:-------:| |
| Full (default) configuration: | 983 (4.7%) | 1014 (2.5%) | 2.5 (5%) | 0 (0%) | 100 MHz | |
| Minimal configuration (CPU + GPIO): | 685 (3.3%) | 290 (0.7%) | 1 (2%) | 0 (0%) | 100 MHz | |
|
| __Intel Cyclone IV (EP4CE22F17C6)__ | LUTs | FFs | Memory bits | DSPs | f_max | |
|:------------------------------------|:---------:|:---------:|:-----------:|:------:|:-------:| |
| Full (default) configuration: | 1869 (8%) | 1137 (5%) | 65800 (11%) | 0 (0%) | 121 MHz | |
| Minimal configuration (CPU + GPIO): | 590 (3%) | 230 (1%) | 49408 (8%) | 0 (0%) | 122 MHz | |
| __Intel Cyclone IV (EP4CE22F17C6)__ | LUTs | FFs | Memory bits | DSPs | f_max | |
|:-------------------------------------|:---------:|:--------:|:-----------:|:------:|:-------:| |
| Full (default) configuration: | 1648 (7%) | 990 (4%) | 65800 (11%) | 0 (0%) | 122 MHz | |
| Minimal configuration (CPU + GPIO): | 596 (3%) | 233 (1%) | 49408 (8%) | 0 (0%) | 126 MHz | |
|
| __Lattice iCE40 UltraPlus** (iCE40UP5K-SG48I)__ | LUTs | FFs | EBRs | DSPs | SRAMs | f_max* | |
|:-------------------------------------------------|:----------:|:----------:|:-------:|:------:|:-------:|:---------:| |
| Full (default) configuration: | 3928 (74%) | 1923 (36%) | 9 (30%) | 0 (0%) | 2 (50%) | 20.25 MHz | |
| Minimal configuration (CPU + GPIO + Bootloader): | 1812 (34%) | 755 (14%) | 4 (13%) | 0 (0%) | 2 (50%) | 20.25 MHz | |
| __Lattice iCE40 UltraPlus (iCE40UP5K-SG48I)__ | LUTs | FFs | EBRs | DSPs | SRAMs | f_max* | |
|:-----------------------------------------------|:----------:|:----------:|:--------:|:------:|:------:|:------:| |
| Full (default) configuration: | 2600 (49%) | 1152 (21%) | 16 (53%) | 0 (0%) | 0 (0%) | 20 MHz | |
| Minimal configuration (CPU + GPIO): | 1365 (25%) | 493 (9%) | 12 (40%) | 0 (0%) | 0 (0%) | 20 MHz | |
|
*) Constrained |
|
**) Using optimized memory modules for IMEM (32kB) & DMEM(12kB) from the `rtl\fpga_specific\lattice_ice40up` folder |
|
|
### Device Utilization by Entity |
|
The following table shows the required resources for each module of the NEO430 processor system. Note that the provided |
numbers only represent a coarse overview as logic elements might be merged and optimized beyond entity boundaries. |
numbers only represent a coarse overview as logic elements might be merged and optimized beyond module boundaries. |
|
Mapping results generated for HW version 0x0406. The full (default) hardware configuration includes all optional |
Mapping results generated for HW version 0x0320. The full (default) hardware configuration includes all optional |
processor modules (excluding the CFU but including the TRNG), an IMEM size of 4kB and a DMEM size of |
2kB. Results were generated using Intel Quartus Prime Lite 17.1. |
|
| __Intel Cyclone IV (EP4CE22F17C6)__ | LUTs | FFs | Memory Bits | DSPs | |
|:---------------------------------------|:----:|:---:|:-----------:|:----:| |
|:---------------------------------------|:----:|:---:|:------------|:----:| |
| Bootloader Memory (Boot ROM, 2kB) | 2 | 1 | 16384 | 0 | |
| Central Processing Unit (CPU) | 525 | 169 | 264 | 0 | |
| Checksum Unit (CRC) | 111 | 94 | 0 | 0 | |
| Central Processing Unit (CPU) | 506 | 171 | 256 | 0 | |
| Checksum Unit (CRC) | 110 | 94 | 0 | 0 | |
| Custom Functions Unit (CFU)* | - | - | - | - | |
| Data Memory (DMEM, 2kB) | 5 | 1 | 16384 | 0 | |
| External Interrupts Controller (EXIRQ) | 70 | 55 | 0 | 0 | |
| Frequency Generator (FREQ_GEN) | 140 | 130 | 0 | 0 | |
| GPIO Port Unit (GPIO) | 50 | 45 | 0 | 0 | |
| High-Precision Timer (TIMER) | 66 | 57 | 0 | 0 | |
| Instruction Memory (IMEM, 4kB) | 5 | 1 | 32768 | 0 | |
| Multiplier & Divider (MULDIV) | 209 | 134 | 0 | 0 | |
| Pulse-Width Modulation Unit (PWM) | 96 | 66 | 0 | 0 | |
| Serial Peripheral Interface (SPI) | 82 | 59 | 0 | 0 | |
| System Info Memory (SYSCONFIG) | 12 | 11 | 0 | 0 | |
| True Random Number Generator (TRNG) | 92 | 76 | 0 | 0 | |
| Two Wire Interface (TWI) | 78 | 43 | 0 | 0 | |
| Universal Asynchronous Rx/Tx (UART) | 130 | 91 | 0 | 0 | |
| Watchdog Timer (WDT) | 53 | 37 | 0 | 0 | |
| Wishbone Interface (WB32) | 129 | 117 | 0 | 0 | |
| Data Memory (DMEM, 2kB) | 6 | 1 | 16384 | 0 | |
| External Interrupts Controller (EXIRQ) | 72 | 54 | 0 | 0 | |
| High-Precision Timer (TIMER) | 70 | 55 | 0 | 0 | |
| Instruction Memory (IMEM, 4kB) | 4 | 1 | 32768 | 0 | |
| IO Port Unit (GPIO) | 49 | 45 | 0 | 0 | |
| Multiplier & Divider (MULDIV) | 184 | 131 | 0 | 0 | |
| Pulse-Width Modulation Unit (PWM) | 80 | 66 | 0 | 0 | |
| Serial Peripheral Interface (SPI) | 57 | 43 | 0 | 0 | |
| System Info Memory (SYSCONFIG) | 15 | 13 | 0 | 0 | |
| True Random Number Generator (TRNG) | 44 | 36 | 0 | 0 | |
| Two Wire Interface (TWI) | 80 | 41 | 0 | 0 | |
| Universal Asynchronous Rx/Tx (UART) | 129 | 89 | 0 | 0 | |
| Watchdog TImer (WDT) | 49 | 36 | 0 | 0 | |
| Wishbone Interface (WB32) | 128 | 117 | 0 | 0 | |
|
*) Hardware requirements defined by user application |
|
|
|
## HW-SW Ecosystem |
|
The NEO430 Processor porjects provides driver libraries for the CPU itself and all included peripheral modules. These libraries |
provide a certain level of hardware abstraction and allow an easier usage of the different hardware module. Hw modules that cannot |
be "explicitly" used (like CPU modules or the different memories) are not listed below. Also, there is no CFU driver library or |
example project - this has to be provided by the CFU designer. |
|
| Hardware unit | VHDL source | C library source | C library header | SW example project | |
|:---------------------------------------|:-----------:|:----------------:|:----------------:|:------------------:| |
| Main CPU defines file | - | - | [neo430.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430.h) | - | |
| Central Processing Unit (CPU) | [neo430_cpu.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_cpu.vhd) | [neo430_cpu.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_cpu.c) | [neo430_cpu.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_cpu.h) |- | |
| Checksum Unit (CRC16/32) | [neo430_crc.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_crc.vhd) | [neo430_crc.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_crc.c) | [neo430_crc.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_crc.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/crc_test) | |
| External Interrupts Controller (EXIRQ) | [neo430_exirq.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_exirq.vhd) | [neo430_exirq.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_exirq.c) | [neo430_exirq.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_exirq.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/exirq_test) | |
| Frequency Generator (FREQ_GEN) | [neo430_freq_gen.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_freq_gen.vhd) | [neo430_freq_gen.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_freq_gen.c) | [neo430_freq_gen.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_freq_gen.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/freq_gen_demo) | |
| IO Port Unit (GPIO) | [neo430_gpio.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_gpio.vhd) | [neo430_gpio.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_gpio.c) | [neo430_gpio.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_gpio.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/blink_led) | |
| Multiplier & Divider (MULDIV) | [neo430_muldiv.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_muldiv.vhd) | [neo430_muldiv.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_muldiv.c) | [neo430_muldiv.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_muldiv.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/muldiv_test) | |
| Pulse-Width Modulation Unit (PWM) | [neo430_pwm.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_pwm.vhd) | [neo430_pwm.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_pwm.c) | [neo430_pwm.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_pwm.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/pwm_demo) | |
| Serial Peripheral Interface (SPI) | [neo430_spi.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_spi.vhd) | [neo430_spi.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_spi.c) | [neo430_spi.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_spi.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/bootloader) | |
| High-Precision Timer (TIMER) | [neo430_timer.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_timer.vhd) | [neo430_timer.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_timer.c) | [neo430_timer.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_timer.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/timer_simple) | |
| True Random Number Generator (TRNG) | [neo430_trng.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_trng.vhd) | [neo430_trng.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_trng.c) | [neo430_trng.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_trng.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/trng_test) | |
| Two Wire Interface (TWI) | [neo430_twi.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_twi.vhd) | [neo430_twi.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_twi.c) | [neo430_twi.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_twi.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/twi_test) | |
| Universal Asynchronous Rx/Tx (UART) | [neo430_uart.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_uart.vhd) | [neo430_uart.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_uart.c) | [neo430_uart.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_uart.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/uart_irq) | |
| Watchdog Timer (WDT) | [neo430_wdt.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_wdt.vhd) | [neo430_wdt.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_wdt.c) | [neo430_wdt.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_wdt.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/wdt_test) | |
| Wishbone Interface (WB32) | [neo430_wb_interface.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_wb_interface.vhd) | [neo430_wishbone.c](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/source/neo430_wishbone.c) | [neo430_wishbone.h](https://github.com/stnolting/neo430/blob/master/sw/lib/neo430/include/neo430_wishbone.h) | [example](https://github.com/stnolting/neo430/tree/master/sw/example/wb_terminal) | |
|
|
|
## Performance |
|
In contrast to most mainstream processors the NEO430 processor does not implement a pipelined instruction execution. Instead, |
306,7 → 268,7
| -Os + NEO430_MULDIV* | 12.98 | 0.129 Coremarks/MHz | |
| -O2 + NEO430_MULDIV* | 15.26 | 0.152 Coremarks/MHz | |
|
*) Using the NEO430 MULDIV unit for the core of the matrix multiplications. |
*) Using the NEO430 MULDIV unit for the core of the matrix multiplications |
|
Even though a score of 6.57 can outnumber certain architectures and configurations (see the score table on the coremark |
homepage), the relative score of 0.065 coremarks per second might pretty low. But you have to keep in mind that benchmark |
335,13 → 297,9
* Next, install the free `MSP430-GCC` compiler toolchain from the TI homepage (select the "compiler only" package according to your system OS): |
|
https://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/latest/index_FDS.html |
|
* Alternatively, you can [directly download a copy](https://github.com/stnolting/msp430-gcc) of the msp430-gcc toolchain for Windows/Linux from github |
|
* Make sure `GNU Make` and a native `GCC` compiler are installed (double check for the newest versions) |
|
* Create a new HW project with your FPGA synthesis tool of choice. Add all files from the `rtl\core` folder to this project (and add them to a new library called "neo430"). |
|
* Follow the instructions from the "Let's Get It Started" section of the NEO430 documentary: [![NEO430 Datasheet](https://raw.githubusercontent.com/stnolting/neo430/master/doc/figures/PDF_32.png) NEO430 Datasheet](https://raw.githubusercontent.com/stnolting/neo430/master/doc/NEO430.pdf "NEO430 Datasheet from GitHub") |
|
* This documentary will guide you to create a simple test setup, which serves as ["hello word" FPGA demo](https://github.com/stnolting/neo430/blob/master/rtl/top_templates/neo430_test.vhd): |
372,7 → 330,7
|
## Citation |
|
If you are using the NEO430 in some kind of publication, please cite it as follows: |
If you are using the NEO430 for some kind of publication, please cite it as follows: |
|
> S. Nolting, "The NEO430 Processor", github.com/stnolting/neo430 |
|
382,6 → 340,8
|
This is a hobby project released under the BSD 3-Clause license. No copyright infringement intended. |
|
|
|
**BSD 3-Clause License** |
|
Copyright (c) 2020, Stephan Nolting. All rights reserved. |
422,11 → 382,7
"AXI", "AXI4" and "AXI4-Lite" are trademarks of Arm Holdings plc. |
|
|
[![Continous Integration provided by Travis CI](https://travis-ci.com/images/logos/TravisCI-Full-Color.png)](https://travis-ci.com/stnolting/neo430) |
|
Continous integration provided by [Travis CI](https://travis-ci.com/stnolting/neo430). |
|
|
![Open Source Hardware Logo https://www.oshwa.org](https://raw.githubusercontent.com/stnolting/neo430/master/doc/figures/oshw_logo.png) |
|
This project is not affiliated with or endorsed by the Open Source Initiative (https://www.oshwa.org / https://opensource.org). |
/neo430/trunk/neo430/doc/NEO430.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/neo430/trunk/neo430/doc/figures/neo430_arch.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/neo430/trunk/neo430/rtl/core/neo430_freq_gen.vhd
File deleted
/neo430/trunk/neo430/rtl/core/neo430_bootloader_image.vhd
516,25 → 516,25
000505 => x"4382", |
000506 => x"ffee", |
000507 => x"4382", |
000508 => x"ff88", |
000509 => x"4382", |
000510 => x"ffa8", |
000511 => x"435c", |
000512 => x"12b0", |
000513 => x"f6a6", |
000514 => x"40b2", |
000515 => x"f00a", |
000516 => x"c000", |
000517 => x"403c", |
000518 => x"4b00", |
000519 => x"434d", |
000508 => x"ffa8", |
000509 => x"435c", |
000510 => x"12b0", |
000511 => x"f6a6", |
000512 => x"40b2", |
000513 => x"f00a", |
000514 => x"c000", |
000515 => x"403c", |
000516 => x"4b00", |
000517 => x"434d", |
000518 => x"12b0", |
000519 => x"f532", |
000520 => x"12b0", |
000521 => x"f532", |
000522 => x"12b0", |
000523 => x"f5d2", |
000524 => x"436c", |
000525 => x"12b0", |
000526 => x"f660", |
000521 => x"f5d2", |
000522 => x"436c", |
000523 => x"12b0", |
000524 => x"f660", |
000525 => x"4382", |
000526 => x"ffb6", |
000527 => x"4382", |
000528 => x"ffb0", |
000529 => x"4038", |
968,10 → 968,10
000957 => x"0a0a", |
000958 => x"4c42", |
000959 => x"3a56", |
000960 => x"4120", |
000961 => x"7270", |
000962 => x"3120", |
000963 => x"2037", |
000960 => x"4d20", |
000961 => x"7261", |
000962 => x"3320", |
000963 => x"2031", |
000964 => x"3032", |
000965 => x"3032", |
000966 => x"480a", |
/neo430/trunk/neo430/rtl/core/neo430_control.vhd
375,8 → 375,6
ctrl_nxt(ctrl_rf_in_sel_c) <= '1'; -- select addr gen feedback (only relevant for last two 'when') |
ctrl_nxt(ctrl_mem_rd_c) <= '1'; -- Memory read (fast) (only relevant for last two 'when' 4) |
mem_rd <= '1'; -- Memory read (only relevant for last two 'when' 5) |
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "010"; -- add +2 |
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source/destination: PC |
-- |
case am is -- addressing mode |
-- "000-" = CLASS II, SRC/DST: register direct [ACTUAL DON'T CARE; STATE NOT USED] |
410,10 → 408,10
-- "1101" = CLASS I, SRC: indirect, DST: indexed |
-- |
-- "1111" = CLASS I, SRC: indirect auto inc, DST: indexed |
--> ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source/destination: PC |
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source/destination: PC |
ctrl_nxt(ctrl_adr_bp_en_c) <= '1'; -- directly output RF.out to address bus |
--> ctrl_nxt(ctrl_mem_rd_c) <= '1'; -- Memory read (fast) |
--> ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "010"; -- add +2 |
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "010"; -- add +2 |
--> ctrl_nxt(ctrl_rf_in_sel_c) <= '1'; -- select addr gen feedback |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write back |
ctrl_nxt(ctrl_alu_in_sel_c) <= '1'; -- get data from memory |
422,10 → 420,10
|
when others => |
-- "1011" = CLASS I, SRC: indexed/symbolic/absolute, DST: indexed |
--> ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source/destination: PC |
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source/destination: PC |
ctrl_nxt(ctrl_adr_mar_wr_c) <= '1'; -- write to MAR |
--> mem_rd <= '1'; -- Memory read |
--> ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "010"; -- add +2 |
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "010"; -- add +2 |
--> ctrl_nxt(ctrl_rf_in_sel_c) <= '1'; -- select addr gen feedback |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write back |
state_nxt <= TRANS_2; |
/neo430/trunk/neo430/rtl/core/neo430_package.vhd
40,7 → 40,7
|
-- Processor Hardware Version ------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
constant hw_version_c : std_ulogic_vector(15 downto 0) := x"0406"; -- no touchy! |
constant hw_version_c : std_ulogic_vector(15 downto 0) := x"0404"; -- no touchy! |
|
-- Danger Zone (Advanced Hardware Configuration) ------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
79,8 → 79,8
|
-- Boot ROM -- |
constant boot_base_c : std_ulogic_vector(15 downto 0) := x"F000"; -- bootloader base address, fixed! |
constant boot_size_c : natural := 2*1024; -- bytes, max 2048 bytes! |
constant boot_max_size_c : natural := 2*1024; -- bytes, fixed! |
constant boot_size_c : natural := 2048; -- bytes, max 2048 bytes! |
constant boot_max_size_c : natural := 2048; -- bytes, fixed! |
|
-- IO: Peripheral Devices ("IO") Area -- |
-- Each device must use 2 bytes or a multiple of 2 bytes as address space! |
92,19 → 92,19
constant muldiv_base_c : std_ulogic_vector(15 downto 0) := x"FF80"; |
constant muldiv_size_c : natural := 8; -- bytes |
|
constant muldiv_opa_resx_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0000"); |
constant muldiv_opb_umul_resy_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0002"); |
constant muldiv_opb_smul_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0004"); |
constant muldiv_opb_udiv_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0006"); |
constant muldiv_opa_ctrl_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0000"); |
constant muldiv_opb_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0002"); |
constant muldiv_resx_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0004"); |
constant muldiv_resy_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0006"); |
|
-- IO: Frequency Generator (FREQ_GEN) -- |
constant freq_gen_base_c : std_ulogic_vector(15 downto 0) := x"FF88"; |
constant freq_gen_size_c : natural := 8; -- bytes |
-- IO: reserved -- |
--constant reserved_base_c : std_ulogic_vector(15 downto 0) := x"FF88"; |
--constant reserved_size_c : natural := 8; -- bytes |
|
constant freq_gen_ctrl_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(freq_gen_base_c) + x"0000"); |
constant freq_gen_tw_ch0_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(freq_gen_base_c) + x"0002"); |
constant freq_gen_tw_ch1_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(freq_gen_base_c) + x"0004"); |
constant freq_gen_tw_ch2_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(freq_gen_base_c) + x"0006"); |
--constant reserved_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(reserved_base_c) + x"0000"); |
--constant reserved_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(reserved_base_c) + x"0002"); |
--constant reserved_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(reserved_base_c) + x"0004"); |
--constant reserved_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(reserved_base_c) + x"0006"); |
|
-- IO: Wishbone32 Interface (WB32) -- |
constant wb32_base_c : std_ulogic_vector(15 downto 0) := x"FF90"; |
149,7 → 149,7
constant timer_ctrl_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(timer_base_c) + x"0000"); |
constant timer_cnt_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(timer_base_c) + x"0002"); |
constant timer_thres_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(timer_base_c) + x"0004"); |
--constant timer_???_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(timer_base_c) + x"0006"); |
constant timer_nco_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(timer_base_c) + x"0006"); |
|
-- IO: Watchdog Timer (WDT) -- |
constant wdt_base_c : std_ulogic_vector(15 downto 0) := x"FFB8"; |
360,8 → 360,8
gpio_i : in std_ulogic_vector(15 downto 0); -- parallel input |
-- pwm channels -- |
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels |
-- arbitrary frequency generator -- |
freq_gen_o : out std_ulogic_vector(02 downto 0); -- programmable frequency output |
-- timer frequency generator -- |
timer_fg_o : out std_ulogic; -- programmable frequency output |
-- serial com -- |
uart_txd_o : out std_ulogic; -- UART send data |
uart_rxd_i : in std_ulogic; -- UART receive data |
652,6 → 652,8
-- clock generator -- |
clkgen_en_o : out std_ulogic; -- enable clock generator |
clkgen_i : in std_ulogic_vector(07 downto 0); |
-- frequency generator -- |
timer_fg_o : out std_ulogic; -- programmable frequency output |
-- interrupt -- |
irq_o : out std_ulogic -- interrupt request |
); |
786,25 → 788,6
); |
end component; |
|
-- Component: Arbitrary Frequency Generator (FREG_GEN)) ----------------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neo430_freq_gen |
port ( |
-- host access -- |
clk_i : in std_ulogic; -- global clock line |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
addr_i : in std_ulogic_vector(15 downto 0); -- address |
data_i : in std_ulogic_vector(15 downto 0); -- data in |
data_o : out std_ulogic_vector(15 downto 0); -- data out |
-- clock generator -- |
clkgen_en_o : out std_ulogic; -- enable clock generator |
clkgen_i : in std_ulogic_vector(07 downto 0); |
-- frequency generator -- |
freq_gen_o : out std_ulogic_vector(02 downto 0) -- programmable frequency output |
); |
end component; |
|
-- Component: System Configuration (SYSCONFIG) -------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neo430_sysconfig |
829,7 → 812,6
SPI_USE : boolean := true; -- implement SPI? |
TRNG_USE : boolean := true; -- implement TRNG? |
EXIRQ_USE : boolean := true; -- implement EXIRQ? |
FREQ_GEN_USE : boolean := true; -- implement FREQ_GEN? |
-- boot configuration -- |
BOOTLD_USE : boolean := true; -- implement and use bootloader? |
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? |
/neo430/trunk/neo430/rtl/core/neo430_pwm.vhd
157,7 → 157,7
end if; |
-- channels -- |
for i in 0 to num_pwm_channels_c-1 loop |
-- constrain to virtual size configured by SIZE control register bit |
-- constrain to virtual size configured by SIZE register |
if (unsigned(pwm_cnt and mask) >= unsigned(pwm_ch(i) and mask)) or (enable = '0') then |
pwm_out(i) <= '0'; |
else |
/neo430/trunk/neo430/rtl/core/neo430_timer.vhd
5,6 → 5,8
-- # counter value reaches the programmable threshold an interrupt can be triggered. Optionally, # |
-- # the counter can be automatically reset when reaching the threshold value to restart counting. # |
-- # Configure THRES before enabling the timer to prevent false interrupt requests. # |
-- # The time also features a numerically controlled oscillator (NCO) for generating arbitrary # |
-- # frequency outputs: f_out = ((f_cpu / nco_prsc) * tuning_word[15:0]) / 2^17 # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
56,6 → 58,8
-- clock generator -- |
clkgen_en_o : out std_ulogic; -- enable clock generator |
clkgen_i : in std_ulogic_vector(07 downto 0); |
-- frequency generator -- |
timer_fg_o : out std_ulogic; -- programmable frequency output |
-- interrupt -- |
irq_o : out std_ulogic -- interrupt request |
); |
75,6 → 79,10
constant ctrl_prsc0_c : natural := 4; -- r/w: prescaler select bit 0 |
constant ctrl_prsc1_c : natural := 5; -- r/w: prescaler select bit 1 |
constant ctrl_prsc2_c : natural := 6; -- r/w: prescaler select bit 2 |
constant ctrl_nco_en_c : natural := 7; -- r/w: enable NCO |
constant ctrl_nco_prsc0_c : natural := 8; -- r/w: NCO prescaler select bit 0 |
constant ctrl_nco_prsc1_c : natural := 9; -- r/w: NCO prescaler select bit 1 |
constant ctrl_nco_prsc2_c : natural := 10; -- r/w: NCO prescaler select bit 2 |
|
-- access control -- |
signal acc_en : std_ulogic; -- module access enable |
82,18 → 90,23
signal wr_en : std_ulogic; -- word write enable |
|
-- timer regs -- |
signal ctrl : std_ulogic_vector(06 downto 0); -- r/w: control register |
signal cnt : std_ulogic_vector(15 downto 0); -- r/-: counter register |
signal thres : std_ulogic_vector(15 downto 0); -- -/w: threshold register |
signal cnt : std_ulogic_vector(15 downto 0); -- r/-: counter register |
signal ctrl : std_ulogic_vector(10 downto 0); -- r/w: control register |
|
-- prescaler clock generator -- |
signal prsc_tick : std_ulogic; |
|
-- timer control -- |
signal match : std_ulogic; -- set if thres == cnt |
signal match : std_ulogic; -- thres = cnt |
signal irq_fire : std_ulogic; |
signal irq_fire_ff : std_ulogic; |
|
-- nco -- |
signal nco_prsc_tick : std_ulogic; |
signal nco_tuning_word : std_ulogic_vector(15 downto 0); -- -/w: NCO tuning word |
signal nco_phase_accu : std_ulogic_vector(16 downto 0); |
|
begin |
|
-- Access Control ----------------------------------------------------------- |
113,14 → 126,21
thres <= data_i; |
end if; |
if (addr = timer_ctrl_addr_c) then |
ctrl(ctrl_en_c) <= data_i(ctrl_en_c); |
ctrl(ctrl_arst_c) <= data_i(ctrl_arst_c); |
ctrl(ctrl_irq_en_c) <= data_i(ctrl_irq_en_c); |
ctrl(ctrl_run_c) <= data_i(ctrl_run_c); |
ctrl(ctrl_prsc0_c) <= data_i(ctrl_prsc0_c); |
ctrl(ctrl_prsc1_c) <= data_i(ctrl_prsc1_c); |
ctrl(ctrl_prsc2_c) <= data_i(ctrl_prsc2_c); |
ctrl(ctrl_en_c) <= data_i(ctrl_en_c); |
ctrl(ctrl_arst_c) <= data_i(ctrl_arst_c); |
ctrl(ctrl_irq_en_c) <= data_i(ctrl_irq_en_c); |
ctrl(ctrl_run_c) <= data_i(ctrl_run_c); |
ctrl(ctrl_prsc0_c) <= data_i(ctrl_prsc0_c); |
ctrl(ctrl_prsc1_c) <= data_i(ctrl_prsc1_c); |
ctrl(ctrl_prsc2_c) <= data_i(ctrl_prsc2_c); |
ctrl(ctrl_nco_en_c) <= data_i(ctrl_nco_en_c); |
ctrl(ctrl_nco_prsc0_c) <= data_i(ctrl_nco_prsc0_c); |
ctrl(ctrl_nco_prsc1_c) <= data_i(ctrl_nco_prsc1_c); |
ctrl(ctrl_nco_prsc2_c) <= data_i(ctrl_nco_prsc2_c); |
end if; |
if (addr = timer_nco_addr_c) then |
nco_tuning_word <= data_i; |
end if; |
end if; |
end if; |
end process wr_access; |
161,6 → 181,25
irq_o <= irq_fire and (not irq_fire_ff); |
|
|
-- NCO core (number controlled oscillator) ---------------------------------- |
-- ----------------------------------------------------------------------------- |
nco_core: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- NCO clock enable -- |
nco_prsc_tick <= clkgen_i(to_integer(unsigned(ctrl(ctrl_nco_prsc2_c downto ctrl_nco_prsc0_c)))); |
-- phase accu -- |
if ((ctrl(ctrl_en_c) and ctrl(ctrl_nco_en_c)) = '0') then -- disabled |
nco_phase_accu <= (others => '0'); |
elsif (nco_prsc_tick = '1') then -- enabled; wait for clock enable tick |
nco_phase_accu <= std_ulogic_vector(unsigned(nco_phase_accu) + unsigned('0' & nco_tuning_word)); |
end if; |
-- output -- |
timer_fg_o <= nco_phase_accu(nco_phase_accu'left); -- MSB (carry_out) is output |
end if; |
end process nco_core; |
|
|
-- Read access -------------------------------------------------------------- |
-- ----------------------------------------------------------------------------- |
rd_access: process(clk_i) |
169,17 → 208,23
data_o <= (others => '0'); |
if (rden_i = '1') and (acc_en = '1') then |
if (addr = timer_ctrl_addr_c) then |
data_o(ctrl_en_c) <= ctrl(ctrl_en_c); |
data_o(ctrl_arst_c) <= ctrl(ctrl_arst_c); |
data_o(ctrl_irq_en_c) <= ctrl(ctrl_irq_en_c); |
data_o(ctrl_run_c) <= ctrl(ctrl_run_c); |
data_o(ctrl_prsc0_c) <= ctrl(ctrl_prsc0_c); |
data_o(ctrl_prsc1_c) <= ctrl(ctrl_prsc1_c); |
data_o(ctrl_prsc2_c) <= ctrl(ctrl_prsc2_c); |
data_o(ctrl_en_c) <= ctrl(ctrl_en_c); |
data_o(ctrl_arst_c) <= ctrl(ctrl_arst_c); |
data_o(ctrl_irq_en_c) <= ctrl(ctrl_irq_en_c); |
data_o(ctrl_run_c) <= ctrl(ctrl_run_c); |
data_o(ctrl_prsc0_c) <= ctrl(ctrl_prsc0_c); |
data_o(ctrl_prsc1_c) <= ctrl(ctrl_prsc1_c); |
data_o(ctrl_prsc2_c) <= ctrl(ctrl_prsc2_c); |
data_o(ctrl_nco_en_c) <= ctrl(ctrl_nco_en_c); |
data_o(ctrl_nco_prsc0_c) <= ctrl(ctrl_nco_prsc0_c); |
data_o(ctrl_nco_prsc1_c) <= ctrl(ctrl_nco_prsc1_c); |
data_o(ctrl_nco_prsc2_c) <= ctrl(ctrl_nco_prsc2_c); |
else--if (addr = timer_cnt_addr_c) then |
data_o <= cnt; |
-- else -- (addr = timer_thres_addr_c) then |
-- else--if (addr = timer_thres_addr_c) then |
-- data_o <= thres; |
-- else -- timer_nco_addr_c |
-- data_o <= nco_tuning_word; |
end if; |
end if; |
end if; |
/neo430/trunk/neo430/rtl/core/neo430_top.vhd
16,7 → 16,7
-- # - Optional 16-bit multiplier/divider unit (MULDIV) # |
-- # - Optional 16-bit IN and 16-bit OUT GPIO port with pin-change interrupt (GPIO) # |
-- # - Optional 32-bit Wishbone interface (WB32) # |
-- # - Optional High precision timer (TIMER) # |
-- # - Optional High precision timer (TIMER) with frequency generator output # |
-- # - Optional Universal Asynchronous Receiver and Transmitter (UART) # |
-- # - Optional Serial Peripheral Interface (SPI) # |
-- # - Optional Internal ROM for bootloader (BOOTLD) # |
27,7 → 27,6
-- # - Optional Two Wire Serial Interface (TWI) # |
-- # - Optional True Random Number Generator (TRNG) # |
-- # - Optional External Interrupts Controller (EXIRQ) # |
-- # - Optional Arbitrary Frequency Generator (FREQ_GEN) # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
103,8 → 102,8
gpio_i : in std_ulogic_vector(15 downto 0); -- parallel input |
-- pwm channels -- |
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels |
-- arbitrary frequency generator -- |
freq_gen_o : out std_ulogic_vector(02 downto 0); -- programmable frequency output |
-- timer frequency generator -- |
timer_fg_o : out std_ulogic; -- programmable frequency output |
-- serial com -- |
uart_txd_o : out std_ulogic; -- UART send data |
uart_rxd_i : in std_ulogic; -- UART receive data |
132,24 → 131,23
architecture neo430_top_rtl of neo430_top is |
|
-- generators -- |
signal rst_i_sync0 : std_ulogic; |
signal rst_i_sync1 : std_ulogic; |
signal rst_gen : std_ulogic_vector(03 downto 0) := (others => '0'); -- reset on bitstream upload |
signal ext_rst : std_ulogic; |
signal sys_rst : std_ulogic; |
signal wdt_rst : std_ulogic; |
signal clk_div : std_ulogic_vector(11 downto 0); |
signal clk_div_ff : std_ulogic_vector(11 downto 0); |
signal clk_gen : std_ulogic_vector(07 downto 0); |
signal timer_cg_en : std_ulogic; |
signal uart_cg_en : std_ulogic; |
signal spi_cg_en : std_ulogic; |
signal wdt_cg_en : std_ulogic; |
signal pwm_cg_en : std_ulogic; |
signal twi_cg_en : std_ulogic; |
signal cfu_cg_en : std_ulogic; |
signal freq_gen_cg_en : std_ulogic; |
|
signal rst_i_sync0 : std_ulogic; |
signal rst_i_sync1 : std_ulogic; |
signal rst_gen : std_ulogic_vector(03 downto 0) := (others => '0'); -- reset on bitstream upload |
signal ext_rst : std_ulogic; |
signal sys_rst : std_ulogic; |
signal wdt_rst : std_ulogic; |
signal clk_div : std_ulogic_vector(11 downto 0); |
signal clk_div_ff : std_ulogic_vector(11 downto 0); |
signal clk_gen : std_ulogic_vector(07 downto 0); |
signal timer_cg_en : std_ulogic; |
signal uart_cg_en : std_ulogic; |
signal spi_cg_en : std_ulogic; |
signal wdt_cg_en : std_ulogic; |
signal pwm_cg_en : std_ulogic; |
signal twi_cg_en : std_ulogic; |
signal cfu_cg_en : std_ulogic; |
|
type cpu_bus_t is record |
rd_en : std_ulogic; |
wr_en : std_ulogic_vector(01 downto 0); |
181,7 → 179,6
signal twi_rdata : std_ulogic_vector(15 downto 0); |
signal trng_rdata : std_ulogic_vector(15 downto 0); |
signal exirq_rdata : std_ulogic_vector(15 downto 0); |
signal freq_gen_rdata : std_ulogic_vector(15 downto 0); |
signal sysconfig_rdata : std_ulogic_vector(15 downto 0); |
|
-- interrupt system -- |
234,7 → 231,7
clk_div <= (others => '0'); |
elsif rising_edge(clk_i) then |
-- anybody needing fresh clocks? |
if ((timer_cg_en or uart_cg_en or spi_cg_en or wdt_cg_en or pwm_cg_en or twi_cg_en or cfu_cg_en or freq_gen_cg_en) = '1') then |
if ((timer_cg_en or uart_cg_en or spi_cg_en or wdt_cg_en or pwm_cg_en or twi_cg_en or cfu_cg_en) = '1') then |
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1); |
end if; |
end if; |
282,7 → 279,7
|
-- final CPU read data -- |
cpu_bus.rdata <= rom_rdata or ram_rdata or boot_rdata or muldiv_rdata or |
wb_rdata or uart_rdata or spi_rdata or gpio_rdata or freq_gen_rdata or |
wb_rdata or uart_rdata or spi_rdata or gpio_rdata or |
timer_rdata or wdt_rdata or sysconfig_rdata or crc_rdata or |
cfu_rdata or pwm_rdata or twi_rdata or trng_rdata or exirq_rdata; |
|
527,6 → 524,8
-- clock generator -- |
clkgen_en_o => timer_cg_en, -- enable clock generator |
clkgen_i => clk_gen, |
-- frequency generator -- |
timer_fg_o => timer_fg_o, -- programmable frequency output |
-- interrupt -- |
irq_o => timer_irq -- interrupt request |
); |
537,6 → 536,7
timer_rdata <= (others => '0'); |
timer_irq <= '0'; |
timer_cg_en <= '0'; |
timer_fg_o <= '0'; |
end generate; |
|
|
734,35 → 734,6
end generate; |
|
|
-- Arbitrary Frequency Generator (FREW_GEN)) -------------------------------- |
-- ----------------------------------------------------------------------------- |
neo430_freq_gen_inst_true: |
if (FREQ_GEN_USE = true) generate |
neo430_freq_gen_inst: neo430_freq_gen |
port map ( |
-- host access -- |
clk_i => clk_i, -- global clock line |
rden_i => io_rd_en, -- read enable |
wren_i => io_wr_en, -- write enable |
addr_i => cpu_bus.addr, -- address |
data_i => cpu_bus.wdata, -- data in |
data_o => freq_gen_rdata, -- data out |
-- clock generator -- |
clkgen_en_o => freq_gen_cg_en, -- enable clock generator |
clkgen_i => clk_gen, |
-- frequency generator -- |
freq_gen_o => freq_gen_o -- programmable frequency output |
); |
end generate; |
|
neo430_freq_gen_inst_false: |
if (FREQ_GEN_USE = false) generate |
freq_gen_cg_en <= '0'; |
freq_gen_rdata <= (others => '0'); |
freq_gen_o <= (others => '0'); |
end generate; |
|
|
-- System Configuration ----------------------------------------------------- |
-- ----------------------------------------------------------------------------- |
neo430_sysconfig_inst: neo430_sysconfig |
787,7 → 758,6
SPI_USE => SPI_USE, -- implement SPI? |
TRNG_USE => TRNG_USE, -- implement TRNG? |
EXIRQ_USE => EXIRQ_USE, -- implement EXIRQ? |
FREQ_GEN_USE => FREQ_GEN_USE, -- implement FREQ_GEN? |
-- boot configuration -- |
BOOTLD_USE => BOOTLD_USE, -- implement and use bootloader? |
IMEM_AS_ROM => IMEM_AS_ROM -- implement IMEM as read-only memory? |
/neo430/trunk/neo430/rtl/core/neo430_muldiv.vhd
1,12 → 1,14
-- ################################################################################################# |
-- # << NEO430 - 16-Bit Unsigned Multiplier & Divider Unit >> # |
-- # ********************************************************************************************* # |
-- # NOTE: This unit uses "repeated trial subtraction" as division algorithm (restoring). # |
-- # NOTE: This unit uses "repeated trial subtraction" as division algorithm. # |
-- # NOTE: This unit uses "shifted add" as multiplication algorithm. Set 'use_dsp_mul_c' in the # |
-- # package file to TRUE to use DSP slices for multiplication. # |
-- # # |
-- # The division unit only supports unsigned divisions. # |
-- # The multiplication unit supports signed and unsigned division. # |
-- # OpA is used for storing the first operand as well as for function configuration. Set this # |
-- # register to 0 reset the unit. Afterwards, set it to 0b01 for multiplication or to 0b10 for # |
-- # division. Afterwards, write the actual operand. The actual operation is started by # |
-- # writing OpB. # |
-- # # |
-- # Division: DIVIDEND / DIVIDER = QUOTIENT + REMAINDER (16-bit) / DIVIDER (16-bit) # |
-- # Multiplication: FACTOR1 * FACTOR2 = PRODUCT (32-bit) # |
71,28 → 73,25
signal acc_en : std_ulogic; -- module access enable |
signal addr : std_ulogic_vector(15 downto 0); -- access address |
signal wr_en : std_ulogic; -- only full 16-bit word accesses! |
signal rd_en : std_ulogic; |
|
-- control -- |
signal ctrl_state : std_ulogic; |
signal operation : std_ulogic; -- '1' division, '0' multiplication |
signal func_rst : std_ulogic; |
|
-- accessible regs -- |
signal opa, opb : std_ulogic_vector(15 downto 0); |
signal resx, resy : std_ulogic_vector(15 downto 0); |
signal operation : std_ulogic; -- '1' division, '0' multiplication |
signal signed_op : std_ulogic; |
|
-- arithmetic core & arbitration -- |
signal start : std_ulogic; |
signal run : std_ulogic; |
signal enable : std_ulogic_vector(15 downto 0); |
signal try_sub : std_ulogic_vector(16 downto 0); |
signal remainder : std_ulogic_vector(15 downto 0); |
signal quotient : std_ulogic_vector(15 downto 0); |
signal product : std_ulogic_vector(31 downto 0); |
signal do_add : std_ulogic_vector(16 downto 0); |
signal sign_cycle : std_ulogic; |
signal opa_sext : std_ulogic; |
signal opb_sext : std_ulogic; |
signal p_sext : std_ulogic; |
signal dsp_mul_res : std_ulogic_vector(33 downto 0); |
signal start : std_ulogic; |
signal run : std_ulogic; |
signal enable : std_ulogic_vector(15 downto 0); |
signal try_sub : std_ulogic_vector(16 downto 0); |
signal remainder : std_ulogic_vector(15 downto 0); |
signal quotient : std_ulogic_vector(15 downto 0); |
signal product : std_ulogic_vector(31 downto 0); |
signal do_add : std_ulogic_vector(16 downto 0); |
|
begin |
|
101,7 → 100,6
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = muldiv_base_c(hi_abb_c downto lo_abb_c)) else '0'; |
addr <= muldiv_base_c(15 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 1) & '0'; -- word aligned |
wr_en <= acc_en and wren_i; |
rd_en <= acc_en and rden_i; |
|
|
-- Write access ------------------------------------------------------------- |
109,37 → 107,34
wr_access: process(clk_i) |
begin |
if rising_edge(clk_i) then |
start <= '0'; |
opa_sext <= opa(opa'left) and signed_op; |
opb_sext <= opb(opb'left) and signed_op; |
start <= '0'; |
if (wr_en = '1') then -- only full word accesses! |
-- operands -- |
if (addr = muldiv_opa_resx_addr_c) then -- dividend or factor 1 |
opa <= data_i; |
if (addr = muldiv_opa_ctrl_addr_c) then -- reset/control OR dividend or mul_factor a |
opa <= data_i; |
end if; |
if (addr = muldiv_opb_umul_resy_addr_c) or |
(addr = muldiv_opb_smul_addr_c) or |
(addr = muldiv_opb_udiv_addr_c) then -- divisor or factor 2 |
if (addr = muldiv_opb_addr_c) then -- divisor or mul_factor b |
opb <= data_i; |
start <= '1'; -- trigger operation |
start <= '1'; -- start operation |
end if; |
-- operation: division/multiplication -- |
if (addr = muldiv_opb_umul_resy_addr_c) or (addr = muldiv_opb_smul_addr_c) then -- multiplication |
operation <= '0'; |
else -- division |
operation <= '1'; |
-- operation configuration -- |
if (func_rst = '1') then -- reset configuration |
ctrl_state <= '0'; |
elsif (ctrl_state = '0') then -- get new configuration |
if (wr_en = '1') then |
operation <= opa(1); -- '1' division, '0' multiplication |
ctrl_state <= '1'; |
end if; |
-- else -- execute configuration |
end if; |
-- signed/unsigned operation -- |
if (addr = muldiv_opb_smul_addr_c) then |
signed_op <= '1'; |
else |
signed_op <= '0'; |
end if; |
end if; |
end if; |
end process wr_access; |
|
-- reset when OpA is zero -- |
func_rst <= '1' when (opa = x"0000") else '0'; |
|
|
-- Arithmetic core ---------------------------------------------------------- |
-- ----------------------------------------------------------------------------- |
arithmetic_core: process(clk_i) |
170,7 → 165,7
else |
if (use_dsp_mul_c = false) then -- implement serial multiplication |
if (start = '1') then -- load factor 1 |
product(31 downto 16) <= (others => opa_sext); |
product(31 downto 16) <= (others => '0'); |
product(15 downto 0) <= opa; |
elsif (run = '1') then |
product(31 downto 15) <= do_add(16 downto 0); |
177,36 → 172,19
product(14 downto 0) <= product(15 downto 1); |
end if; |
else -- use DSP for multiplication |
product(31 downto 0) <= dsp_mul_res(31 downto 0); |
product(31 downto 0) <= std_ulogic_vector(unsigned(opa) * unsigned(opb)); |
end if; |
end if; |
end if; |
end process arithmetic_core; |
|
-- DSP multiplication -- |
dsp_mul_res <= std_ulogic_vector(signed(opa_sext & opa) * signed(opb_sext & opb)); |
|
-- DIV: try another subtraction -- |
try_sub <= std_ulogic_vector(unsigned('0' & remainder(14 downto 0) & quotient(15)) - unsigned('0' & opb)); |
|
-- MUL: do another addition -- |
mul_update: process(product, sign_cycle, p_sext, opb_sext, opb) |
begin |
if (product(0) = '1') then |
if (sign_cycle = '1') then -- for signed operation only: take care of negative weighted MSB |
do_add <= std_ulogic_vector(unsigned(p_sext & product(31 downto 16)) - unsigned(opb_sext & opb)); |
else |
do_add <= std_ulogic_vector(unsigned(p_sext & product(31 downto 16)) + unsigned(opb_sext & opb)); |
end if; |
else |
do_add <= p_sext & product(31 downto 16); |
end if; |
end process mul_update; |
-- MUL: do another addition |
do_add <= std_ulogic_vector(unsigned('0' & product(31 downto 16)) + unsigned('0' & opb)) when (product(0) = '1') else ('0' & product(31 downto 16)); |
|
sign_cycle <= enable(enable'left) and signed_op; |
p_sext <= product(product'left) and signed_op; |
|
|
-- Read access -------------------------------------------------------------- |
-- ----------------------------------------------------------------------------- |
rd_access: process(clk_i) |
213,10 → 191,10
begin |
if rising_edge(clk_i) then |
data_o <= (others => '0'); |
if (rd_en = '1') then -- valid read access |
if (addr = muldiv_opa_resx_addr_c) then |
if (acc_en = '1') and (rden_i = '1') then -- valid read access |
if (addr = muldiv_resx_addr_c) then |
data_o <= resx; -- quotient or product low word |
else -- muldiv_opb_umul_resy_addr_c => |
else -- muldiv_resy_addr_c => |
data_o <= resy; -- remainder or product high word |
end if; |
end if; |
/neo430/trunk/neo430/rtl/core/neo430_sysconfig.vhd
64,7 → 64,6
SPI_USE : boolean := true; -- implement SPI? |
TRNG_USE : boolean := true; -- implement TRNG? |
EXIRQ_USE : boolean := true; -- implement EXIRQ? |
FREQ_GEN_USE : boolean := true; -- implement FREQ_GEN? |
-- boot configuration -- |
BOOTLD_USE : boolean := true; -- implement and use bootloader? |
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? |
115,22 → 114,22
sysinfo_mem(0) <= hw_version_c; -- HW version |
|
-- CPUID1: System setup (available HW units / IO / peripheral devices) -- |
sysinfo_mem(1)(00) <= '1' when (MULDIV_USE = true) else '0'; -- MULDIV present? |
sysinfo_mem(1)(01) <= '1' when (WB32_USE = true) else '0'; -- WB32 present? |
sysinfo_mem(1)(02) <= '1' when (WDT_USE = true) else '0'; -- WDT present? |
sysinfo_mem(1)(03) <= '1' when (GPIO_USE = true) else '0'; -- GPIO present? |
sysinfo_mem(1)(04) <= '1' when (TIMER_USE = true) else '0'; -- TIMER present? |
sysinfo_mem(1)(05) <= '1' when (UART_USE = true) else '0'; -- UART present? |
sysinfo_mem(1)(06) <= '1' when (FREQ_GEN_USE = true) else '0'; -- FREQ_GEN present? |
sysinfo_mem(1)(07) <= '1' when (BOOTLD_USE = true) else '0'; -- bootloader present? |
sysinfo_mem(1)(08) <= '1' when (IMEM_AS_ROM = true) else '0'; -- IMEM implemented as true ROM? |
sysinfo_mem(1)(09) <= '1' when (CRC_USE = true) else '0'; -- CRC present? |
sysinfo_mem(1)(10) <= '1' when (CFU_USE = true) else '0'; -- CFU present? |
sysinfo_mem(1)(11) <= '1' when (PWM_USE = true) else '0'; -- PWM present? |
sysinfo_mem(1)(12) <= '1' when (TWI_USE = true) else '0'; -- TWI present? |
sysinfo_mem(1)(13) <= '1' when (SPI_USE = true) else '0'; -- SPI present? |
sysinfo_mem(1)(14) <= '1' when (TRNG_USE = true) else '0'; -- TRNG present? |
sysinfo_mem(1)(15) <= '1' when (EXIRQ_USE = true) else '0'; -- EXIRQ present? |
sysinfo_mem(1)(00) <= bool_to_ulogic_f(MULDIV_USE); -- MULDIV present? |
sysinfo_mem(1)(01) <= bool_to_ulogic_f(WB32_USE); -- WB32 present? |
sysinfo_mem(1)(02) <= bool_to_ulogic_f(WDT_USE); -- WDT present? |
sysinfo_mem(1)(03) <= bool_to_ulogic_f(GPIO_USE); -- GPIO present? |
sysinfo_mem(1)(04) <= bool_to_ulogic_f(TIMER_USE); -- TIMER present? |
sysinfo_mem(1)(05) <= bool_to_ulogic_f(UART_USE); -- UART present? |
sysinfo_mem(1)(06) <= '0'; -- reserved |
sysinfo_mem(1)(07) <= bool_to_ulogic_f(BOOTLD_USE); -- bootloader present? |
sysinfo_mem(1)(08) <= bool_to_ulogic_f(IMEM_AS_ROM); -- IMEM implemented as true ROM? |
sysinfo_mem(1)(09) <= bool_to_ulogic_f(CRC_USE); -- CRC present? |
sysinfo_mem(1)(10) <= bool_to_ulogic_f(CFU_USE); -- CFU present? |
sysinfo_mem(1)(11) <= bool_to_ulogic_f(PWM_USE); -- PWM present? |
sysinfo_mem(1)(12) <= bool_to_ulogic_f(TWI_USE); -- TWI present? |
sysinfo_mem(1)(13) <= bool_to_ulogic_f(SPI_USE); -- SPI present? |
sysinfo_mem(1)(14) <= bool_to_ulogic_f(TRNG_USE); -- TRNG present? |
sysinfo_mem(1)(15) <= bool_to_ulogic_f(EXIRQ_USE); -- EXIRQ present? |
|
-- CPUID2: User code -- |
sysinfo_mem(2) <= USER_CODE; |
/neo430/trunk/neo430/rtl/top_templates/neo430_test.vhd
71,29 → 71,28
neo430_top_test_inst: neo430_top |
generic map ( |
-- general configuration -- |
CLOCK_SPEED => 100000000, -- main clock in Hz |
IMEM_SIZE => 4*1024, -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE => 2*1024, -- internal DMEM size in bytes, max 12kB (default=2kB) |
CLOCK_SPEED => 100000000, -- main clock in Hz |
IMEM_SIZE => 4*1024, -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE => 2*1024, -- internal DMEM size in bytes, max 12kB (default=2kB) |
-- additional configuration -- |
USER_CODE => x"CAFE", -- custom user code |
USER_CODE => x"CAFE", -- custom user code |
-- module configuration -- |
MULDIV_USE => true, -- implement multiplier/divider unit? (default=true) |
WB32_USE => true, -- implement WB32 unit? (default=true) |
WDT_USE => true, -- implement WDT? (default=true) |
GPIO_USE => true, -- implement GPIO unit? (default=true) |
TIMER_USE => true, -- implement timer? (default=true) |
UART_USE => true, -- implement UART? (default=true) |
CRC_USE => true, -- implement CRC unit? (default=true) |
CFU_USE => false, -- implement custom functions unit? (default=false) |
PWM_USE => true, -- implement PWM controller? (default=true) |
TWI_USE => true, -- implement two wire serial interface? (default=true) |
SPI_USE => true, -- implement SPI? (default=true) |
TRNG_USE => false, -- implement TRNG? (default=false) |
EXIRQ_USE => true, -- implement EXIRQ? (default=true) |
FREQ_GEN_USE => true, -- implement FREQ_GEN? (default=true) |
MULDIV_USE => true, -- implement multiplier/divider unit? (default=true) |
WB32_USE => true, -- implement WB32 unit? (default=true) |
WDT_USE => true, -- implement WDT? (default=true) |
GPIO_USE => true, -- implement GPIO unit? (default=true) |
TIMER_USE => true, -- implement timer? (default=true) |
UART_USE => true, -- implement UART? (default=true) |
CRC_USE => true, -- implement CRC unit? (default=true) |
CFU_USE => false, -- implement custom functions unit? (default=false) |
PWM_USE => true, -- implement PWM controller? (default=true) |
TWI_USE => true, -- implement two wire serial interface? (default=true) |
SPI_USE => true, -- implement SPI? (default=true) |
TRNG_USE => false, -- implement TRNG? (default=false) |
EXIRQ_USE => true, -- implement EXIRQ? (default=true) |
-- boot configuration -- |
BOOTLD_USE => true, -- implement and use bootloader? (default=true) |
IMEM_AS_ROM => false -- implement IMEM as read-only memory? (default=false) |
BOOTLD_USE => true, -- implement and use bootloader? (default=true) |
IMEM_AS_ROM => false -- implement IMEM as read-only memory? (default=false) |
) |
port map ( |
-- global control -- |
104,8 → 103,8
gpio_i => x"0000", -- parallel input |
-- pwm channels -- |
pwm_o => open, -- pwm channels |
-- arbitrary frequency generator -- |
freq_gen_o => open, -- programmable frequency output |
-- timer frequency generator -- |
timer_fg_o => open, -- programmable frequency output |
-- serial com -- |
uart_txd_o => uart_txd_o, -- UART send data |
uart_rxd_i => uart_rxd_i, -- UART receive data |
/neo430/trunk/neo430/rtl/top_templates/neo430_top_avm.vhd
42,29 → 42,28
entity neo430_top_avm is |
generic ( |
-- general configuration -- |
CLOCK_SPEED : natural := 100000000; -- main clock in Hz |
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes, max 12kB (default=2kB) |
CLOCK_SPEED : natural := 100000000; -- main clock in Hz |
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes, max 12kB (default=2kB) |
-- additional configuration -- |
USER_CODE : std_logic_vector(15 downto 0) := x"0000"; -- custom user code |
USER_CODE : std_logic_vector(15 downto 0) := x"0000"; -- custom user code |
-- module configuration -- |
MULDIV_USE : boolean := true; -- implement multiplier/divider unit? (default=true) |
WB32_USE : boolean := true; -- implement WB32 unit? (default=true) |
WDT_USE : boolean := true; -- implement WDT? (default=true) |
GPIO_USE : boolean := true; -- implement GPIO unit? (default=true) |
TIMER_USE : boolean := true; -- implement timer? (default=true) |
UART_USE : boolean := true; -- implement UART? (default=true) |
CRC_USE : boolean := true; -- implement CRC unit? (default=true) |
CFU_USE : boolean := false; -- implement custom functions unit? (default=false) |
PWM_USE : boolean := true; -- implement PWM controller? |
TWI_USE : boolean := true; -- implement two wire serial interface? (default=true) |
SPI_USE : boolean := true; -- implement SPI? (default=true) |
TRNG_USE : boolean := false; -- implement TRNG? (default=false) |
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true) |
FREQ_GEN_USE : boolean := true; -- implement FREQ_GEN? (default=true) |
MULDIV_USE : boolean := true; -- implement multiplier/divider unit? (default=true) |
WB32_USE : boolean := true; -- implement WB32 unit? (default=true) |
WDT_USE : boolean := true; -- implement WDT? (default=true) |
GPIO_USE : boolean := true; -- implement GPIO unit? (default=true) |
TIMER_USE : boolean := true; -- implement timer? (default=true) |
UART_USE : boolean := true; -- implement UART? (default=true) |
CRC_USE : boolean := true; -- implement CRC unit? (default=true) |
CFU_USE : boolean := false; -- implement custom functions unit? (default=false) |
PWM_USE : boolean := true; -- implement PWM controller? |
TWI_USE : boolean := true; -- implement two wire serial interface? (default=true) |
SPI_USE : boolean := true; -- implement SPI? (default=true) |
TRNG_USE : boolean := false; -- implement TRNG? (default=false) |
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true) |
-- boot configuration -- |
BOOTLD_USE : boolean := true; -- implement and use bootloader? (default=true) |
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? (default=false) |
BOOTLD_USE : boolean := true; -- implement and use bootloader? (default=true) |
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? (default=false) |
); |
port ( |
-- global control -- |
75,8 → 74,8
gpio_i : in std_logic_vector(15 downto 0); -- parallel input |
-- pwm channels -- |
pwm_o : out std_logic_vector(03 downto 0); -- pwm channels |
-- arbitrary frequency generator -- |
freq_gen_o : out std_logic_vector(02 downto 0); -- programmable frequency output |
-- timer frequency generator -- |
timer_fg_o : out std_logic; -- programmable frequency output |
-- UART -- |
uart_txd_o : out std_logic; -- UART send data |
uart_rxd_i : in std_logic; -- UART receive data |
143,7 → 142,7
signal spi_cs_o_int : std_ulogic_vector(05 downto 0); |
signal irq_i_int : std_ulogic_vector(07 downto 0); |
signal irq_ack_o_int : std_ulogic_vector(07 downto 0); |
signal freq_gen_o_int : std_ulogic_vector(02 downto 0); |
signal timer_fg_o_int : std_ulogic; |
constant usrcode_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(USER_CODE); |
|
-- misc -- |
156,29 → 155,28
neo430_top_inst: neo430_top |
generic map ( |
-- general configuration -- |
CLOCK_SPEED => CLOCK_SPEED, -- main clock in Hz |
IMEM_SIZE => IMEM_SIZE, -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE => DMEM_SIZE, -- internal DMEM size in bytes, max 12kB (default=2kB) |
CLOCK_SPEED => CLOCK_SPEED, -- main clock in Hz |
IMEM_SIZE => IMEM_SIZE, -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE => DMEM_SIZE, -- internal DMEM size in bytes, max 12kB (default=2kB) |
-- additional configuration -- |
USER_CODE => usrcode_c, -- custom user code |
USER_CODE => usrcode_c, -- custom user code |
-- module configuration -- |
MULDIV_USE => MULDIV_USE, -- implement multiplier/divider unit? (default=true) |
WB32_USE => WB32_USE, -- implement WB32 unit? (default=true) |
WDT_USE => WDT_USE, -- implement WDT? (default=true) |
GPIO_USE => GPIO_USE, -- implement GPIO unit? (default=true) |
TIMER_USE => TIMER_USE, -- implement timer? (default=true) |
UART_USE => UART_USE, -- implement UART? (default=true) |
CRC_USE => CRC_USE, -- implement CRC unit? (default=true) |
CFU_USE => CFU_USE, -- implement CF unit? (default=false) |
PWM_USE => PWM_USE, -- implement PWM controller? (default=true) |
TWI_USE => TWI_USE, -- implement two wire serial interface? (default=true) |
SPI_USE => SPI_USE, -- implement SPI? (default=true) |
TRNG_USE => TRNG_USE, -- implement TRNG? (default=false) |
EXIRQ_USE => EXIRQ_USE, -- implement EXIRQ? (default=true) |
FREQ_GEN_USE => FREQ_GEN_USE, -- implement FREQ_GEN? (default=true) |
MULDIV_USE => MULDIV_USE, -- implement multiplier/divider unit? (default=true) |
WB32_USE => WB32_USE, -- implement WB32 unit? (default=true) |
WDT_USE => WDT_USE, -- implement WDT? (default=true) |
GPIO_USE => GPIO_USE, -- implement GPIO unit? (default=true) |
TIMER_USE => TIMER_USE, -- implement timer? (default=true) |
UART_USE => UART_USE, -- implement UART? (default=true) |
CRC_USE => CRC_USE, -- implement CRC unit? (default=true) |
CFU_USE => CFU_USE, -- implement CF unit? (default=false) |
PWM_USE => PWM_USE, -- implement PWM controller? (default=true) |
TWI_USE => TWI_USE, -- implement two wire serial interface? (default=true) |
SPI_USE => SPI_USE, -- implement SPI? (default=true) |
TRNG_USE => TRNG_USE, -- implement TRNG? (default=false) |
EXIRQ_USE => EXIRQ_USE, -- implement EXIRQ? (default=true) |
-- boot configuration -- |
BOOTLD_USE => BOOTLD_USE, -- implement and use bootloader? (default=true) |
IMEM_AS_ROM => IMEM_AS_ROM -- implement IMEM as read-only memory? (default=false) |
BOOTLD_USE => BOOTLD_USE, -- implement and use bootloader? (default=true) |
IMEM_AS_ROM => IMEM_AS_ROM -- implement IMEM as read-only memory? (default=false) |
) |
port map ( |
-- global control -- |
189,8 → 187,6
gpio_i => gpio_i_int, -- parallel input |
-- pwm channels -- |
pwm_o => pwm_o_int, -- pwm channels |
-- arbitrary frequency generator -- |
freq_gen_o => freq_gen_o_int, -- programmable frequency output |
-- serial com -- |
uart_txd_o => uart_txd_o_int, -- UART send data |
uart_rxd_i => uart_rxd_i_int, -- UART receive data |
231,7 → 227,7
spi_mosi_o <= std_logic(spi_mosi_o_int); |
spi_cs_o <= std_logic_vector(spi_cs_o_int); |
ext_ack_o <= std_logic_vector(irq_ack_o_int); |
freq_gen_o <= std_logic_vector(freq_gen_o_int); |
timer_fg_o <= std_logic(timer_fg_o_int); |
|
|
-- Wishbone-to-Avalon Bridge ------------------------------------------------ |
/neo430/trunk/neo430/rtl/top_templates/neo430_top_axi4lite.vhd
42,29 → 42,28
entity neo430_top_axi4lite is |
generic ( |
-- general configuration -- |
CLOCK_SPEED : natural := 100000000; -- main clock in Hz |
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes, max 32kB (default=4kB) |
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes, max 28kB (default=2kB) |
CLOCK_SPEED : natural := 100000000; -- main clock in Hz |
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes, max 32kB (default=4kB) |
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes, max 28kB (default=2kB) |
-- additional configuration -- |
USER_CODE : std_logic_vector(15 downto 0) := x"0000"; -- custom user code |
USER_CODE : std_logic_vector(15 downto 0) := x"0000"; -- custom user code |
-- module configuration -- |
MULDIV_USE : boolean := true; -- implement multiplier/divider unit? (default=true) |
WB32_USE : boolean := true; -- implement WB32 unit? (default=true) |
WDT_USE : boolean := true; -- implement WDT? (default=true) |
GPIO_USE : boolean := true; -- implement GPIO unit? (default=true) |
TIMER_USE : boolean := true; -- implement timer? (default=true) |
UART_USE : boolean := true; -- implement UART? (default=true) |
CRC_USE : boolean := true; -- implement CRC unit? (default=true) |
CFU_USE : boolean := false; -- implement custom functions unit? (default=false) |
PWM_USE : boolean := true; -- implement PWM controller? |
TWI_USE : boolean := true; -- implement two wire serial interface? (default=true) |
SPI_USE : boolean := true; -- implement SPI? (default=true) |
TRNG_USE : boolean := false; -- implement TRNG? (default=false) |
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true) |
FREQ_GEN_USE : boolean := true; -- implement FREQ_GEN? (default=true) |
MULDIV_USE : boolean := true; -- implement multiplier/divider unit? (default=true) |
WB32_USE : boolean := true; -- implement WB32 unit? (default=true) |
WDT_USE : boolean := true; -- implement WDT? (default=true) |
GPIO_USE : boolean := true; -- implement GPIO unit? (default=true) |
TIMER_USE : boolean := true; -- implement timer? (default=true) |
UART_USE : boolean := true; -- implement UART? (default=true) |
CRC_USE : boolean := true; -- implement CRC unit? (default=true) |
CFU_USE : boolean := false; -- implement custom functions unit? (default=false) |
PWM_USE : boolean := true; -- implement PWM controller? |
TWI_USE : boolean := true; -- implement two wire serial interface? (default=true) |
SPI_USE : boolean := true; -- implement SPI? (default=true) |
TRNG_USE : boolean := false; -- implement TRNG? (default=false) |
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true) |
-- boot configuration -- |
BOOTLD_USE : boolean := true; -- implement and use bootloader? (default=true) |
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? (default=false) |
BOOTLD_USE : boolean := true; -- implement and use bootloader? (default=true) |
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? (default=false) |
); |
port ( |
-- GPIO -- |
72,8 → 71,8
gpio_i : in std_logic_vector(15 downto 0); -- parallel input |
-- pwm channels -- |
pwm_o : out std_logic_vector(03 downto 0); -- pwm channels |
-- arbitrary frequency generator -- |
freq_gen_o : out std_logic_vector(02 downto 0); -- programmable frequency output |
-- timer frequency generator -- |
timer_fg_o : out std_logic; -- programmable frequency output |
-- UART -- |
uart_txd_o : out std_logic; -- UART send data |
uart_rxd_i : in std_logic; -- UART receive data |
145,7 → 144,7
signal spi_cs_o_int : std_ulogic_vector(05 downto 0); |
signal irq_i_int : std_ulogic_vector(07 downto 0); |
signal irq_ack_o_int : std_ulogic_vector(07 downto 0); |
signal freq_gen_o_int : std_ulogic_vector(02 downto 0); |
signal timer_fg_o_int : std_ulogic; |
constant usrcode_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(USER_CODE); |
|
-- AXI arbiter -- |
163,29 → 162,28
neo430_top_inst: neo430_top |
generic map ( |
-- general configuration -- |
CLOCK_SPEED => CLOCK_SPEED, -- main clock in Hz |
IMEM_SIZE => IMEM_SIZE, -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE => DMEM_SIZE, -- internal DMEM size in bytes, max 12kB (default=2kB) |
CLOCK_SPEED => CLOCK_SPEED, -- main clock in Hz |
IMEM_SIZE => IMEM_SIZE, -- internal IMEM size in bytes, max 32kB (default=4kB) |
DMEM_SIZE => DMEM_SIZE, -- internal DMEM size in bytes, max 28kB (default=2kB) |
-- additional configuration -- |
USER_CODE => usrcode_c, -- custom user code |
USER_CODE => usrcode_c, -- custom user code |
-- module configuration -- |
MULDIV_USE => MULDIV_USE, -- implement multiplier/divider unit? (default=true) |
WB32_USE => WB32_USE, -- implement WB32 unit? (default=true) |
WDT_USE => WDT_USE, -- implement WDT? (default=true) |
GPIO_USE => GPIO_USE, -- implement GPIO unit? (default=true) |
TIMER_USE => TIMER_USE, -- implement timer? (default=true) |
UART_USE => UART_USE, -- implement UART? (default=true) |
CRC_USE => CRC_USE, -- implement CRC unit? (default=true) |
CFU_USE => CFU_USE, -- implement CF unit? (default=false) |
PWM_USE => PWM_USE, -- implement PWM controller? (default=true) |
TWI_USE => TWI_USE, -- implement two wire serial interface? (default=true) |
SPI_USE => SPI_USE, -- implement SPI? (default=true) |
TRNG_USE => TRNG_USE, -- implement TRNG? (default=false) |
EXIRQ_USE => EXIRQ_USE, -- implement EXIRQ? (default=true) |
FREQ_GEN_USE => FREQ_GEN_USE, -- implement FREQ_GEN? (default=true) |
MULDIV_USE => MULDIV_USE, -- implement multiplier/divider unit? (default=true) |
WB32_USE => WB32_USE, -- implement WB32 unit? (default=true) |
WDT_USE => WDT_USE, -- implement WDT? (default=true) |
GPIO_USE => GPIO_USE, -- implement GPIO unit? (default=true) |
TIMER_USE => TIMER_USE, -- implement timer? (default=true) |
UART_USE => UART_USE, -- implement UART? (default=true) |
CRC_USE => CRC_USE, -- implement CRC unit? (default=true) |
CFU_USE => CFU_USE, -- implement CF unit? (default=false) |
PWM_USE => PWM_USE, -- implement PWM controller? (default=true) |
TWI_USE => TWI_USE, -- implement two wire serial interface? (default=true) |
SPI_USE => SPI_USE, -- implement SPI? (default=true) |
TRNG_USE => TRNG_USE, -- implement TRNG? (default=false) |
EXIRQ_USE => EXIRQ_USE, -- implement EXIRQ? (default=true) |
-- boot configuration -- |
BOOTLD_USE => BOOTLD_USE, -- implement and use bootloader? (default=true) |
IMEM_AS_ROM => IMEM_AS_ROM -- implement IMEM as read-only memory? (default=false) |
BOOTLD_USE => BOOTLD_USE, -- implement and use bootloader? (default=true) |
IMEM_AS_ROM => IMEM_AS_ROM -- implement IMEM as read-only memory? (default=false) |
) |
port map ( |
-- global control -- |
196,8 → 194,6
gpio_i => gpio_i_int, -- parallel input |
-- pwm channels -- |
pwm_o => pwm_o_int, -- pwm channels |
-- arbitrary frequency generator -- |
freq_gen_o => freq_gen_o_int, -- programmable frequency output |
-- serial com -- |
uart_txd_o => uart_txd_o_int, -- UART send data |
uart_rxd_i => uart_rxd_i_int, -- UART receive data |
236,7 → 232,7
spi_mosi_o <= std_logic(spi_mosi_o_int); |
spi_cs_o <= std_logic_vector(spi_cs_o_int); |
ext_ack_o <= std_logic_vector(irq_ack_o_int); |
freq_gen_o <= std_logic_vector(freq_gen_o_int); |
timer_fg_o <= std_logic(timer_fg_o_int); |
|
|
-- Wishbone-to-AXI4-Lite-compatible Bridge ---------------------------------- |
/neo430/trunk/neo430/rtl/top_templates/neo430_top_std_logic.vhd
42,29 → 42,28
entity neo430_top_std_logic is |
generic ( |
-- general configuration -- |
CLOCK_SPEED : natural := 100000000; -- main clock in Hz |
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes, max 12kB (default=2kB) |
CLOCK_SPEED : natural := 100000000; -- main clock in Hz |
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes, max 12kB (default=2kB) |
-- additional configuration -- |
USER_CODE : std_logic_vector(15 downto 0) := x"0000"; -- custom user code |
USER_CODE : std_logic_vector(15 downto 0) := x"0000"; -- custom user code |
-- module configuration -- |
MULDIV_USE : boolean := true; -- implement multiplier/divider unit? (default=true) |
WB32_USE : boolean := true; -- implement WB32 unit? (default=true) |
WDT_USE : boolean := true; -- implement WDT? (default=true) |
GPIO_USE : boolean := true; -- implement GPIO unit? (default=true) |
TIMER_USE : boolean := true; -- implement timer? (default=true) |
UART_USE : boolean := true; -- implement UART? (default=true) |
CRC_USE : boolean := true; -- implement CRC unit? (default=true) |
CFU_USE : boolean := false; -- implement custom functions unit? (default=false) |
PWM_USE : boolean := true; -- implement PWM controller? |
TWI_USE : boolean := true; -- implement two wire serial interface? (default=true) |
SPI_USE : boolean := true; -- implement SPI? (default=true) |
TRNG_USE : boolean := false; -- implement TRNG? (default=false) |
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true) |
FREQ_GEN_USE : boolean := true; -- implement FREQ_GEN? (default=true) |
MULDIV_USE : boolean := true; -- implement multiplier/divider unit? (default=true) |
WB32_USE : boolean := true; -- implement WB32 unit? (default=true) |
WDT_USE : boolean := true; -- implement WDT? (default=true) |
GPIO_USE : boolean := true; -- implement GPIO unit? (default=true) |
TIMER_USE : boolean := true; -- implement timer? (default=true) |
UART_USE : boolean := true; -- implement UART? (default=true) |
CRC_USE : boolean := true; -- implement CRC unit? (default=true) |
CFU_USE : boolean := false; -- implement custom functions unit? (default=false) |
PWM_USE : boolean := true; -- implement PWM controller? |
TWI_USE : boolean := true; -- implement two wire serial interface? (default=true) |
SPI_USE : boolean := true; -- implement SPI? (default=true) |
TRNG_USE : boolean := false; -- implement TRNG? (default=false) |
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true) |
-- boot configuration -- |
BOOTLD_USE : boolean := true; -- implement and use bootloader? (default=true) |
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? (default=false) |
BOOTLD_USE : boolean := true; -- implement and use bootloader? (default=true) |
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? (default=false) |
); |
port ( |
-- global control -- |
75,8 → 74,8
gpio_i : in std_logic_vector(15 downto 0); -- parallel input |
-- pwm channels -- |
pwm_o : out std_logic_vector(03 downto 0); -- pwm channels |
-- arbitrary frequency generator -- |
freq_gen_o : out std_logic_vector(02 downto 0); -- programmable frequency output |
-- timer frequency generator -- |
timer_fg_o : out std_logic; -- programmable frequency output |
-- serial com -- |
uart_txd_o : out std_logic; -- UART send data |
uart_rxd_i : in std_logic; -- UART receive data |
126,7 → 125,7
signal wb_stb_o_int : std_ulogic; |
signal wb_cyc_o_int : std_ulogic; |
signal wb_ack_i_int : std_ulogic; |
signal freq_gen_o_int : std_ulogic_vector(02 downto 0); |
signal timer_fg_o_int : std_ulogic; |
|
begin |
|
135,29 → 134,28
neo430_top_inst: neo430_top |
generic map ( |
-- general configuration -- |
CLOCK_SPEED => CLOCK_SPEED, -- main clock in Hz |
IMEM_SIZE => IMEM_SIZE, -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE => DMEM_SIZE, -- internal DMEM size in bytes, max 12kB (default=2kB) |
CLOCK_SPEED => CLOCK_SPEED, -- main clock in Hz |
IMEM_SIZE => IMEM_SIZE, -- internal IMEM size in bytes, max 48kB (default=4kB) |
DMEM_SIZE => DMEM_SIZE, -- internal DMEM size in bytes, max 12kB (default=2kB) |
-- additional configuration -- |
USER_CODE => usrcode_c, -- custom user code |
USER_CODE => usrcode_c, -- custom user code |
-- module configuration -- |
MULDIV_USE => MULDIV_USE, -- implement multiplier/divider unit? (default=true) |
WB32_USE => WB32_USE, -- implement WB32 unit? (default=true) |
WDT_USE => WDT_USE, -- implement WDT? (default=true) |
GPIO_USE => GPIO_USE, -- implement GPIO unit? (default=true) |
TIMER_USE => TIMER_USE, -- implement timer? (default=true) |
UART_USE => UART_USE, -- implement UART? (default=true) |
CRC_USE => CRC_USE, -- implement CRC unit? (default=true) |
CFU_USE => CFU_USE, -- implement CF unit? (default=false) |
PWM_USE => PWM_USE, -- implement PWM controller? (default=true) |
TWI_USE => TWI_USE, -- implement two wire serial interface? (default=true) |
SPI_USE => SPI_USE, -- implement SPI? (default=true) |
TRNG_USE => TRNG_USE, -- implement TRNG? (default=false) |
EXIRQ_USE => EXIRQ_USE, -- implement EXIRQ? (default=true) |
FREQ_GEN_USE => FREQ_GEN_USE, -- implement FREQ_GEN? (default=true) |
MULDIV_USE => MULDIV_USE, -- implement multiplier/divider unit? (default=true) |
WB32_USE => WB32_USE, -- implement WB32 unit? (default=true) |
WDT_USE => WDT_USE, -- implement WDT? (default=true) |
GPIO_USE => GPIO_USE, -- implement GPIO unit? (default=true) |
TIMER_USE => TIMER_USE, -- implement timer? (default=true) |
UART_USE => UART_USE, -- implement UART? (default=true) |
CRC_USE => CRC_USE, -- implement CRC unit? (default=true) |
CFU_USE => CFU_USE, -- implement CF unit? (default=false) |
PWM_USE => PWM_USE, -- implement PWM controller? (default=true) |
TWI_USE => TWI_USE, -- implement two wire serial interface? (default=true) |
SPI_USE => SPI_USE, -- implement SPI? (default=true) |
TRNG_USE => TRNG_USE, -- implement TRNG? (default=false) |
EXIRQ_USE => EXIRQ_USE, -- implement EXIRQ? (default=true) |
-- boot configuration -- |
BOOTLD_USE => BOOTLD_USE, -- implement and use bootloader? (default=true) |
IMEM_AS_ROM => IMEM_AS_ROM -- implement IMEM as read-only memory? (default=false) |
BOOTLD_USE => BOOTLD_USE, -- implement and use bootloader? (default=true) |
IMEM_AS_ROM => IMEM_AS_ROM -- implement IMEM as read-only memory? (default=false) |
) |
port map ( |
-- global control -- |
168,8 → 166,6
gpio_i => gpio_i_int, -- parallel input |
-- pwm channels -- |
pwm_o => pwm_o_int, -- pwm channels |
-- arbitrary frequency generator -- |
freq_gen_o => freq_gen_o_int, -- programmable frequency output |
-- serial com -- |
uart_txd_o => uart_txd_o_int, -- UART send data |
uart_rxd_i => uart_rxd_i_int, -- UART receive data |
218,7 → 214,7
wb_stb_o <= std_logic(wb_stb_o_int); |
wb_cyc_o <= std_logic(wb_cyc_o_int); |
ext_ack_o <= std_logic_vector(irq_ack_o_int); |
freq_gen_o <= std_logic_vector(freq_gen_o_int); |
timer_fg_o <= std_logic(timer_fg_o_int); |
|
|
end neo430_top_std_logic_rtl; |
/neo430/trunk/neo430/sw/example/freq_gen_demo/main.c
File deleted
/neo430/trunk/neo430/sw/example/timer_simple/main.c
86,10 → 86,26
// enable global IRQs |
neo430_eint(); |
|
|
// test frequency generator |
neo430_timer_nco_enable(); |
uint32_t nco_target_frequency = 0, nco_real_frequency; |
|
while(1) { |
neo430_sleep(); |
neo430_uart_br_print("Target freq.: 0x"); |
neo430_uart_print_hex_dword(nco_target_frequency); |
|
nco_real_frequency = neo430_timer_nco_set(nco_target_frequency); |
|
neo430_uart_br_print(", Real freq.: 0x"); |
neo430_uart_print_hex_dword(nco_real_frequency); |
neo430_uart_br_print("\n"); |
|
nco_target_frequency++; // go through all possible frequencies |
neo430_cpu_delay_ms(250); // wait 250ms |
} |
|
|
return 0; |
} |
|
/neo430/trunk/neo430/sw/example/README.md
0,0 → 1,107
## Example SW Project |
|
|
### blink_led |
|
A simple "hello world" program blinking some LEDs. You can use this as your first test program. |
|
|
### cfu_test |
|
This program tests if the CFU is synthesized and performs a simple write and read-back using all |
CFU registers. |
|
|
### coremark |
|
CPU performance benchmark. You will see a warning when compiling this project to use a specific |
flag in your command to really compile it. |
|
|
### crc_test |
|
Allows a user-defined test of the NEO430 checksum unit. |
|
|
### exirq_test |
|
Shows how to use the external interrupts controller. |
|
|
### game_of_life |
|
The classic game of life for the NEO430. Aww, so pretty :D |
|
|
### gpio_interrupt |
|
Shows how to use the pin-change interrupts of the GPIO module. |
|
|
### gpio_pwm_demo |
|
This example just uses a sw pwm for the GPIO outputs. |
|
|
### hw_analysis |
|
This program checks which optional modules are synthesized in your design and gives some basic |
information regarding HW version and memory configuration. |
|
|
### morse_translator |
|
A kinda useless program that outputs a user-defined text as Morse code to an LED connected to |
the GPIO output. |
|
|
### muldiv_test |
|
This test program tests the multiplier and divider unit using ALL possible test cases and compares |
the results to a pure-sw reference. |
|
|
### nested_irq |
|
A simple example showing how to implement nested IRQs for the NEO430. |
|
|
### prime_numbers |
|
This program outputs prime numbers using the NEO430 version of printf. |
|
|
### pwm_demo |
|
Just an example on how to use the NEO430 PWM unit. |
|
|
### timer_simple |
|
As the name suggests, a simple how-to for the TIMER unit. |
|
|
### trng_test |
|
This sw project uses the TRNG. It can generate a histogram based on the generated random data or just |
output raw random data. |
|
|
### twi_test |
|
An interactive program to check the TWI bus. |
|
|
### uart_irq |
|
Shows how to use the UART with RX and TX interrupts. |
|
|
### wb_terminal |
|
A terminal program to explore devices connected to the Wishbone bus. |
|
|
### wdt_test |
|
A simple usage example for the watchdog timer. |
/neo430/trunk/neo430/sw/lib/neo430/include/neo430.h
86,46 → 86,26
// ---------------------------------------------------------------------------- |
// Unsigned Multiplier/Divider Unit (MULDIV) |
// ---------------------------------------------------------------------------- |
#define MULDIV_OPA_RESX (*(REG16 0xFF80)) // r/w: operand A (dividend or factor1) / resx: quotient or product low word |
#define MULDIV_OPB_UMUL_RESY (*(REG16 0xFF82)) // r/w: operand B (factor2) for unsigned multiplication / resy: remainder or product high word |
#define MULDIV_OPB_SMUL (*(REG16 0xFF84)) // -/w: operand B (factor2) for signed multiplication |
#define MULDIV_OPB_UDIV (*(REG16 0xFF86)) // -/w: operand B (divisor) for unsigned division |
#define MULDIV_R32bit (*(ROM32 (&MULDIV_OPA_RESX))) // r/-: read result as 32-bit data word |
#define MULDIV_OPA_CTRL (*(REG16 0xFF80)) // -/w: operand A (dividend or factor1) / function config |
#define MULDIV_OPB (*(REG16 0xFF82)) // -/w: operand B (factor2) for multiplication |
#define MULDIV_RESX (*(ROM16 0xFF84)) // r/-: quotient or product low word |
#define MULDIV_RESY (*(ROM16 0xFF86)) // r/-: remainder or product high word |
#define MULDIV_R32bit (*(ROM32 (&MULDIV_RESX))) // r/-: read result as 32-bit data word |
|
// function config bits |
#define MULDIV_CONFIG_MUL ((uint16_t)(0b01 << 0)) |
#define MULDIV_CONFIG_DIV ((uint16_t)(0b10 << 0)) |
|
|
// ---------------------------------------------------------------------------- |
// Frequency Generator (FREQ_GEN) |
// reserved |
// ---------------------------------------------------------------------------- |
#define FREQ_GEN_CT (*(REG16 0xFF88)) // r/w: control register |
#define FREQ_GEN_TW_CH0 (*(REG16 0xFF8A)) // -/w: tuning word channel 0 |
#define FREQ_GEN_TW_CH1 (*(REG16 0xFF8C)) // -/w: tuning word channel 1 |
#define FREQ_GEN_TW_CH2 (*(REG16 0xFF8E)) // -/w: tuning word channel 2 |
//#define reserved (*(REG16 0xFF88)) // -/-: reserved |
//#define reserved (*(REG16 0xFF8A)) // -/-: reserved |
//#define reserved (*(REG16 0xFF8E)) // -/-: reserved |
//#define reserved (*(REG16 0xFF8E)) // -/-: reserved |
|
// FREQ_GEN control register |
#define FREQ_GEN_CT_CH0_EN 0 // r/w: enable NCO channel 0 |
#define FREQ_GEN_CT_CH1_EN 1 // r/w: enable NCO channel 1 |
#define FREQ_GEN_CT_CH2_EN 2 // r/w: enable NCO channel 2 |
#define FREQ_GEN_CT_CH0_PRSC0 3 // r/w: prescaler select bit 0 for channel 0 |
#define FREQ_GEN_CT_CH0_PRSC1 4 // r/w: prescaler select bit 1 for channel 0 |
#define FREQ_GEN_CT_CH0_PRSC2 5 // r/w: prescaler select bit 2 for channel 0 |
#define FREQ_GEN_CT_CH1_PRSC0 6 // r/w: prescaler select bit 0 for channel 1 |
#define FREQ_GEN_CT_CH1_PRSC1 7 // r/w: prescaler select bit 1 for channel 1 |
#define FREQ_GEN_CT_CH1_PRSC2 8 // r/w: prescaler select bit 2 for channel 1 |
#define FREQ_GEN_CT_CH2_PRSC0 9 // r/w: prescaler select bit 0 for channel 2 |
#define FREQ_GEN_CT_CH2_PRSC1 10 // r/w: prescaler select bit 1 for channel 2 |
#define FREQ_GEN_CT_CH2_PRSC2 11 // r/w: prescaler select bit 2 for channel 2 |
|
// clock prescalers |
#define FREQ_GEN_PRSC_2 0 // CLK/2 |
#define FREQ_GEN_PRSC_4 1 // CLK/4 |
#define FREQ_GEN_PRSC_8 2 // CLK/8 |
#define FREQ_GEN_PRSC_64 3 // CLK/64 |
#define FREQ_GEN_PRSC_128 4 // CLK/128 |
#define FREQ_GEN_PRSC_1024 5 // CLK/1024 |
#define FREQ_GEN_PRSC_2048 6 // CLK/2048 |
#define FREQ_GEN_PRSC_4096 7 // CLK/4096 |
|
|
// ---------------------------------------------------------------------------- |
// Wishbone Bus Adapter (WB32) |
// ---------------------------------------------------------------------------- |
236,19 → 216,23
// ---------------------------------------------------------------------------- |
// High-Precision Timer (TIMER) |
// ---------------------------------------------------------------------------- |
#define TMR_CT (*(REG16 0xFFB0)) // r/w: control register |
#define TMR_CNT (*(ROM16 0xFFB2)) // r/-: counter register |
#define TMR_THRES (*(REG16 0xFFB4)) // -/w: threshold register |
//#define reserved (*(REG16 0xFFB6)) // reserved |
#define TMR_CT (*(REG16 0xFFB0)) // r/w: control register |
#define TMR_CNT (*(ROM16 0xFFB2)) // r/-: counter register |
#define TMR_THRES (*(REG16 0xFFB4)) // -/w: threshold register |
#define TMR_NCO (*(REG16 0xFFB6)) // -/w: frequency generator |
|
// Timer control register |
#define TMR_CT_EN 0 // r/w: timer unit global enable |
#define TMR_CT_ARST 1 // r/w: auto reset on match |
#define TMR_CT_IRQ 2 // r/w: interrupt enable |
#define TMR_CT_RUN 3 // r/w: start/stop timer |
#define TMR_CT_PRSC0 4 // r/w: clock prescaler select bit 0 |
#define TMR_CT_PRSC1 5 // r/w: clock prescaler select bit 1 |
#define TMR_CT_PRSC2 6 // r/w: clock prescaler select bit 2 |
#define TMR_CT_EN 0 // r/w: timer unit global enable |
#define TMR_CT_ARST 1 // r/w: auto reset on match |
#define TMR_CT_IRQ 2 // r/w: interrupt enable |
#define TMR_CT_RUN 3 // r/w: start/stop timer |
#define TMR_CT_PRSC0 4 // r/w: clock prescaler select bit 0 |
#define TMR_CT_PRSC1 5 // r/w: clock prescaler select bit 1 |
#define TMR_CT_PRSC2 6 // r/w: clock prescaler select bit 2 |
#define TMR_CT_NCO_EN 7 // r/w: NCO enable |
#define TMR_CT_NCO_PRSC0 8 // r/w: NCO prescaler select bit 0 |
#define TMR_CT_NCO_PRSC1 9 // r/w: NCO prescaler select bit 1 |
#define TMR_CT_NCO_PRSC2 10 // r/w: NCO prescaler select bit 2 |
|
// Timer clock prescaler select: |
#define TMR_PRSC_2 0 // CLK/2 |
466,7 → 450,7
#define SYS_GPIO_EN 3 // r/-: GPIO synthesized |
#define SYS_TIMER_EN 4 // r/-: TIMER synthesized |
#define SYS_UART_EN 5 // r/-: UART synthesized |
#define SYS_FREQ_GEN_EN 6 // r/-: FREQ_GEN synthesized |
//#define SYS_???_EN 6 // r/-: reserved |
#define SYS_BTLD_EN 7 // r/-: Bootloader installed and enabled |
#define SYS_IROM_EN 8 // r/-: Implement IMEM as true ROM |
#define SYS_CRC_EN 9 // r/-: CRC synthesized |
484,7 → 468,6
#include "neo430_cpu.h" |
#include "neo430_crc.h" |
#include "neo430_exirq.h" |
#include "neo430_freq_gen.h" |
#include "neo430_gpio.h" |
#include "neo430_muldiv.h" |
#include "neo430_pwm.h" |
/neo430/trunk/neo430/sw/lib/neo430/include/neo430_timer.h
37,9 → 37,12
|
// prototypes |
void neo430_timer_enable(void); // enable timer unit |
void neo430_timer_disable(void); // disable (and reset) timer unit |
void neo430_timer_disable(void); // disable timer unit |
void neo430_timer_run(void); // run timer |
void neo430_timer_pause(void); // pause timer |
uint8_t neo430_timer_config_freq(uint32_t f_timer, uint16_t *thres); // configure timer frequency |
void neo430_timer_nco_enable(void); // enable programmable frequency output |
void neo430_timer_nco_disable(void); // disable programmable frequency output |
uint32_t neo430_timer_nco_set(uint32_t frequency); // set programmable output frequency, returns actual output frequency |
|
#endif // neo430_timer_h |
/neo430/trunk/neo430/sw/lib/neo430/source/neo430_timer.c
35,7 → 35,10
#include "neo430.h" |
#include "neo430_timer.h" |
|
// Private function prototypes |
static uint32_t neo430_timer_nco_real_output(uint16_t tuning_word, uint16_t prsc_shift); |
|
|
/* ------------------------------------------------------------ |
* INFO Activate Timer |
* ------------------------------------------------------------ */ |
46,7 → 49,7
|
|
/* ------------------------------------------------------------ |
* INFO Deactivate (and reset) Timer |
* INFO Dectivate Timer |
* ------------------------------------------------------------ */ |
void neo430_timer_disable(void) { |
|
64,7 → 67,7
|
|
/* ------------------------------------------------------------ |
* INFO Pause Timer |
* INFO Stop Timer |
* ------------------------------------------------------------ */ |
void neo430_timer_pause(void) { |
|
110,3 → 113,110
|
return 0; |
} |
|
|
/* ------------------------------------------------------------ |
* INFO Enable programmable frequency output (NCO) |
* ------------------------------------------------------------ */ |
void neo430_timer_nco_enable(void) { |
|
TMR_CT |= (1<<TMR_CT_NCO_EN); |
} |
|
|
/* ------------------------------------------------------------ |
* INFO Disable programmable frequency output (NCO) |
* ------------------------------------------------------------ */ |
void neo430_timer_nco_disable(void) { |
|
TMR_CT &= ~(1<<TMR_CT_NCO_EN); |
} |
|
|
/* ------------------------------------------------------------ |
* INFO Set frequency programmable frequency output |
* INFO f_out = ((f_cpu / nco_prsc) * tuning_word[15:0]) / 2^17 |
* PARAM frequency: output frequency in Hz (no fractions possible here) |
* RETURN the actual output frequency |
* ------------------------------------------------------------ */ |
uint32_t neo430_timer_nco_set(uint32_t frequency) { |
|
// tuning_word = (f_out * 2^17) / (f_cpu / nco_prsc) |
|
uint32_t f_cpu = CLOCKSPEED_32bit; |
|
int16_t i; |
uint16_t prsc_shift = 12; // start with highest prescaler (4096 => 12) |
|
if (frequency > (f_cpu/4)) { |
return 0; |
} |
|
uint64_t freq_tmp; |
uint32_t freq_real; |
uint32_t freq_diff; |
|
uint32_t freq_diff_best = 0xffffffff; // max |
uint16_t tuning_word_best = 0; |
uint16_t prsc_best = 0; |
uint32_t freq_real_best = 0; |
|
// check all possible prescaler |
for(i=7; i>=0; i--) { |
|
freq_tmp = (uint64_t)frequency; |
freq_tmp = freq_tmp << (17 + prsc_shift); // multiply via bit shifts |
freq_tmp = freq_tmp / f_cpu; |
|
uint16_t tuning_word = (uint16_t)(freq_tmp); |
|
// add 1 to tuning word (for rounding issues) |
freq_real = neo430_timer_nco_real_output(tuning_word+1, prsc_shift); |
|
freq_diff = freq_real - frequency; |
if ((int32_t)freq_diff < 0) { |
freq_diff = 0 - freq_diff; |
} |
|
// best result yet? |
if (freq_diff < freq_diff_best) { |
tuning_word_best = tuning_word; |
prsc_best = i; |
freq_diff_best = freq_diff; |
freq_real_best = freq_real; |
} |
|
// compute next prescaler |
if ((i == 5) || (i == 3)) { |
prsc_shift = prsc_shift - 3; |
} |
else { |
prsc_shift = prsc_shift - 1; |
} |
} |
|
// write config to NCO |
uint16_t timer_ctrl = TMR_CT; |
timer_ctrl &= ~(0b111 << TMR_CT_NCO_PRSC0); // clear old prescaler config |
TMR_CT = timer_ctrl | (prsc_best << TMR_CT_NCO_PRSC0); // set new prescaler config |
TMR_NCO = tuning_word_best; // set timer's NCO tuning word |
|
return freq_real_best; |
} |
|
|
/* ------------------------------------------------------------ |
* INFO Compute actual NCO output frequency based on tuning word and prescaler |
* RETURN the actual output frequency in Hz |
* ------------------------------------------------------------ */ |
static uint32_t neo430_timer_nco_real_output(uint16_t tuning_word, uint16_t prsc_shift) { |
|
// f_out = ((f_cpu/nco_prsc) * tuning_word[15:0]) / 2^17 |
|
uint32_t f_cpu = CLOCKSPEED_32bit; |
uint64_t f_out = (uint64_t)f_cpu; |
f_out = f_out * tuning_word; |
f_out = f_out >> (17 + prsc_shift); // divide by 2^17 * PRSC |
|
return (uint32_t)f_out; |
} |
/neo430/trunk/neo430/sw/lib/neo430/source/neo430_muldiv.c
35,7 → 35,11
#include "neo430.h" |
#include "neo430_muldiv.h" |
|
// private prototypes |
static inline void neo430_muldiv_set_mul(void); |
static inline void neo430_muldiv_set_div(void); |
|
|
/* ------------------------------------------------------------ |
* INFO Unsigned 16x16-bit multiplication |
* PARAM 16-bit factor a |
44,8 → 48,9
* ------------------------------------------------------------ */ |
uint32_t neo430_umul32(uint16_t a, uint16_t b) { |
|
MULDIV_OPA_RESX = a; |
MULDIV_OPB_UMUL_RESY = b; |
neo430_muldiv_set_mul(); |
MULDIV_OPA_CTRL = a; |
MULDIV_OPB = b; |
|
// HW processing delay |
asm volatile("nop"); |
64,9 → 69,18
* ------------------------------------------------------------ */ |
int32_t neo430_mul32(int16_t a, int16_t b) { |
|
MULDIV_OPA_RESX = (uint16_t)a; |
MULDIV_OPB_SMUL = (uint16_t)b; |
int16_t sign = a ^ b; |
|
// make positive / unsigned |
if (a < 0) |
a = 0 - a; |
if (b < 0) |
b = 0 - b; |
|
neo430_muldiv_set_mul(); |
MULDIV_OPA_CTRL = (uint16_t)a; |
MULDIV_OPB = (uint16_t)b; |
|
// HW processing delay |
asm volatile("nop"); |
asm volatile("nop"); |
74,7 → 88,10
|
int32_t r = (int32_t)MULDIV_R32bit; |
|
return r; |
if (sign < 0) |
return 0 - r; |
else |
return r; |
} |
|
|
86,8 → 103,9
* ------------------------------------------------------------ */ |
uint16_t neo430_udiv16(uint16_t dividend, uint16_t divisor) { |
|
MULDIV_OPA_RESX = dividend; |
MULDIV_OPB_UDIV = divisor; |
neo430_muldiv_set_div(); |
MULDIV_OPA_CTRL = dividend; |
MULDIV_OPB = divisor; |
|
// HW processing delay |
asm volatile("nop"); |
94,7 → 112,7
asm volatile("nop"); |
asm volatile("nop"); |
|
return MULDIV_OPA_RESX; |
return MULDIV_RESX; |
} |
|
|
112,8 → 130,9
if (divisor < 0) |
divisor = 0 - divisor; |
|
MULDIV_OPA_RESX = (uint16_t)dividend; |
MULDIV_OPB_UDIV = (uint16_t)divisor; |
neo430_muldiv_set_div(); |
MULDIV_OPA_CTRL = (uint16_t)dividend; |
MULDIV_OPB = (uint16_t)divisor; |
|
// HW processing delay |
asm volatile("nop"); |
120,7 → 139,7
asm volatile("nop"); |
asm volatile("nop"); |
|
int16_t r = (int16_t)MULDIV_OPA_RESX; |
int16_t r = (int16_t)MULDIV_RESX; |
|
if (dividend < 0) |
return 0 - r; |
137,8 → 156,9
* ------------------------------------------------------------ */ |
uint16_t neo430_umod16(uint16_t dividend, uint16_t divisor) { |
|
MULDIV_OPA_RESX = dividend; |
MULDIV_OPB_UDIV = divisor; |
neo430_muldiv_set_div(); |
MULDIV_OPA_CTRL = dividend; |
MULDIV_OPB = divisor; |
|
// HW processing delay |
asm volatile("nop"); |
145,7 → 165,7
asm volatile("nop"); |
asm volatile("nop"); |
|
return MULDIV_OPB_UMUL_RESY; |
return MULDIV_RESY; |
} |
|
|
165,8 → 185,9
if (divisor < 0) |
divisor = 0 - divisor; |
|
MULDIV_OPA_RESX = (uint16_t)dividend_int; |
MULDIV_OPB_UDIV = (uint16_t)divisor; |
neo430_muldiv_set_div(); |
MULDIV_OPA_CTRL = (uint16_t)dividend_int; |
MULDIV_OPB = (uint16_t)divisor; |
|
// HW processing delay |
asm volatile("nop"); |
173,7 → 194,7
asm volatile("nop"); |
asm volatile("nop"); |
|
int16_t r = (int16_t)MULDIV_OPB_UMUL_RESY; |
int16_t r = (int16_t)MULDIV_RESY; |
|
if (dividend < 0) |
return 0 - r; |
191,8 → 212,9
* ------------------------------------------------------------ */ |
uint16_t neo430_umoddiv16(uint16_t *remainder, uint16_t dividend, uint16_t divisor) { |
|
MULDIV_OPA_RESX = dividend; |
MULDIV_OPB_UDIV = divisor; |
neo430_muldiv_set_div(); |
MULDIV_OPA_CTRL = dividend; |
MULDIV_OPB = divisor; |
|
// HW processing delay |
asm volatile("nop"); |
199,8 → 221,8
asm volatile("nop"); |
asm volatile("nop"); |
|
*remainder = MULDIV_OPB_UMUL_RESY; |
return MULDIV_OPA_RESX; |
*remainder = MULDIV_RESY; |
return MULDIV_RESX; |
} |
|
|
222,8 → 244,9
if (divisor < 0) |
divisor = 0 - divisor; |
|
MULDIV_OPA_RESX = (uint16_t)dividend_int; |
MULDIV_OPB_UDIV = (uint16_t)divisor; |
neo430_muldiv_set_div(); |
MULDIV_OPA_CTRL = (uint16_t)dividend_int; |
MULDIV_OPB = (uint16_t)divisor; |
|
// HW processing delay |
asm volatile("nop"); |
230,8 → 253,8
asm volatile("nop"); |
asm volatile("nop"); |
|
int16_t q = (int16_t)MULDIV_OPA_RESX; |
int16_t r = (int16_t)MULDIV_OPB_UMUL_RESY; |
int16_t q = (int16_t)MULDIV_RESX; |
int16_t r = (int16_t)MULDIV_RESY; |
|
if (dividend < 0) |
*remainder = 0 - r; |
243,3 → 266,24
else |
return q; |
} |
|
|
/* ------------------------------------------------------------ |
* INFO Configure MULDIV for multiplication |
* ------------------------------------------------------------ */ |
static inline void neo430_muldiv_set_mul(void) { |
|
MULDIV_OPA_CTRL = 0x0000; // reset |
MULDIV_OPA_CTRL = MULDIV_CONFIG_MUL; // configure for multiplication |
} |
|
|
/* ------------------------------------------------------------ |
* INFO Configure MULDIV for division |
* ------------------------------------------------------------ */ |
static inline void neo430_muldiv_set_div(void) { |
|
MULDIV_OPA_CTRL = 0x0000; // reset |
MULDIV_OPA_CTRL = MULDIV_CONFIG_DIV; // configure for division |
} |
|
/neo430/trunk/neo430/sw/bootloader/bootloader.c
139,9 → 139,6
// disable EXIRQ |
EXIRQ_CT = 0; |
|
// disable FREQ_GEN |
FREQ_GEN_CT = 0; |
|
// init GPIO |
GPIO_IRQMASK = 0; // no pin change interrupt please, thanks |
neo430_gpio_port_set(1<<STATUS_LED); // activate status LED, clear all others |
162,6 → 159,7
|
// Timeout counter: init timer, irq tick @ ~1Hz (prescaler = 4096) |
// THR = f_main / (1Hz + 4096) -1 |
TMR_NCO = 0; // disable frequency generator |
TMR_CT = 0; // reset timer |
//uint32_t clock = CLOCKSPEED_32bit >> 14; // divide by 4096 |
TMR_THRES = (CLOCKSPEED_HI << 2) -1; // "fake" ;D |
/neo430/trunk/neo430/sim/neo430_tb.vhd
122,7 → 122,6
SPI_USE => true, -- implement SPI? (default=true) |
TRNG_USE => false, -- implement TRNG? (default=false) - CANNOT BE SIMULATED! |
EXIRQ_USE => true, -- implement EXIRQ? (default=true) |
FREQ_GEN_USE => true, -- implement FREQ_GEN? (default=true) |
-- boot configuration -- |
BOOTLD_USE => false, -- implement and use bootloader? (default=true) |
IMEM_AS_ROM => false -- implement IMEM as read-only memory? (default=false) |
136,8 → 135,8
gpio_i => x"0000", -- parallel input |
-- pwm channels -- |
pwm_o => open, -- pwm channels |
-- arbitrary frequency generator -- |
freq_gen_o => open, -- programmable frequency output |
-- timer frequency generator -- |
timer_fg_o => open, -- programmable frequency output |
-- serial com -- |
uart_txd_o => uart_txd, -- UART send data |
uart_rxd_i => uart_txd, -- UART receive data |
/neo430/trunk/neo430/sim/ghdl/ghdl_run.sh
26,7 → 26,6
ghdl -a --work=neo430 $srcdir_core/neo430_crc.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_dmem.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_exirq.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_freq_gen.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_gpio.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_imem.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_muldiv.vhd |
/neo430/trunk/neo430/travis_ci/hw_check.sh
29,7 → 29,6
ghdl -a --work=neo430 $srcdir_core/neo430_crc.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_dmem.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_exirq.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_freq_gen.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_gpio.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_imem.vhd |
ghdl -a --work=neo430 $srcdir_core/neo430_muldiv.vhd |