machxo2: Add two new examples: blinky_ext and aforementioned UART.
This commit is contained in:
parent
74b5e846a5
commit
73c851d8e0
@ -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
|
||||
|
||||
|
19
machxo2/examples/blinky_ext.v
Normal file
19
machxo2/examples/blinky_ext.v
Normal file
@ -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
|
209
machxo2/examples/uart.v
Normal file
209
machxo2/examples/uart.v
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user