Commit 287d8152 authored by Lucas Russo's avatar Lucas Russo

system_test/*: new testbench

parent 5221b0d9
......@@ -30,7 +30,7 @@ library ieee;
use ieee.std_logic_misc.all;
use ieee.std_logic_unsigned.all;
-- Memoryies NGC
-- Memories NGC
library UNISIM;
use UNISIM.vcomponents.all;
......
This diff is collapsed.
action = "simulation"
target = "xilinx"
files = [ "dbe_bpm_simple_top.vhd", "system_test_tb.vhd" ];
modules = { "local" : ["../../.." ] };
To run this testbench example with ISim:
1 - hdlmake2 --make-isim
2 - make
3 - make fuse TOP_MODULE=<top_module_name_without_extension>
[FUSE_OUTPUT=<simulation_executable_name>]
4 - ./<isim_project_name> --gui
or
5 - ./isim_proj --gui
To clean the generated files:
1 - make clean
===============================================
This example testbench is needs more testing as it did not compile
with ISim. Fatal Error occured:
"FATAL_ERROR:Simulator:CompilerAssert.h:40:1.45 - Internal Compiler Error
in file ../src/VhdlDecl.cpp at line 3154 Process will terminate. For
technical support on this issue, please open a WebCase with this project
attached at http://www.xilinx.com/support.
FATAL_ERROR:Simulator:CompilerAssert.h:40:1.45 - Internal Compiler Error
in file ../src/VhdlDecl.cpp at line 3154 Process will terminate. For
technical support on this issue, please open a WebCase with this project
attached at http://www.xilinx.com/support."
This diff is collapsed.
PLATFORM = lm32
OBJS_WRC = main.o gpio.o dma.o uart.o fmc150.o target/lm32/crt0.o
CROSS_COMPILE ?= /opt/gcc-lm32/bin/lm32-elf-
CFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled -I.
LDFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled -nostdlib -T target/lm32/ram.ld
CC=$(CROSS_COMPILE)gcc
OBJCOPY=$(CROSS_COMPILE)objcopy
OBJDUMP=$(CROSS_COMPILE)objdump
CFLAGS= $(CFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude $(PTPD_CFLAGS) -Iptp-noposix/PTPWRd
LDFLAGS= $(LDFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude
SIZE = $(CROSS_COMPILE)size
OBJS=$(OBJS_PLATFORM) $(OBJS_WRC) $(OBJS_PTPD) $(OBJS_PTPD_FREE)
OUTPUT=main
all: $(OBJS)
$(SIZE) -t $(OBJS)
${CC} -o $(OUTPUT).elf $(OBJS) $(LDFLAGS)
${OBJCOPY} -O binary $(OUTPUT).elf $(OUTPUT).bin
${OBJDUMP} -d $(OUTPUT).elf > $(OUTPUT)_disasm.S
./genraminit $(OUTPUT).bin 0 > $(OUTPUT).ram
clean:
rm -f $(OBJS) $(OUTPUT).elf $(OUTPUT).bin $(OUTPUT).ram $(OUTPUT)_disasm.S
%.o: %.c %.h
${CC} $(CFLAGS) $(PTPD_CFLAGS) $(INCLUDE_DIR) $(LIB_DIR) -c $^ -o $@
#include "dma.h"
/* DMA user interface definition */
inline int read_is_addr(dma_t dma)
{
return dma->RD_ADDR;
}
inline void write_is_addr(dma_t dma, int addr)
{
dma->WR_ADDR = (uint32_t) addr;
}
inline int read_strd(dma_t dma)
{
return dma->RD_STRD;
}
inline void write_strd(dma_t dma, int strd)
{
dma->WR_STRD = (uint32_t) strd;
}
inline int read_tr_count(dma_t dma)
{
return dma->TR_COUNT;
}
#include "board.h"
#include "inttypes.h"
#include "fmc150.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if(argc < 3) return -1;
FILE *f = fopen(argv[1],"rb");
if(!f) return -1;
unsigned char x[4];
int i=0;
int n = atoi(argv[2]);
while(!feof(f)){
fread(x,1,4,f);
printf("write %x %02X%02X%02X%02X\n", i++, x[0],x[1],x[2],x[3]);
}
for(;i<n;){
printf("write %x %02X%02X%02X%02X\n", i++, 0,0,0,0);
}
fclose(f);
return 0;
}
#include "gpio.h"
/* GPIO user interface definition */
inline void gpio_out(gpio_t gpio, int pin, int val)
{
if(val)
gpio->SODR = (1<<pin);
else
gpio->CODR = (1<<pin);
}
inline void gpio_dir(gpio_t gpio, int pin, int val)
{
if(val)
gpio->DDR |= (1<<pin);
else
gpio->DDR &= ~(1<<pin);
}
inline int gpio_in(gpio_t gpio, int pin)
{
return gpio->PSR & (1<<pin) ? 1 : 0;
}
#ifndef _BOARD_H_
#define _BOARD_H_
/* Automate the address peripheral discover */
/****************************/
/* General Definitions */
/****************************/
/* 100 MHz ??? */
#define CPU_CLOCK 1000000
/*************************/
/* Base addresses */
/*************************/
/* RAM Definitions */
/* First RAM port */
#define BASE_RAM_PORT_0 0x00000000
/* Second RAM port */
#define BASE_RAM_PORT_1 0x10000000
/* DMA definitions */
#define BASE_DMA_ADDR 0x20000400
/* FMC definitions */
#define BASE_FMC150_ADDR 0x20000500
/* Simple UART definitions */
#define BASE_UART_ADDR 0x20000600
#define UART_BAUDRATE 9600
/* Simple LED GPIO definitions */
#define BASE_LEDS_ADDR 0x20000700
/* Simple Button GPIO definitions */
#define BASE_BUTTONS_ADDR 0x20000800
#endif
#ifndef __DMA_H
#define __DMA_H
#include "inttypes.h"
#include "board.h"
/*
This structure must conform to what it is specified in the
FPGA software-acessible registers. See general-cores/cores/wishbone/wb_dma.vhd
*/
struct DMA_WB
{
uint32_t RD_ADDR; /* Read issue address register */
uint32_t WR_ADDR; /* Write issue address register */
uint32_t RD_STRD; /* Read stride */
uint32_t WR_STRD; /* Write stride */
uint32_t TR_COUNT; /* Transfer count */
};
typedef volatile struct DMA_WB * dma_t;
/* DMA user interface */
int read_is_addr(dma_t dma);
void write_is_addr(dma_t dma, int addr);
int read_strd(dma_t dma);
void write_strd(dma_t dma, int strd);
int read_tr_count(dma_t dma);
#endif
#ifndef _FMC150_H_
#define _FMC150_H_
#include "inttypes.h"
#include "board.h"
#include "wb_fmc150.h"
/* Type definitions */
typedef volatile struct FMC150_WB * fmc150_t;
/* DMA user interface */
/*int read_is_addr(dma_t dma);
void write_is_addr(dma_t dma, int addr);
int read_strd(dma_t dma);
void write_strd(dma_t dma, int strd);
int read_tr_count(dma_t dma);*/
#endif
#ifndef _GPIO_H_
#define _GPIO_H_
#include "inttypes.h"
#include "board.h"
/*
This structure must conform to what it is specified in the
FPGA software-acessible registers. See general-cores/cores/wishbone/wb_gpio_port.vhd
*/
struct GPIO_WB
{
uint32_t CODR; /* Clear output register */
uint32_t SODR; /* Set output register */
uint32_t DDR; /* Data direction register (1 means out) */
uint32_t PSR; /* Pin state register */
};
typedef volatile struct GPIO_WB * gpio_t;
//static volatile struct GPIO_WB *__gpio = (volatile struct GPIO_WB *) BASE_GPIO;
/* GPIO user interface */
void gpio_out(gpio_t gpio, int pin, int val);
void gpio_dir(gpio_t gpio, int pin, int val);
int gpio_in(gpio_t gpio, int pin);
#endif
#ifndef __WRAPPED_INTTYPES_H
#define __WRAPPED_INTTYPES_H
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef signed long long uint64_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
#endif
#ifndef _UART_H_
#define _UART_H_
#include "wb_uart.h"
/* Type definitions */
typedef volatile struct UART_WB * uart_t;
int mprintf(char const *format, ...);
void uart_init(uart_t uart);
void uart_write_byte(uart_t uart, unsigned char c);
int uart_poll(uart_t uart);
int uart_read_byte(uart_t uart);
#endif
/*
Register definitions for slave core: FMC ADC/DAC interface registers
* File : wb_fmc150.h
* Author : auto-generated by wbgen2 from xfmc150.wb
* Created : Thu Oct 11 10:21:39 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE xfmc150.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_XFMC150_WB
#define __WBGEN2_REGDEFS_XFMC150_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Input Flags for Pulsing Registers */
/* definitions for register: Input Flags for FMC150 */
/* definitions for field: SPI Read/Write flag in reg: Input Flags for FMC150 */
#define FMC150_FLGS_IN_SPI_RW WBGEN2_GEN_MASK(0, 1)
/* definitions for field: External Clock for ADC in reg: Input Flags for FMC150 */
#define FMC150_FLGS_IN_EXT_CLK WBGEN2_GEN_MASK(1, 1)
/* definitions for register: Address for Chips on FMC150 */
/* definitions for register: Data In for Chips on FMC150 */
/* definitions for register: Chipselect for Chips on FMC150 */
/* definitions for field: Chipselect for cdce72010 in reg: Chipselect for Chips on FMC150 */
#define FMC150_CS_CDCE72010 WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Chipselect for ads62p49 in reg: Chipselect for Chips on FMC150 */
#define FMC150_CS_ADS62P49 WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Chipselect for dac3283 in reg: Chipselect for Chips on FMC150 */
#define FMC150_CS_DAC3283 WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Chipselect for amc7823 in reg: Chipselect for Chips on FMC150 */
#define FMC150_CS_AMC7823 WBGEN2_GEN_MASK(3, 1)
/* definitions for register: ADC Delay */
/* definitions for field: ADC Strobe delay in reg: ADC Delay */
#define FMC150_ADC_DLY_STR_MASK WBGEN2_GEN_MASK(0, 5)
#define FMC150_ADC_DLY_STR_SHIFT 0
#define FMC150_ADC_DLY_STR_W(value) WBGEN2_GEN_WRITE(value, 0, 5)
#define FMC150_ADC_DLY_STR_R(reg) WBGEN2_GEN_READ(reg, 0, 5)
/* definitions for field: ADC Channel A delay in reg: ADC Delay */
#define FMC150_ADC_DLY_CHA_MASK WBGEN2_GEN_MASK(8, 5)
#define FMC150_ADC_DLY_CHA_SHIFT 8
#define FMC150_ADC_DLY_CHA_W(value) WBGEN2_GEN_WRITE(value, 8, 5)
#define FMC150_ADC_DLY_CHA_R(reg) WBGEN2_GEN_READ(reg, 8, 5)
/* definitions for field: ADC Strobe delay in reg: ADC Delay */
#define FMC150_ADC_DLY_CHB_MASK WBGEN2_GEN_MASK(16, 5)
#define FMC150_ADC_DLY_CHB_SHIFT 16
#define FMC150_ADC_DLY_CHB_W(value) WBGEN2_GEN_WRITE(value, 16, 5)
#define FMC150_ADC_DLY_CHB_R(reg) WBGEN2_GEN_READ(reg, 16, 5)
/* definitions for register: Data Out From Chips on FMC150 */
/* definitions for register: Flags out from Chips on FMC150 */
/* definitions for field: SPI Busy in reg: Flags out from Chips on FMC150 */
#define FMC150_FLGS_OUT_SPI_BUSY WBGEN2_GEN_MASK(0, 1)
/* definitions for field: CDCE72010 PLL Status in reg: Flags out from Chips on FMC150 */
#define FMC150_FLGS_OUT_PLL_STATUS WBGEN2_GEN_MASK(1, 1)
/* definitions for field: FPGA ADC clock locked in reg: Flags out from Chips on FMC150 */
#define FMC150_FLGS_OUT_ADC_CLK_LOCKED WBGEN2_GEN_MASK(2, 1)
/* definitions for field: FMC present in reg: Flags out from Chips on FMC150 */
#define FMC150_FLGS_OUT_FMC_PRST WBGEN2_GEN_MASK(3, 1)
PACKED struct FMC150_WB {
/* [0x0]: REG Input Flags for Pulsing Registers */
uint32_t FLGS_PULSE;
/* [0x4]: REG Input Flags for FMC150 */
uint32_t FLGS_IN;
/* [0x8]: REG Address for Chips on FMC150 */
uint32_t ADDR;
/* [0xc]: REG Data In for Chips on FMC150 */
uint32_t DATA_IN;
/* [0x10]: REG Chipselect for Chips on FMC150 */
uint32_t CS;
/* [0x14]: REG ADC Delay */
uint32_t ADC_DLY;
/* [0x18]: REG Data Out From Chips on FMC150 */
uint32_t DATA_OUT;
/* [0x1c]: REG Flags out from Chips on FMC150 */
uint32_t FLGS_OUT;
};
#endif
/*
Register definitions for slave core: Simple Wishbone UART
* File : wb_uart.h
* Author : auto-generated by wbgen2 from simple_uart_wb.wb
* Created : Tue Oct 4 18:46:41 2011
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_SIMPLE_UART_WB_WB
#define __WBGEN2_REGDEFS_SIMPLE_UART_WB_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Status Register */
/* definitions for field: TX busy in reg: Status Register */
#define UART_SR_TX_BUSY WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX ready in reg: Status Register */
#define UART_SR_RX_RDY WBGEN2_GEN_MASK(1, 1)
/* definitions for register: Baudrate control register */
/* definitions for register: Transmit data regsiter */
/* definitions for field: Transmit data in reg: Transmit data regsiter */
#define UART_TDR_TX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_TDR_TX_DATA_SHIFT 0
#define UART_TDR_TX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_TDR_TX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: Receive data regsiter */
/* definitions for field: Received data in reg: Receive data regsiter */
#define UART_RDR_RX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_RDR_RX_DATA_SHIFT 0
#define UART_RDR_RX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_RDR_RX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: Host VUART Tx register */
/* definitions for field: TX Data in reg: Host VUART Tx register */
#define UART_HOST_TDR_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_HOST_TDR_DATA_SHIFT 0
#define UART_HOST_TDR_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_HOST_TDR_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: TX Ready in reg: Host VUART Tx register */
#define UART_HOST_TDR_RDY WBGEN2_GEN_MASK(8, 1)
/* definitions for register: Host VUART Rx register */
/* definitions for field: RX Data in reg: Host VUART Rx register */
#define UART_HOST_RDR_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_HOST_RDR_DATA_SHIFT 0
#define UART_HOST_RDR_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_HOST_RDR_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: RX Ready in reg: Host VUART Rx register */
#define UART_HOST_RDR_RDY WBGEN2_GEN_MASK(8, 1)
/* definitions for field: RX FIFO Count in reg: Host VUART Rx register */
#define UART_HOST_RDR_COUNT_MASK WBGEN2_GEN_MASK(9, 16)
#define UART_HOST_RDR_COUNT_SHIFT 9
#define UART_HOST_RDR_COUNT_W(value) WBGEN2_GEN_WRITE(value, 9, 16)
#define UART_HOST_RDR_COUNT_R(reg) WBGEN2_GEN_READ(reg, 9, 16)
PACKED struct UART_WB {
/* [0x0]: REG Status Register */
uint32_t SR;
/* [0x4]: REG Baudrate control register */
uint32_t BCR;
/* [0x8]: REG Transmit data regsiter */
uint32_t TDR;
/* [0xc]: REG Receive data regsiter */
uint32_t RDR;
/* [0x10]: REG Host VUART Tx register */
uint32_t HOST_TDR;
/* [0x14]: REG Host VUART Rx register */
uint32_t HOST_RDR;
};
#endif
#include "gpio.h"
#include "dma.h"
//#include "fmc150.h"
#include "uart.h"
/* Each loop iteration takes 4 cycles.
* It runs at 100MHz.
* Sleep 0.2 second.
*/
#define LED_DELAY (100000000/4/5)
#define UART_DELAY (100000000/4/5)
static inline int delay(int x)
{
while(x--) asm volatile("nop");
}
/* Placeholder for IRQ vector */
void _irq_entry(void){}
int main(void)
{
int i, j;
gpio_t leds = (volatile struct GPIO_WB *) BASE_LEDS_ADDR;
gpio_t buttons = (volatile struct GPIO_WB *) BASE_BUTTONS_ADDR;
dma_t dma = (volatile struct DMA_WB *) BASE_DMA_ADDR;
uart_t uart = (volatile struct UART_WB *) BASE_UART_ADDR;
/* Initialize Board. Should be in a speparete function and file */
uart_init(uart);
/* It would be nice to employ a callback system. For this to work,
a hardware timer should be running with a eishbone interface
and a interrupt pin to LM32 processor */
/* Test UART */
uart_write_byte(uart, 'A');
delay(UART_DELAY);
uart_write_byte(uart, 'B');
delay(UART_DELAY);
uart_write_byte(uart, 'C');
delay(UART_DELAY);
uart_write_byte(uart, 'D');
delay(UART_DELAY);
uart_write_byte(uart, 'E');
delay(UART_DELAY);
uart_write_byte(uart, 'F');
delay(UART_DELAY);
uart_write_byte(uart, 'G');
delay(UART_DELAY);
uart_write_byte(uart, 'H');
delay(UART_DELAY);
/* Test LEDs */
while (1) {
/* Rotate the LEDs */
for (i = 0; i < 8; ++i) {
// Set led at position i
gpio_out(leds, i, 1);
/* Each loop iteration takes 4 cycles.
* It runs at 100MHz.
* Sleep 0.2 second.
*/
delay(LED_DELAY);
// Clear led at position i
gpio_out(leds, i, 0);
}
}
return 0;
}
/****************************************************************************
**
** Name: crt0ram.S
**
** Description:
** Implements boot-code that calls LatticeDDInit (that calls main())
** Implements exception handlers (actually, redirectors)
**
** $Revision: $
**
** Disclaimer:
**
** This source code is intended as a design reference which
** illustrates how these types of functions can be implemented. It
** is the user's responsibility to verify their design for
** consistency and functionality through the use of formal
** verification methods. Lattice Semiconductor provides no warranty
** regarding the use or functionality of this code.
**
** --------------------------------------------------------------------
**
** Lattice Semiconductor Corporation
** 5555 NE Moore Court
** Hillsboro, OR 97214
** U.S.A
**
** TEL: 1-800-Lattice (USA and Canada)
** (503)268-8001 (other locations)
**
** web: http://www.latticesemi.com
** email: techsupport@latticesemi.com
**
** --------------------------------------------------------------------------
**
** Change History (Latest changes on top)
**
** Ver Date Description
** --------------------------------------------------------------------------
** 3.8 Apr-15-2011 Added __MICO_USER_<handler>_HANDLER__ preprocessor to
** allow customers to implement their own handlers for:
** DATA_ABORT, INST_ABORT
**
** 3.1 Jun-18-2008 Added __MICO_NO_INTERRUPTS__ preprocessor
** option to exclude invoking MicoISRHandler
** to reduce code-size in apps that don't use
** interrupts
**
** 3.0 Mar-25-2008 Added Header
**
**---------------------------------------------------------------------------
*****************************************************************************/
/*
* LatticeMico32 C startup code.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* From include/sys/signal.h */
#define SIGINT 2 /* interrupt */
#define SIGTRAP 5 /* trace trap */
#define SIGFPE 8 /* arithmetic exception */
#define SIGSEGV 11 /* segmentation violation */
//#define MICO32_FULL_CONTEXT_SAVE_RESTORE
/* Exception handlers - Must be 32 bytes long. */
.section .boot, "ax", @progbits
.global _start
_start:
.global _reset_handler
.type _reset_handler, @function
_reset_handler:
xor r0, r0, r0
wcsr IE, r0
wcsr IM, r0
mvhi r1, hi(_reset_handler)
ori r1, r1, lo(_reset_handler)
wcsr EBA, r1
calli _crt0
nop
.size _reset_handler, .-_reset_handler
.extern _irq_entry
.org 0xc0
.global _interrupt_handler
.type _interrupt_handler, @function
_interrupt_handler:
sw (sp+0), ra
calli _save_all
mvi r1, SIGINT
#ifndef __MICO_NO_INTERRUPTS__
calli _irq_entry
#else
wcsr IE, r0
#endif
bi _restore_all_and_return
nop
nop
nop
.org 0x100
.global _crt0
.type _crt0, @function
_crt0:
/* Clear r0 */
xor r0, r0, r0
/* Setup stack and global pointer */
mvhi sp, hi(_fstack)
ori sp, sp, lo(_fstack)
mvhi gp, hi(_gp)
ori gp, gp, lo(_gp)
mvhi r1, hi(_fbss)
ori r1, r1, lo(_fbss)
mvi r2, 0
mvhi r3, hi(_ebss)
ori r3, r3, lo(_ebss)
sub r3, r3, r1
calli memset
mvi r1, 0
mvi r2, 0
mvi r3, 0
calli main
loopf:
bi loopf
.global _save_all
.type _save_all, @function
_save_all:
#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE
addi sp, sp, -128
#else
addi sp, sp, -60
#endif
sw (sp+4), r1
sw (sp+8), r2
sw (sp+12), r3
sw (sp+16), r4
sw (sp+20), r5
sw (sp+24), r6
sw (sp+28), r7
sw (sp+32), r8
sw (sp+36), r9
sw (sp+40), r10
#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE
sw (sp+44), r11
sw (sp+48), r12
sw (sp+52), r13
sw (sp+56), r14
sw (sp+60), r15
sw (sp+64), r16
sw (sp+68), r17
sw (sp+72), r18
sw (sp+76), r19
sw (sp+80), r20
sw (sp+84), r21
sw (sp+88), r22
sw (sp+92), r23
sw (sp+96), r24
sw (sp+100), r25
sw (sp+104), r26
sw (sp+108), r27
sw (sp+120), ea
sw (sp+124), ba
/* ra and sp need special handling, as they have been modified */
lw r1, (sp+128)
sw (sp+116), r1
mv r1, sp
addi r1, r1, 128
sw (sp+112), r1
#else
sw (sp+52), ea
sw (sp+56), ba
/* ra and sp need special handling, as they have been modified */
lw r1, (sp+60)
sw (sp+48), r1
mv r1, sp
addi r1, r1, 60
sw (sp+44), r1
#endif
// xor r1, r1, r1
// wcsr ie, r1
ret
.size _save_all, .-_save_all
.global _restore_all_and_return
.type _restore_all_and_return, @function
/* Restore all registers and return from exception */
_restore_all_and_return:
// addi r1, r0, 2
// wcsr ie, r1
lw r1, (sp+4)
lw r2, (sp+8)
lw r3, (sp+12)
lw r4, (sp+16)
lw r5, (sp+20)
lw r6, (sp+24)
lw r7, (sp+28)
lw r8, (sp+32)
lw r9, (sp+36)
lw r10, (sp+40)
#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE
lw r11, (sp+44)
lw r12, (sp+48)
lw r13, (sp+52)
lw r14, (sp+56)
lw r15, (sp+60)
lw r16, (sp+64)
lw r17, (sp+68)
lw r18, (sp+72)
lw r19, (sp+76)
lw r20, (sp+80)
lw r21, (sp+84)
lw r22, (sp+88)
lw r23, (sp+92)
lw r24, (sp+96)
lw r25, (sp+100)
lw r26, (sp+104)
lw r27, (sp+108)
lw ra, (sp+116)
lw ea, (sp+120)
lw ba, (sp+124)
/* Stack pointer must be restored last, in case it has been updated */
lw sp, (sp+112)
#else
lw ra, (sp+48)
lw ea, (sp+52)
lw ba, (sp+56)
/* Stack pointer must be restored last, in case it has been updated */
lw sp, (sp+44)
#endif
nop
eret
.size _restore_all_and_return, .-_restore_all_and_return
#include "irq.h"
void disable_irq()
{
unsigned int ie, im;
unsigned int Mask = ~1;
/* disable peripheral interrupts in case they were enabled */
asm volatile ("rcsr %0,ie":"=r"(ie));
ie &= (~0x1);
asm volatile ("wcsr ie, %0"::"r"(ie));
/* disable mask-bit in im */
asm volatile ("rcsr %0, im":"=r"(im));
im &= Mask;
asm volatile ("wcsr im, %0"::"r"(im));
}
void enable_irq()
{
unsigned int ie, im;
unsigned int Mask = 1;
/* disable peripheral interrupts in-case they were enabled*/
asm volatile ("rcsr %0,ie":"=r"(ie));
ie &= (~0x1);
asm volatile ("wcsr ie, %0"::"r"(ie));
/* enable mask-bit in im */
asm volatile ("rcsr %0, im":"=r"(im));
im |= Mask;
asm volatile ("wcsr im, %0"::"r"(im));
ie |= 0x1;
asm volatile ("wcsr ie, %0"::"r"(ie));
}
/*
* Simulator Link script for Lattice Mico32.
* Contributed by Jon Beniston <jon@beniston.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
OUTPUT_FORMAT("elf32-lm32")
ENTRY(_start)
/*INPUT() */
GROUP(-lgcc -lc)
MEMORY
{
ram : ORIGIN = 0x00000000, LENGTH = 0x10000
}
SECTIONS
{
.boot : { *(.boot) } > ram
/* Code */
.text :
{
. = ALIGN(4);
_ftext = .;
_ftext_rom = LOADADDR(.text);
*(.text .stub .text.* .gnu.linkonce.t.*)
*(.gnu.warning)
KEEP (*(.init))
KEEP (*(.fini))
/* Constructors and destructors */
KEEP (*crtbegin*.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
KEEP (*crtbegin*.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
KEEP (*(.jcr))
_etext = .;
} > ram =0
/* Exception handlers */
.eh_frame_hdr : { *(.eh_frame_hdr) } > ram
.eh_frame : { KEEP (*(.eh_frame)) } > ram
.gcc_except_table : { *(.gcc_except_table) *(.gcc_except_table.*) } > ram
/* Read-only data */
.rodata :
{
. = ALIGN(4);
_frodata = .;
_frodata_rom = LOADADDR(.rodata);
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
_erodata = .;
} > ram
/* Data */
.data :
{
. = ALIGN(4);
_fdata = .;
_fdata_rom = LOADADDR(.data);
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
SORT(CONSTRUCTORS)
_gp = ALIGN(16) + 0x7ff0;
*(.sdata .sdata.* .gnu.linkonce.s.*)
_edata = .;
} > ram
/* BSS */
.bss :
{
. = ALIGN(4);
_fbss = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
_end = .;
PROVIDE (end = .);
} > ram
/* First location in stack is highest address in RAM */
PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 4);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
#include "board.h"
#include "inttypes.h"
#include "uart.h"
#define CALC_BAUD(baudrate) (((((unsigned long long)baudrate*8ULL)<<(16-7))+(CPU_CLOCK>>8))/(CPU_CLOCK>>7))
//static volatile struct UART_WB *uart = (volatile struct UART_WB *) BASE_UART;
void uart_init(uart_t uart)
{
uart->BCR = CALC_BAUD(UART_BAUDRATE);
}
void uart_write_byte(uart_t uart, unsigned char c)
{
/* wait until not busy */
while(uart->SR & UART_SR_TX_BUSY);
uart->TDR = c;
if(c == '\n')
uart_write_byte(uart, '\r');
}
int uart_poll(uart_t uart)
{
return uart->SR & UART_SR_RX_RDY;
}
int uart_read_byte(uart_t uart)
{
return uart->RDR & 0xff;
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment