diff --git a/example_projects/gowin_fmax_test_prj_template_v1/.gitignore b/example_projects/gowin_fmax_test_prj_template_v1/.gitignore
new file mode 100755
index 0000000..f477cea
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/.gitignore
@@ -0,0 +1,21 @@
+#------------------------------------------------------------------------------
+# .gitignore for Gowin IDE
+# Konstantin Pavlov, pavlovconst@gmail.com
+#------------------------------------------------------------------------------
+
+# INFO ------------------------------------------------------------------------
+# rename the file to ".gitignore" and place into your Gowin project directory
+#
+
+
+# junk files
+*.gprj.user
+impl/gwsynthesis/*.html
+impl/gwsynthesis/*.xml
+impl/gwsynthesis/*.log
+impl/gwsynthesis/*.vg
+
+# junk directories
+/impl/pnr
+/impl/temp
+
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/clean_gowin.bat b/example_projects/gowin_fmax_test_prj_template_v1/clean_gowin.bat
new file mode 100755
index 0000000..10eda8b
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/clean_gowin.bat
@@ -0,0 +1,28 @@
+@echo off
+rem ------------------------------------------------------------------------------
+rem clean_gowin.bat
+rem published as part of https://github.com/pConst/basic_verilog
+rem Konstantin Pavlov, pavlovconst@gmail.com
+rem ------------------------------------------------------------------------------
+
+rem Use this file as a boilerplate for your custom clean script
+rem for Gowin IDE projects
+
+
+rem preserving .\impl\gwsynthesis\test.prj file
+del /s /f /q .\impl\gwsynthesis\*.html
+del /s /f /q .\impl\gwsynthesis\*.xml
+del /s /f /q .\impl\gwsynthesis\*.log
+del /s /f /q .\impl\gwsynthesis\*.vg
+
+del /s /f /q .\impl\pnr\*
+rmdir /s /q .\impl\pnr\
+
+del /s /f /q .\impl\temp\*
+rmdir /s /q .\impl\temp\
+
+del /s /f /q .*.gprj.user
+
+pause
+goto :eof
+
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/impl/gwsynthesis/test.prj b/example_projects/gowin_fmax_test_prj_template_v1/impl/gwsynthesis/test.prj
new file mode 100755
index 0000000..31e62ff
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/impl/gwsynthesis/test.prj
@@ -0,0 +1,23 @@
+
+
+
+ beta
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/impl/project_process_config.json b/example_projects/gowin_fmax_test_prj_template_v1/impl/project_process_config.json
new file mode 100755
index 0000000..5c7e9f1
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/impl/project_process_config.json
@@ -0,0 +1,80 @@
+{
+ "Allow_Duplicate_Modules" : false,
+ "Annotated_Properties_for_Analyst" : true,
+ "BACKGROUND_PROGRAMMING" : "off",
+ "COMPRESS" : false,
+ "CRC_CHECK" : true,
+ "Clock_Conversion" : true,
+ "DONE" : false,
+ "DOWNLOAD_SPEED" : "default",
+ "Default_Enum_Encoding" : "default",
+ "Disable_Insert_Pad" : false,
+ "ENCRYPTION_KEY" : false,
+ "ENCRYPTION_KEY_TEXT" : "00000000000000000000000000000000",
+ "FORMAT" : "binary",
+ "FSM Compiler" : true,
+ "Fanout_Guide" : 10000,
+ "Frequency" : "Auto",
+ "Generate_Constraint_File_of_Ports" : false,
+ "Generate_IBIS_File" : false,
+ "Generate_Plain_Text_Timing_Report" : false,
+ "Generate_Post_PNR_Simulation_Model_File" : false,
+ "Generate_Post_Place_File" : false,
+ "Generate_SDF_File" : false,
+ "GwSyn_Loop_Limit" : 2000,
+ "HOTBOOT" : false,
+ "I2C" : false,
+ "I2C_SLAVE_ADDR" : "00",
+ "Implicit_Initial_Value_Support" : false,
+ "IncludePath" : [
+
+ ],
+ "Incremental_Compile" : "",
+ "Initialize_Primitives" : false,
+ "JTAG" : false,
+ "MODE_IO" : false,
+ "MSPI" : false,
+ "Multiple_File_Compilation_Unit" : true,
+ "Number_of_Critical_Paths" : "",
+ "Number_of_Start/End_Points" : "",
+ "OUTPUT_BASE_NAME" : "test",
+ "POWER_ON_RESET" : false,
+ "PRINT_BSRAM_VALUE" : true,
+ "PROGRAM_DONE_BYPASS" : false,
+ "Pipelining" : true,
+ "PlaceInRegToIob" : true,
+ "PlaceIoRegToIob" : true,
+ "PlaceOutRegToIob" : true,
+ "Place_Option" : "0",
+ "Process_Configuration_Verion" : "1.0",
+ "Promote_Physical_Constraint_Warning_to_Error" : true,
+ "Push_Tristates" : true,
+ "READY" : false,
+ "RECONFIG_N" : false,
+ "Ram_RW_Check" : true,
+ "Report_Auto-Placed_Io_Information" : false,
+ "Resolve_Mixed_Drivers" : false,
+ "Resource_Sharing" : true,
+ "Retiming" : false,
+ "Route_Option" : "0",
+ "Run_Timing_Driven" : true,
+ "SECURE_MODE" : false,
+ "SECURITY_BIT" : true,
+ "SPI_FLASH_ADDR" : "00000000",
+ "SSPI" : false,
+ "Show_All_Warnings" : false,
+ "Synthesis On/Off Implemented as Translate On/Off" : false,
+ "Synthesize_tool" : "GowinSyn",
+ "TopModule" : "",
+ "USERCODE" : "default",
+ "Unused_Pin" : "As_input_tri_stated_with_pull_up",
+ "Update_Compile_Point_Timing_Data" : false,
+ "Use_Clock_Period_for_Unconstrainted IO" : false,
+ "Use_SCF" : false,
+ "VHDL_Standard" : "VHDL_Std_1993",
+ "Verilog_Standard" : "Vlg_Std_Sysv2017",
+ "WAKE_UP" : "0",
+ "Write_Vendor_Constraint_File" : true,
+ "dsp_balance" : false,
+ "show_all_warnings" : false
+}
\ No newline at end of file
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll.ipc b/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll.ipc
new file mode 100755
index 0000000..72406bb
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll.ipc
@@ -0,0 +1,24 @@
+[General]
+ipc_version=4
+file=sys_pll
+module=sys_pll
+target_device=gw1nr9c-004
+type=clock_rpll
+version=1.0
+
+[Config]
+CKLOUTD3=false
+CLKFB_SOURCE=0
+CLKIN_FREQ=27
+CLKOUTD=false
+CLKOUTP=false
+CLKOUT_BYPASS=false
+CLKOUT_DIVIDE_DYN=true
+CLKOUT_FREQ=250
+CLKOUT_TOLERANCE=3
+DYNAMIC=false
+LANG=0
+LOCK_EN=true
+MODE_GENERAL=true
+PLL_PWD=false
+RESET_PLL=false
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll.mod b/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll.mod
new file mode 100755
index 0000000..639fbe4
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll.mod
@@ -0,0 +1,31 @@
+-series GW1NR
+-device GW1NR-9C
+-package QFN88P
+-part_number GW1NR-LV9QN88PC6/I5
+
+
+-mod_name sys_pll
+-file_name sys_pll
+-path J:/fpga_tests/fifo_single_clock_reg_v2_test_gw/ip/sys_pll/
+-type PLL
+-rPll true
+-file_type vlg
+-dev_type GW1NR-9C
+-dyn_idiv_sel false
+-idiv_sel 4
+-dyn_fbdiv_sel false
+-fbdiv_sel 37
+-dyn_odiv_sel false
+-odiv_sel 2
+-dyn_da_en false
+-rst_sig false
+-rst_sig_p false
+-fclkin 27
+-clkfb_sel 0
+-en_lock true
+-clkout_bypass false
+-en_clkoutp false
+-clkoutp_bypass false
+-en_clkoutd false
+-clkoutd_bypass false
+-en_clkoutd3 false
\ No newline at end of file
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll.v b/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll.v
new file mode 100755
index 0000000..351fef6
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll.v
@@ -0,0 +1,63 @@
+//Copyright (C)2014-2022 Gowin Semiconductor Corporation.
+//All rights reserved.
+//File Title: IP file
+//GOWIN Version: V1.9.8.05
+//Part Number: GW1NR-LV9QN88PC6/I5
+//Device: GW1NR-9C
+//Created Time: Sun May 15 09:43:06 2022
+
+module sys_pll (clkout, lock, clkin);
+
+output clkout;
+output lock;
+input clkin;
+
+wire clkoutp_o;
+wire clkoutd_o;
+wire clkoutd3_o;
+wire gw_gnd;
+
+assign gw_gnd = 1'b0;
+
+rPLL rpll_inst (
+ .CLKOUT(clkout),
+ .LOCK(lock),
+ .CLKOUTP(clkoutp_o),
+ .CLKOUTD(clkoutd_o),
+ .CLKOUTD3(clkoutd3_o),
+ .RESET(gw_gnd),
+ .RESET_P(gw_gnd),
+ .CLKIN(clkin),
+ .CLKFB(gw_gnd),
+ .FBDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
+ .IDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
+ .ODSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
+ .PSDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
+ .DUTYDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
+ .FDLY({gw_gnd,gw_gnd,gw_gnd,gw_gnd})
+);
+
+defparam rpll_inst.FCLKIN = "27";
+defparam rpll_inst.DYN_IDIV_SEL = "false";
+defparam rpll_inst.IDIV_SEL = 3;
+defparam rpll_inst.DYN_FBDIV_SEL = "false";
+defparam rpll_inst.FBDIV_SEL = 36;
+defparam rpll_inst.DYN_ODIV_SEL = "false";
+defparam rpll_inst.ODIV_SEL = 2;
+defparam rpll_inst.PSDA_SEL = "0000";
+defparam rpll_inst.DYN_DA_EN = "false";
+defparam rpll_inst.DUTYDA_SEL = "1000";
+defparam rpll_inst.CLKOUT_FT_DIR = 1'b1;
+defparam rpll_inst.CLKOUTP_FT_DIR = 1'b1;
+defparam rpll_inst.CLKOUT_DLY_STEP = 0;
+defparam rpll_inst.CLKOUTP_DLY_STEP = 0;
+defparam rpll_inst.CLKFB_SEL = "internal";
+defparam rpll_inst.CLKOUT_BYPASS = "false";
+defparam rpll_inst.CLKOUTP_BYPASS = "false";
+defparam rpll_inst.CLKOUTD_BYPASS = "false";
+defparam rpll_inst.DYN_SDIV_SEL = 2;
+defparam rpll_inst.CLKOUTD_SRC = "CLKOUT";
+defparam rpll_inst.CLKOUTD3_SRC = "CLKOUT";
+defparam rpll_inst.DEVICE = "GW1NR-9C";
+
+endmodule //sys_pll
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll_tmp.v b/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll_tmp.v
new file mode 100755
index 0000000..ca5c1d1
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/ip/sys_pll/sys_pll_tmp.v
@@ -0,0 +1,18 @@
+//Copyright (C)2014-2022 Gowin Semiconductor Corporation.
+//All rights reserved.
+//File Title: Template file for instantiation
+//GOWIN Version: V1.9.8.05
+//Part Number: GW1NR-LV9QN88PC6/I5
+//Device: GW1NR-9C
+//Created Time: Sun May 15 09:43:06 2022
+
+//Change the instance name and port connections to the signal names
+//--------Copy here to design--------
+
+ sys_pll your_instance_name(
+ .clkout(clkout_o), //output clkout
+ .lock(lock_o), //output lock
+ .clkin(clkin_i) //input clkin
+ );
+
+//--------Copy end-------------------
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/src/clk_divider.sv b/example_projects/gowin_fmax_test_prj_template_v1/src/clk_divider.sv
new file mode 100755
index 0000000..5e25735
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/src/clk_divider.sv
@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------
+// clk_divider.sv
+// published as part of https://github.com/pConst/basic_verilog
+// Konstantin Pavlov, pavlovconst@gmail.com
+//------------------------------------------------------------------------------
+
+// INFO ------------------------------------------------------------------------
+// Divides main clock to get derivative slower synchronous clocks
+//
+
+/* --- INSTANTIATION TEMPLATE BEGIN ---
+
+clk_divider #(
+ .WIDTH( 32 )
+) CD1 (
+ .clk( clk ),
+ .nrst( 1'b1 ),
+ .ena( 1'b1 ),
+ .out( )
+);
+
+--- INSTANTIATION TEMPLATE END ---*/
+
+
+module clk_divider #( parameter
+ WIDTH = 32
+)(
+ input clk,
+ input nrst,
+ input ena,
+ output logic [(WIDTH-1):0] out = '0
+);
+
+
+always_ff @(posedge clk) begin
+ if ( ~nrst ) begin
+ out[(WIDTH-1):0] <= '0;
+ end else if (ena) begin
+ out[(WIDTH-1):0] <= out[(WIDTH-1):0] + 1'b1;
+ end
+end
+
+endmodule
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/src/clogb2.svh b/example_projects/gowin_fmax_test_prj_template_v1/src/clogb2.svh
new file mode 100755
index 0000000..5c7336e
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/src/clogb2.svh
@@ -0,0 +1,24 @@
+//------------------------------------------------------------------------------
+// clogb2.svh
+// published as part of https://github.com/pConst/basic_verilog
+// Konstantin Pavlov, pavlovconst@gmail.com
+//------------------------------------------------------------------------------
+
+// INFO ------------------------------------------------------------------------
+// Calculates counter/address width based on specified vector/RAM depth
+//
+// Function should be instantiated inside a module
+// But you are free to call it from anywhere by its hierarchical name
+//
+// To add clogb2 function to your module:
+// `include "clogb2.svh"
+//
+
+function integer clogb2;
+ input integer depth;
+
+ for( clogb2=0; depth>0; clogb2=clogb2+1 ) begin
+ depth = depth >> 1;
+ end
+endfunction
+
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/src/define.svh b/example_projects/gowin_fmax_test_prj_template_v1/src/define.svh
new file mode 100755
index 0000000..4f63580
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/src/define.svh
@@ -0,0 +1,32 @@
+//------------------------------------------------------------------------------
+// Gowin test project template
+// published as part of https://github.com/pConst/basic_verilog
+// Konstantin Pavlov, pavlovconst@gmail.com
+//------------------------------------------------------------------------------
+
+
+// Vivado bugfix ===============================================================
+
+ // This is a workaround for Vivado bug of not providing errors
+ // when using undeclared signals in your code
+ // See https://forums.xilinx.com/t5/Synthesis/Bug-in-handling-undeclared-signals-in-instance-statement-named/td-p/300127
+ //`define VIVADO_MODULE_HEADER `default_nettype none
+ //`define VIVADO_MODULE_FOOTER `default_nettype wire
+
+ // Declare these stubs to safely reuse your Vivado modules in non-Xilinx FPGA projects
+ `define VIVADO_MODULE_HEADER
+ `define VIVADO_MODULE_FOOTER
+
+// =============================================================================
+
+ `define INC( AVAL ) \
+ ``AVAL <= ``AVAL + 1'b1;
+
+ `define DEC( AVAL ) \
+ ``AVAL <= ``AVAL - 1'b1;
+
+ `define SET( AVAL ) \
+ ``AVAL <= 1'b1;
+
+ `define RESET( AVAL ) \
+ ``AVAL <= 1'b0;
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/src/delay.sv b/example_projects/gowin_fmax_test_prj_template_v1/src/delay.sv
new file mode 100755
index 0000000..3d7b69f
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/src/delay.sv
@@ -0,0 +1,211 @@
+//------------------------------------------------------------------------------
+// delay.sv
+// published as part of https://github.com/pConst/basic_verilog
+// Konstantin Pavlov, pavlovconst@gmail.com
+//------------------------------------------------------------------------------
+
+// INFO -------------------------------------------------------------------------
+// Static Delay for arbitrary signal, v2
+// Another equivalent names for this module:
+// conveyor.sv
+// synchronizer.sv
+//
+// Tip for Xilinx-based implementations: Leave nrst=1'b1 and ena=1'b1 on
+// purpose of inferring Xilinx`s SRL16E/SRL32E primitives
+//
+// CAUTION: delay module is widely used for synchronizing signals across clock
+// domains. When synchronizing, please exclude input data paths from timing
+// analysis manually by writing appropriate set_false_path SDC constraint
+//
+// Version 2 introduces "ALTERA_BLOCK_RAM" option to implement delays using
+// block RAM. Quartus can make shifters on block RAM automatically
+// using 'altshift_taps' internal module when "Auto Shift Register
+// Replacement" option is ON
+//
+
+/* --- INSTANTIATION TEMPLATE BEGIN ---
+
+delay #(
+ .LENGTH( 2 ),
+ .WIDTH( 1 ),
+ .TYPE( "CELLS" ),
+ .REGISTER_OUTPUTS( "FALSE" )
+) S1 (
+ .clk( clk ),
+ .nrst( 1'b1 ),
+ .ena( 1'b1 ),
+
+ .in( ),
+ .out( )
+);
+
+--- INSTANTIATION TEMPLATE END ---*/
+
+
+module delay #( parameter
+ LENGTH = 2, // delay/synchronizer chain length
+ WIDTH = 1, // signal width
+
+ TYPE = "CELLS", // "ALTERA_BLOCK_RAM" infers block ram fifo
+ // "ALTERA_TAPS" infers altshift_taps
+ // all other values infer registers
+
+ REGISTER_OUTPUTS = "FALSE", // for block RAM implementations: "TRUE" means that
+ // last delay stage will be implemented
+ // by means of cell registers to improve timing
+ // all other values infer block RAMs only
+
+ CNTR_W = $clog2(LENGTH)
+)(
+ input clk,
+ input nrst,
+ input ena,
+
+ input [WIDTH-1:0] in,
+ output [WIDTH-1:0] out
+);
+
+generate
+
+ if ( LENGTH == 0 ) begin
+
+ assign out[WIDTH-1:0] = in[WIDTH-1:0];
+
+ end else if( LENGTH == 1 ) begin
+
+ logic [WIDTH-1:0] data = '0;
+ always_ff @(posedge clk) begin
+ if( ~nrst ) begin
+ data[WIDTH-1:0] <= '0;
+ end else if( ena ) begin
+ data[WIDTH-1:0] <= in[WIDTH-1:0];
+ end
+ end
+ assign out[WIDTH-1:0] = data[WIDTH-1:0];
+
+ end else begin
+ if( TYPE=="ALTERA_BLOCK_RAM" && LENGTH>=3 ) begin
+
+ logic [WIDTH-1:0] fifo_out;
+ logic full;
+ logic [CNTR_W-1:0] usedw;
+
+ logic fifo_out_ena;
+ if( REGISTER_OUTPUTS=="TRUE" ) begin
+ assign fifo_out_ena = (usedw[CNTR_W-1:0] == LENGTH-1);
+ end else begin
+ assign fifo_out_ena = full;
+ end
+
+ scfifo #(
+ .LPM_WIDTH( WIDTH ),
+ .LPM_NUMWORDS( LENGTH ), // must be at least 4
+ .LPM_WIDTHU( CNTR_W ),
+ .LPM_SHOWAHEAD( "ON" ),
+ .UNDERFLOW_CHECKING( "ON" ),
+ .OVERFLOW_CHECKING( "ON" ),
+ .ENABLE_ECC( "FALSE" ),
+ .ALLOW_RWCYCLE_WHEN_FULL( "ON" ),
+ .USE_EAB( "ON" )
+ ) internal_fifo (
+ .clock( clk ),
+ .aclr( 1'b0 ),
+ .sclr( ~nrst ),
+
+ .data( in[WIDTH-1:0] ),
+ .wrreq( ena ),
+ .rdreq( ena && fifo_out_ena ),
+
+ .q( fifo_out[WIDTH-1:0] ),
+ .empty( ),
+ .full( full ),
+ .almost_full( ),
+ .almost_empty( ),
+ .usedw( usedw[CNTR_W-1:0] ),
+ .eccstatus( )
+ );
+
+ logic [WIDTH-1:0] reg_out = '0;
+ always_ff @(posedge clk) begin
+ if( ~nrst ) begin
+ reg_out[WIDTH-1:0] <= '0;
+ end else if( ena && fifo_out_ena ) begin
+ reg_out[WIDTH-1:0] <= fifo_out[WIDTH-1:0];
+ end
+ end
+
+ if( REGISTER_OUTPUTS=="TRUE" ) begin
+ assign out[WIDTH-1:0] = reg_out[WIDTH-1:0];
+ end else begin
+ // avoiding first word fall-through
+ assign out[WIDTH-1:0] = (fifo_out_ena)?(fifo_out[WIDTH-1:0]):('0);
+ end
+
+ end else if( TYPE=="ALTERA_TAPS" && LENGTH>=2 ) begin
+
+ logic [WIDTH-1:0] fifo_out;
+ logic [CNTR_W-1:0] delay_cntr = CNTR_W'(LENGTH-1);
+
+ logic fifo_out_ena;
+ assign fifo_out_ena = (delay_cntr[CNTR_W-1:0] == '0);
+
+ always_ff @(posedge clk) begin
+ if( ~nrst ) begin
+ delay_cntr[CNTR_W-1:0] <= CNTR_W'(LENGTH-1);
+ end else if( ena && ~fifo_out_ena ) begin
+ delay_cntr[CNTR_W-1:0] <= delay_cntr[CNTR_W-1:0] - 1'b1;
+ end
+ end
+
+ altshift_taps #(
+ .intended_device_family( "Cyclone V" ),
+ .lpm_hint( "RAM_BLOCK_TYPE=AUTO" ),
+ .lpm_type( "altshift_taps" ),
+ .number_of_taps( 1 ),
+ .tap_distance( (REGISTER_OUTPUTS=="TRUE")?(LENGTH-1):(LENGTH) ), // min. of 3
+ .width( WIDTH )
+ ) internal_taps (
+ //.aclr( 1'b0 ),
+ //.sclr( ~nrst ),
+ .clock( clk ),
+ .clken( ena ),
+ .shiftin( in[WIDTH-1:0] ),
+ .shiftout( fifo_out[WIDTH-1:0] )
+ );
+
+ if( REGISTER_OUTPUTS=="TRUE" ) begin
+ logic [WIDTH-1:0] reg_out = '0;
+ always_ff @(posedge clk) begin
+ if( ~nrst ) begin
+ reg_out[WIDTH-1:0] <= '0;
+ end else if( ena && fifo_out_ena ) begin
+ reg_out[WIDTH-1:0] <= fifo_out[WIDTH-1:0];
+ end
+ end
+ assign out[WIDTH-1:0] = reg_out[WIDTH-1:0];
+ end else begin
+ assign out[WIDTH-1:0] = fifo_out[WIDTH-1:0];
+ end
+
+ end else begin
+
+ logic [LENGTH:1][WIDTH-1:0] data = '0;
+ always_ff @(posedge clk) begin
+ integer i;
+ if( ~nrst ) begin
+ data <= '0;
+ end else if( ena ) begin
+ for(i=LENGTH-1; i>0; i--) begin
+ data[i+1][WIDTH-1:0] <= data[i][WIDTH-1:0];
+ end
+ data[1][WIDTH-1:0] <= in[WIDTH-1:0];
+ end
+ end
+ assign out[WIDTH-1:0] = data[LENGTH][WIDTH-1:0];
+
+ end // if TYPE
+ end // if LENGTH
+
+endgenerate
+
+endmodule
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/src/edge_detect.sv b/example_projects/gowin_fmax_test_prj_template_v1/src/edge_detect.sv
new file mode 100755
index 0000000..8c3bed3
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/src/edge_detect.sv
@@ -0,0 +1,100 @@
+//------------------------------------------------------------------------------
+// edge_detect.sv
+// published as part of https://github.com/pConst/basic_verilog
+// Konstantin Pavlov, pavlovconst@gmail.com
+//------------------------------------------------------------------------------
+
+// INFO ------------------------------------------------------------------------
+// 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)
+//
+// In case when "in" port has toggle rate 100% (changes every clock period)
+// "rising" and "falling" outputs will completely replicate input
+// "both" output will be always active in this case
+//
+
+
+/* --- INSTANTIATION TEMPLATE BEGIN ---
+
+edge_detect #(
+ .WIDTH( 32 ),
+ .REGISTER_OUTPUTS( 1'b1 )
+) in_ed (
+ .clk( clk ),
+ .anrst( 1'b1 ),
+ .in( in[31:0] ),
+ .rising( in_rise[31:0] ),
+ .falling( ),
+ .both( )
+);
+
+--- INSTANTIATION TEMPLATE END ---*/
+
+
+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 anrst,
+
+ 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 [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[WIDTH-1:0] <= in[WIDTH-1:0];
+ end
+end
+
+logic [WIDTH-1:0] rising_comb;
+logic [WIDTH-1:0] falling_comb;
+logic [WIDTH-1:0] both_comb;
+always_comb begin
+ 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==1'b0 ) begin
+
+ // combinational outputs, no delay
+ always_comb begin
+ 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 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[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
+
+ end // end else
+endgenerate
+
+endmodule
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/src/main.sdc b/example_projects/gowin_fmax_test_prj_template_v1/src/main.sdc
new file mode 100755
index 0000000..224ec9c
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/src/main.sdc
@@ -0,0 +1,9 @@
+#------------------------------------------------------------------------------
+# Gowin test project template
+# published as part of https://github.com/pConst/basic_verilog
+# Konstantin Pavlov, pavlovconst@gmail.com
+#------------------------------------------------------------------------------
+
+# main reference clock, 27 MHz
+create_clock -period 37.037-waveform { 0.000 18.518 } [get_ports {clk27}]
+
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/src/main.sv b/example_projects/gowin_fmax_test_prj_template_v1/src/main.sv
new file mode 100755
index 0000000..7fdf7d6
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/src/main.sv
@@ -0,0 +1,131 @@
+//------------------------------------------------------------------------------
+// Gowin test project template
+// published as part of https://github.com/pConst/basic_verilog
+// Konstantin Pavlov, pavlovconst@gmail.com
+//------------------------------------------------------------------------------
+
+// INFO ------------------------------------------------------------------------
+// Gowin IDE test project template, v1
+// Compatible with Tang Nano 9K board
+//
+// - use this as a boilerplate project for fast prototyping
+// - inputs and outputs are registered to allow valid timequest output
+// even if your custom logic/IPs have combinational outputs
+// - SDC constraint file assigns clk to 500MHz to force fitter to synthesize
+// the fastest possible circuit
+//
+
+`timescale 1ns / 1ps
+
+`include "define.svh"
+
+
+`define WIDTH 16
+
+module main(
+ input clk27,
+
+ input [1:0] key,
+ output [5:0] led,
+
+ input [`WIDTH-1:0] in_data,
+ output logic [`WIDTH-1:0] out_data
+);
+
+
+// clocks ======================================================================
+
+logic sys_pll_locked; // asyn
+logic clk250;
+
+logic nrst;
+
+sys_pll sys_pll_b (
+ .clkin( clk27 ),
+ .clkout( clk250 ),
+ .lock( sys_pll_locked )
+);
+
+assign led[0] = sys_pll_locked;
+
+logic [31:0] div_clk250;
+clk_divider #(
+ .WIDTH( 32 )
+) cd_500 (
+ .clk( clk250 ),
+ .nrst( nrst ),
+ .ena( 1'b1 ),
+ .out( div_clk250[31:0] )
+);
+
+assign led[1] = div_clk250[27];
+
+// nrst ========================================================================
+logic [1:0] key_s;
+
+always_ff @(posedge clk250) begin
+ nrst <= ~key_s[0]; // external reset
+end
+
+assign led[2] = ~key_s[0];
+assign led[3] = ~key_s[1];
+
+// buttons =====================================================================
+
+delay #(
+ .LENGTH( 2 ),
+ .WIDTH( 2 )
+) sw_SYNC_ATTR (
+ .clk( clk250 ),
+ .nrst( 1'b1 ), // dont use nrst here!
+ .ena( 1'b1 ),
+ .in( ~key[1:0] ),
+ .out( key_s[1:0] )
+);
+
+logic [1:0] key_s_rise;
+logic [1:0] key_s_fall;
+
+edge_detect #(
+ .WIDTH( 2 )
+) sw_s_ed (
+ .clk( clk250 ),
+ .anrst( 1'b1 ),
+ .in( key_s[1:0] ),
+ .rising( key_s_rise[1:0] ),
+ .falling( key_s_fall[1:0] ),
+ .both( )
+);
+
+// =============================================================================
+
+// input registers
+logic [`WIDTH-1:0] in_data_reg = 0;
+always_ff @(posedge clk250) begin
+ if( ~nrst ) begin
+ in_data_reg[`WIDTH-1:0] <= '0;
+ end else begin
+ in_data_reg[`WIDTH-1:0] <= in_data[`WIDTH-1:0];
+ end
+end
+
+// place your test logic here ==================================================
+
+logic [`WIDTH-1:0] out_data_comb = 0;
+always_comb begin
+ out_data_comb[`WIDTH-1:0] <= in_data_reg[`WIDTH-1:0] ^ div_clk250[31:0];
+end
+
+// output registers
+always_ff @(posedge clk250) begin
+ if( ~nrst ) begin
+ out_data[`WIDTH-1:0] <= 0;
+ end else begin
+ out_data[`WIDTH-1:0] <= out_data_comb[`WIDTH-1:0];
+ end
+end
+
+`include "clogb2.svh"
+
+endmodule
+
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/src/test.cst b/example_projects/gowin_fmax_test_prj_template_v1/src/test.cst
new file mode 100755
index 0000000..4f4b21e
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/src/test.cst
@@ -0,0 +1,26 @@
+#------------------------------------------------------------------------------
+# Gowin test project template
+# published as part of https://github.com/pConst/basic_verilog
+# Konstantin Pavlov, pavlovconst@gmail.com
+#------------------------------------------------------------------------------
+
+IO_LOC "led[5]" 16;
+IO_PORT "led[5]" PULL_MODE=UP DRIVE=8;
+IO_LOC "led[4]" 15;
+IO_PORT "led[4]" PULL_MODE=UP DRIVE=8;
+IO_LOC "led[3]" 14;
+IO_PORT "led[3]" PULL_MODE=UP DRIVE=8;
+IO_LOC "led[2]" 13;
+IO_PORT "led[2]" PULL_MODE=UP DRIVE=8;
+IO_LOC "led[1]" 11;
+IO_PORT "led[1]" PULL_MODE=UP DRIVE=8;
+IO_LOC "led[0]" 10;
+IO_PORT "led[0]" PULL_MODE=UP DRIVE=8;
+
+IO_LOC "key[0]" 4;
+IO_PORT "key[0]" PULL_MODE=UP;
+IO_LOC "key[1]" 3;
+IO_PORT "key[1]" PULL_MODE=UP;
+
+IO_LOC "clk27" 52;
+IO_PORT "clk27" IO_TYPE=LVCMOS33 PULL_MODE=UP;
diff --git a/example_projects/gowin_fmax_test_prj_template_v1/test.gprj b/example_projects/gowin_fmax_test_prj_template_v1/test.gprj
new file mode 100755
index 0000000..880a8fa
--- /dev/null
+++ b/example_projects/gowin_fmax_test_prj_template_v1/test.gprj
@@ -0,0 +1,18 @@
+
+
+
+ FPGA
+ 5
+ gw1nr9c-004
+
+
+
+
+
+
+
+
+
+
+
+