From 73c851d8e0073010329edc6c9e5de7d63037fefe Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 8 Feb 2021 03:27:49 -0500 Subject: machxo2: Add two new examples: blinky_ext and aforementioned UART. --- machxo2/examples/README.md | 10 ++ machxo2/examples/blinky_ext.v | 19 ++++ machxo2/examples/uart.v | 209 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 machxo2/examples/blinky_ext.v create mode 100644 machxo2/examples/uart.v (limited to 'machxo2') 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 -- cgit v1.2.3