diff --git a/Makefile b/Makefile index e1e7b38..d88d73a 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ BIN = $(TOP).bin SVF = $(TOP).svf TIME_RPT = $(TOP).rpt STAT = $(TOP).stat -BOARD ?= ice40hx8k-b-evn +BOARD ?= edufpga PROGRAM ?= hello C_SRC = $(filter-out programs/uip/fsdata.c, $(wildcard programs/$(PROGRAM)/*.c)) OBJ = $(sort $(addsuffix .o, $(basename $(C_SRC))) start.o) diff --git a/boards/edufpga-defines.sv b/boards/edufpga-defines.sv index b09fa72..45482fd 100644 --- a/boards/edufpga-defines.sv +++ b/boards/edufpga-defines.sv @@ -1 +1,4 @@ // Defines for EDU-FPGA +`define PMOD0 +`define PMOD1 +`define ARDUINO diff --git a/boards/edufpga.pcf b/boards/edufpga.pcf index ce84c79..6eb0140 100644 --- a/boards/edufpga.pcf +++ b/boards/edufpga.pcf @@ -1,11 +1,87 @@ -set_io clk 94 -set_io leds[0] 1 -set_io leds[1] 2 -set_io leds[2] 3 -set_io leds[3] 4 -set_io leds[4] 7 -set_io leds[5] 8 -set_io leds[6] 9 -set_io leds[7] 10 -set_io uart_rx 55 -set_io uart_tx 56 +# clock +set_io clk 94 #input + +# uart +set_io uart_rx 55 #input +set_io uart_tx 56 #output + +# real board leds +set_io leds[0] 1 #output +set_io leds[1] 2 #output +set_io leds[2] 3 #output +set_io leds[3] 4 #output + +# real board buttons +set_io buttons[0] 31 #input +set_io buttons[1] 32 #input +set_io buttons[2] 33 #input +set_io buttons[3] 34 #input + +#set_io leds[4] 7 #output +#set_io leds[5] 8 #output +#set_io leds[6] 9 #output +#set_io leds[7] 10 #output + +#set_io buttons[4] 11 #input +#set_io buttons[5] 12 #input +#set_io buttons[6] 15 #input +#set_io buttons[7] 16 #input + +# pmod0 (near arduino connector) +set_io pmod0[0] 11 #output +set_io pmod0[1] 12 #output +set_io pmod0[2] 15 #output +set_io pmod0[3] 16 #output +set_io pmod0[4] 7 #output +set_io pmod0[5] 8 #output +set_io pmod0[6] 9 #output +set_io pmod0[7] 10 #output + + +#pmod1 +set_io pmod1[0] 24 #input +set_io pmod1[1] 23 #input +set_io pmod1[2] 22 #input +set_io pmod1[3] 21 #input +set_io pmod1[4] 20 #input +set_io pmod1[5] 19 #input +set_io pmod1[6] 18 #input +set_io pmod1[7] 17 #input + + + +# arduino connector +set_io arduino[0] 107 #output +set_io arduino[1] 106 #output +set_io arduino[2] 105 #output +set_io arduino[3] 104 #output +set_io arduino[4] 99 #output +set_io arduino[5] 98 #output +set_io arduino[6] 97 #output +set_io arduino[7] 96 #output +set_io arduino[8] 95 #output +set_io arduino[9] 85 #output +set_io arduino[10] 84 #output +set_io arduino[11] 83 #output +set_io arduino[12] 82 #output +set_io arduino[13] 81 #output +set_io arduino[14] 80 #output +set_io arduino[15] 79 #output + + +set_io arduino[16] 122 #output +set_io arduino[17] 124 #output +set_io arduino[18] 125 #output +set_io arduino[19] 128 #output +set_io arduino[20] 129 #output +set_io arduino[21] 130 #output +set_io arduino[22] 134 #output +set_io arduino[23] 135 #output +set_io arduino[24] 136 #output +set_io arduino[25] 137 #output +set_io arduino[26] 138 #output +set_io arduino[27] 139 #output +set_io arduino[28] 141 #output +set_io arduino[29] 143 #output +set_io arduino[30] 142 #output +set_io arduino[31] 144 #output diff --git a/icicle.sv b/icicle.sv index bda3441..9ce7609 100644 --- a/icicle.sv +++ b/icicle.sv @@ -17,7 +17,7 @@ `define RESET_VECTOR 32'h00000000 `endif -module icicle ( +module icicle #( parameter LEDCOUNT, parameter BUTTONCOUNT) ( input clk, input reset, @@ -36,7 +36,19 @@ module icicle ( `endif /* LEDs */ - output logic [7:0] leds, + output logic [LEDCOUNT -1 :0] leds, + + /* BUTTONS */ + input [BUTTONCOUNT - 1:0] buttons, + + /* PMOD0 */ + output logic [7:0] pmod0, + + /* PMOD1 */ + input [7:0] pmod1, + + /* ARDUINO */ + output logic [31:0] arduino, /* UART */ input uart_rx, @@ -69,8 +81,8 @@ module icicle ( logic mem_ready; logic mem_fault; - assign mem_read_value = ram_read_value | leds_read_value | uart_read_value | timer_read_value | flash_read_value; - assign mem_ready = ram_ready | leds_ready | uart_ready | timer_ready | flash_ready | mem_fault; + assign mem_read_value = ram_read_value | leds_read_value | buttons_read_value | pmod0_read_value | pmod1_read_value | arduino_read_value | uart_read_value | timer_read_value | flash_read_value; + assign mem_ready = ram_ready | leds_ready | buttons_ready | pmod0_ready | pmod1_ready | arduino_ready | uart_ready | timer_ready | flash_ready | mem_fault; bus_arbiter bus_arbiter ( .clk(clk), @@ -135,6 +147,10 @@ module icicle ( logic ram_sel; logic leds_sel; + logic buttons_sel; + logic pmod0_sel; + logic pmod1_sel; + logic arduino_sel; logic uart_sel; logic timer_sel; logic flash_sel; @@ -142,18 +158,26 @@ module icicle ( always_comb begin ram_sel = 0; leds_sel = 0; + buttons_sel = 0; + pmod0_sel = 0; + pmod1_sel = 0; + arduino_sel = 0; uart_sel = 0; timer_sel = 0; flash_sel = 0; mem_fault = 0; casez (mem_address) - 32'b00000000_00000000_????????_????????: ram_sel = 1; - 32'b00000000_00000001_00000000_000000??: leds_sel = 1; - 32'b00000000_00000010_00000000_0000????: uart_sel = 1; - 32'b00000000_00000011_00000000_0000????: timer_sel = 1; - 32'b00000001_????????_????????_????????: flash_sel = 1; - default: mem_fault = 1; + 32'b00000000_00000000_????????_????????: ram_sel = 1; + 32'b00000000_00000001_00000000_000000??: leds_sel = 1; // 0x00010000 + 32'b00000000_00000001_00000000_000001??: buttons_sel = 1; // 0x00010004 + 32'b00000000_00000001_00000000_000010??: pmod0_sel = 1; // 0x00010008 + 32'b00000000_00000001_00000000_000011??: pmod1_sel = 1; // 0x0001000c + 32'b00000000_00000001_00000000_000100??: arduino_sel = 1; // 0x00010010 + 32'b00000000_00000010_00000000_0000????: uart_sel = 1; // 0x00020000 + 32'b00000000_00000011_00000000_0000????: timer_sel = 1; // 0x00030000 + 32'b00000001_????????_????????_????????: flash_sel = 1; + default: mem_fault = 1; endcase end @@ -175,17 +199,84 @@ module icicle ( .ready_out(ram_ready) ); + /* LEDs */ logic [31:0] leds_read_value; logic leds_ready; - assign leds_read_value = {24'b0, leds_sel ? leds : 8'b0}; + assign leds_read_value = {(32-LEDCOUNT)'b0, leds_sel ? leds : LEDCOUNT'b0}; assign leds_ready = leds_sel; always_ff @(posedge clk) begin if (leds_sel && mem_write_mask[0]) - leds <= mem_write_value[7:0]; + leds <= mem_write_value[LEDCOUNT -1:0]; end + /* BUTTONS */ + + logic [31:0] buttons_read_value; + logic buttons_ready; + + assign buttons_read_value = {(32-BUTTONCOUNT)'b0, buttons_sel ? buttons : BUTTONCOUNT'b0}; + assign buttons_ready = buttons_sel; + + /* PMOD0 */ + + logic [31:0] pmod0_read_value; + logic pmod0_ready; + +`ifdef PMOD0 + assign pmod0_read_value = {24'b0, pmod0_sel ? pmod0 : 8'b0}; + assign pmod0_ready = pmod0_sel; + + always_ff @(posedge clk) begin + if (pmod0_sel && mem_write_mask[0]) + pmod0 <= mem_write_value[7:0]; + end +`else + assign pmod0_read_value = 0; + assign pmod0_ready = pmod0_sel; +`endif + + /* PMOD1 */ + + logic [31:0] pmod1_read_value; + logic pmod1_ready; + +`ifdef PMOD1 + assign pmod1_read_value = {24'b0, pmod1_sel ? pmod1 : 8'b0}; + assign pmod1_ready = pmod1_sel; +`else + assign pmod1_read_value = 0; + assign pmod1_ready = pmod1_sel; +`endif + + /* ARDUINO */ + + logic [31:0] arduino_read_value; + logic arduino_ready; + +`ifdef ARDUINO + assign arduino_read_value = {arduino_sel ? arduino : 32'b0}; + assign arduino_ready = arduino_sel; + + always_ff @(posedge clk) begin + if (arduino_sel && mem_write_mask[0]) + arduino[7:0] <= mem_write_value[7:0]; + if (arduino_sel && mem_write_mask[1]) + arduino[15:8] <= mem_write_value[15:8]; + if (arduino_sel && mem_write_mask[2]) + arduino[23:16] <= mem_write_value[23:16]; + if (arduino_sel && mem_write_mask[3]) + arduino[31:24] <= mem_write_value[31:24]; + end + +`else + assign arduino_read_value = 0; + assign arduino_ready = arduino_sel; +`endif + + /* UART */ + logic [31:0] uart_read_value; logic uart_ready; @@ -207,6 +298,8 @@ module icicle ( .ready_out(uart_ready) ); + /* TIMER */ + logic [31:0] timer_read_value; logic timer_ready; @@ -227,6 +320,8 @@ module icicle ( .ready_out(timer_ready) ); + /* FLASH */ + logic [31:0] flash_read_value; logic flash_ready; diff --git a/programs/buttons2leds/main.c b/programs/buttons2leds/main.c new file mode 100644 index 0000000..4692136 --- /dev/null +++ b/programs/buttons2leds/main.c @@ -0,0 +1,47 @@ +#include + +// 32'b00000000_00000001_00000000_000000??: leds_sel = 1; +// 32'b00000000_00000001_00000000_000001??: buttons_sel = + +#define LEDS *((volatile uint32_t *) 0x00010000) +#define BUTTONS *((volatile uint32_t *) 0x00010004) +#define UART_BAUD *((volatile uint32_t *) 0x00020000) +#define UART_STATUS *((volatile uint32_t *) 0x00020004) +#define UART_DATA *((volatile int32_t *) 0x00020008) +#define MTIME *((volatile uint64_t *) 0x00030000) +#define MTIMECMP *((volatile uint64_t *) 0x00030008) + +#define UART_STATUS_TX_READY 0x1 +#define UART_STATUS_RX_READY 0x2 + +#define BAUD_RATE 9600 + +static void uart_putc(char c) { + while (!(UART_STATUS & UART_STATUS_TX_READY)); + UART_DATA = c; +} + +static void uart_puts(const char *str) { + char c; + while ((c = *str++)) { + uart_putc(c); + } +} + +static inline uint32_t rdcycle(void) { + uint32_t cycle; + asm volatile ("rdcycle %0" : "=r"(cycle)); + return cycle; +} + +int main() { + UART_BAUD = FREQ / BAUD_RATE; + LEDS = 0xAA; + + for (;;) { + uart_puts("Press buttons, should turn on leds!\r\n"); + LEDS = ~BUTTONS; + uint32_t start = rdcycle(); + while ((rdcycle() - start) <= FREQ); + } +} diff --git a/programs/buttons2ledsArduinoShiftPmodToPmod/main.c b/programs/buttons2ledsArduinoShiftPmodToPmod/main.c new file mode 100644 index 0000000..efb04a8 --- /dev/null +++ b/programs/buttons2ledsArduinoShiftPmodToPmod/main.c @@ -0,0 +1,56 @@ +#include + + +#define LEDS *((volatile uint32_t *) 0x00010000) +#define BUTTONS *((volatile uint32_t *) 0x00010004) +#define PMOD0 *((volatile uint32_t *) 0x00010008) +#define PMOD1 *((volatile uint32_t *) 0x0001000c) +#define ARDUINO *((volatile uint32_t *) 0x00010010) +#define UART_BAUD *((volatile uint32_t *) 0x00020000) +#define UART_STATUS *((volatile uint32_t *) 0x00020004) +#define UART_DATA *((volatile int32_t *) 0x00020008) +#define MTIME *((volatile uint64_t *) 0x00030000) +#define MTIMECMP *((volatile uint64_t *) 0x00030008) + +#define UART_STATUS_TX_READY 0x1 +#define UART_STATUS_RX_READY 0x2 + +#define BAUD_RATE 9600 + +static void uart_putc(char c) { + while (!(UART_STATUS & UART_STATUS_TX_READY)); + UART_DATA = c; +} + +static void uart_puts(const char *str) { + char c; + while ((c = *str++)) { + uart_putc(c); + } +} + +static inline uint32_t rdcycle(void) { + uint32_t cycle; + asm volatile ("rdcycle %0" : "=r"(cycle)); + return cycle; +} + +int main() { + unsigned int shift = 0x01010101; + UART_BAUD = FREQ / BAUD_RATE; + + for (;;) { + uart_puts("Press buttons, should turn on leds, while the arduino connector shifts and pmod0 mimics pmod1!\r\n"); + LEDS = ~BUTTONS; + PMOD0 = PMOD1; + + ARDUINO = shift; + shift = shift << 1; + if (shift == 0x01010100) { + shift |= 1; + } + + uint32_t start = rdcycle(); + while ((rdcycle() - start) <= FREQ); + } +} diff --git a/programs/buttons2ledsPmodCounter/main.c b/programs/buttons2ledsPmodCounter/main.c new file mode 100644 index 0000000..b7a0a97 --- /dev/null +++ b/programs/buttons2ledsPmodCounter/main.c @@ -0,0 +1,50 @@ +#include + +// 32'b00000000_00000001_00000000_000000??: leds_sel = 1; +// 32'b00000000_00000001_00000000_000001??: buttons_sel = + +#define LEDS *((volatile uint32_t *) 0x00010000) +#define BUTTONS *((volatile uint32_t *) 0x00010004) +#define PMOD0 *((volatile uint32_t *) 0x00010008) +#define UART_BAUD *((volatile uint32_t *) 0x00020000) +#define UART_STATUS *((volatile uint32_t *) 0x00020004) +#define UART_DATA *((volatile int32_t *) 0x00020008) +#define MTIME *((volatile uint64_t *) 0x00030000) +#define MTIMECMP *((volatile uint64_t *) 0x00030008) + +#define UART_STATUS_TX_READY 0x1 +#define UART_STATUS_RX_READY 0x2 + +#define BAUD_RATE 9600 + +static void uart_putc(char c) { + while (!(UART_STATUS & UART_STATUS_TX_READY)); + UART_DATA = c; +} + +static void uart_puts(const char *str) { + char c; + while ((c = *str++)) { + uart_putc(c); + } +} + +static inline uint32_t rdcycle(void) { + uint32_t cycle; + asm volatile ("rdcycle %0" : "=r"(cycle)); + return cycle; +} + +int main() { + char counter = 0; + UART_BAUD = FREQ / BAUD_RATE; + PMOD0 = counter; + + for (;;) { + uart_puts("Press buttons, should turn on leds, while counter goes up in pmod0!\r\n"); + LEDS = ~BUTTONS; + PMOD0 = counter++; + uint32_t start = rdcycle(); + while ((rdcycle() - start) <= FREQ); + } +} diff --git a/top.sv b/top.sv index 3407044..8e51d56 100644 --- a/top.sv +++ b/top.sv @@ -3,7 +3,11 @@ `include "pll.sv" `include "sync.sv" -module top ( +module top #( + parameter LEDCOUNT = 4, + parameter BUTTONCOUNT = 4 +) +( `ifndef INTERNAL_OSC input clk, `endif @@ -17,7 +21,25 @@ module top ( `endif /* LEDs */ - output logic [7:0] leds, + output logic [LEDCOUNT -1:0] leds, + + /* BUTTONS */ + input [BUTTONCOUNT - 1:0] buttons, + + /* PMOD0 */ +`ifdef PMOD0 + output logic [7:0] pmod0, +`endif + + /* PMOD1 */ +`ifdef PMOD1 + input [7:0] pmod1, +`endif + + /* ARDUINO */ +`ifdef ARDUINO + output logic [31:0] arduino, +`endif /* UART */ input uart_rx, @@ -33,6 +55,8 @@ module top ( ); `endif + + `ifdef SPI_FLASH logic flash_io0_en; logic flash_io0_in; @@ -105,7 +129,7 @@ module top ( .out(pll_locked) ); - icicle icicle ( + icicle #( .LEDCOUNT(LEDCOUNT), .BUTTONCOUNT(BUTTONCOUNT)) icicle ( .clk(pll_clk), .reset(reset), @@ -126,6 +150,24 @@ module top ( /* LEDs */ .leds(leds), + /* BUTTONs */ + .buttons(buttons), + + /* PMOD0 */ +`ifdef PMOD0 + .pmod0(pmod0), +`endif + + /* PMOD1 */ +`ifdef PMOD1 + .pmod1(pmod1), +`endif + + /* ARDUINO */ +`ifdef ARDUINO + .arduino(arduino), +`endif + /* UART */ .uart_rx(uart_rx), .uart_tx(uart_tx)