URL
https://opencores.org/ocsvn/neo430/neo430/trunk
Subversion Repositories neo430
Compare Revisions
- This comparison shows the changes necessary to convert path
/neo430
- from Rev 134 to Rev 135
- ↔ Reverse comparison
Rev 134 → Rev 135
/trunk/rtl/core/neo430_application_image.vhd
6,7 → 6,7
|
package neo430_application_image is |
|
type application_init_image_t is array (0 to (2**16)-1) of std_ulogic_vector(15 downto 0); |
type application_init_image_t is array (0 to 65535) of std_ulogic_vector(15 downto 0); |
constant application_init_image : application_init_image_t := ( |
000000 => x"4303", |
000001 => x"4218", |
/trunk/rtl/core/neo430_bootloader_image.vhd
6,7 → 6,7
|
package neo430_bootloader_image is |
|
type bootloader_init_image_t is array (0 to (2**16)-1) of std_ulogic_vector(15 downto 0); |
type bootloader_init_image_t is array (0 to 65535) of std_ulogic_vector(15 downto 0); |
constant bootloader_init_image : bootloader_init_image_t := ( |
000000 => x"4303", |
000001 => x"4302", |
/trunk/rtl/core/neo430_cfu.vhd
1,12 → 1,14
-- ################################################################################################# |
-- # << NEO430 - Custom Functions Unit >> # |
-- # ********************************************************************************************* # |
-- # This unit is a template for implementing custom function, which are directly memory-mapped # |
-- # into the CPU's address space. The address space of this unit is 16 bytes large. This unit can # |
-- # be accessed using full word (16-bit) or byte-wide accesses. # |
-- # This unit is a template for implementing custom functions, which are directly memory-mapped # |
-- # into the CPU's IO address space. The address space of this unit is 16 bytes large. This unit # |
-- # can be accessed using full word (16-bit) or byte-wide accesses. # |
-- # In the original state, this unit only provides 8 16-bit register (also accessible in byte # |
-- # mode), that do not perform any kind of data manipulation. # |
-- # Examplary applications: multiplier, divider, complex artihmetic, rocket science, ... # |
-- # # |
-- # Take a look at the rtl\cfu_templates folder for some example CFU implementations. # |
-- # ********************************************************************************************* # |
-- # This file is part of the NEO430 Processor project: https://github.com/stnolting/neo430 # |
-- # Copyright by Stephan Nolting: stnolting@gmail.com # |
/trunk/rtl/core/neo430_control.vhd
256,6 → 256,7
when BRANCH => -- branch operation |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source/destination: PC |
ctrl_nxt(ctrl_adr_off1_c downto ctrl_adr_off0_c) <= "00"; -- add immediate offset |
ctrl_nxt(ctrl_adr_imm_en_c) <= '1'; -- add immediate |
ctrl_nxt(ctrl_rf_in_sel_c) <= '1'; -- select addr feedback |
ctrl_nxt(ctrl_rf_wb_en_c) <= branch_taken; -- valid RF write back if branch taken |
484,8 → 485,8
when PUSHCALL_0 => -- PUSH/CALL cycle 0 (stack update) |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_sp_c; -- source/destination: SP |
ctrl_nxt(ctrl_adr_off1_c downto ctrl_adr_off0_c) <= "11"; -- add -2 |
ctrl_nxt(ctrl_adr_mar_wr_c) <= '1'; -- write to MAR |
ctrl_nxt(ctrl_adr_off1_c downto ctrl_adr_off0_c) <= "11"; -- add -2 |
ctrl_nxt(ctrl_adr_mar_sel_c) <= '1'; -- use result from adder |
ctrl_nxt(ctrl_rf_in_sel_c) <= '1'; -- select addr feedback |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write back |
549,7 → 550,7
state_nxt <= IFETCH_0; -- done! |
|
|
when IRQ_0 => -- IRQ processing cycle 0 |
when IRQ_0 => -- IRQ processing cycle 0: SP=SP-2, disable sleep mode |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_rf_dsleep_c) <= '1'; -- disable sleep mode |
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_sp_c; -- source/destination: SP |
560,7 → 561,7
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write back |
state_nxt <= IRQ_1; |
|
when IRQ_1 => -- IRQ processing cycle 1 |
when IRQ_1 => -- IRQ processing cycle 1: Buffer PC for memory write |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source: PC |
ctrl_nxt(ctrl_alu_opa_wr_c) <= '1'; -- write PC to OpA |
567,7 → 568,7
ctrl_nxt(ctrl_alu_opb_wr_c) <= '1'; -- write PC to OpB |
state_nxt <= IRQ_2; |
|
when IRQ_2 => -- IRQ processing cycle 2 |
when IRQ_2 => -- IRQ processing cycle 2: Write PC (push), SP=SP-2 |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_cmd3_c downto ctrl_alu_cmd0_c) <= alu_mov_c; |
ctrl_nxt(ctrl_mem_wr_c) <= '1'; -- write memory request (store PC) |
579,7 → 580,7
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write back |
state_nxt <= IRQ_3; |
|
when IRQ_3 => -- IRQ processing cycle 3 |
when IRQ_3 => -- IRQ processing cycle 3: Buffer SR for memory write, clear SR, set IRQ vector address |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_sr_c; -- source: SR |
ctrl_nxt(ctrl_alu_opa_wr_c) <= '1'; -- write to OpA |
590,7 → 591,7
ctrl_nxt(ctrl_mem_rd_c) <= '1'; -- Memory read (fast) |
state_nxt <= IRQ_4; |
|
when IRQ_4 => -- IRQ processing cycle 4 |
when IRQ_4 => -- IRQ processing cycle 4: Write SR (push), get IRQ vector |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_cmd3_c downto ctrl_alu_cmd0_c) <= alu_mov_c; |
ctrl_nxt(ctrl_mem_wr_c) <= '1'; -- write memory request |
598,7 → 599,7
ctrl_nxt(ctrl_alu_opa_wr_c) <= '1'; -- write to OpA |
state_nxt <= IRQ_5; |
|
when IRQ_5 => -- IRQ processing cycle 5 |
when IRQ_5 => -- IRQ processing cycle 5: Store IRQ vector to PC |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_cmd3_c downto ctrl_alu_cmd0_c) <= alu_mov_c; |
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- destination: PC |
/trunk/rtl/core/neo430_dmem.vhd
73,6 → 73,8
begin |
if rising_edge(clk_i) then |
rden <= rden_i and acc_en; |
|
-- write access LOW byte -- |
if (acc_en = '1') and (wren_i(0) = '1') then -- write low byte |
if (is_power_of_two(DMEM_SIZE, 16) = true) then |
dmem_file(addr)(07 downto 0) <= data_i(07 downto 0); |
83,6 → 85,8
report "DMEM write access out of range since DMEM_SIZE is not a power of 2!" severity error; |
end if; |
end if; |
|
-- write access HIGH byte -- |
if (acc_en = '1') and (wren_i(1) = '1') then -- write high byte |
if (is_power_of_two(DMEM_SIZE, 16) = true) then |
dmem_file(addr)(15 downto 8) <= data_i(15 downto 8); |
93,6 → 97,8
report "DMEM write access out of range since DMEM_SIZE is not a power of 2!" severity error; |
end if; |
end if; |
|
-- read access (both bytes) -- |
if (is_power_of_two(DMEM_SIZE, 16) = false) then |
-- modified read-access: to prevent simulation errors when DMEM_SIZE is not a power of 2 -- |
if (addr < DMEM_SIZE/2) then |
/trunk/rtl/core/neo430_imem.vhd
113,6 → 113,8
begin |
if rising_edge(clk_i) then |
rden <= rden_i and acc_en; |
|
-- write access -- |
if (IMEM_AS_ROM = false) then -- implement IMEM as true RAM? |
if (acc_en = '1') and (upen_i = '1') then -- valid write access at all? |
if (wren_i(0) = '1') then -- write low byte |
137,6 → 139,8
end if; |
end if; |
end if; |
|
-- read access -- |
if (is_power_of_two(IMEM_SIZE, 16) = false) then |
-- modified read-access: to prevent simulation errors when IMEM_SIZE is not a power of 2 -- |
if (addr < IMEM_SIZE/2) then |
/trunk/rtl/core/neo430_reg_file.vhd
21,7 → 21,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 15.08.2017 # |
-- # Stephan Nolting, Hannover, Germany 13.10.2017 # |
-- ################################################################################################# |
|
library ieee; |
66,23 → 66,24
signal c_flag, z_flag, n_flag, i_flag, s_flag, v_flag, q_flag, r_flag : std_ulogic; |
|
-- misc -- |
signal in_data_tmp : std_ulogic_vector(15 downto 0); -- input selection tmp |
signal in_data : std_ulogic_vector(15 downto 0); -- input selection |
signal boot_addr : std_ulogic_vector(15 downto 0); -- the boot address |
signal in_data : std_ulogic_vector(15 downto 0); -- input selection |
signal boot_addr : std_ulogic_vector(15 downto 0); -- the boot address |
|
begin |
|
-- Boot address Selection --------------------------------------------------- |
-- ----------------------------------------------------------------------------- |
-- Boot from beginning of IMEM if no bootloader is used |
-- Boot from beginning of boot ROM if bootloader IS used |
-- Boot from beginning of IMEM if *NO* bootloader is used |
-- Boot from beginning of boot ROM if bootloader *IS USED* |
boot_addr <= imem_base_c when (BOOTLD_USE = false) else boot_base_c; |
-- By not using a reset-like init of the PC, the CP can be mapped into a dedicated |
-- block RAM saving logic resources ;) |
|
|
-- Input Operand Selection -------------------------------------------------- |
-- ----------------------------------------------------------------------------- |
in_data_tmp <= alu_i when (ctrl_i(ctrl_rf_in_sel_c) = '0') else addr_i; |
in_data <= in_data_tmp when (ctrl_i(ctrl_rf_boot_c) = '0') else boot_addr; |
in_data <= boot_addr when (ctrl_i(ctrl_rf_boot_c) = '1') else |
addr_i when (ctrl_i(ctrl_rf_in_sel_c) = '1') else alu_i; |
|
|
-- Register File Write Access ----------------------------------------------- |
90,42 → 91,38
sreg_write: process(rst_i, clk_i) |
begin |
if (rst_i = '0') then |
c_flag <= '0'; -- carry |
z_flag <= '0'; -- zero |
n_flag <= '0'; -- negative |
i_flag <= '0'; -- interrupts disabled |
s_flag <= '0'; -- sleep disabled |
v_flag <= '0'; -- overflow |
q_flag <= '0'; -- clear pending IRQ buffer |
r_flag <= '0'; -- IMEM (ROM) write access disabled |
sreg <= (others => '0'); -- here we NEED a true hardware reset |
elsif rising_edge(clk_i) then |
-- status register -- |
if ((ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) = reg_sr_c) and |
(ctrl_i(ctrl_rf_ad_c) = '0') and (ctrl_i(ctrl_rf_wb_en_c) = '1')) then -- only write in reg-addr-mode! |
c_flag <= in_data(sreg_c_c); |
z_flag <= in_data(sreg_z_c); |
n_flag <= in_data(sreg_n_c); |
i_flag <= in_data(sreg_i_c); |
s_flag <= in_data(sreg_s_c); |
v_flag <= in_data(sreg_v_c); |
q_flag <= in_data(sreg_q_c); |
r_flag <= in_data(sreg_r_c); |
sreg(sreg_c_c) <= in_data(sreg_c_c); |
sreg(sreg_z_c) <= in_data(sreg_z_c); |
sreg(sreg_n_c) <= in_data(sreg_n_c); |
sreg(sreg_i_c) <= in_data(sreg_i_c); |
sreg(sreg_s_c) <= in_data(sreg_s_c); |
sreg(sreg_v_c) <= in_data(sreg_v_c); |
sreg(sreg_q_c) <= in_data(sreg_q_c); |
sreg(sreg_r_c) <= in_data(sreg_r_c); |
else -- automatic update |
q_flag <= '0'; -- auto-clear |
sreg(sreg_q_c) <= '0'; -- auto-clear |
if (ctrl_i(ctrl_rf_dsleep_c) = '1') then -- disable sleep mode |
s_flag <= '0'; |
sreg(sreg_s_c) <= '0'; |
end if; |
if (ctrl_i(ctrl_rf_fup_c) = '1') then -- update ALU flags |
c_flag <= flag_i(flag_c_c); |
z_flag <= flag_i(flag_z_c); |
n_flag <= flag_i(flag_n_c); |
v_flag <= flag_i(flag_v_c); |
sreg(sreg_c_c) <= flag_i(flag_c_c); |
sreg(sreg_z_c) <= flag_i(flag_z_c); |
sreg(sreg_n_c) <= flag_i(flag_n_c); |
sreg(sreg_v_c) <= flag_i(flag_v_c); |
end if; |
end if; |
end if; |
end process sreg_write; |
|
-- gp regs (including PW, dummy SR and dummy CG) -- |
-- status register output -- |
sreg_o <= sreg; |
|
-- gp regs (including PC, dummy SR and dummy CG) -- |
rf_write: process(clk_i) |
begin |
if rising_edge(clk_i) then |
135,49 → 132,29
end if; |
end process rf_write; |
|
-- assign virtual SREG -- |
virtual_sreg: process(c_flag, z_flag, n_flag, i_flag, s_flag, v_flag, q_flag, r_flag) |
begin |
sreg <= (others => '0'); |
sreg(sreg_c_c) <= c_flag; |
sreg(sreg_z_c) <= z_flag; |
sreg(sreg_n_c) <= n_flag; |
sreg(sreg_i_c) <= i_flag; |
sreg(sreg_s_c) <= s_flag; |
sreg(sreg_v_c) <= v_flag; |
sreg(sreg_q_c) <= q_flag; |
sreg(sreg_r_c) <= r_flag; |
end process virtual_sreg; |
|
-- output -- |
sreg_o <= sreg; |
|
|
-- Register File Read Access ------------------------------------------------ |
-- ----------------------------------------------------------------------------- |
rf_read: process(ctrl_i, reg_file, sreg) |
variable const_sel_v : std_ulogic_vector(02 downto 0); |
variable const_gen_v : std_ulogic_vector(15 downto 0); |
begin |
-- constant generator -- |
const_sel_v := ctrl_i(ctrl_rf_adr0_c) & ctrl_i(ctrl_rf_as1_c) & ctrl_i(ctrl_rf_as0_c); |
case const_sel_v is |
when "000" => const_gen_v := sreg; -- read SR |
when "001" => const_gen_v := x"0000"; -- absolute addressing mode |
when "010" => const_gen_v := x"0004"; -- +4 |
when "011" => const_gen_v := x"0008"; -- +8 |
when "100" => const_gen_v := x"0000"; -- 0 |
when "101" => const_gen_v := x"0001"; -- +1 |
when "110" => const_gen_v := x"0002"; -- +2 |
when "111" => const_gen_v := x"FFFF"; -- -1 |
when others => const_gen_v := x"0000"; |
end case; |
|
-- output select -- |
if ((ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) = reg_sr_c) or |
(ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) = reg_cg_c)) then |
data_o <= const_gen_v; |
-- constant generator / SR read access -- |
const_sel_v := ctrl_i(ctrl_rf_adr0_c) & ctrl_i(ctrl_rf_as1_c) & ctrl_i(ctrl_rf_as0_c); |
case const_sel_v is |
when "000" => data_o <= sreg; -- read SR |
when "001" => data_o <= x"0000"; -- absolute addressing mode |
when "010" => data_o <= x"0004"; -- +4 |
when "011" => data_o <= x"0008"; -- +8 |
when "100" => data_o <= x"0000"; -- 0 |
when "101" => data_o <= x"0001"; -- +1 |
when "110" => data_o <= x"0002"; -- +2 |
when "111" => data_o <= x"FFFF"; -- -1 |
when others => data_o <= x"0000"; |
end case; |
else |
-- register file read access -- |
data_o <= reg_file(to_integer(unsigned(ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c)))); |
end if; |
end process rf_read; |
/trunk/sw/bootloader/make.bat
21,7 → 21,7
@REM # You should have received a copy of the GNU Lesser General Public License along with this # |
@REM # source; if not, download it from https://www.gnu.org/licenses/lgpl-3.0.en.html # |
@REM # ********************************************************************************************* # |
@REM # Stephan Nolting, Hannover, Germany 06.10.2017 # |
@REM # Stephan Nolting, Hannover, Germany 14.10.2017 # |
@REM ################################################################################################# |
|
|
/trunk/sw/common/Makefile
21,7 → 21,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 06.10.2017 # |
# Stephan Nolting, Hannover, Germany 14.10.2017 # |
################################################################################################# |
|
|
54,7 → 54,7
#------------------------------------------------------------------------------- |
# Tools |
#------------------------------------------------------------------------------- |
#C ompiler tools (obsolete!!!) |
#C ompiler tools |
AS = $(BIN_PATH)/msp430-elf-as |
CC = $(BIN_PATH)/msp430-elf-gcc |
LD = $(BIN_PATH)/msp430-elf-ld |
65,9 → 65,7
|
# Compiler flags |
CC_OPTS = -pipe -nostartfiles -fwhole-program -fdata-sections -ffunction-sections -Xlinker --gc-sections -Wl,-static -Wall |
ifeq ($(USE_TIMSP430_GCC),true) |
CC_OPTS += -minrt -Xassembler --mY -mhwmult=none |
endif |
CC_OPTS += -minrt -Xassembler --mY -mhwmult=none |
|
#------------------------------------------------------------------------------- |
# Paths |
117,6 → 115,9
# Assembly listing file |
$(APP_ASM): main.elf |
@$(OBJDUMP) -D -S -z $< > $@ |
if grep -qR "dadd" $@; \ |
then echo "NEO430: WARNING! 'DADD' instruction might be used! Make sure it is synthesized!"; \ |
fi |
|
# Generate NEO430 executable image for bootloader update |
$(APP_BIN): image.bin $(IMAGE_GEN) |
128,6 → 129,7
@echo Installing application image to rtl/core/neo430_application_image.vhd |
@cp neo430_application_image.vhd ../../rtl/core/. |
|
|
#------------------------------------------------------------------------------- |
# Clean up |
#------------------------------------------------------------------------------- |
/trunk/sw/common/compile.bat
21,7 → 21,7
@REM # You should have received a copy of the GNU Lesser General Public License along with this # |
@REM # source; if not, download it from https://www.gnu.org/licenses/lgpl-3.0.en.html # |
@REM # ********************************************************************************************* # |
@REM # Stephan Nolting, Hannover, Germany 06.10.2017 # |
@REM # Stephan Nolting, Hannover, Germany 13.10.2017 # |
@REM ################################################################################################# |
|
|
45,9 → 45,7
|
@REM Compiler flags |
@set CC_OPTS= -nostartfiles -pipe -fwhole-program -fdata-sections -ffunction-sections -Xlinker --gc-sections -Wl,-static -Wall |
@if %USE_TIMSP430_GCC%==true ( |
@set CC_OPTS=%CC_OPTS% -minrt -Xassembler --mY -mhwmult=none |
) |
@set CC_OPTS=%CC_OPTS% -minrt -Xassembler --mY -mhwmult=none |
|
@REM Assemble start-up code |
@%AS% -mcpu=msp430 crt0.asm -mY -o crt0.elf |
80,7 → 78,7
|
@REM Check if "DADD" is used |
@echo off |
@find /I /C "dadd " main.s > NUL |
@find /I /C "dadd" main.s > NUL |
@echo on |
@if %errorlevel% equ 0 echo NEO430: WARNING! 'DADD' instruction might be used! Make sure it is synthesized! |
|
/trunk/sw/example/game_of_life/main.c
73,7 → 73,6
xorshift32(); |
} |
|
|
// initialize universe using random data |
for (x=0; x<NUM_CELLS_X/8; x++) { |
for (y=0; y<NUM_CELLS_Y; y++) { |
81,7 → 80,6
} |
} |
|
|
while(1) { |
|
// user abort? |
/trunk/sw/tools/image_gen/image_gen.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/sw/tools/image_gen/main.cpp
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 20.12.2016 # |
// # Stephan Nolting, Hannover, Germany 13.10.2017 # |
// ################################################################################################# |
|
#include <stdint.h> |
30,14 → 30,14
int main(int argc, char *argv[]) { |
|
if (argc != 4) { |
printf("< NEO430 program image generator >\n" |
printf("<<< NEO430 executable image generator >>>\n" |
"Three arguments are required.\n" |
"1st: Option\n" |
" -app_bin : Generate application executable binary (with header!) \n" |
" -app_img : Generate application raw executable memory image (text file, no header!)\n" |
" -bld_img : Generate bootloader raw executable memory image (text file, no header!)\n" |
"2nd: Input file\n" |
"3rd: Output file\n"); |
"2nd: Input file (raw binary image)\n" |
"3rd: Output file (as selected)\n"); |
return 1; |
} |
|
126,7 → 126,7
"\r\n" |
"package neo430_application_image is\r\n" |
"\r\n" |
" type application_init_image_t is array (0 to (2**16)-1) of std_ulogic_vector(15 downto 0);\r\n" |
" type application_init_image_t is array (0 to 65535) of std_ulogic_vector(15 downto 0);\r\n" |
" constant application_init_image : application_init_image_t := (\r\n"); |
fputs(tmp_string, output); |
|
168,7 → 168,7
"\r\n" |
"package neo430_bootloader_image is\r\n" |
"\r\n" |
" type bootloader_init_image_t is array (0 to (2**16)-1) of std_ulogic_vector(15 downto 0);\r\n" |
" type bootloader_init_image_t is array (0 to 65535) of std_ulogic_vector(15 downto 0);\r\n" |
" constant bootloader_init_image : bootloader_init_image_t := (\r\n"); |
fputs(tmp_string, output); |
|