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

Subversion Repositories neo430

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neo430/trunk
    from Rev 122 to Rev 123
    Reverse comparison

Rev 122 → Rev 123

/doc/NEO430.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/rtl/cfu_templates/multiplier/README.txt
0,0 → 1,45
***************************************************************************************************
* Multiply-and-accumulate unit for the custom function unit (CFU) slot of the NEO430 processor *
* By Stephan Nolting *
***************************************************************************************************
 
This unit implements a 16-bit times 16-bit multiplier computing a 32-bit wide result.
The operations can be either signed or unsigned.
Furthermore, the unit provides an internal 32-bit accumulator to perform multiply-and-accumulate operations.
It is partly compatible to the original MSP430 multiplier.
 
 
This unit features seven interface registers, that can only be accessed in word (16-bit) mode.
Write the first operand to one of the following register to perform the according operations:
 
- CFU_MAC16_MPY : Operand A for unsigned multiplication (write-only)
- CFU_MAC16_MPYS : Operand A for signed multiplication (write-only)
- CFU_MAC16_MAC : Operand A for unsigned multiply-and-accumulate (write-only)
- CFU_MAC16_MACS : Operand A for signed multiply-and-accumulate (write-only)
 
The second operand is always written to the OP2 register, regardless of the actual operation:
 
- CFU_MAC16_OP2 : Operand B for all operations (write-only)
 
The final 32-bit wide result is split-up into two 16-bit registers:
 
- CFU_MAC16_RESLO : Low word of the result (read-only)
- CFU_MAC16_RESHI : high word of the result (read-only)
 
The result can also be "read" as 32-bit value:
 
- CFU_MAC16_RES_32bit : 32-bit wide result (read-only)
 
 
To install the hardware of this unit, replace the original neo430_cfu.vhd in the rtl\core folder with the
neo430_cfu.vhd from this folder.
 
Include the header file from this folder to you application code to install the required software driver functions.
 
The header file (cfu_mac16.h) provides the required definitions of the unit's interface registers
as well as some rudimentary multiplication/multiply-and-accumulate operations implemented as inlined
C functions.
 
Include the cfu_mac16.h AFTER you have included the general NEO430 include file:
#include ".../lib/neo430/neo430.h"
#include ".../cfu_mac16.h"
/rtl/cfu_templates/multiplier/cfu_mac16.h
0,0 → 1,179
// #################################################################################################
// # < neo430_cfu_mac16.h - MAC16 CFU Access Wrapper > #
// # ********************************************************************************************* #
// # This file is part of the NEO430 Processor project: https://github.com/stnolting/neo430 #
// # Copyright by Stephan Nolting: stnolting@gmail.com #
// # #
// # This source file may be used and distributed without restriction provided that this copyright #
// # statement is not removed from the file and that any derivative work contains the original #
// # copyright notice and the associated disclaimer. #
// # #
// # This source file is free software; you can redistribute it and/or modify it under the terms #
// # of the GNU Lesser General Public License as published by the Free Software Foundation, #
// # either version 3 of the License, or (at your option) any later version. #
// # #
// # This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; #
// # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. #
// # See the GNU Lesser General Public License for more details. #
// # #
// # You should have received a copy of the GNU Lesser General Public License along with this #
// # source; if not, download it from https://www.gnu.org/licenses/lgpl-3.0.en.html #
// # ********************************************************************************************* #
// # Stephan Nolting, Hannover, Germany 19.07.2017 #
// #################################################################################################
 
#ifndef neo430_cfu_mac16_h
#define neo430_cfu_mac16_h
 
// Interface register address definitions
#define CFU_MAC16_MPY CFU_REG0 // -/w: operand one - multiply unsigned
#define CFU_MAC16_MPYS CFU_REG1 // -/w: operand one - multiply signed
#define CFU_MAC16_MAC CFU_REG2 // -/w: operand one - multiply-accumulate unsigned
#define CFU_MAC16_MACS CFU_REG3 // -/w: operand one - multiply-accumulate signed
#define CFU_MAC16_OP2 CFU_REG4 // -/w: operand two
#define CFU_MAC16_RESLO CFU_REG5 // r/-: result low word
#define CFU_MAC16_RESHI CFU_REG6 // r/-: result high word
#define CFU_MAC16_RES_32bit (*(REG32 (&CFU_MAC16_RESLO))) // r/-: result word
 
 
// Function prototypes
inline uint16_t cfu_mul_u16_u16_u16(uint16_t a, uint16_t b);
inline int16_t cfu_mul_s16_s16_s16(int16_t a, int16_t b);
 
