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

Subversion Repositories neo430

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 193 to Rev 194
    Reverse comparison

Rev 193 → Rev 194

/neo430/trunk/neo430/README.md
1,10 → 1,8
# The NEO430 Processor
 
[![Build Status](https://travis-ci.com/stnolting/neo430.svg?branch=master)](https://travis-ci.com/stnolting/neo430)
[![GitHub release](https://img.shields.io/github/v/release/stnolting/neo430?include_prereleases)](https://GitHub.com/stnolting/neo430/releases/)
[![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)
[![documentation](https://img.shields.io/badge/documentation-available-brightgreen)](https://raw.githubusercontent.com/stnolting/neo430/master/doc/NEO430.pdf)
[![license](https://img.shields.io/github/license/stnolting/neo430)](https://github.com/stnolting/neo430/blob/master/LICENSE)
 
## Table of Content
12,6 → 10,7
* [Introduction](#Introduction)
* [Processor Features](#Processor-Features)
* [Differences to the Original MSP430 Processors](#Differences-to-the-Original-MSP430-Processors)
* [Top Entity](#Top-Entity)
* [Implementation Results](#Implementation-Results)
* [Performance](#Performance)
* [Quick Start](#Quick-Start)
98,7 → 97,7
- No hardware debugging interface
- No analog components
- No support of TI's Code Composer Studio
- No support of CPU's DADD instruction (which is never used by the compiler...)
- No support of CPU's DADD operation
- Just 4 CPU interrupt channels
- Single clock domain for complete processor
- Different numbers of instruction execution cycles
109,6 → 108,71
 
 
 
## Top Entity
 
The top entity of the processor is [neo430_top.vhd](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_top.vhd) (in the rtl\core folder).
Just instantiate this file in you project and you are ready to go! All signals of this top entity are of type *std_ulogic* or *std_ulogic_vector*, respectively.
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 |
|:-------------|:-----------------------:|:-------------:|:---------------------------------------------------------|
| CLOCK_SPEED | natural | 100000000 | Clock speed of CPU clock input "clk_i" in Hz |
| 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 |
| 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 | 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 |
 
 
 
## Implementation Results
 
Mapping results generated for HW version 0x0320. The full (default) hardware configuration includes
186,30 → 250,33
evaluates to **7.33 cycles/instruction resulting in 0.136 MIPS per MHz (worst case)**.
 
 
### Coremark Benchmark
### CoreMark Benchmark
 
The [coremark CPU benchmark](https://www.eembc.org/coremark/) was executed on the NEO430 and is available in the
The [CoreMark CPU benchmark](https://www.eembc.org/coremark/) was executed on the NEO430 and is available in the
project's [sw/example/coremark](https://github.com/stnolting/neo430/blob/master/sw/example/coremark) folder This benchmark
tests the capabilities of the CPU itself rather than the functions provided by the whole system / SoC.
 
~~~
Hardware: 100 MHz, 32kB IMEM, 12kB DMEM, HW verison 0x0401, no peripherals used (except for the TIMER and the UART)
Hardware: 100 MHz, 32kB IMEM, 12kB DMEM, HW verison 0x0404, no peripherals used (except for the TIMER and the UART)
Software: msp430-gcc 8.3.0 for Linux, MEM_METHOD is MEM_STACK, 2000 coremark iterations
~~~
 
|__Optimization__ | __Coremark Score__ | __Relative Score__ |
|:-------------------:|:------------------:|:---------------------:|
| -Os | 6.56 | 0.066 Coremarks/MHz |
| -O3 | 6.92 | 0.069 Coremarks/MHz |
| -O3 + NEO430_MULDIV | 14.82 | 0.148 Coremarks/MHz |
|__Optimization__ | __Coremark Score__ | __Relative Score__ |
|:--------------------:|:------------------:|:---------------------:|
| -Os | 6.57 | 0.065 Coremarks/MHz |
| -O2 | 7.16 | 0.072 Coremarks/MHz |
| -Os + NEO430_MULDIV* | 12.98 | 0.129 Coremarks/MHz |
| -O2 + NEO430_MULDIV* | 15.26 | 0.152 Coremarks/MHz |
 
Even though a score of 6.38 can outnumber certain architectures and configurations (see the score table on the coremark
homepage), the relative score of 0.064 coremarks per second might pretty low. But you have to keep in mind that benchmark
*) 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
was executed using only the resources of the CPU itself. The CPU consists of only ~500 Intel Cyclone IV LUTs and does not
contain any sophisticated ALU operations like multiplication or barrel shifting. Also, all instructions are executed in a
multi-cycle scheme requiring several clock cycles to complete. When explicitly using the NEO430 MULDIV unit for performing
the matrix-operations benchmark scenario (among other operations, it is based on matrix-scalar, matrix-vector and
matrix-matrix multiplications) the **coremark score is increased to 12.56**. By using additional HW accelerators from the
matrix-matrix multiplications) the **coremark score is increased to 15.26**. By using additional HW accelerators from the
NEO430 ecosystem (like the CRC unit) or by using the MULDIV unit also for address and index computations the performance
and thus, the coremark score can be further increased
 
/neo430/trunk/neo430/doc/NEO430.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/neo430/trunk/neo430/rtl/core/neo430_bootloader_image.vhd
970,8 → 970,8
000959 => x"3a56",
000960 => x"4d20",
000961 => x"7261",
000962 => x"3220",
000963 => x"2039",
000962 => x"3320",
000963 => x"2031",
000964 => x"3032",
000965 => x"3032",
000966 => x"480a",
/neo430/trunk/neo430/rtl/core/neo430_control.vhd
54,8 → 54,7
irq_vec_o : out std_ulogic_vector(01 downto 0); -- irq channel address
imm_o : out std_ulogic_vector(15 downto 0); -- branch offset
-- irq lines --
irq_i : in std_ulogic_vector(03 downto 0); -- IRQ lines
irq_ack_o : out std_ulogic_vector(03 downto 0) -- IRQ acknowledge
irq_i : in std_ulogic_vector(03 downto 0) -- IRQ lines^
);
end neo430_control;
 
697,9 → 696,6
end case;
end process;
 
-- ack output --
irq_ack_o <= irq_ack_mask;
 
-- interrupt priority encoder --
irq_priority: process(irq_buf)
begin
711,7 → 707,7
irq_vec_nxt <= "01";
when "0100" | "1100" => -- "-100"
irq_vec_nxt <= "10";
when others => -- "1000"
when others => -- "1000" ("0000" -> dont't care)
irq_vec_nxt <= "11";
end case;
end process irq_priority;
/neo430/trunk/neo430/rtl/core/neo430_cpu.vhd
58,8 → 58,7
mem_data_o : out std_ulogic_vector(15 downto 0); -- write data
mem_data_i : in std_ulogic_vector(15 downto 0); -- read data
-- interrupt system --
irq_i : in std_ulogic_vector(03 downto 0); -- interrupt requests
irq_ack_o : out std_ulogic_vector(03 downto 0) -- IRQ acknowledge
irq_i : in std_ulogic_vector(03 downto 0) -- interrupt requests
);
end neo430_cpu;
 
99,8 → 98,7
irq_vec_o => irq_sel, -- irq channel address
imm_o => imm, -- branch offset
-- irq lines --
irq_i => irq_i, -- IRQ lines
irq_ack_o => irq_ack_o -- IRQ acknowledge
irq_i => irq_i -- IRQ lines
);
 
 
/neo430/trunk/neo430/rtl/core/neo430_exirq.vhd
71,12 → 71,12
architecture neo430_exirq_rtl of neo430_exirq is
 
-- control register bits --
constant ctrl_irq_sel0_c : natural := 0; -- r/w: IRQ source bit 0 (r); SW IRQ select / ACK select (w)
constant ctrl_irq_sel1_c : natural := 1; -- r/w: IRQ source bit 1 (r); SW IRQ select / ACK select (w)
constant ctrl_irq_sel2_c : natural := 2; -- r/w: IRQ source bit 2 (r); SW IRQ select / ACK select (w)
constant ctrl_irq_sel0_c : natural := 0; -- r/w: IRQ source bit 0 (r); SW IRQ select (w)
constant ctrl_irq_sel1_c : natural := 1; -- r/w: IRQ source bit 1 (r); SW IRQ select (w)
constant ctrl_irq_sel2_c : natural := 2; -- r/w: IRQ source bit 2 (r); SW IRQ select (w)
constant ctrl_en_c : natural := 3; -- r/w: unit enable
constant ctrl_sw_irq_c : natural := 4; -- -/w: use irq_sel as SW IRQ trigger, auto-clears
constant ctrl_ack_irq_c : natural := 5; -- -/w: use irq_sel as ACK select, auto-clears
constant ctrl_ack_irq_c : natural := 5; -- -/w: ACK current IRQ, auto-clears
-- ...
constant ctrl_en_irq0_c : natural := 8; -- r/w: IRQ channel 0 enable
constant ctrl_en_irq1_c : natural := 9; -- r/w: IRQ channel 1 enable
175,6 → 175,9
irq_core: process(clk_i)
begin
if rising_edge(clk_i) then
-- ack output --
ext_ack_o <= ack_mask;
 
-- irq buffer --
for i in 0 to 7 loop
-- keep requests until they are acknowledged
184,20 → 187,17
 
-- mini state FSM - defaults --
cpu_irq_o <= '0';
ext_ack_o <= (others => '0');
 
-- mini state FSM --
if (state = '0') or (enable = '0') then -- idle or deactivated
state <= '0';
irq_src_reg <= irq_src; -- capture source
if (irq_fire = '1') then
cpu_irq_o <= '1'; -- trigger CPU
cpu_irq_o <= '1'; -- trigger CPU interrupt
state <= '1'; -- go to active IRQ state
end if;
else -- active IRQ
if (ack_trig = '1') then
ext_ack_o <= ack_mask;
state <= '0';
if (ack_trig = '1') or (enable = '0') then
state <= '0';
end if;
end if;
end if;
219,10 → 219,10
 
-- ACK priority decoder -----------------------------------------------------
-- -----------------------------------------------------------------------------
ack_priority_dec: process(ack_trig, irq_src_reg)
ack_priority_dec: process(state, ack_trig, irq_src_reg)
variable irq_ack_v : std_ulogic_vector(3 downto 0);
begin
irq_ack_v := ack_trig & irq_src_reg;
irq_ack_v := (ack_trig and state) & irq_src_reg;
case irq_ack_v is
when "1000" => ack_mask <= "00000001";
when "1001" => ack_mask <= "00000010";
/neo430/trunk/neo430/rtl/core/neo430_package.vhd
401,8 → 401,7
irq_vec_o : out std_ulogic_vector(01 downto 0); -- irq channel address
imm_o : out std_ulogic_vector(15 downto 0); -- branch offset
-- irq lines --
irq_i : in std_ulogic_vector(03 downto 0); -- IRQ lines
irq_ack_o : out std_ulogic_vector(03 downto 0) -- IRQ acknowledge
irq_i : in std_ulogic_vector(03 downto 0) -- IRQ lines
);
end component;
 
485,8 → 484,7
mem_data_o : out std_ulogic_vector(15 downto 0); -- write data
mem_data_i : in std_ulogic_vector(15 downto 0); -- read data
-- interrupt system --
irq_i : in std_ulogic_vector(03 downto 0); -- interrupt requests
irq_ack_o : out std_ulogic_vector(03 downto 0) -- IRQ acknowledge
irq_i : in std_ulogic_vector(03 downto 0) -- interrupt requests
);
end component;
 
/neo430/trunk/neo430/rtl/core/neo430_pwm.vhd
157,8 → 157,8
end if;
-- channels --
for i in 0 to num_pwm_channels_c-1 loop
-- constrain counter to virtual size configured by SIZE register
if (unsigned(pwm_cnt and mask) >= unsigned(pwm_ch(i))) or (enable = '0') then
-- 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
pwm_out(i) <= '1';
/neo430/trunk/neo430/rtl/core/neo430_timer.vhd
91,7 → 91,7
 
-- timer regs --
signal cnt : std_ulogic_vector(15 downto 0); -- r/-: counter register
signal thres : std_ulogic_vector(15 downto 0); -- r/w: threshold register
signal thres : std_ulogic_vector(15 downto 0); -- -/w: threshold register
signal ctrl : std_ulogic_vector(10 downto 0); -- r/w: control register
 
-- prescaler clock generator --
175,7 → 175,7
match <= '1' when (cnt = thres) else '0';
 
-- interrupt line --
irq_fire <= match and ctrl(ctrl_en_c) and ctrl(ctrl_irq_en_c) and ctrl(ctrl_run_c);
irq_fire <= match and ctrl(ctrl_en_c) and ctrl(ctrl_irq_en_c); -- and ctrl(ctrl_run_c);
 
-- edge detector --
irq_o <= irq_fire and (not irq_fire_ff);
219,12 → 219,12
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);
elsif (addr = timer_cnt_addr_c) then
else--if (addr = timer_cnt_addr_c) then
data_o <= cnt;
else--if (addr = timer_thres_addr_c) then
data_o <= thres;
-- else -- timer_nco_addr_c
-- data_o <= nco_tuning_word;
-- 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
133,7 → 133,7
-- generators --
signal rst_i_sync0 : std_ulogic;
signal rst_i_sync1 : std_ulogic;
signal rst_gen : std_ulogic_vector(03 downto 0) := (others => '0'); -- perform reset on bitstream upload
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;
182,16 → 182,13
signal sysconfig_rdata : std_ulogic_vector(15 downto 0);
 
-- interrupt system --
signal irq : std_ulogic_vector(03 downto 0);
signal irq_ack : std_ulogic_vector(03 downto 0);
signal timer_irq : std_ulogic;
signal uart_irq : std_ulogic;
signal spi_irq : std_ulogic;
signal twi_irq : std_ulogic;
signal gpio_irq : std_ulogic;
signal xirq_sync0 : std_ulogic;
signal xirq_sync1 : std_ulogic;
signal ext_irq : std_ulogic;
signal irq : std_ulogic_vector(03 downto 0);
signal timer_irq : std_ulogic;
signal uart_irq : std_ulogic;
signal spi_irq : std_ulogic;
signal twi_irq : std_ulogic;
signal gpio_irq : std_ulogic;
signal ext_irq : std_ulogic;
 
-- misc --
signal imem_up_en : std_ulogic;
233,7 → 230,8
if (sys_rst = '0') then
clk_div <= (others => '0');
elsif rising_edge(clk_i) 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 -- anybody needing clocks?
-- 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) = '1') then
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
end if;
end if;
276,8 → 274,7
mem_data_o => cpu_bus.wdata, -- write data
mem_data_i => cpu_bus.rdata, -- read data
-- interrupt system --
irq_i => irq, -- interrupt request lines
irq_ack_o => irq_ack -- IRQ acknowledge
irq_i => irq -- interrupt request lines
);
 
-- final CPU read data --
732,22 → 729,11
neo430_exirq_inst_false:
if (EXIRQ_USE = false) generate
exirq_rdata <= (others => '0');
ext_ack_o <= "0000000" & irq_ack(3);
ext_irq <= xirq_sync1;
ext_ack_o <= (others => '0');
ext_irq <= '0';
end generate;
 
-- sync for single external IRQ if EXIRQ is not implemented --
external_irq_sync: process(clk_i)
begin
if rising_edge(clk_i) then
if (EXIRQ_USE = false) then
xirq_sync0 <= ext_irq_i(0);
xirq_sync1 <= xirq_sync0;
end if;
end if;
end process external_irq_sync;
 
 
-- System Configuration -----------------------------------------------------
-- -----------------------------------------------------------------------------
neo430_sysconfig_inst: neo430_sysconfig
/neo430/trunk/neo430/sw/example/coremark/core_main.c
102,7 → 102,7
 
#ifndef RUN_COREMARK
#pragma warning ("COREMARK HAS NOT BEEN COMPILED! Use >>make clean compile CC_USER_FLAGS+=-DRUN_COREMARK<< to compile it.")
while(1) {}
return 0;
#endif
// -----------------------------------------------
 
/neo430/trunk/neo430/sw/example/coremark/core_portme.c
135,12 → 135,15
(1<<TMR_CT_ARST) | // auto-reset on match
(1<<TMR_CT_IRQ) | // interrupt enable
(0<<TMR_CT_RUN); // timer not running yet
neo430_timer_config_freq(NEO430_TIMER_F);
 
neo430_printf("NEO430: clock speed : %n Hz\n", CLOCKSPEED_32bit);
neo430_printf("NEO430: timer THRES : %u\n", TMR_THRES);
neo430_printf("NEO430: timer CTRL : %x\n", TMR_CT);
neo430_printf("NEO430: timer IRQs/s : %u\n", (uint16_t)NEO430_TIMER_F);
uint16_t timer_thres;
if (neo430_timer_config_freq(NEO430_TIMER_F, &timer_thres)) {
neo430_printf("NEO430: timer frequency config error!\n");
while(1);
}
 
neo430_printf("NEO430: clock speed = %n Hz\n", CLOCKSPEED_32bit);
neo430_printf("NEO430: timer IRQs/s = %u\n", (uint16_t)NEO430_TIMER_F);
#if USE_NEO430_MUL
neo430_printf("NEO430: using NEO430 MULDIV unit for matrix core operations\n");
#endif
/neo430/trunk/neo430/sw/example/coremark/core_portme.h
32,8 → 32,8
// Manual NEO430 config:
#define BAUD_RATE (19200)
#define ITERATIONS (2000)
#define NEO430_TIMER_F (10) // Hertz
#define FLAGS_STR "-Os" // compiler optimization
#define NEO430_TIMER_F (10) // Hz
#define FLAGS_STR "-> see makefile" // compiler optimization
 
#ifndef USE_NEO430_MULTIPLIER
#define USE_NEO430_MUL 0 // set 1 to use MULDIV unit for matrix core operations
/neo430/trunk/neo430/sw/example/game_of_life/main.c
38,10 → 38,11
#include <neo430.h>
 
// Configuration
#define NUM_CELLS_X 160 // must be a multiple of 8
#define NUM_CELLS_Y 40
#define BAUD_RATE 19200
#define UNI_DELAY 500 // delay between iterations in ms
#define NUM_CELLS_X 160 // must be a multiple of 8
#define NUM_CELLS_Y 40
#define BAUD_RATE 19200
#define GEN_DELAY 500 // delay between iterations in ms
#define TRNG_TAP_MASK 0b01010001000000 // highly experimental!
 
// Global variables
uint8_t universe[2][NUM_CELLS_X/8][NUM_CELLS_Y];
62,6 → 63,8
 
uint8_t u = 0, cell = 0, n = 0;
int16_t x, y;
uint16_t trng_available = 0;
uint8_t trng_data = 0;
 
// setup UART
neo430_uart_setup(BAUD_RATE);
77,15 → 80,36
neo430_printf("Press any key to start a random-initialized torus-style universe of %ux%u cells.\n", NUM_CELLS_X, NUM_CELLS_Y);
neo430_printf("You can pause/restart the simulation by pressing any key.\n");
 
// randomize until key pressed
while (neo430_uart_char_received() == 0) {
neo430_xorshift32();
// check if TRNG was synthesized
if ((SYS_FEATURES & (1<<SYS_TRNG_EN))) {
neo430_printf("TRNG detected. Using TRNG for universe initialization.\n");
neo430_trng_enable(TRNG_TAP_MASK);
trng_available = 1;
}
 
if (trng_available) {
neo430_uart_getc(); // wait for pressed key
}
else {
// randomize until key pressed
while (neo430_uart_char_received() == 0) {
neo430_xorshift32();
}
}
 
// initialize universe using random data
for (x=0; x<NUM_CELLS_X/8; x++) {
for (y=0; y<NUM_CELLS_Y; y++) {
universe[0][x][y] = (uint8_t)neo430_xorshift32();
if (trng_available) {
if (neo430_trng_get(&trng_data)) {
neo430_printf("TRNG error!\n");
return 1;
}
universe[0][x][y] = (uint8_t)trng_data; // use data from TRNG
}
else {
universe[0][x][y] = (uint8_t)neo430_xorshift32(); // use data von PRNG
}
}
}
 
123,7 → 147,7
generation++;
 
// wait 500ms
neo430_cpu_delay_ms(UNI_DELAY);
neo430_cpu_delay_ms(GEN_DELAY);
}
 
return 0;
/neo430/trunk/neo430/sw/example/nested_irqs/main.c
83,8 → 83,10
 
// configure timer frequency
neo430_timer_disable();
if (neo430_timer_config_freq(1000)) // 1kHz to increment every 1ms
uint16_t timer_thres;
if (neo430_timer_config_freq(1000, &timer_thres)) { // 1kHz to increment every 1ms
neo430_uart_br_print("Invalid TIMER frequency!\n");
}
 
neo430_printf("THR: %x, CTR: %x\n", TMR_THRES, TMR_CT);
TMR_CT |= (1<<TMR_CT_EN) | (1<<TMR_CT_ARST) | (1<<TMR_CT_IRQ) | (1<<TMR_CT_RUN); // enable timer, auto-reset, irq enabled, start timer
/neo430/trunk/neo430/sw/example/timer_simple/main.c
76,8 → 76,10
 
// configure timer frequency
neo430_timer_disable();
if (neo430_timer_config_freq(BLINK_FREQ))
uint16_t timer_thres;
if (neo430_timer_config_freq(BLINK_FREQ, &timer_thres)) {
neo430_uart_br_print("Invalid TIMER frequency!\n");
}
 
TMR_CT |= (1<<TMR_CT_EN) | (1<<TMR_CT_ARST) | (1<<TMR_CT_IRQ) | (1<<TMR_CT_RUN); // enable timer, auto-reset, irq enabled, timer start
 
/neo430/trunk/neo430/sw/lib/neo430/include/neo430.h
218,7 → 218,7
// ----------------------------------------------------------------------------
#define TMR_CT (*(REG16 0xFFB0)) // r/w: control register
#define TMR_CNT (*(ROM16 0xFFB2)) // r/-: counter register
#define TMR_THRES (*(REG16 0xFFB4)) // r/w: threshold register
#define TMR_THRES (*(REG16 0xFFB4)) // -/w: threshold register
#define TMR_NCO (*(REG16 0xFFB6)) // -/w: frequency generator
 
// Timer control register
401,9 → 401,9
#define EXIRQ_CT (*(REG16 0xFFEE)) // r/w: control register
 
// EXIRQ control register
#define EXIRQ_CT_SEL0 0 // r/w: IRQ source bit 0 / SW_IRQ select / ACK select
#define EXIRQ_CT_SEL1 1 // r/w: IRQ source bit 1 / SW_IRQ select / ACK select
#define EXIRQ_CT_SEL2 2 // r/w: IRQ source bit 2 / SW_IRQ select / ACK select
#define EXIRQ_CT_SEL0 0 // r/w: IRQ source bit 0 / SW_IRQ select
#define EXIRQ_CT_SEL1 1 // r/w: IRQ source bit 1 / SW_IRQ select
#define EXIRQ_CT_SEL2 2 // r/w: IRQ source bit 2 / SW_IRQ select
#define EXIRQ_CT_EN 3 // r/w: unit enable
#define EXIRQ_CT_SW_IRQ 4 // -/w: use irq_sel as SW IRQ trigger, auto-clears
#define EXIRQ_CT_ACK_IRQ 5 // -/w: use irq_sel as ACK select, auto-clears
/neo430/trunk/neo430/sw/lib/neo430/include/neo430_timer.h
40,7 → 40,7
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); // configure timer frequency
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
/neo430/trunk/neo430/sw/lib/neo430/source/neo430_exirq.c
95,7 → 95,7
 
// apply sw irq enable bit and according irq select
uint16_t exirq_ctrl = EXIRQ_CT & (~(0b111 << EXIRQ_CT_SEL0)); // clear IRQ src output
EXIRQ_CT = exirq_ctrl | (1<<EXIRQ_CT_SW_IRQ) | (irq_sel<<EXIRQ_CT_SEL0);
EXIRQ_CT = exirq_ctrl | (1<<EXIRQ_CT_SW_IRQ) | (irq_sel<<EXIRQ_CT_SEL0); // set dst. IRQ and set SW_IRQ flag
}
 
 
/neo430/trunk/neo430/sw/lib/neo430/source/neo430_timer.c
77,10 → 77,10
 
/* ------------------------------------------------------------
* INFO Configure timer period
* PARAM Timer frequency in Hz (1Hz ... F_CPU/2)
* RETURN 0 if successful, !=0 if error
* PARAM Timer frequency in Hz (1 ... F_CPU/2), uint16_t pointer to store computed THRES value
* RETURN 0 if successful, 0xff if error
* ------------------------------------------------------------ */
uint8_t neo430_timer_config_freq(uint32_t f_timer) {
uint8_t neo430_timer_config_freq(uint32_t f_timer, uint16_t *thres) {
 
uint32_t clock = CLOCKSPEED_32bit;
uint32_t ticks = (clock / f_timer) >> 1; // divide by lowest prescaler (= f/2)
92,18 → 92,22
 
// find prescaler
while(prsc < 8) {
if (ticks <= 0x0000ffff)
if (ticks <= 0x0000ffff) {
break;
}
else {
if ((prsc == 2) || (prsc == 4))
if ((prsc == 2) || (prsc == 4)) {
ticks >>= 3;
else
}
else {
ticks >>= 1;
}
prsc++;
}
}
 
TMR_THRES = (uint16_t)ticks;
*thres = (uint16_t)ticks;
TMR_CT &= ~(7<<TMR_CT_PRSC0); // clear prsc bits
TMR_CT |= (prsc<<TMR_CT_PRSC0);
 

powered by: WebSVN 2.1.0

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