Skip to content

Commit

Permalink
Added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mmicko committed May 9, 2018
1 parent d1ee064 commit 2787003
Show file tree
Hide file tree
Showing 9 changed files with 489 additions and 0 deletions.
3 changes: 3 additions & 0 deletions tests/led/apio.ini
@@ -0,0 +1,3 @@
[env]
board = fpga101

5 changes: 5 additions & 0 deletions tests/led/led.v
@@ -0,0 +1,5 @@
module led (
output LED_B
);
assign LED_B = 1'b0;
endmodule
24 changes: 24 additions & 0 deletions tests/led/led_tb.v
@@ -0,0 +1,24 @@
`default_nettype none
`timescale 100 ns / 10 ns

module led_tb();

reg clk = 0;

wire led;

always
#5 clk = ~clk;

led unit(.LED_B(led));


initial begin
$dumpfile("led_tb.vcd");
$dumpvars(0, led_tb);

#100 $display("finish");
$finish;
end

endmodule
44 changes: 44 additions & 0 deletions tests/led/pinout.pcf
@@ -0,0 +1,44 @@
# 12 MHz clock
set_io -nowarn CLK 35 # input

# LCD connector
set_io -nowarn LCD_CLK 18 # output
set_io -nowarn LCD_DEN 19 # output
set_io -nowarn LCD_VS 11 # output
set_io -nowarn LCD_HS 9 # output
set_io -nowarn LCD_RST 2 # output
set_io -nowarn LCD_D7 6 # output
set_io -nowarn LCD_D6 44 # output
set_io -nowarn LCD_D5 4 # output
set_io -nowarn LCD_D4 3 # output
set_io -nowarn LCD_D3 48 # output
set_io -nowarn LCD_D2 45 # output
set_io -nowarn LCD_D1 47 # output
set_io -nowarn LCD_D0 46 # output
set_io -nowarn LCD_PWM 13 # output

# Buttons
set_io -nowarn B0 23 # input
set_io -nowarn B1 25 # input
set_io -nowarn B2 26 # input
set_io -nowarn B3 27 # input
set_io -nowarn B4 21 # input
set_io -nowarn B5 12 # input

# Audio jack
set_io -nowarn AUDIO 37 # output

# PMOD connector
set_io -nowarn PMOD0 32
set_io -nowarn PMOD1 31
set_io -nowarn PMOD2 34
set_io -nowarn PMOD3 43
set_io -nowarn PMOD4 36
set_io -nowarn PMOD5 42
set_io -nowarn PMOD6 38
set_io -nowarn PMOD7 28

# RGB LED Driver
set_io -nowarn LED_G 39 # output
set_io -nowarn LED_B 40 # output
set_io -nowarn LED_R 41 # output
27 changes: 27 additions & 0 deletions tests/riscv/Makefile
@@ -0,0 +1,27 @@
RISCV_TOOLS_PREFIX = riscv64-unknown-elf-
CXX = $(RISCV_TOOLS_PREFIX)g++
CC = $(RISCV_TOOLS_PREFIX)gcc
AS = $(RISCV_TOOLS_PREFIX)gcc
ICEPROG = iceprog

all: firmware.bin

# ---- iCE40 UP5k Breakout Board ----

upload: firmware.bin
$(ICEPROG) -o 1M firmware.bin

# ---- Example Firmware ----
firmware.elf: sections.lds start.s firmware.c sections.c
$(CC) -O3 -nostartfiles -mabi=ilp32 -march=rv32ic -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -o firmware.elf start.s sections.c firmware.c -lgcc

firmware.bin: firmware.elf
$(RISCV_TOOLS_PREFIX)objcopy -O binary firmware.elf firmware.bin

# ---- Clean ----

clean:
rm -f firmware.elf firmware.bin

.PHONY: upload clean

166 changes: 166 additions & 0 deletions tests/riscv/firmware.c
@@ -0,0 +1,166 @@
#include <stdint.h>
#include <stdbool.h>

#define reg_uart_clkdiv (*(volatile uint32_t*)0x02000004)
#define reg_uart_data (*(volatile uint32_t*)0x02000008)

#define reg_io ((volatile uint32_t*)0x03000000)
#define reg_text ((volatile uint32_t*)0x04000000)
#define reg_attr ((volatile uint32_t*)0x05000000)
#define reg_tone ((volatile uint32_t*)0x06000000)

#define LCD_WIDTH 40
#define LCD_HEIGHT 15


static int cursor_x = 0;
static int cursor_y = 0;
static int cursor_addr = 0;


void lcd_clear()
{
cursor_x = 0;
cursor_y = 0;
cursor_addr = 0;

for(int i = 0; i < 600; i++)
reg_text[i] = 0x20;
for(int i = 0; i < 600; i++)
reg_attr[i] = 0x1f;
}

// --------------------------------------------------------
void lcd_newline() {
if(cursor_y < (LCD_HEIGHT - 1)) {
cursor_x = 0;
cursor_y++;
cursor_addr = cursor_y * LCD_WIDTH;

} else {
lcd_clear();
cursor_y = 0;
cursor_x = 0;
cursor_addr = 0;
}
}