inline uint32_t cfu_mul_u16_u16_u32(uint16_t a, uint16_t b);
inline int32_t cfu_mul_s16_s16_s32(int16_t a, int16_t b);
 
inline void cfu_mac_clear_accu(void);
 
inline uint16_t cfu_mac_u16_u16_u16(uint16_t a, uint16_t b);
inline int16_t cfu_mac_s16_s16_s16(int16_t a, int16_t b);
 
inline uint32_t cfu_mac_u16_u16_u32(uint16_t a, uint16_t b);
inline int32_t cfu_mac_s16_s16_s32(int16_t a, int16_t b);
 
 
 
/* ------------------------------------------------------------
* INFO Unsigned 16x16=16 multiplication
* PARAM a unsigned 16-bit operand a
* PARAM b unsigned 16-bit operand b
* RETURN unsigned 16-bit result (lower result word)
* ------------------------------------------------------------ */
inline uint16_t cfu_mul_u16_u16_u16(uint16_t a, uint16_t b) {
 
CFU_MAC16_MPY = a;
CFU_MAC16_OP2 = b;
return CFU_MAC16_RESLO;
}
 
 
/* ------------------------------------------------------------
* INFO Signed 16x16=16 multiplication
* PARAM a signed 16-bit operand a
* PARAM b signed 16-bit operand b
* RETURN signed 16-bit result (lower result word)
* ------------------------------------------------------------ */
inline int16_t cfu_mul_s16_s16_s16(int16_t a, int16_t b) {
 
CFU_MAC16_MPYS = (uint16_t)a;
CFU_MAC16_OP2 = (uint16_t)b;
return (int16_t)CFU_MAC16_RESLO;
}
 
 
/* ------------------------------------------------------------
* INFO Unsigned 16x16=32 multiplication
* PARAM a signed 16-bit operand a
* PARAM b signed 16-bit operand b
* RETURN signed 16-bit result
* ------------------------------------------------------------ */
inline uint32_t cfu_mul_u16_u16_u32(uint16_t a, uint16_t b) {
 
CFU_MAC16_MPY = a;
CFU_MAC16_OP2 = b;
return CFU_MAC16_RES_32bit;
}
 
 
/* ------------------------------------------------------------
* INFO Signed 16x16=32 multiplication
* PARAM a signed 16-bit operand a
* PARAM b signed 16-bit operand b
* RETURN signed 32-bit result (lower result word)
* ------------------------------------------------------------ */
inline int32_t cfu_mul_s16_s16_s32(int16_t a, int16_t b) {
 
CFU_MAC16_MPYS = (uint16_t)a;
CFU_MAC16_OP2 = (uint16_t)b;
return (int32_t)CFU_MAC16_RES_32bit;
}
 
 
 
