Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ Properties proven in formal:
Every module builds from the top-level Makefile.

```
make MOD=uart_rx # run a module's testbench
make wave MOD=uart_rx # run the testbench and open the waveform in Surfer
make formal MOD=uart_rx # run the module's SymbiYosys proof
make cocotb # run the top-level cocotb loopback test
./synth_stats.sh uart # report a module's synthesis cost
./fmax.sh uart tt_uart clk # fmax and utilization
make MOD=uart_rx # run a module's testbench
make wave MOD=uart_rx # run the testbench and open the waveform in Surfer
make formal MOD=uart_rx # run the module's SymbiYosys proof
make cocotb # run the top-level cocotb loopback test
./synth_stats.sh uart # report a module's synthesis cost
./fmax.sh uart_tx tt_uart_tx clk # fmax and utilization
```

## Synthesis
Expand All @@ -82,11 +82,12 @@ Synthesized for the Digilent Basys 3 (Xilinx Artix-7).

### Post-route timing

`fmax.sh` places and routes the core in a registered-boundary harness and reports the maximum clock frequency. The frequency comes from the open nextpnr-xilinx flow, which is experimental and not vendor signed timing analysis.
`fmax.sh` places and routes each module in a registered-boundary harness and reports the maximum clock frequency. This data relies on the experimental nextpnr-xilinx open-source toolchain, meaning frequencies are unverified and lack vendor-signed timing analysis.

| Module | LUTs | Flip-flops | Block RAMs | Fmax |
|--------|------|------------|------------|------|
| `uart` | 63 | 60 | 0 | 277 MHz |
| `uart_tx` | 25 | 26 | 0 | 316 MHz |
| `uart_rx` | 32 | 34 | 0 | 296 MHz |

### Tool versions

Expand Down
26 changes: 26 additions & 0 deletions fmax/tt_uart_rx.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// UART RX harness
module tt_uart_rx (
input logic clk,
input logic rst_n,
input logic si,
output logic so
);
localparam int NOUT = 10;

logic rx_serial_r;
logic [NOUT-1:0] out_w, out_r;

always_ff @(posedge clk) rx_serial_r <= si;

uart_rx dut (
.clk (clk),
.rst_n (rst_n),
.rx_serial(rx_serial_r),
.rx_data (out_w[7:0]),
.rx_valid(out_w[8]),
.rx_error(out_w[9])
);

always_ff @(posedge clk) out_r <= out_w;
always_ff @(posedge clk) so <= ^out_r;
endmodule
16 changes: 6 additions & 10 deletions fmax/tt_uart.sv → fmax/tt_uart_tx.sv
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
// UART timing harness
module tt_uart (
// UART TX harness
module tt_uart_tx (
input logic clk,
input logic rst_n,
input logic si,
output logic so
);
localparam int NIN = 10;
localparam int NOUT = 12;
localparam int NIN = 9;
localparam int NOUT = 2;

logic [NIN-1:0] in_r;
logic [NOUT-1:0] out_w, out_r;

always_ff @(posedge clk) in_r <= {in_r[NIN-2:0], si};

uart dut (
uart_tx dut (
.clk (clk),
.rst_n (rst_n),
.tx_data (in_r[7:0]),
.tx_valid (in_r[8]),
.tx_ready (out_w[0]),
.tx_serial(out_w[1]),
.rx_serial(in_r[9]),
.rx_data (out_w[9:2]),
.rx_valid (out_w[10]),
.rx_error (out_w[11])
.tx_serial(out_w[1])
);

always_ff @(posedge clk) out_r <= out_w;
Expand Down
Loading