aboutsummaryrefslogtreecommitdiffstats
path: root/machxo2/examples
diff options
context:
space:
mode:
Diffstat (limited to 'machxo2/examples')
-rw-r--r--machxo2/examples/.gitignore11
-rw-r--r--machxo2/examples/README.md110
-rw-r--r--machxo2/examples/blinky.v17
-rw-r--r--machxo2/examples/blinky_ext.v19
-rw-r--r--machxo2/examples/blinky_tb.v38
-rw-r--r--machxo2/examples/demo.sh22
-rw-r--r--machxo2/examples/mitertest.sh85
-rw-r--r--machxo2/examples/rgbcount.v33
-rw-r--r--machxo2/examples/simple.sh34
-rw-r--r--machxo2/examples/simtest.sh39
-rw-r--r--machxo2/examples/tinyfpga.v28
-rw-r--r--machxo2/examples/uart.v209
12 files changed, 645 insertions, 0 deletions
diff --git a/machxo2/examples/.gitignore b/machxo2/examples/.gitignore
new file mode 100644
index 00000000..8a87cc8d
--- /dev/null
+++ b/machxo2/examples/.gitignore
@@ -0,0 +1,11 @@
+*_simtest*
+*.vcd
+*.png
+*.log
+*.smt2
+pack*.v
+place*.v
+pnr*.v
+abc.history
+*.txt
+*.bit
diff --git a/machxo2/examples/README.md b/machxo2/examples/README.md
new file mode 100644
index 00000000..3542da70
--- /dev/null
+++ b/machxo2/examples/README.md
@@ -0,0 +1,110 @@
+# MachXO2 Architecture Example
+This directory contains a simple example of running `nextpnr-machxo2`:
+
+* `simple.sh` produces nextpnr output in the files `{pack,place,pnr}*.json`,
+ as well as pre-pnr and post-pnr diagrams in `{pack,place,pnr}*.{dot, png}`.
+* `simtest.sh` extends `simple.sh` by generating `{pack,place,pnr}*.v` from
+ `{pack,place,pnr}*.json`. The script calls the [`iverilog`](http://iverilog.icarus.com)
+ compiler and `vvp` runtime to compare the behavior of `{pack,place,pnr}*.v`
+ and the original Verilog input (using a testbench `*_tb.v`). This is known as
+ post-place-and-route simulation.
+* `mitertest.sh` is similar to `simtest.sh`, but more comprehensive. This
+ script creates a [miter circuit](https://www21.in.tum.de/~lammich/2015_SS_Seminar_SAT/resources/Equivalence_Checking_11_30_08.pdf)
+ to compare the output port values of `{pack,place,pnr}*.v` against the
+ original Verilog code _when both modules are fed the same values on their input
+ ports._
+
+ All possible inputs and resulting outputs can be tested in reasonable time by
+ using `yosys`' built-in SAT solver or [`z3`](https://github.com/Z3Prover/z3),
+ an external SMT solver.
+* `demo.sh` creates bitstreams for [TinyFPGA Ax](https://tinyfpga.com/a-series-guide.html)
+ and writes the resulting bitstream to MachXO2's internal flash using
+ [`tinyproga`](https://github.com/tinyfpga/TinyFPGA-A-Programmer).
+
+As `nextpnr-machxo2` is developed the contents `simple.sh`, `simtest.sh`,
+`mitertest.sh`, and `demo.sh` are subject to change.
+
+## How To Run
+Each script requires a prefix that matches one of the self-contained Verilog
+examples in this directory. For instance, to create a bitstream from
+`tinyfpga.v`, use `demo.sh tinyfpga` (the `*` glob used throughout this file
+is filled with the the prefix).
+
+Each of `simple.sh`, `simtest.sh`, and `mitertest.sh` runs yosys and nextpnr
+to validate a Verilog design in various ways. They require an additional `mode`
+argument- `pack`, `place`, or `pnr`- which stops `nextpnr-machxo2` after the
+specified phase and writes out a JSON file of the results in
+`{pack,place,pnr}*.json`; `pnr` runs all of the Pack, Place, and Route phases.
+
+`mitertest.sh` requires an third option- `sat` or `smt`- to choose between
+verifying the miter with either yosys' built-in SAT solver, or an external
+SMT solver.
+
+Each script will exit if it finds an input Verilog example it knows it can't
+handle. To keep file count lower, all yosys scripts are written inline inside
+the `sh` scripts using the `-p` option.
+
+### Clean
+To clean output files from _all_ scripts, run:
+
+```
+rm -rf *.dot *.json *.png *.vcd *.smt2 *.log *.txt *.bit {pack,place,pnr}*.v *_simtest*
+```
+
+## Known Issues
+In principle, `mitertest.sh` should work in `sat` or `smt` mode with all
+example Verilog files which don't use the internal oscillator (OSCH) or other
+hard IP. However, as of this writing, only `blinky.v` passes correctly for a
+few reasons:
+
+ 1. The sim models for MachXO2 primitives used by the `gate` module contain
+ `initial` values _by design_, as it matches chip behavior. Without any of
+ the following in the `gold` module (like `blinky_ext.v` currently):
+
+ * An external reset signal
+ * Internal power-on reset signal (e.g. `reg int_rst = 1'd1;`)
+ * `initial` values to manually set registers
+
+ the `gold` and `gate` modules will inherently not match.
+
+ Examples using an internal power-on reset (e.g. `uart.v`) also have issues
+ that I haven't debugged yet in both `sat` and `smt` mode.
+ 2. To keep the `gold`/`gate` generation simpler, examples are currently
+ assumed to _not_ instantiate MachXO2 simulation primitives directly
+ (`FACADE_IO`, `FACADE_FF`, etc).
+ 3. `synth_machxo2` runs `deminout` on `inouts` when generating the `gate`
+ module. This is not handled yet when generating the `gold` module.
+
+## Verilog Examples
+* `blinky.v`/`blinky_tb.v`- A blinky example meant for simulation.
+* `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
+* `YOSYS`- Set to the location of the `yosys` binary to test. Defaults to the
+ `yosys` on the path. You may want to set this to a `yosys` binary in your
+ source tree if doing development.
+* `NEXTPNR`- Set to the location of the `nextpnr-machxo2` binary to test.
+ Defaults to the `nextpnr-machxo2` binary at the root of the `nextpnr` source
+ tree. This should be set, for instance, if doing an out-of-tree build of
+ `nextpnr-machxo2`.
+* `CELLS_SIM`- Set to the location of `machxo2/cells_sim.v` simulation models.
+ Defaults to whatever `yosys-config` associated with the above `YOSYS` binary
+ returns. You may want to set this to `/path/to/yosys/src/share/machxo2/cells_sim.v`
+ if doing development; `yosys-config` cannot find these "before-installation"
+ simulation models.
+* `TRELLIS_DB`- Set to the location of the Project Trellis database to use.
+ Defaults to nothing, which means `ecppack` will use whatever database is on
+ its path.
diff --git a/machxo2/examples/blinky.v b/machxo2/examples/blinky.v
new file mode 100644
index 00000000..57bad543
--- /dev/null
+++ b/machxo2/examples/blinky.v
@@ -0,0 +1,17 @@
+module top(input clk, rst, output [7:0] leds);
+
+// TODO: Test miter circuit without reset value. SAT and SMT diverge without
+// reset value (SAT succeeds, SMT fails). I haven't figured out the correct
+// init set of options to make SAT fail.
+// "sat -verify -prove-asserts -set-init-def -seq 1 miter" causes assertion
+// failure in yosys.
+reg [7:0] ctr = 8'h00;
+always @(posedge clk)
+ if (rst)
+ ctr <= 8'h00;
+ else
+ ctr <= ctr + 1'b1;
+
+assign leds = ctr;
+
+endmodule
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/blinky_tb.v b/machxo2/examples/blinky_tb.v
new file mode 100644
index 00000000..f9925e6f
--- /dev/null
+++ b/machxo2/examples/blinky_tb.v
@@ -0,0 +1,38 @@
+`timescale 1ns / 1ps
+module blinky_tb;
+
+reg clk = 1'b0, rst = 1'b0;
+reg [7:0] ctr_gold = 8'h00;
+wire [7:0] ctr_gate;
+top dut_i(.clk(clk), .rst(rst), .leds(ctr_gate));
+
+task oneclk;
+ begin
+ clk = 1'b1;
+ #10;
+ clk = 1'b0;
+ #10;
+ end
+endtask
+
+initial begin
+ $dumpfile("blinky_simtest.vcd");
+ $dumpvars(0, blinky_tb);
+ #100;
+ rst = 1'b1;
+ repeat (5) oneclk;
+ #5
+ rst = 1'b0;
+ #5
+ repeat (500) begin
+ if (ctr_gold !== ctr_gate) begin
+ $display("mismatch gold=%b gate=%b", ctr_gold, ctr_gate);
+ $stop;
+ end
+ oneclk;
+ ctr_gold = ctr_gold + 1'b1;
+ end
+ $finish;
+end
+
+endmodule
diff --git a/machxo2/examples/demo.sh b/machxo2/examples/demo.sh
new file mode 100644
index 00000000..00cb0cd0
--- /dev/null
+++ b/machxo2/examples/demo.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+if [ $# -lt 1 ]; then
+ echo "Usage: $0 prefix"
+ exit -1
+fi
+
+if ! grep -q "(\*.*LOC.*\*)" $1.v; then
+ echo "$1.v does not have LOC constraints for tinyfpga_a."
+ exit -2
+fi
+
+if [ ! -z ${TRELLIS_DB+x} ]; then
+ DB_ARG="--db $TRELLIS_DB"
+fi
+
+set -ex
+
+${YOSYS:-yosys} -p "synth_machxo2 -json $1.json" $1.v
+${NEXTPNR:-../../nextpnr-machxo2} --1200 --package QFN32 --no-iobs --json $1.json --textcfg $1.txt
+ecppack --compress $DB_ARG $1.txt $1.bit
+tinyproga -b $1.bit
diff --git a/machxo2/examples/mitertest.sh b/machxo2/examples/mitertest.sh
new file mode 100644
index 00000000..cfae28b7
--- /dev/null
+++ b/machxo2/examples/mitertest.sh
@@ -0,0 +1,85 @@
+#!/usr/bin/env bash
+
+if [ $# -lt 3 ]; then
+ echo "Usage: $0 prefix nextpnr_mode solve_mode"
+ exit -1
+fi
+
+if grep -q "OSCH" $1.v; then
+ echo "$1.v uses blackbox primitive OSCH and cannot be simulated."
+ exit -2
+fi
+
+case $2 in
+ "pack")
+ NEXTPNR_MODE="--pack-only"
+ ;;
+ "place")
+ NEXTPNR_MODE="--no-route"
+ ;;
+ "pnr")
+ NEXTPNR_MODE=""
+ ;;
+ *)
+ echo "nextpnr_mode string must be \"pack\", \"place\", or \"pnr\""
+ exit -3
+ ;;
+esac
+
+case $3 in
+ "sat")
+ SAT=1
+ ;;
+ "smt")
+ SMT=1
+ ;;
+ *)
+ echo "solve_mode string must be \"sat\", or \"smt\""
+ exit -4
+ ;;
+esac
+
+do_sat() {
+ ${YOSYS:-yosys} -l ${2}${1}_miter_sat.log -p "read_verilog ${1}.v
+ rename top gold
+ read_verilog ${2}${1}.v
+ rename top gate
+ read_verilog +/machxo2/cells_sim.v
+
+ miter -equiv -make_assert -flatten gold gate ${2}${1}_miter
+ hierarchy -top ${2}${1}_miter
+ sat -verify -prove-asserts -tempinduct ${2}${1}_miter"
+}
+
+do_smt() {
+ ${YOSYS:-yosys} -l ${2}${1}_miter_smt.log -p "read_verilog ${1}.v
+ rename top gold
+ read_verilog ${2}${1}.v
+ rename top gate
+ read_verilog +/machxo2/cells_sim.v
+
+ miter -equiv -make_assert gold gate ${2}${1}_miter
+ hierarchy -top ${2}${1}_miter; proc;
+ opt_clean
+ write_verilog ${2}${1}_miter.v
+ write_smt2 ${2}${1}_miter.smt2"
+
+ yosys-smtbmc -s z3 --dump-vcd ${2}${1}_miter_bmc.vcd ${2}${1}_miter.smt2
+ yosys-smtbmc -s z3 -i --dump-vcd ${2}${1}_miter_tmp.vcd ${2}${1}_miter.smt2
+}
+
+set -ex
+
+${YOSYS:-yosys} -p "read_verilog ${1}.v
+ synth_machxo2 -noiopad -json ${1}.json"
+${NEXTPNR:-../../nextpnr-machxo2} $NEXTPNR_MODE --1200 --package QFN32 --no-iobs --json ${1}.json --write ${2}${1}.json
+${YOSYS:-yosys} -p "read_verilog -lib +/machxo2/cells_sim.v
+ read_json ${2}${1}.json
+ clean -purge
+ write_verilog -noattr -norename ${2}${1}.v"
+
+if [ $3 = "sat" ]; then
+ do_sat $1 $2
+elif [ $3 = "smt" ]; then
+ do_smt $1 $2
+fi
diff --git a/machxo2/examples/rgbcount.v b/machxo2/examples/rgbcount.v
new file mode 100644
index 00000000..bf5c7518
--- /dev/null
+++ b/machxo2/examples/rgbcount.v
@@ -0,0 +1,33 @@
+// Modified from:
+// https://github.com/tinyfpga/TinyFPGA-A-Series/tree/master/template_a2
+// https://tinyfpga.com/a-series-guide.html used as a basis.
+
+module top (
+ (* LOC="21" *)
+ inout pin6,
+ (* LOC="26" *)
+ inout pin9_jtgnb,
+ (* LOC="27" *)
+ inout pin10_sda,
+);
+ wire clk;
+
+ OSCH #(
+ .NOM_FREQ("2.08")
+ ) internal_oscillator_inst (
+ .STDBY(1'b0),
+ .OSC(clk)
+ );
+
+ reg [23:0] led_timer;
+
+ always @(posedge clk) begin
+ led_timer <= led_timer + 1;
+ end
+
+ // left side of board
+ assign pin9_jtgnb = led_timer[23];
+ assign pin10_sda = led_timer[22];
+ assign pin6 = led_timer[21];
+
+endmodule
diff --git a/machxo2/examples/simple.sh b/machxo2/examples/simple.sh
new file mode 100644
index 00000000..1da60933
--- /dev/null
+++ b/machxo2/examples/simple.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+if [ $# -lt 2 ]; then
+ echo "Usage: $0 prefix mode"
+ exit -1
+fi
+
+case $2 in
+ "pack")
+ NEXTPNR_MODE="--pack-only"
+ ;;
+ "place")
+ NEXTPNR_MODE="--no-route"
+ ;;
+ "pnr")
+ NEXTPNR_MODE=""
+ ;;
+ *)
+ echo "Mode string must be \"pack\", \"place\", or \"pnr\""
+ exit -2
+ ;;
+esac
+
+set -ex
+
+${YOSYS:-yosys} -p "read_verilog ${1}.v
+ synth_machxo2 -json ${1}.json
+ show -format png -prefix ${1}"
+${NEXTPNR:-../../nextpnr-machxo2} $NEXTPNR_MODE --1200 --package QFN32 --no-iobs --json ${1}.json --write ${2}${1}.json
+${YOSYS:-yosys} -p "read_verilog -lib +/machxo2/cells_sim.v
+ read_json ${2}${1}.json
+ clean -purge
+ show -format png -prefix ${2}${1}
+ write_verilog -noattr -norename ${2}${1}.v"
diff --git a/machxo2/examples/simtest.sh b/machxo2/examples/simtest.sh
new file mode 100644
index 00000000..2c7f6f30
--- /dev/null
+++ b/machxo2/examples/simtest.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+
+if [ $# -lt 2 ]; then
+ echo "Usage: $0 prefix mode"
+ exit -1
+fi
+
+case $2 in
+ "pack")
+ NEXTPNR_MODE="--pack-only"
+ ;;
+ "place")
+ NEXTPNR_MODE="--no-route"
+ ;;
+ "pnr")
+ NEXTPNR_MODE=""
+ ;;
+ *)
+ echo "Mode string must be \"pack\", \"place\", or \"pnr\""
+ exit -2
+ ;;
+esac
+
+if [ ! -f ${1}_tb.v ]; then
+ echo "No testbench file (${1}_tb.v) found for ${1}.v"
+ exit -3
+fi
+
+set -ex
+
+${YOSYS:-yosys} -p "read_verilog ${1}.v
+ synth_machxo2 -json ${1}.json"
+${NEXTPNR:-../../nextpnr-machxo2} $NEXTPNR_MODE --1200 --package QFN32 --no-iobs --json ${1}.json --write ${2}${1}.json
+${YOSYS:-yosys} -p "read_verilog -lib +/machxo2/cells_sim.v
+ read_json ${2}${1}.json
+ clean -purge
+ write_verilog -noattr -norename ${2}${1}.v"
+iverilog -o ${1}_simtest ${CELLS_SIM:-`${YOSYS:yosys}-config --datdir/machxo2/cells_sim.v`} ${1}_tb.v ${2}${1}.v
+vvp -N ./${1}_simtest
diff --git a/machxo2/examples/tinyfpga.v b/machxo2/examples/tinyfpga.v
new file mode 100644
index 00000000..bd26d8eb
--- /dev/null
+++ b/machxo2/examples/tinyfpga.v
@@ -0,0 +1,28 @@
+// Modified from:
+// https://github.com/tinyfpga/TinyFPGA-A-Series/tree/master/template_a2
+// https://tinyfpga.com/a-series-guide.html used as a basis.
+
+module top (
+ (* LOC="13" *)
+ inout pin1
+);
+
+
+ wire clk;
+
+ OSCH #(
+ .NOM_FREQ("16.63")
+ ) internal_oscillator_inst (
+ .STDBY(1'b0),
+ .OSC(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