/* ------------------------------------------------------------
* INFO Clear accumulator
* ------------------------------------------------------------ */
inline void cfu_mac_clear_accu(void) {
 
CFU_MAC16_MPY = 0;
CFU_MAC16_OP2 = 0;
}
 
 
/* ------------------------------------------------------------
* INFO Unsigned 16x16=16 multiply-and-accumulate
* PARAM a unsigned 16-bit operand a
* PARAM b unsigned 16-bit operand b
* RETURN unsigned 16-bit result (lower result word)
* ------------------------------------------------------------ */
inline uint16_t cfu_mac_u16_u16_u16(uint16_t a, uint16_t b) {
 
CFU_MAC16_MAC = a;
CFU_MAC16_OP2 = b;
return CFU_MAC16_RESLO;
}
 
 
/* ------------------------------------------------------------
* INFO Signed 16x16=16 multiply-and-accumulate
* PARAM a signed 16-bit operand a
* PARAM b signed 16-bit operand b
* RETURN signed 16-bit result (lower result word)
* ------------------------------------------------------------ */
inline int16_t cfu_mac_s16_s16_s16(int16_t a, int16_t b) {
 
CFU_MAC16_MACS = (uint16_t)a;
CFU_MAC16_OP2 = (uint16_t)b;
return (int16_t)CFU_MAC16_RESLO;
}
 
 
/* ------------------------------------------------------------
* INFO Unsigned 16x16=32 multiply-and-accumulate
* PARAM a signed 16-bit operand a
* PARAM b signed 16-bit operand b
* RETURN signed 16-bit result
* ------------------------------------------------------------ */
inline uint32_t cfu_mac_u16_u16_u32(uint16_t a, uint16_t b) {
 
CFU_MAC16_MAC = a;
CFU_MAC16_OP2 = b;
return CFU_MAC16_RES_32bit;
}
 
 
/* ------------------------------------------------------------
* INFO Signed 16x16=32 multiply-and-accumulate
* PARAM a signed 16-bit operand a
* PARAM b signed 16-bit operand b
* RETURN signed 32-bit result (lower result word)
* ------------------------------------------------------------ */
inline int32_t cfu_mac_s16_s16_s32(int16_t a, int16_t b) {
 
CFU_MAC16_MACS = (uint16_t)a;
CFU_MAC16_OP2 = (uint16_t)b;
return (int32_t)CFU_MAC16_RES_32bit;
}
 
 
#endif // neo430_cfu_mac16_h
/rtl/cfu_templates/multiplier/neo430_cfu.vhd
0,0 → 1,173
-- #################################################################################################
-- # << NEO430 - 16x16=32-Bit Multiply/Acuumulate Unit >> #
-- # ********************************************************************************************* #
-- # NOTE: This unit is NOT fully compatible to the original TI MSP430 multiplier! #
-- # ********************************************************************************************* #
-- # This file is part of the NEO430 Processor project: http://opencores.org/project,neo430 #
-- # Copyright 2015-2016, Stephan Nolting: stnolting@gmail.com #
-- # #
-- # This source file may be used and distributed without restriction provided that this copyright #
-- # statement is not removed from the file and that any derivative work contains the original #
-- # copyright notice and the associated disclaimer. #
-- # #
-- # This source file is free software; you can redistribute it and/or modify it under the terms #
-- # of the GNU Lesser General Public License as published by the Free Software Foundation, #
-- # either version 3 of the License, or (at your option) any later version. #
-- # #
-- # This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; #
-- # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. #
-- # See the GNU Lesser General Public License for more details. #
-- # #
-- # You should have received a copy of the GNU Lesser General Public License along with this #
-- # source; if not, download it from http://www.gnu.org/licenses/lgpl-3.0.en.html #
-- # ********************************************************************************************* #
-- # Stephan Nolting, Hannover, Germany 19.07.2016 #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library work;
use work.neo430_package.all;
 
entity neo430_cfu is
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic_vector(01 downto 0); -- 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
);
end neo430_cfu;
 
architecture neo430_cfu_mac16_rtl of neo430_cfu is
 
-- interface register addresses --
constant mac16_base_c : std_ulogic_vector(15 downto 0) := cfu_base_c;
constant mac16_size_c : natural := cfu_size_c;
 
constant mac16_mpy_addr_c : std_ulogic_vector(15 downto 0) := cfu_reg0_addr_c; -- -/w: operand A for unsigned multiplication
constant mac16_mpys_addr_c : std_ulogic_vector(15 downto 0) := cfu_reg1_addr_c; -- -/w: operand A for signed multiplication
constant mac16_mac_addr_c : std_ulogic_vector(15 downto 0) := cfu_reg2_addr_c; -- -/w: operand A for unsigned dmultiply-and-add
constant mac16_macs_addr_c : std_ulogic_vector(15 downto 0) := cfu_reg3_addr_c; -- -/w: operand A for signed dmultiply-and-add
constant mac16_op2_addr_c : std_ulogic_vector(15 downto 0) := cfu_reg4_addr_c; -- -/w: operand B (for all operations)
constant mac16_reslo_addr_c : std_ulogic_vector(15 downto 0) := cfu_reg5_addr_c; -- r/-: low part of result
constant mac16_reshi_addr_c : std_ulogic_vector(15 downto 0) := cfu_reg6_addr_c; -- r/-: high part of result
 
-- IO space: module base address --
constant hi_abb_c : natural := index_size(io_size_c)-1; -- high address boundary bit
constant lo_abb_c : natural := index_size(mac16_size_c); -- low address boundary bit
 
-- access control --
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!
 
-- accessible regs --
signal op_a, op_b : std_ulogic_vector(15 downto 0);
signal mac_res : std_ulogic_vector(32 downto 0);
 
-- control --
signal mode : std_ulogic_vector(01 downto 0); -- function select
signal run : std_ulogic;
signal run_s0 : std_ulogic;
signal run_s1 : std_ulogic;
 
-- mac core --
signal op_a_int, op_a_ff : std_ulogic_vector(16 downto 0);
signal op_b_int, op_b_ff : std_ulogic_vector(16 downto 0);
signal mul_res : std_ulogic_vector(33 downto 0);
 
