diff --git a/openfpga_flow/benchmarks/micro_benchmark/config_loader/bitstream_loader.v b/openfpga_flow/benchmarks/micro_benchmark/config_loader/bitstream_loader.v new file mode 100644 index 000000000..69a92ff92 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/config_loader/bitstream_loader.v @@ -0,0 +1,114 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 05/05/2021 09:43:10 AM +// Design Name: +// Module Name: bitstream_loader +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module bitstream_loader( + input prog_clk, + input start, + output config_chain_head, + output reg done + ); + + parameter BITSTREAM_FILE=""; + parameter BITSTREAM_SIZE=6140; + + reg [BITSTREAM_SIZE<=2 ? 2 : $clog2(BITSTREAM_SIZE):0] bitstream_index; + + reg [13:0] bram_addr; + reg [3:0] bram_line_index; + + wire bram_output; + assign config_chain_head = bram_output; + + EFX_RAM_5K #( + .READ_WIDTH(1), + .WRITE_WIDTH(0), + + .INIT_0(256'h00000000000000000000000000000000000000000000007f00000000000000ff), + .INIT_1(256'h0000fff8ffffffff000000000000000000000000000000000000000000000000), + .INIT_2(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_4(256'h00000003f8000000000000000000000000000000000000000000000000000000), + .INIT_5(256'h0000000000000000078000000000000000000000000000000000000000000000), + .INIT_6(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_7(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_8(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_9(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_F(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_10(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_11(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_12(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_13(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_14(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_15(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_16(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_17(256'h0021000000000000000000000000000000000000000000000000000000000000), + ) + EFX_RAM_5K_inst ( + // Port A Data: 16-bit (each) output: Port A data + .WDATA(0), // Write data + .WADDR(0), // Write address + .WE(0), // Write enable + + .WCLK(0), + .WCLKE(0), + + .RDATA(bram_output), + .RADDR(bram_addr), + .RE(1'b1), + .RCLK(prog_clk) + ); + + + initial begin + bram_addr <= 0; + bram_line_index <= 0; + bitstream_index <= 0; + done <= 1'b0; + end + + always @(posedge prog_clk) begin + if (start && !done) begin + + bram_addr <= bram_addr + 1; + bitstream_index <= bitstream_index + 1; + end + if (bitstream_index == BITSTREAM_SIZE) begin + done <= 1'b1; + end + end + + +endmodule + + + + + + + + + \ No newline at end of file diff --git a/openfpga_flow/benchmarks/micro_benchmark/config_loader/configuration_manager.v b/openfpga_flow/benchmarks/micro_benchmark/config_loader/configuration_manager.v new file mode 100644 index 000000000..e3c20c2c1 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/config_loader/configuration_manager.v @@ -0,0 +1,71 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 05/05/2021 10:29:55 AM +// Design Name: +// Module Name: configuration_manager +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + +`include "clock_divider.v" +`include "pulse_generator.v" + +module configuration_manager( + input clk_in, + output prog_reset, + output prog_clk, + output ccff_head, + output configuration_done + ); + + parameter START_CYCLE=3; // Start configuration on cycle 3 of prog_clk + parameter CONFIGURATION_CLK_DIV_SIZE=12; // Divide clk_in (50MHz) by 4096 (2^12) times + + wire prog_clk_out; // prog_clk signal from clk_divider + wire ccff_head_out; + + assign ccff_head = ccff_head_out & ~prog_reset; + assign prog_clk = prog_clk_out & ~configuration_done; // prog_clk will stop when configuration done + + // PRESET + // Programming reset will be enabled until START_CYCLE + reset_generator #( + .INITIAL_VALUE(1), + .ACTIVE_CYCLES(START_CYCLE) + ) prog_reset_generator( + .clk(~prog_clk), + .pulse(prog_reset) + ); + + + // PROG_CLK + // Divide pl_clk (50MHz) by 4096 (2^12) times + clock_divider #( + .CLK_DIVIDER_SIZE(CONFIGURATION_CLK_DIV_SIZE) + ) prog_clk_divider ( + .clk_in(clk_in), + .clk_out(prog_clk_out) + ); + + + // Instantiate bitstream loader + bitstream_loader loader ( + .prog_clk(prog_clk), + .config_chain_head(ccff_head_out), + .start(~prog_reset), + .done(configuration_done) + ); + +endmodule diff --git a/openfpga_flow/benchmarks/micro_benchmark/signal_gen/clock_divider.v b/openfpga_flow/benchmarks/micro_benchmark/signal_gen/clock_divider.v new file mode 100644 index 000000000..3cb3f9899 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/signal_gen/clock_divider.v @@ -0,0 +1,50 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 05/03/2021 03:25:29 PM +// Design Name: +// Module Name: clk_divider +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + +// Uncomment if using Vivado to synthesize the design. This will enable the initial block +// If using Yosys, initial blocks are not supported, and cannot be included. +// `define VIVADO_SYNTHESIS + +module clock_divider ( + input clk_in, + output reg clk_out + ); + + parameter CLK_DIVIDER_SIZE=8; + + reg [CLK_DIVIDER_SIZE - 1:0] clkdiv_counter; + +`ifdef VIVADO_SYNTHESIS + initial begin + clkdiv_counter <= 0; + clk_out <= 0; + end +`endif + + // Divide pl_clk (50MHz) to 1MHz + always @(posedge clk_in) begin + if (clkdiv_counter == 1 << CLK_DIVIDER_SIZE - 1) begin + clk_out <= ~clk_out; + end + clkdiv_counter <= clkdiv_counter +1; + end + +endmodule diff --git a/openfpga_flow/benchmarks/micro_benchmark/signal_gen/pulse_generator.v b/openfpga_flow/benchmarks/micro_benchmark/signal_gen/pulse_generator.v new file mode 100644 index 000000000..1f092e6a0 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/signal_gen/pulse_generator.v @@ -0,0 +1,82 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 05/03/2021 03:37:44 PM +// Design Name: +// Module Name: pulse_generator +// Project Name: +// Target Devices: +// Tool Versions: +// Description: A simple pulse generator with configurable initial values and waiting cycles +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + +// Uncomment if using Vivado to synthesize the design. This will enable the initial block +// If using Yosys, initial blocks are not supported, and cannot be included. +// `define VIVADO_SYNTHESIS + +module pulse_generator( + input clk_in, + input repeated, // Specify if the pulse should be generated repeatedly + output reg pulse + ); + + + parameter INITIAL_VALUE=0; // Define the initial value for the pulse, either 0 or 1; The pulse logic level will be a flip over the initial value + parameter WAIT_CYCLES=0; // Define the number of clock cycles to wait before the pulse is applied + parameter PULSE_WIDTH=1; // Define the length of the pulse width + parameter PULSE_COUNTER_SIZE=10; // Define the size of the pulse width counter + + reg [WAIT_CYCLES<=2 ? 2 : $clog2(WAIT_CYCLES) : 0] wait_cycle_counter; // Size of wait counter is determined by WAIT_CYCLES + reg [PULSE_COUNTER_SIZE - 1 : 0] pulse_width_counter; + reg pulse_start; + reg pulse_end; + +`ifdef VIVADO_SYNTHESIS + initial begin + pulse <= INITIAL_VALUE; + pulse_start <= 1'b0; + pulse_end <= 1'b0; + wait_cycle_counter <= 0; + pulse_width_counter <= 0; + end +`endif + + // Wait a number of clock cycles, hold the initial value + always @(posedge clk_in) begin + if (wait_cycle_counter == WAIT_CYCLES) begin + pulse_start <= 1'b1; + end + if (~pulse_start) begin + wait_cycle_counter <= wait_cycle_counter + 1; + end + end + + // Wait a number of clock cycles, hold the initial value + always @(posedge clk_in) begin + pulse <= INITIAL_VALUE; + if (pulse_start && ~pulse_end) begin + // Reach the pulse width limit, stop counting + if (pulse_width_counter < PULSE_WIDTH) begin + pulse <= ~INITIAL_VALUE; + if (~repeated) begin + pulse_end = 1'b1; + end + end + // When pulse ends, flip to initial value + if (pulse_end) begin + pulse <= INITIAL_VALUE; + end + pulse_width_counter <= pulse_width_counter + 1; + end + end + +endmodule diff --git a/openfpga_flow/benchmarks/micro_benchmark/signal_gen/reset_generator.v b/openfpga_flow/benchmarks/micro_benchmark/signal_gen/reset_generator.v new file mode 100644 index 000000000..bbb73e440 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/signal_gen/reset_generator.v @@ -0,0 +1,53 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 05/03/2021 04:52:18 PM +// Design Name: +// Module Name: reset_generator +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + +// Uncomment if using Vivado to synthesize the design. This will enable the initial block +// If using Yosys, initial blocks are not supported, and cannot be included. +// `define VIVADO_SYNTHESIS + +module reset_generator( + input clk, + output reg pulse + ); + + parameter INITIAL_VALUE=0; // Define the initial value for the pulse, either 0 or 1; The pulse logic level will be a flip over the initial value + parameter ACTIVE_CYCLES=0; // Define the number of clock cycles to wait before the pulse is applied + + reg [ACTIVE_CYCLES<=2 ? 2 : $clog2(ACTIVE_CYCLES) - 1 : 0] active_cycle_counter; + +`ifdef VIVADO_SYNTHESIS + initial begin + clkdiv_counter <= 0; + active_cycle_counter <= 0; + pulse <= INITIAL_VALUE; + end +`endif + + // Wait a number of clock cycles, hold the initial value + always @(posedge clk) begin + if (active_cycle_counter == ACTIVE_CYCLES) begin + pulse <= ~pulse; + end else begin + active_cycle_counter <= active_cycle_counter + 1; + end + end + +endmodule diff --git a/openfpga_flow/regression_test_scripts/micro_benchmark_reg_test.sh b/openfpga_flow/regression_test_scripts/micro_benchmark_reg_test.sh index 28b24aef3..5f958e261 100755 --- a/openfpga_flow/regression_test_scripts/micro_benchmark_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/micro_benchmark_reg_test.sh @@ -15,3 +15,5 @@ run-task benchmark_sweep/mac_units --debug --show_thread_logs # Otherwise, it will fail run-task benchmark_sweep/mcnc_big20 --debug --show_thread_logs #python3 openfpga_flow/scripts/run_modelsim.py mcnc_big20 --run_sim + +run-task benchmark_sweep/signal_gen --debug --show_thread_logs diff --git a/openfpga_flow/tasks/benchmark_sweep/signal_gen/config/task.conf b/openfpga_flow/tasks/benchmark_sweep/signal_gen/config/task.conf new file mode 100644 index 000000000..9ada9e960 --- /dev/null +++ b/openfpga_flow/tasks/benchmark_sweep/signal_gen/config/task.conf @@ -0,0 +1,44 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = true +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/write_full_testbench_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout= +openfpga_fast_configuration= + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/signal_gen/clock_divider.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/signal_gen/pulse_generator.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/signal_gen/reset_generator.v + +[SYNTHESIS_PARAM] +bench0_top = clock_divider +bench0_chan_width = 300 + +bench1_top = pulse_generator +bench1_chan_width = 300 + +bench2_top = reset_generator +bench2_chan_width = 300 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test=