mirror of https://github.com/YosysHQ/picorv32.git
Added "make table.txt" vivado scripts
This commit is contained in:
parent
2bd43fff68
commit
dee66e136e
20
README.md
20
README.md
|
@ -311,6 +311,26 @@ makes it easy to install them side-by-side with the regular riscv-tools, which
|
|||
are using the name prefix `riscv64-unknown-elf-` by default.
|
||||
|
||||
|
||||
Evaluation: Timing on Xilinx 7-Series FPGAs
|
||||
-------------------------------------------
|
||||
|
||||
The following table lists the maximum clock speeds that PicoRV32 can run at on
|
||||
Xilinx 7-Series FPGAs. This are the values reported by Vivado 2015.1 post
|
||||
place&route static timing analysis (report_timing).
|
||||
|
||||
| Device | Speedgrade | Clock Period (Freq.) |
|
||||
|:-------------------- |:----------:| --------------------:|
|
||||
| Xilinx Artix-7T | -1 | 5.1 ns (196 MHz) |
|
||||
| Xilinx Artix-7T | -2 | 4.1 ns (243 MHz) |
|
||||
| Xilinx Artix-7T | -3 | 3.6 ns (277 MHz) |
|
||||
| Xilinx Kintex-7T | -1 | 3.3 ns (303 MHz) |
|
||||
| Xilinx Kintex-7T | -2 | 2.6 ns (384 MHz) |
|
||||
| Xilinx Kintex-7T | -3 | 2.5 ns (400 MHz) |
|
||||
| Xilinx Virtex-7T | -1 | 3.1 ns (322 MHz) |
|
||||
| Xilinx Virtex-7T | -2 | 2.6 ns (384 MHz) |
|
||||
| Xilinx Virtex-7T | -3 | 2.4 ns (416 MHz) |
|
||||
|
||||
|
||||
Todos:
|
||||
------
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@ synth_*.log
|
|||
synth_*.mmi
|
||||
synth_*.bit
|
||||
synth_*.v
|
||||
tab_*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
VIVADO = /opt/Xilinx/Vivado/2014.4/bin/vivado
|
||||
export VIVADO = /opt/Xilinx/Vivado/2015.1/bin/vivado
|
||||
|
||||
help:
|
||||
@echo "Usage: make {synth_speed|synth_area|synth_soc}"
|
||||
|
@ -8,3 +8,13 @@ synth_%:
|
|||
$(VIVADO) -nojournal -log $@.log -mode batch -source $@.tcl
|
||||
rm -rf .Xil fsm_encoding.os synth_*.backup.log usage_statistics_webtalk.*
|
||||
|
||||
tab_%/results.txt:
|
||||
bash tabtest.sh $@
|
||||
|
||||
table.txt: tab_small_xc7a_1/results.txt tab_small_xc7a_2/results.txt tab_small_xc7a_3/results.txt
|
||||
table.txt: tab_small_xc7k_1/results.txt tab_small_xc7k_2/results.txt tab_small_xc7k_3/results.txt
|
||||
table.txt: tab_small_xc7v_1/results.txt tab_small_xc7v_2/results.txt tab_small_xc7v_3/results.txt
|
||||
|
||||
table.txt:
|
||||
bash table.sh > table.txt
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
|
||||
dashes="----------------------------------------------------------------"
|
||||
printf '| %-20s | %-10s | %-20s |\n' "Device" "Speedgrade" "Clock Period (Freq.)"
|
||||
printf '|:%.20s |:%.10s:| %.20s:|\n' $dashes $dashes $dashes
|
||||
|
||||
for x in $( grep -H . tab_*/results.txt )
|
||||
do
|
||||
read _ size device grade _ speed < <( echo "$x" | tr _/: ' ' )
|
||||
case "$device" in
|
||||
xc7a) d="Xilinx Artix-7T" ;;
|
||||
xc7k) d="Xilinx Kintex-7T" ;;
|
||||
xc7v) d="Xilinx Virtex-7T" ;;
|
||||
esac
|
||||
speedtxt=$( printf '%s.%s ns (%d MHz)' ${speed%?} ${speed#?} $((10000 / speed)) )
|
||||
printf '| %-20s | %-10s | %20s |\n' "$d" "-$grade" "$speedtxt"
|
||||
done
|
|
@ -0,0 +1,71 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
read _ ip dev grade _ < <( echo $* | tr '_/' ' '; )
|
||||
|
||||
# rm -rf tab_${ip}_${dev}_${grade}
|
||||
mkdir -p tab_${ip}_${dev}_${grade}
|
||||
cd tab_${ip}_${dev}_${grade}
|
||||
|
||||
best_speed=99
|
||||
speed=30
|
||||
step=16
|
||||
|
||||
synth_case() {
|
||||
if [ -f test_${1}.txt ]; then
|
||||
echo "Reusing cached tab_${ip}_${dev}_${grade}/test_${1}."
|
||||
return
|
||||
fi
|
||||
|
||||
case "${dev}" in
|
||||
xc7a) xl_device="xc7a15t-fgg484-${grade}" ;;
|
||||
xc7k) xl_device="xc7k70t-fbg676-${grade}" ;;
|
||||
xc7v) xl_device="xc7v585t-ffg1761-${grade}" ;;
|
||||
esac
|
||||
|
||||
cat > test_${1}.tcl <<- EOT
|
||||
read_verilog ../tabtest.v
|
||||
read_verilog ../../../picorv32.v
|
||||
read_xdc test_${1}.xdc
|
||||
synth_design -flatten_hierarchy full -part ${xl_device} -top top
|
||||
opt_design -sweep -remap
|
||||
place_design -directive Explore
|
||||
phys_opt_design -retime -rewire -critical_pin_opt -placement_opt -critical_cell_opt
|
||||
route_design -directive Explore
|
||||
place_design -post_place_opt
|
||||
phys_opt_design -retime
|
||||
route_design -directive NoTimingRelaxation
|
||||
report_utilization
|
||||
report_timing
|
||||
EOT
|
||||
|
||||
cat > test_${1}.xdc <<- EOT
|
||||
create_clock -period ${speed%?}.${speed#?} [get_ports clk]
|
||||
EOT
|
||||
|
||||
echo "Running tab_${ip}_${dev}_${grade}/test_${1}.."
|
||||
if ! $VIVADO -nojournal -log test_${1}.log -mode batch -source test_${1}.tcl > /dev/null 2>&1; then
|
||||
cat test_${1}.log
|
||||
exit 1
|
||||
fi
|
||||
mv test_${1}.log test_${1}.txt
|
||||
}
|
||||
|
||||
while [ $step -gt 0 ]; do
|
||||
synth_case $speed
|
||||
|
||||
if grep -q '^Slack.*(VIOLATED)' test_${speed}.txt; then
|
||||
[ $speed -eq 38 ] || step=$((step / 2))
|
||||
speed=$((speed + step))
|
||||
elif grep -q '^Slack.*(MET)' test_${speed}.txt; then
|
||||
[ $speed -lt $best_speed ] && best_speed=$speed
|
||||
step=$((step / 2))
|
||||
speed=$((speed - step))
|
||||
else
|
||||
echo "ERROR: No slack line found in $PWD/test_${speed}.txt!"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo $best_speed > results.txt
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
|
||||
module top (
|
||||
input clk, io_resetn,
|
||||
output io_trap,
|
||||
|
||||
output io_mem_axi_awvalid,
|
||||
input io_mem_axi_awready,
|
||||
output [31:0] io_mem_axi_awaddr,
|
||||
output [ 2:0] io_mem_axi_awprot,
|
||||
|
||||
output io_mem_axi_wvalid,
|
||||
input io_mem_axi_wready,
|
||||
output [31:0] io_mem_axi_wdata,
|
||||
output [ 3:0] io_mem_axi_wstrb,
|
||||
|
||||
input io_mem_axi_bvalid,
|
||||
output io_mem_axi_bready,
|
||||
|
||||
output io_mem_axi_arvalid,
|
||||
input io_mem_axi_arready,
|
||||
output [31:0] io_mem_axi_araddr,
|
||||
output [ 2:0] io_mem_axi_arprot,
|
||||
|
||||
input io_mem_axi_rvalid,
|
||||
output io_mem_axi_rready,
|
||||
input [31:0] io_mem_axi_rdata,
|
||||
|
||||
input [31:0] io_irq,
|
||||
output [31:0] io_eoi
|
||||
);
|
||||
wire resetn;
|
||||
wire trap;
|
||||
wire mem_axi_awvalid;
|
||||
wire mem_axi_awready;
|
||||
wire [31:0] mem_axi_awaddr;
|
||||
wire [2:0] mem_axi_awprot;
|
||||
wire mem_axi_wvalid;
|
||||
wire mem_axi_wready;
|
||||
wire [31:0] mem_axi_wdata;
|
||||
wire [3:0] mem_axi_wstrb;
|
||||
wire mem_axi_bvalid;
|
||||
wire mem_axi_bready;
|
||||
wire mem_axi_arvalid;
|
||||
wire mem_axi_arready;
|
||||
wire [31:0] mem_axi_araddr;
|
||||
wire [2:0] mem_axi_arprot;
|
||||
wire mem_axi_rvalid;
|
||||
wire mem_axi_rready;
|
||||
wire [31:0] mem_axi_rdata;
|
||||
wire [31:0] irq;
|
||||
wire [31:0] eoi;
|
||||
|
||||
delay4 #( 1) delay_resetn (clk, io_resetn , resetn );
|
||||
delay4 #( 1) delay_trap (clk, trap , io_trap );
|
||||
delay4 #( 1) delay_mem_axi_awvalid (clk, mem_axi_awvalid, io_mem_axi_awvalid);
|
||||
delay4 #( 1) delay_mem_axi_awready (clk, io_mem_axi_awready, mem_axi_awready);
|
||||
delay4 #(32) delay_mem_axi_awaddr (clk, mem_axi_awaddr , io_mem_axi_awaddr );
|
||||
delay4 #( 3) delay_mem_axi_awprot (clk, mem_axi_awprot , io_mem_axi_awprot );
|
||||
delay4 #( 1) delay_mem_axi_wvalid (clk, mem_axi_wvalid , io_mem_axi_wvalid );
|
||||
delay4 #( 1) delay_mem_axi_wready (clk, io_mem_axi_wready , mem_axi_wready );
|
||||
delay4 #(32) delay_mem_axi_wdata (clk, mem_axi_wdata , io_mem_axi_wdata );
|
||||
delay4 #( 4) delay_mem_axi_wstrb (clk, mem_axi_wstrb , io_mem_axi_wstrb );
|
||||
delay4 #( 1) delay_mem_axi_bvalid (clk, io_mem_axi_bvalid , mem_axi_bvalid );
|
||||
delay4 #( 1) delay_mem_axi_bready (clk, mem_axi_bready , io_mem_axi_bready );
|
||||
delay4 #( 1) delay_mem_axi_arvalid (clk, mem_axi_arvalid, io_mem_axi_arvalid);
|
||||
delay4 #( 1) delay_mem_axi_arready (clk, io_mem_axi_arready, mem_axi_arready);
|
||||
delay4 #(32) delay_mem_axi_araddr (clk, mem_axi_araddr , io_mem_axi_araddr );
|
||||
delay4 #( 3) delay_mem_axi_arprot (clk, mem_axi_arprot , io_mem_axi_arprot );
|
||||
delay4 #( 1) delay_mem_axi_rvalid (clk, io_mem_axi_rvalid , mem_axi_rvalid );
|
||||
delay4 #( 1) delay_mem_axi_rready (clk, mem_axi_rready , io_mem_axi_rready );
|
||||
delay4 #(32) delay_mem_axi_rdata (clk, io_mem_axi_rdata , mem_axi_rdata );
|
||||
delay4 #(32) delay_irq (clk, io_irq , irq );
|
||||
delay4 #(32) delay_eoi (clk, eoi , io_eoi );
|
||||
|
||||
picorv32_axi core (
|
||||
.clk (clk ),
|
||||
.resetn (resetn ),
|
||||
.trap (trap ),
|
||||
.mem_axi_awvalid(mem_axi_awvalid),
|
||||
.mem_axi_awready(mem_axi_awready),
|
||||
.mem_axi_awaddr (mem_axi_awaddr ),
|
||||
.mem_axi_awprot (mem_axi_awprot ),
|
||||
.mem_axi_wvalid (mem_axi_wvalid ),
|
||||
.mem_axi_wready (mem_axi_wready ),
|
||||
.mem_axi_wdata (mem_axi_wdata ),
|
||||
.mem_axi_wstrb (mem_axi_wstrb ),
|
||||
.mem_axi_bvalid (mem_axi_bvalid ),
|
||||
.mem_axi_bready (mem_axi_bready ),
|
||||
.mem_axi_arvalid(mem_axi_arvalid),
|
||||
.mem_axi_arready(mem_axi_arready),
|
||||
.mem_axi_araddr (mem_axi_araddr ),
|
||||
.mem_axi_arprot (mem_axi_arprot ),
|
||||
.mem_axi_rvalid (mem_axi_rvalid ),
|
||||
.mem_axi_rready (mem_axi_rready ),
|
||||
.mem_axi_rdata (mem_axi_rdata ),
|
||||
.irq (irq ),
|
||||
.eoi (eoi )
|
||||
);
|
||||
endmodule
|
||||
|
||||
module delay4 #(
|
||||
parameter WIDTH = 1
|
||||
) (
|
||||
input clk,
|
||||
input [WIDTH-1:0] in,
|
||||
output reg [WIDTH-1:0] out
|
||||
);
|
||||
reg [WIDTH-1:0] q1, q2, q3;
|
||||
always @(posedge clk) begin
|
||||
q1 <= in;
|
||||
q2 <= q1;
|
||||
q3 <= q2;
|
||||
out <= q3;
|
||||
end
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue