aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--machxo2/examples/README.md10
-rw-r--r--machxo2/examples/blinky_ext.v19
-rw-r--r--machxo2/examples/uart.v209
3 files changed, 238 insertions, 0 deletions
diff --git a/machxo2/examples/README.md b/machxo2/examples/README.md
index fd84dc93..977d6d8a 100644
--- a/machxo2/examples/README.md
+++ b/machxo2/examples/README.md
@@ -57,6 +57,16 @@ rm -rf *.dot *.json *.png *.vcd *.smt2 *.log *.txt *.bit {pack,place,pnr}*.v bli
* `tinyfpga.v`- Blink the LED on TinyFPA Ax.
* `rgbcount.v`- Blink an RGB LED using TinyFPGA Ax, more closely-based on
[the TinyFPGA Ax guide](https://tinyfpga.com/a-series-guide.html).
+* `blinky_ext.v`- Blink the LED on TinyFPA Ax using an external pin (pin 6).
+* `uart.v`- UART loopback demo at 19200 baud. Requires the following pins:
+ * Pin 1- RX LED
+ * Pin 2- TX (will echo RX)
+ * Pin 3- RX
+ * Pin 4- TX LED
+ * Pin 5- Load LED
+ * Pin 6- 12 MHz clock input
+ * Pin 7- Take LED
+ * Pin 8- Empty LED
## Environment Variables For Scripts
diff --git a/machxo2/examples/blinky_ext.v b/machxo2/examples/blinky_ext.v
new file mode 100644
index 00000000..a8bdd588
--- /dev/null
+++ b/machxo2/examples/blinky_ext.v
@@ -0,0 +1,19 @@
+// Modified from:
+// https://github.com/tinyfpga/TinyFPGA-A-Series/tree/master/template_a2
+
+module top (
+ (* LOC="13" *)
+ output pin1,
+ (* LOC="21" *)
+ input clk
+);
+
+ reg [23:0] led_timer;
+
+ always @(posedge clk) begin
+ led_timer <= led_timer + 1;
+ end
+
+ // left side of board
+ assign pin1 = led_timer[23];
+endmodule
diff --git a/machxo2/examples/uart.v b/machxo2/examples/uart.v
new file mode 100644
index 00000000..f1d95bd8
--- /dev/null
+++ b/machxo2/examples/uart.v
@@ -0,0 +1,209 @@
+/* Example UART derived from: https://github.com/cr1901/migen_uart.
+ Requires 12MHz clock and runs at 19,200 baud. */
+
+/* Machine-generated using Migen */
+
+module top(
+ (* LOC = "14" *)
+ output tx,
+ (* LOC = "16" *)
+ input rx,
+ (* LOC = "13" *)
+ output rx_led,
+ (* LOC = "17" *)
+ output tx_led,
+ (* LOC = "20" *)
+ output load_led,
+ (* LOC = "23" *)
+ output take_led,
+ (* LOC = "25" *)
+ output empty_led,
+ (* LOC = "21" *)
+ input clk
+);
+
+wire [7:0] out_data;
+wire [7:0] in_data;
+reg wr = 1'd0;
+reg rd = 1'd0;
+wire tx_empty;
+wire rx_empty;
+wire tx_ov;
+wire rx_ov;
+wire sout_load;
+wire [7:0] sout_out_data;
+wire sout_shift;
+reg sout_empty = 1'd1;
+reg sout_overrun = 1'd0;
+reg [3:0] sout_count = 4'd0;
+reg [9:0] sout_reg = 10'd0;
+reg sout_tx;
+wire sin_rx;
+wire sin_shift;
+wire sin_take;
+reg [7:0] sin_in_data = 8'd0;
+wire sin_edge;
+reg sin_empty = 1'd1;
+reg sin_busy = 1'd0;
+reg sin_overrun = 1'd0;
+reg sin_sync_rx = 1'd0;
+reg [8:0] sin_reg = 9'd0;
+reg sin_rx_prev = 1'd0;
+reg [3:0] sin_count = 4'd0;
+wire out_active;
+wire in_active;
+reg shift_out_strobe = 1'd0;
+reg shift_in_strobe = 1'd0;
+reg [9:0] in_counter = 10'd0;
+reg [9:0] out_counter = 10'd0;
+wire sys_clk;
+wire sys_rst;
+wire por_clk;
+reg int_rst = 1'd1;
+
+// synthesis translate_off
+reg dummy_s;
+initial dummy_s <= 1'd0;
+// synthesis translate_on
+
+assign tx_led = (~tx);
+assign rx_led = (~rx);
+assign load_led = sout_load;
+assign take_led = sin_take;
+assign empty_led = sin_empty;
+assign out_data = in_data;
+assign in_data = sin_in_data;
+assign sout_out_data = out_data;
+assign sin_take = rd;
+assign sout_load = wr;
+assign tx = sout_tx;
+assign sin_rx = rx;
+assign tx_empty = sout_empty;
+assign rx_empty = sin_empty;
+assign tx_ov = sout_overrun;
+assign rx_ov = sin_overrun;
+assign sout_shift = shift_out_strobe;
+assign sin_shift = shift_in_strobe;
+assign out_active = (~sout_empty);
+assign in_active = sin_busy;
+
+// synthesis translate_off
+reg dummy_d;
+// synthesis translate_on
+always @(*) begin
+ sout_tx <= 1'd0;
+ if (sout_empty) begin
+ sout_tx <= 1'd1;
+ end else begin
+ sout_tx <= sout_reg[0];
+ end
+// synthesis translate_off
+ dummy_d <= dummy_s;
+// synthesis translate_on
+end
+assign sin_edge = ((sin_rx_prev == 1'd1) & (sin_sync_rx == 1'd0));
+assign sys_clk = clk;
+assign por_clk = clk;
+assign sys_rst = int_rst;
+
+always @(posedge por_clk) begin
+ int_rst <= 1'd0;
+end
+
+always @(posedge sys_clk) begin
+ wr <= 1'd0;
+ rd <= 1'd0;
+ if ((~sin_empty)) begin
+ wr <= 1'd1;
+ rd <= 1'd1;
+ end
+ if (sout_load) begin
+ if (sout_empty) begin
+ sout_reg[0] <= 1'd0;
+ sout_reg[8:1] <= sout_out_data;
+ sout_reg[9] <= 1'd1;
+ sout_empty <= 1'd0;
+ sout_overrun <= 1'd0;
+ sout_count <= 1'd0;
+ end else begin
+ sout_overrun <= 1'd1;
+ end
+ end
+ if (((~sout_empty) & sout_shift)) begin
+ sout_reg[8:0] <= sout_reg[9:1];
+ sout_reg[9] <= 1'd0;
+ if ((sout_count == 4'd9)) begin
+ sout_empty <= 1'd1;
+ sout_count <= 1'd0;
+ end else begin
+ sout_count <= (sout_count + 1'd1);
+ end
+ end
+ sin_sync_rx <= sin_rx;
+ sin_rx_prev <= sin_sync_rx;
+ if (sin_take) begin
+ sin_empty <= 1'd1;
+ sin_overrun <= 1'd0;
+ end
+ if (((~sin_busy) & sin_edge)) begin
+ sin_busy <= 1'd1;
+ end
+ if ((sin_shift & sin_busy)) begin
+ sin_reg[8] <= sin_sync_rx;
+ sin_reg[7:0] <= sin_reg[8:1];
+ if ((sin_count == 4'd9)) begin
+ sin_in_data <= sin_reg[8:1];
+ sin_count <= 1'd0;
+ sin_busy <= 1'd0;
+ if ((~sin_empty)) begin
+ sin_overrun <= 1'd1;
+ end else begin
+ sin_empty <= 1'd0;
+ end
+ end else begin
+ sin_count <= (sin_count + 1'd1);
+ end
+ end
+ out_counter <= 1'd0;
+ in_counter <= 1'd0;
+ if (in_active) begin
+ shift_in_strobe <= 1'd0;
+ in_counter <= (in_counter + 1'd1);
+ if ((in_counter == 9'd311)) begin
+ shift_in_strobe <= 1'd1;
+ end
+ if ((in_counter == 10'd623)) begin
+ in_counter <= 1'd0;
+ end
+ end
+ if (out_active) begin
+ shift_out_strobe <= 1'd0;
+ out_counter <= (out_counter + 1'd1);
+ if ((out_counter == 10'd623)) begin
+ out_counter <= 1'd0;
+ shift_out_strobe <= 1'd1;
+ end
+ end
+ if (sys_rst) begin
+ wr <= 1'd0;
+ rd <= 1'd0;
+ sout_empty <= 1'd1;
+ sout_overrun <= 1'd0;
+ sout_count <= 4'd0;
+ sout_reg <= 10'd0;
+ sin_in_data <= 8'd0;
+ sin_empty <= 1'd1;
+ sin_busy <= 1'd0;
+ sin_overrun <= 1'd0;
+ sin_sync_rx <= 1'd0;
+ sin_reg <= 9'd0;
+ sin_rx_prev <= 1'd0;
+ sin_count <= 4'd0;
+ shift_out_strobe <= 1'd0;
+ shift_in_strobe <= 1'd0;
+ in_counter <= 10'd0;
+ out_counter <= 10'd0;
+ end
+end
+
+endmodule