begin
 
-- Access Control -----------------------------------------------------------
-- -----------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = mac16_base_c(hi_abb_c downto lo_abb_c)) else '0';
addr <= mac16_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(0) and wren_i(1);
 
 
-- Write access -------------------------------------------------------------
-- -----------------------------------------------------------------------------
wr_access: process(clk_i)
begin
if rising_edge(clk_i) then
run <= '0';
if (wr_en = '1') then -- only full word accesses!
-- operands --
case addr is
when mac16_mpy_addr_c | mac16_mpys_addr_c | mac16_mac_addr_c | mac16_macs_addr_c => -- operand A
op_a <= data_i;
when mac16_op2_addr_c => -- operand B
run <= '1'; -- trigger operation
op_b <= data_i;
when others =>
NULL;
end case;
-- operation --
case (addr) is
when mac16_mpy_addr_c =>
mode <= "00"; -- multiply unsigned
when mac16_mpys_addr_c =>
mode <= "01"; -- multiply signed
when mac16_mac_addr_c =>
mode <= "10"; -- multiply-accumulate unsigned
when mac16_macs_addr_c =>
mode <= "11"; -- multiply-accumulate signed
when others =>
NULL;
end case;
end if;
end if;
end process wr_access;
 
-- signed/unsigned mode --
op_a_int <= (op_a(15) and mode(0)) & op_a(15 downto 0); -- final operand A (16-bit)
op_b_int <= (op_b(15) and mode(0)) & op_b(15 downto 0); -- final operand B (16-bit)
 
 
-- MAC core -----------------------------------------------------------------
-- -----------------------------------------------------------------------------
mac_core: process(clk_i)
begin
if rising_edge(clk_i) then
-- stage 0 --
op_a_ff <= op_a_int;
op_b_ff <= op_b_int;
run_s0 <= run;
-- stage 1 --
mul_res <= std_ulogic_vector(signed(op_a_ff) * signed(op_b_ff));
run_s1 <= run_s0;
-- stage 2 --
if (run_s1 = '1') then
if (mode(1) = '1') then -- accumulate
mac_res <= std_ulogic_vector(unsigned('0' & mac_res(31 downto 0)) + unsigned('0' & mul_res(31 downto 0)));
else -- simple multiplication
mac_res <= '0' & mul_res(31 downto 0);
end if;
end if;
end if;
end process mac_core;
 
 
-- Read access --------------------------------------------------------------
-- -----------------------------------------------------------------------------
rd_access: process(clk_i)
begin
if rising_edge(clk_i) then
data_o <= (others => '0');
if (acc_en = '1') and (rden_i = '1') then -- valid read access
if (addr = mac16_reslo_addr_c) then
data_o <= mac_res(15 downto 00);
else -- mac16_reshi_addr_c =>
data_o <= mac_res(31 downto 16);
end if;
end if;
end if;
end process rd_access;
 
 
end neo430_cfu_mac16_rtl;
/rtl/core/neo430_cfu.vhd
26,7 → 26,7
-- # You should have received a copy of the GNU Lesser General Public License along with this #
-- # source; if not, download it from https://www.gnu.org/licenses/lgpl-3.0.en.html #
-- # ********************************************************************************************* #
-- # Stephan Nolting, Hannover, Germany 18.06.2017 #
-- # Stephan Nolting, Hannover, Germany 19.06.2017 #
-- #################################################################################################
 
library ieee;
91,7 → 91,7
wr_access: process(clk_i)
begin
if rising_edge(clk_i) then
-- write access to the low byte (bits 7..0) --
-- write access to the low bytes (bits 7..0) --
if (acc_en = '1') and (bwr_en(0) = '1') then -- valid write acces to LO byte
case addr is
when cfu_reg0_addr_c => user_reg0(7 downto 0) <= data_i(7 downto 0);
105,7 → 105,7
when others => NULL;
end case;
end if;
-- write access to the high byte (bits 15..8) --
-- write access to the high bytes (bits 15..8) --
if (acc_en = '1') and (bwr_en(1) = '1') then -- valid write access to HI byte
case addr is
when cfu_reg0_addr_c => user_reg0(15 downto 8) <= data_i(15 downto 8);
/rtl/core/neo430_package.vhd
19,7 → 19,7
-- # You should have received a copy of the GNU Lesser General Public License along with this #
-- # source; if not, download it from https://www.gnu.org/licenses/lgpl-3.0.en.html #
-- # ********************************************************************************************* #
-- # Stephan Nolting, Hannover, Germany 17.07.2017 #
-- # Stephan Nolting, Hannover, Germany 19.07.2017 #
-- #################################################################################################
 
library ieee;
30,7 → 30,7
 
-- Processor Hardware Version -------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(15 downto 0) := x"0120"; -- no touchy!
constant hw_version_c : std_ulogic_vector(15 downto 0) := x"0121"; -- no touchy!
 
-- Internal Functions ---------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
86,7 → 86,7
constant wb32_wr_adr_hi_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(wb32_base_c) + x"0006");
constant wb32_data_lo_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(wb32_base_c) + x"0008");
constant wb32_data_hi_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(wb32_base_c) + x"000A");
--constant ... : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(wb32_base_c) + x"000C");
--constant reserved : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(wb32_base_c) + x"000C");
constant wb32_ctrl_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(wb32_base_c) + x"000E");
 
-- IO: USART --
/rtl/core/neo430_wb_interface.vhd
19,7 → 19,7
-- # You should have received a copy of the GNU Lesser General Public License along with this #
-- # source; if not, download it from https://www.gnu.org/licenses/lgpl-3.0.en.html #
-- # ********************************************************************************************* #
-- # Stephan Nolting, Hannover, Germany 17.07.2017 #
-- # Stephan Nolting, Hannover, Germany 19.07.2017 #
-- #################################################################################################
 
library ieee;
65,10 → 65,9
constant ctrl_pending_c : natural := 15; -- r/-: pending wb transfer
 
-- access control --
signal acc_en : std_ulogic; -- module access enable
signal addr : std_ulogic_vector(15 downto 0); -- access address
signal wr_en : std_ulogic; -- word write enable
signal bwr_en : std_ulogic_vector(01 downto 0); -- byte write enable
signal acc_en : std_ulogic; -- module access enable
signal addr : std_ulogic_vector(15 downto 0); -- access address
signal wr_en : std_ulogic;
 
-- accessible regs --
signal wb_addr : std_ulogic_vector(31 downto 0);
85,11 → 84,9
 
-- Access control -----------------------------------------------------------
-- -----------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = wb32_base_c(hi_abb_c downto lo_abb_c)) else '0';
addr <= wb32_base_c(15 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 1) & '0'; -- word aligned
bwr_en(0) <= acc_en and wren_i(0);
bwr_en(1) <= acc_en and wren_i(1);
wr_en <= acc_en and wren_i(1) and wren_i(0);
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = wb32_base_c(hi_abb_c downto lo_abb_c)) else '0';
addr <= wb32_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(0) and wren_i(1);
 
 
-- Write access -------------------------------------------------------------
97,26 → 94,27
wr_access: process(clk_i)
begin
if rising_edge(clk_i) then
wb_we_o <= '0';
for i in 0 to 1 loop
if (bwr_en(i) = '1') then
if (acc_en = '1') and (wren_i(i) = '1') then -- valid byte write
case addr is
when wb32_rd_adr_lo_addr_c =>
wb_addr(i*8+7 downto i*8) <= data_i(i*8+7 downto i*8);
wb_addr(7+i*8 downto 0+i*8) <= data_i(7+i*8 downto 0+i*8);
wb_we_o <= '0';
when wb32_rd_adr_hi_addr_c =>
wb_addr(i*8+7+16 downto i*8+16) <= data_i(i*8+7 downto i*8);
wb_addr(23+i*8 downto 16+i*8) <= data_i(7+i*8 downto 0+i*8);
wb_we_o <= '0';
when wb32_wr_adr_lo_addr_c =>
wb_addr(i*8+7 downto i*8) <= data_i(i*8+7 downto i*8);
wb_addr(7+i*8 downto 0+i*8) <= data_i(7+i*8 downto 0+i*8);
wb_we_o <= '1';
when wb32_wr_adr_hi_addr_c =>
wb_addr(i*8+7+16 downto i*8+16) <= data_i(i*8+7 downto i*8);
wb_addr(23+i*8 downto 16+i*8) <= data_i(7+i*8 downto 0+i*8);
wb_we_o <= '1';
when wb32_data_lo_addr_c =>
wb_wdata(i*8+7 downto i*8) <= data_i(i*8+7 downto i*8);
wb_wdata(7+i*8 downto 0+i*8) <= data_i(7+i*8 downto 0+i*8);
when wb32_data_hi_addr_c =>
wb_wdata(i*8+7+16 downto i*8+16) <= data_i(i*8+7 downto i*8);
wb_wdata(23+i*8 downto 16+i*8) <= data_i(7+i*8 downto 0+i*8);
when wb32_ctrl_addr_c =>
if (i = 0) then -- low byte
if (i = 0) then
byte_en(0) <= data_i(ctrl_byte_en0_c);
byte_en(1) <= data_i(ctrl_byte_en1_c);
byte_en(2) <= data_i(ctrl_byte_en2_c);
/sw/lib/neo430/neo430.h
23,7 → 23,7
// # You should have received a copy of the GNU Lesser General Public License along with this #
// # source; if not, download it from https://www.gnu.org/licenses/lgpl-3.0.en.html #
// # ********************************************************************************************* #
// # Stephan Nolting, Hannover, Germany 17.07.2017 #
// # Stephan Nolting, Hannover, Germany 19.07.2017 #
// #################################################################################################
 
#ifndef neo430_h
53,34 → 53,34
#define REG16 (volatile uint16_t*)
#define REG32 (volatile uint32_t*)
 
/* --- Custom Functions Unit --- */
#define CFU_REG0 (*(REG16 0xFF80)) // r/w: simple register
#define CFU_REG0_LO (*(REG8 0xFF80)) // r/w: simple register
#define CFU_REG0_HI (*(REG8 0xFF81)) // r/w: simple register
#define CFU_REG1 (*(REG16 0xFF82)) // r/w: simple register
#define CFU_REG1_LO (*(REG8 0xFF82)) // r/w: simple register
#define CFU_REG1_HI (*(REG8 0xFF83)) // r/w: simple register
#define CFU_REG2 (*(REG16 0xFF84)) // r/w: simple register
#define CFU_REG2_LO (*(REG8 0xFF84)) // r/w: simple register
#define CFU_REG2_HI (*(REG8 0xFF85)) // r/w: simple register
#define CFU_REG3 (*(REG16 0xFF86)) // r/w: simple register
#define CFU_REG3_LO (*(REG8 0xFF86)) // r/w: simple register
#define CFU_REG3_HI (*(REG8 0xFF87)) // r/w: simple register
#define CFU_REG4 (*(REG16 0xFF88)) // r/w: simple register
#define CFU_REG4_LO (*(REG8 0xFF88)) // r/w: simple register
#define CFU_REG4_HI (*(REG8 0xFF89)) // r/w: simple register
#define CFU_REG5 (*(REG16 0xFF8A)) // r/w: simple register
#define CFU_REG5_LO (*(REG8 0xFF8A)) // r/w: simple register
#define CFU_REG5_HI (*(REG8 0xFF8B)) // r/w: simple register
#define CFU_REG6 (*(REG16 0xFF8C)) // r/w: simple register
#define CFU_REG6_LO (*(REG8 0xFF8C)) // r/w: simple register
#define CFU_REG6_HI (*(REG8 0xFF8D)) // r/w: simple register
#define CFU_REG7 (*(REG16 0xFF8E)) // r/w: simple register
#define CFU_REG7_LO (*(REG8 0xFF8E)) // r/w: simple register
#define CFU_REG7_HI (*(REG8 0xFF8F)) // r/w: simple register
/* --- Custom Function Unit - CFU --- */
#define CFU_REG0 (*(REG16 0xFF80)) // r/w: simple register, customize it!
#define CFU_REG0_LO (*(REG8 0xFF80)) // r/w: simple register, customize it!
#define CFU_REG0_HI (*(REG8 0xFF81)) // r/w: simple register, customize it!
#define CFU_REG1 (*(REG16 0xFF82)) // r/w: simple register, customize it!
#define CFU_REG1_LO (*(REG8 0xFF82)) // r/w: simple register, customize it!
#define CFU_REG1_HI (*(REG8 0xFF83)) // r/w: simple register, customize it!
#define CFU_REG2 (*(REG16 0xFF84)) // r/w: simple register, customize it!
#define CFU_REG2_LO (*(REG8 0xFF84)) // r/w: simple register, customize it!
#define CFU_REG2_HI (*(REG8 0xFF85)) // r/w: simple register, customize it!
#define CFU_REG3 (*(REG16 0xFF86)) // r/w: simple register, customize it!
#define CFU_REG3_LO (*(REG8 0xFF86)) // r/w: simple register, customize it!
#define CFU_REG3_HI (*(REG8 0xFF87)) // r/w: simple register, customize it!
#define CFU_REG4 (*(REG16 0xFF88)) // r/w: simple register, customize it!
#define CFU_REG4_LO (*(REG8 0xFF88)) // r/w: simple register, customize it!
#define CFU_REG4_HI (*(REG8 0xFF89)) // r/w: simple register, customize it!
#define CFU_REG5 (*(REG16 0xFF8A)) // r/w: simple register, customize it!
#define CFU_REG5_LO (*(REG8 0xFF8A)) // r/w: simple register, customize it!
#define CFU_REG5_HI (*(REG8 0xFF8B)) // r/w: simple register, customize it!
#define CFU_REG6 (*(REG16 0xFF8C)) // r/w: simple register, customize it!
#define CFU_REG6_LO (*(REG8 0xFF8C)) // r/w: simple register, customize it!
#define CFU_REG6_HI (*(REG8 0xFF8D)) // r/w: simple register, customize it!
#define CFU_REG7 (*(REG16 0xFF8E)) // r/w: simple register, customize it!
#define CFU_REG7_LO (*(REG8 0xFF8E)) // r/w: simple register, customize it!
#define CFU_REG7_HI (*(REG8 0xFF8F)) // r/w: simple register, customize it!
 
 
/* --- WB32 --- */
/* --- Wishbone Bus Adapter - WB32 --- */
#define WB32_LRA (*(REG16 0xFF90)) // -/w: low address for read transfer
#define WB32_HRA (*(REG16 0xFF92)) // -/w: high address for read transfer (+trigger)
#define WB32_LWA (*(REG16 0xFF94)) // -/w: low address for write transfer
91,9 → 91,10
#define WB32_CT (*(REG16 0xFF9E)) // r/w: control register
 
// WB32 - 32-bit register access
#define WB32_RA_32bit (*(REG32 0xFF90)) // -/w: address for read transfer (+trigger)
#define WB32_WA_32bit (*(REG32 0xFF94)) // -/w: address for write transfer (+trigger)
#define WB32_D_32bit (*(REG32 0xFF98)) // r/w: read/write data
#define WB32_RA_32bit (*(REG32 (&WB32_LRA))) // -/w: address for read transfer (+trigger)
#define WB32_WA_32bit (*(REG32 (&WB32_LWA))) // -/w: address for write transfer (+trigger)
#define WB32_D_32bit (*(REG32 (&WB32_LD))) // r/w: read/write data (for 32-bit access)
#define WB32_D_8bit (*(REG8 (&WB32_LD))) // r/w: read/write data (for 8-bit access)
 
// WB32 control register
#define WB32_CT_WBSEL0 0 // -/w: wishbone data byte enable bit 0
104,7 → 105,7
#define WB32_CT_PENDING 15 // r/-: pending transfer
 
 
/* --- USART/USI --- */
/* --- Universal Serial Transceiver - USART/USI --- */
#define USI_SPIRTX (*(REG16 0xFFA0)) // r/w: spi receive/transmit register
#define USI_UARTRTX (*(REG16 0xFFA2)) // r/w: uart receive/transmit register
#define USI_BAUD (*(REG16 0xFFA4)) // r/w: uart baud rate generator value
153,7 → 154,7
// 7: CLK/4096
 
 
/* --- GPIO --- */
/* --- Genearl Purpose Inputs/Outputs - GPIO --- */
#define GPIO_IN (*(REG16 0xFFB0)) // r/-: parallel input
#define GPIO_OUT (*(REG16 0xFFB2)) // r/w: parallel output
#define GPIO_CTRL (*(REG16 0xFFB4)) // -/w: control register
167,7 → 168,7
// bit 2: General interrupt enable flag
 
 
/* --- High-Precision Timer --- */
/* --- High-Precision Timer - TIMER --- */
#define TMR_CNT (*(REG16 0xFFC0)) // r/w: counter register
#define TMR_THRES (*(REG16 0xFFC2)) // r/w: threshold register
#define TMR_CT (*(REG16 0xFFC4)) // r/w: control register
191,7 → 192,7
// 7: CLK/4096
 
 
/* --- Watchdog Timer --- */
/* --- Watchdog Timer - WTD --- */
#define WDT_CTRL (*(REG16 0xFFD0)) // r/w: Watchdog control register
 
// Watchdog control register
214,7 → 215,7
// 7: CLK/4096
 
 
/* --- SysConfig --- */
/* --- System Configuration - SYSCONFIG --- */
#define CPUID0 (*(REG16 0xFFE0)) // r/-: HW version
#define CPUID1 (*(REG16 0xFFE2)) // r/-: system configuration
#define CPUID2 (*(REG16 0xFFE4)) // r/-: CPU identifier
223,10 → 224,6
#define CPUID5 (*(REG16 0xFFEA)) // r/-: DMEM/RAM size in bytes
#define CPUID6 (*(REG16 0xFFEC)) // r/-: clock speed lo
#define CPUID7 (*(REG16 0xFFEE)) // r/-: clock speed hi
 