void lcd_putch(char c) {
if((c == '\n') || (cursor_x >= (LCD_WIDTH - 1))) {
lcd_newline();
} else {
reg_text[cursor_addr++] = c;
cursor_x++;
}
}


// --------------------------------------------------------
void putchar(char c)
{
if (c == '\n')
putchar('\r');
if (c != '\r')
lcd_putch(c);
reg_uart_data = c;
}

void print(const char *p)
{
while (*p)
putchar(*(p++));
}

void print_hex(uint32_t v, int digits)
{
for (int i = 7; i >= 0; i--) {
char c = "0123456789abcdef"[(v >> (4*i)) & 15];
if (c == '0' && i >= digits) continue;
putchar(c);
digits = i;
}
}

void delay_cyc(uint32_t cycles) {
uint32_t cycles_begin, cycles_now;
__asm__ volatile ("rdcycle %0" : "=r"(cycles_begin));
do {
__asm__ volatile ("rdcycle %0" : "=r"(cycles_now));
} while((cycles_now - cycles_begin) < cycles);

}

void delay_ms(uint32_t ms)
{
delay_cyc(12050*ms);
}

char getchar_prompt(char *prompt)
{
int32_t c = -1;

uint32_t cycles_begin, cycles_now, cycles;
__asm__ volatile ("rdcycle %0" : "=r"(cycles_begin));

if (prompt)
print(prompt);

while (c == -1) {
__asm__ volatile ("rdcycle %0" : "=r"(cycles_now));
cycles = cycles_now - cycles_begin;
if (cycles > 12000000) {
if (prompt)
print(prompt);
cycles_begin = cycles_now;
}
c = reg_uart_data;
}
return c;
}

char getchar()
{
return getchar_prompt(0);
}

#define TONE_A4 12000000/440/2
#define TONE_B4 12000000/494/2
#define TONE_C5 12000000/523/2
#define TONE_D5 12000000/587/2
#define TONE_E5 12000000/659/2
#define TONE_F5 12000000/698/2
#define TONE_G5 12000000/783/2

void play_tone(int tone, int lenght,int delay)
{
reg_tone[0] = tone;
if (lenght>0) delay_ms(lenght);
reg_tone[0] = 0;
if (delay>0) delay_ms(delay);
}

// --------------------------------------------------------
void main()
{
reg_uart_clkdiv = 1250;

lcd_clear();

print("\n");
print(" ____ _ ____ ____\n");
print(" | _ \\(_) ___ ___/ ___| ___ / ___|\n");
print(" | |_) | |/ __/ _ \\___ \\ / _ \\| |\n");
print(" | __/| | (_| (_) |__) | (_) | |___\n");
print(" |_| |_|\\___\\___/____/ \\___/ \\____|\n");
print("\n");
print(" FPGA 101 Workshop Badge \n");
print(" 26th May - Belgrade - Hackaday\n");


for(int i=0;i<10;i++)
{
play_tone(TONE_A4,200,10);
play_tone(TONE_F5,200,10);
}
}

11 changes: 11 additions & 0 deletions tests/riscv/sections.c
@@ -0,0 +1,11 @@
#include <stdint.h>
#include <string.h>

extern uint32_t _sidata, _sdata, _edata;

void executable_init_sections()
{
for (uint32_t *src = &_sidata, *dest = &_sdata; dest < &_edata;) {
*dest++ = *src++;
}
}
75 changes: 75 additions & 0 deletions tests/riscv/sections.lds
@@ -0,0 +1,75 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x00100000, LENGTH = 0x400000 /* entire flash, 4 MiB */
RAM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x020000 /* 128 KB */
}

SECTIONS {
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.srodata) /* .rodata sections (constants, strings, etc.) */
*(.srodata*) /* .rodata* sections (constants, strings, etc.) */
*(.eh_frame_hdr)
*(.eh_frame) /* .eh_frame sections */
*(.gcc_except_table)
*(.gcc_except_table.*)
__preinit_array_start = .;
*(.preinit_array)
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
*(.init_array.*)
*(.init_array)
__init_array_end = .;
. = ALIGN(4);
_etext = .; /* define a global symbol at end of code */
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
} >FLASH


/* This is the initialized data section
The program executes knowing that the data is in the RAM
but the loader puts the initial values in the FLASH (inidata).
It is one task of the startup to copy the initial values from FLASH to RAM. */
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
_ram_start = .; /* create a global symbol at ram start for garbage collector */
. = ALIGN(4);
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.sdata) /* .sdata sections */
*(.sdata*) /* .sdata* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
} >RAM

/* Uninitialized data section */
.bss :
{
. = ALIGN(4);
_sbss = .; /* define a global symbol at bss start; used by startup code */
*(.bss)
*(.bss*)
*(.sbss)
*(.sbss*)
*(COMMON)

. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end; used by startup code */
} >RAM

/* this is to define the start of the heap, and make sure we have a minimum size */
.heap :
{
. = ALIGN(4);
_heap_start = .; /* define a global symbol at heap start */
} >RAM
}

0 comments on commit 2787003

Please sign in to comment.