diff --git a/README.md b/README.md index ed3e0c7..4ef6f41 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 diff --git a/fmax/tt_uart_rx.sv b/fmax/tt_uart_rx.sv new file mode 100644 index 0000000..572ed5b --- /dev/null +++ b/fmax/tt_uart_rx.sv @@ -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 diff --git a/fmax/tt_uart.sv b/fmax/tt_uart_tx.sv similarity index 63% rename from fmax/tt_uart.sv rename to fmax/tt_uart_tx.sv index 70a79cf..997d57e 100644 --- a/fmax/tt_uart.sv +++ b/fmax/tt_uart_tx.sv @@ -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;