Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
489 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[env] | ||
board = fpga101 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module led ( | ||
output LED_B | ||
); | ||
assign LED_B = 1'b0; | ||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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++; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
Oops, something went wrong.