From 8d956479da90cc660e32e1549890c0eec9b71b6d Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Sun, 1 May 2022 14:57:30 +0300 Subject: [PATCH] Added Fmax computation script for Xilinx Vivado --- .../testbench_template_tb/edge_detect.sv | 73 ++++++++++--------- .../testbench_template_tb/main_tb.sv | 2 +- scripts/Vivado_init.tcl | 13 +++- scripts/get_fmax_vivado.tcl | 18 +++++ 4 files changed, 71 insertions(+), 35 deletions(-) create mode 100755 scripts/get_fmax_vivado.tcl diff --git a/example_projects/testbench_template_tb/edge_detect.sv b/example_projects/testbench_template_tb/edge_detect.sv index 0678010..8c3bed3 100755 --- a/example_projects/testbench_template_tb/edge_detect.sv +++ b/example_projects/testbench_template_tb/edge_detect.sv @@ -1,10 +1,15 @@ //------------------------------------------------------------------------------ // edge_detect.sv +// published as part of https://github.com/pConst/basic_verilog // Konstantin Pavlov, pavlovconst@gmail.com //------------------------------------------------------------------------------ // INFO ------------------------------------------------------------------------ -// Edge detector, ver.3 +// Edge detector, ver.4 +// +// (new!) Added WIDTH parameter to simplify instantiating arrays of edge detectors +// (new!) Made reset to be asynchronous +// // Added parameter to select combinational implementation (zero clocks delay) // or registered implementation (one clocks delay) // @@ -17,12 +22,13 @@ /* --- INSTANTIATION TEMPLATE BEGIN --- edge_detect #( + .WIDTH( 32 ), .REGISTER_OUTPUTS( 1'b1 ) -) ED1[31:0] ( - .clk( {32{clk}} ), - .nrst( {32{1'b1}} ), +) in_ed ( + .clk( clk ), + .anrst( 1'b1 ), .in( in[31:0] ), - .rising( out[31:0] ), + .rising( in_rise[31:0] ), .falling( ), .both( ) ); @@ -31,59 +37,60 @@ edge_detect #( module edge_detect #( parameter + bit [7:0] WIDTH = 1, // signal width bit [0:0] REGISTER_OUTPUTS = 1'b0 // 0 - comb. implementation (default) // 1 - registered implementation )( input clk, - input nrst, + input anrst, - input in, - output logic rising, - output logic falling, - output logic both + input [WIDTH-1:0] in, + output logic [WIDTH-1:0] rising, + output logic [WIDTH-1:0] falling, + output logic [WIDTH-1:0] both ); // data delay line -logic in_d = 0; -always_ff @(posedge clk) begin - if ( ~nrst ) begin - in_d <= 0; +logic [WIDTH-1:0] in_d = '0; +always_ff @(posedge clk or negedge anrst) begin + if ( ~anrst ) begin + in_d[WIDTH-1:0] <= '0; end else begin - in_d <= in; + in_d[WIDTH-1:0] <= in[WIDTH-1:0]; end end -logic rising_comb; -logic falling_comb; -logic both_comb; +logic [WIDTH-1:0] rising_comb; +logic [WIDTH-1:0] falling_comb; +logic [WIDTH-1:0] both_comb; always_comb begin - rising_comb = nrst && (in && ~in_d); - falling_comb = nrst && (~in && in_d); - both_comb = nrst && (rising_comb || falling_comb); + rising_comb[WIDTH-1:0] = {WIDTH{anrst}} & (in[WIDTH-1:0] & ~in_d[WIDTH-1:0]); + falling_comb[WIDTH-1:0] = {WIDTH{anrst}} & (~in[WIDTH-1:0] & in_d[WIDTH-1:0]); + both_comb[WIDTH-1:0] = {WIDTH{anrst}} & (rising_comb[WIDTH-1:0] | falling_comb[WIDTH-1:0]); end generate - if( REGISTER_OUTPUTS=='0 ) begin + if( REGISTER_OUTPUTS==1'b0 ) begin // combinational outputs, no delay always_comb begin - rising = rising_comb; - falling = falling_comb; - both = both_comb; + rising[WIDTH-1:0] = rising_comb[WIDTH-1:0]; + falling[WIDTH-1:0] = falling_comb[WIDTH-1:0]; + both[WIDTH-1:0] = both_comb[WIDTH-1:0]; end // always end else begin // registered outputs, 1 cycle delay - always_ff @(posedge clk) begin - if( ~nrst ) begin - rising <= 0; - falling <= 0; - both <= 0; + always_ff @(posedge clk or negedge anrst) begin + if( ~anrst ) begin + rising[WIDTH-1:0] <= '0; + falling[WIDTH-1:0] <= '0; + both[WIDTH-1:0] <= '0; end else begin - rising <= rising_comb; - falling <= falling_comb; - both <= both_comb; + rising[WIDTH-1:0] <= rising_comb[WIDTH-1:0]; + falling[WIDTH-1:0] <= falling_comb[WIDTH-1:0]; + both[WIDTH-1:0] <= both_comb[WIDTH-1:0]; end // always end // if diff --git a/example_projects/testbench_template_tb/main_tb.sv b/example_projects/testbench_template_tb/main_tb.sv index 7188878..8f57cbe 100755 --- a/example_projects/testbench_template_tb/main_tb.sv +++ b/example_projects/testbench_template_tb/main_tb.sv @@ -73,7 +73,7 @@ clk_divider #( logic [31:0] E_DerivedClocks; edge_detect ed1[31:0] ( .clk( {32{clk200}} ), - .nrst( {32{nrst_once}} ), + .anrst( {32{nrst_once}} ), .in( DerivedClocks[31:0] ), .rising( E_DerivedClocks[31:0] ), .falling( ), diff --git a/scripts/Vivado_init.tcl b/scripts/Vivado_init.tcl index 8c4ffca..9b420fd 100755 --- a/scripts/Vivado_init.tcl +++ b/scripts/Vivado_init.tcl @@ -1,5 +1,6 @@ #------------------------------------------------------------------------------ # Vivado_init.tcl +# published as part of https://github.com/pConst/basic_verilog # Konstantin Pavlov, pavlovconst@gmail.com #------------------------------------------------------------------------------ @@ -81,4 +82,14 @@ proc el_time {} { puts "----------------------------------" puts [ join [ list "TOTAL: " [format "%02d:%02d:%02d" $hs_t $ms_t $ss_t]] "" ] puts "" -} \ No newline at end of file +} + +# compuiting fmax, in MHz, given target clock in MHz +proc fmax {target_clock} { + open_run impl_1 + puts [ join [ list \ + [expr round(1e3/((1e3/$target_clock)-[get_property SLACK [get_timing_paths]]))] \ + " MHz" ] "" ] + puts "" +} + diff --git a/scripts/get_fmax_vivado.tcl b/scripts/get_fmax_vivado.tcl new file mode 100755 index 0000000..1ce930e --- /dev/null +++ b/scripts/get_fmax_vivado.tcl @@ -0,0 +1,18 @@ +#------------------------------------------------------------------------------ +# get_fmax_vivado.tcl +# published as part of https://github.com/pConst/basic_verilog +# Konstantin Pavlov, pavlovconst@gmail.com +#------------------------------------------------------------------------------ + + +fmax 1000 + +# compuiting fmax, in MHz, given target clock in MHz +proc fmax {target_clock} { + open_run impl_1 + puts [ join [ list \ + [expr round(1e3/((1e3/$target_clock)-[get_property SLACK [get_timing_paths]]))] \ + " MHz" ] "" ] + puts "" +} +