// SysConfig - 32-bit register access
#define CLOCKSPEED_32bit (*(REG32 0xFFEC)) // r/-: clock speed (in Hz)
 
// Aliases
#define HW_VERSION CPUID0 // r/-: HW verison number
#define SYS_FEATURES CPUID1 // r/-: synthesized system features
237,6 → 234,9
#define CLOCKSPEED_LO CPUID6 // r/-: clock speed (in Hz) low part
#define CLOCKSPEED_HI CPUID7 // r/-: clock speed (in Hz) high part
 
// SysConfig - 32-bit register access
#define CLOCKSPEED_32bit (*(REG32 (&CLOCKSPEED_LO))) // r/-: clock speed (in Hz)
 
// SYS features
#define SYS_CFU_EN 0 // CFU synthesized
#define SYS_WB32_EN 1 // WB32 synthesized
/sw/lib/neo430/neo430_wishbone.h
20,7 → 20,7
// # source; if not, download it from https://www.gnu.org/licenses/lgpl-3.0.en.html #
// # ********************************************************************************************* #
// # Thanks to Edward Sherriff! #
// # Stephan Nolting, Hannover, Germany 17.07.2017 #
// # Stephan Nolting, Hannover, Germany 19.07.2017 #
// #################################################################################################
 
#ifndef neo430_wishbone_h
147,7 → 147,7
uint8_t wishbone_read8(uint32_t a) {
 
// 8-bit transfer, classic cycle
WB32_CT = 1 << (a & 3); // corresponding byte enable
WB32_CT = 1 << (((uint8_t)a) & 3); // corresponding byte enable
 
// device address aligned to 8-bit + transfer trigger
WB32_RA_32bit = a;
156,7 → 156,7
while((WB32_CT & (1<<WB32_CT_PENDING)) != 0);
 
// select correct byte to be written
volatile uint8_t* in = (uint8_t*)(&WB32_LD + ((uint16_t)a & 3));
volatile uint8_t* in = (uint8_t*)(&WB32_D_8bit + ((uint8_t)a & 3));
return *in;
}
 
169,10 → 169,10
void wishbone_write8(uint32_t a, uint8_t d) {
 
// 8-bit transfer, classic cycle
WB32_CT = 1 << (a & 3); // corresponding byte enable
WB32_CT = 1 << (((uint8_t)a) & 3); // corresponding byte enable
 
// select correct byte to be written
volatile uint8_t* out = (uint8_t*)(&WB32_LD + ((uint16_t)a & 3));
volatile uint8_t* out = (uint8_t*)(&WB32_D_8bit + ((uint8_t)a & 3));
*out = d;
 
// device address aligned to 8-bit + transfer trigger
287,7 → 287,7
uint8_t wishbone_read8_pipelined(uint32_t a) {
 
// 8-bit transfer, pipelined cycle
WB32_CT = (1 << (a & 3)) | 0x10; // corresponding byte enable
WB32_CT = (1 << (((uint8_t)a) & 3)) | 0x10; // corresponding byte enable
 
// device address aligned to 8-bit + transfer trigger
WB32_RA_32bit = a;
296,7 → 296,7
while((WB32_CT & (1<<WB32_CT_PENDING)) != 0);
 
// select correct byte to be read
volatile uint8_t* in = (uint8_t*)(&WB32_LD + ((uint16_t)a & 3));
volatile uint8_t* in = (uint8_t*)(&WB32_D_8bit + ((uint8_t)a & 3));
return *in;
}
 
309,10 → 309,10
void wishbone_write8_pipelined(uint32_t a, uint8_t d) {
 
// 8-bit transfer, pipelined cycle
WB32_CT = (1 << (a & 3)) | 0x10; // corresponding byte enable
WB32_CT = (1 << (((uint8_t)a) & 3)) | 0x10; // corresponding byte enable
 
// select correct byte to be written
volatile uint8_t* out = (uint8_t*)(&WB32_LD + ((uint16_t)a & 3));
volatile uint8_t* out = (uint8_t*)(&WB32_D_8bit + ((uint8_t)a & 3));
*out = d;
 
// device address aligned to 8-bit + transfer trigger

powered by: WebSVN 2.1.0

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