diff --git a/openfpga_flow/benchmarks/config_loader/bitstream_loader.v b/openfpga_flow/benchmarks/config_loader/bitstream_loader.v new file mode 100644 index 000000000..68b04aee1 --- /dev/null +++ b/openfpga_flow/benchmarks/config_loader/bitstream_loader.v @@ -0,0 +1,195 @@ +`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; + + RAMB18E1 #( + // Address Collision Mode: "PERFORMANCE" or "DELAYED_WRITE" + .RDADDR_COLLISION_HWCONFIG("DELAYED_WRITE"), + // Collision check: Values ("ALL", "WARNING_ONLY", "GENERATE_X_ONLY" or "NONE") + .SIM_COLLISION_CHECK("ALL"), + // RAM Mode: "SDP" or "TDP" + .RAM_MODE("TDP"), + // READ_WIDTH_A/B, WRITE_WIDTH_A/B: Read/write width per port + .READ_WIDTH_A(1), // 0-72 + .READ_WIDTH_B(0), // 0-18 + .WRITE_WIDTH_A(0), // 0-18 + .WRITE_WIDTH_B(0), // 0-72 + + .INIT_00(256'h00000000000000000000000000000000000000000000007f00000000000000ff), + .INIT_01(256'h0000fff8ffffffff000000000000000000000000000000000000000000000000), + .INIT_02(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_03(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_04(256'h00000003f8000000000000000000000000000000000000000000000000000000), + .INIT_05(256'h0000000000000000078000000000000000000000000000000000000000000000), + .INIT_06(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_07(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_08(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_09(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_0A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_0B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_0C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_0D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_0E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_0F(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), + .INIT_18(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_19(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_1F(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_20(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_21(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_22(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_23(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_24(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_25(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_26(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_27(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_28(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_29(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_2F(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_30(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_31(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_32(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_33(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_34(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_35(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_36(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_37(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_38(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_39(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3A(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3B(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3C(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3D(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3E(256'h0000000000000000000000000000000000000000000000000000000000000000), + .INIT_3F(256'h0000000000000000000000000000000000000000000000000000000000000000), + + + + // RSTREG_PRIORITY_A, RSTREG_PRIORITY_B: Reset or enable priority ("RSTREG" or "REGCE") + .RSTREG_PRIORITY_A("RSTREG"), + .RSTREG_PRIORITY_B("RSTREG"), + // SRVAL_A, SRVAL_B: Set/reset value for output + .SRVAL_A(18'hFFFFF), + .SRVAL_B(18'h00000), + // Simulation Device: Must be set to "7SERIES" for simulation behavior + .SIM_DEVICE("7SERIES"), + // WriteMode: Value on output upon a write ("WRITE_FIRST", "READ_FIRST", or "NO_CHANGE") + .WRITE_MODE_A("WRITE_FIRST"), + .WRITE_MODE_B("WRITE_FIRST") + ) + RAMB18E1_inst ( + // Port A Data: 16-bit (each) output: Port A data + .DOADO(bram_output), // 16-bit output: A port data/LSB data + .DOPADOP(), // 2-bit output: A port parity/LSB parity + // Port B Data: 16-bit (each) output: Port B data + .DOBDO(), // 16-bit output: B port data/MSB data + .DOPBDOP(), // 2-bit output: B port parity/MSB parity + // Port A Address/Control Signals: 14-bit (each) input: Port A address and control signals (read port + // when RAM_MODE="SDP") + .ADDRARDADDR(bram_addr), // 14-bit input: A port address/Read address + .CLKARDCLK(~prog_clk), // 1-bit input: A port clock/Read clock + .ENARDEN(1'b1), // 1-bit input: A port enable/Read enable + .REGCEAREGCE(1'b1), // 1-bit input: A port register enable/Register enable + .RSTRAMARSTRAM(0), // 1-bit input: A port set/reset + .RSTREGARSTREG(0), // 1-bit input: A port register set/reset + .WEA(2'b00), // 2-bit input: A port write enable + // Port A Data: 16-bit (each) input: Port A data + .DIADI(0), // 16-bit input: A port data/LSB data + .DIPADIP(0), // 2-bit input: A port parity/LSB parity + // Port B Address/Control Signals: 14-bit (each) input: Port B address and control signals (write port + // when RAM_MODE="SDP") + .ADDRBWRADDR(0), // 14-bit input: B port address/Write address + .CLKBWRCLK(0), // 1-bit input: B port clock/Write clock + .ENBWREN(0), // 1-bit input: B port enable/Write enable + .REGCEB(0), // 1-bit input: B port register enable + .RSTRAMB(0), // 1-bit input: B port set/reset + .RSTREGB(0), // 1-bit input: B port register set/reset + .WEBWE(0), // 4-bit input: B port write enable/Write enable + // Port B Data: 16-bit (each) input: Port B data + .DIBDI(0), // 16-bit input: B port data/MSB data + .DIPBDIP(0) // 2-bit input: B port parity/MSB parity + ); + + + 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/config_loader/clock_divider.v b/openfpga_flow/benchmarks/config_loader/clock_divider.v new file mode 100644 index 000000000..4127cd9f3 --- /dev/null +++ b/openfpga_flow/benchmarks/config_loader/clock_divider.v @@ -0,0 +1,45 @@ +`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: +// +////////////////////////////////////////////////////////////////////////////////// + + +module clock_divider ( + input clk_in, + output reg clk_out + ); + + parameter CLK_DIVIDER_SIZE=8; + + reg [CLK_DIVIDER_SIZE - 1:0] clkdiv_counter; + + initial begin + clkdiv_counter <= 0; + clk_out <= 0; + end + + // 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/config_loader/configuration_manager.v b/openfpga_flow/benchmarks/config_loader/configuration_manager.v new file mode 100644 index 000000000..e3c20c2c1 --- /dev/null +++ b/openfpga_flow/benchmarks/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/config_loader/pulse_generator.v b/openfpga_flow/benchmarks/config_loader/pulse_generator.v new file mode 100644 index 000000000..a73fc37f6 --- /dev/null +++ b/openfpga_flow/benchmarks/config_loader/pulse_generator.v @@ -0,0 +1,76 @@ +`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: +// +////////////////////////////////////////////////////////////////////////////////// + +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; + + initial begin + pulse <= INITIAL_VALUE; + pulse_start <= 1'b0; + pulse_end <= 1'b0; + wait_cycle_counter <= 0; + pulse_width_counter <= 0; + end + + // 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/config_loader/reset_generator.v b/openfpga_flow/benchmarks/config_loader/reset_generator.v new file mode 100644 index 000000000..f949e722a --- /dev/null +++ b/openfpga_flow/benchmarks/config_loader/reset_generator.v @@ -0,0 +1,47 @@ +`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: +// +////////////////////////////////////////////////////////////////////////////////// + + +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; + + initial begin + pulse <= INITIAL_VALUE; + active_cycle_counter <= 0; + end + + // Wait a number of clock cycles, hold the initial value + always @(posedge clk) begin + if (active_cycle_counter == ACTIVE_CYCLES) begin + pulse <= ~INITIAL_VALUE; + end else begin + active_cycle_counter <= active_cycle_counter + 1; + end + end + +endmodule diff --git a/openfpga_flow/benchmarks/config_loader/test_top.v b/openfpga_flow/benchmarks/config_loader/test_top.v new file mode 100644 index 000000000..e9a9c3783 --- /dev/null +++ b/openfpga_flow/benchmarks/config_loader/test_top.v @@ -0,0 +1,176 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 03/11/2021 03:01:46 PM +// Design Name: +// Module Name: top +// 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 test_top ( + input sys_clk, + + + // Commented out i/o means it is floating and inaccessable to MPSoC + + // input LUT5_OUT_1_pad, + input GPIO3_pad, + input GPIO0_pad, + input CC_SPYPAD_1_pad, + // input PERF_SPYPAD_0_pad, + // input LUT5_OUT_0_pad, + output RESET_pad, + output CLK_pad, + // input GPIO4_pad, + // input GPIO5_pad, + input GPIO2_pad, + input GPIO1_pad, + input LUT6_OUT_0_pad, + input TEST_EN_pad, + input LUT4_OUT_0_pad, + // input LUT4_OUT_1_pad, + // input LUT4_OUT_2_pad, + // input LUT4_OUT_3_pad, + input SC_HEAD_pad, + input CCFF_TAIL_pad, + input GPIO23_pad, + input GPIO11_pad, + // input GPIO21_pad, + input GPIO22_pad, + input GPIO20_pad, + input GPIO10_pad, + input GPIO8_pad, + input GPIO9_pad, + input GPIO18_pad, + input GPIO19_pad, + input GPIO6_pad, + input GPIO7_pad, + input CC_SPYPAD_0_pad, + input CC_SPYPAD_2_pad, + input SC_TAIL_pad, + input COUT_SPYPAD_0_pad, + output CCFF_HEAD_pad, + // input SHIFTREG_SPY_pad, + // input SC_SPYPAD_0_pad, + output PRESET_pad, + input GPIO12_pad, + input GPIO16_pad, + // input GPIO15_pad, + // input GPIO14_pad, + input GPIO13_pad, + output PROG_CLK_pad, + input GPIO17_pad, + + + output t0_pad, + output t1_pad, + output t2_pad, + input t3_pad, + + output t0_is_output, + output t1_is_output, + output t2_is_output, + output t3_is_output + ); + + + parameter RESET_LENGTH=10; // Start off test with 10 cycle reset + parameter TEST_START_CYCLE=11; // Start the test on cycle 11 + + // Local signals + wire logic_reset; + wire prog_reset; + + wire logic_clk; + wire prog_clk; + + wire ccff_head; + wire configuration_done; + + // ****** GF12 Inputs / MPSoC Outputs ****** + assign RESET_pad = logic_reset; + assign SC_HEAD_pad = 0; + assign CCFF_HEAD_pad = ccff_head; + assign PRESET_pad = prog_reset; + assign PROG_CLK_pad = prog_clk; + assign CLK_pad = logic_clk; + assign TEST_EN_pad = 0; + // ************************* + + + // ******* MPSoC GPIO (4 inputs/outputs) ******* + assign t0_pad = 0; + assign t1_pad = 0; + assign t2_pad = 0; +// assign start_signal = t3_pad; + + assign t0_is_output = 1; + assign t1_is_output = 1; + assign t2_is_output = 1; + assign t3_is_output = 0; + // ******************************************** + + + // ########################### CLOCKS ########################### + + // CLK + // Divide pl_clk (50MHz) by 67108864 (2^26) times + clock_divider #( + .CLK_DIVIDER_SIZE(26) + ) logic_clk_divider ( + .clk_in(sys_clk), + .clk_out(logic_clk) + ); + + // ############################################################## + + + + + // ########################### RESETS ########################### + + // RESET + // Logic reset will be enabled in the first 2 clock cycles + reset_generator #( + .INITIAL_VALUE(1), + .ACTIVE_CYCLES(100) + ) logic_reset_generator( + .clk(sys_clk), + .pulse(logic_reset) + ); + + // ############################################################## + + + + + // ####################### CONFIGURATION ####################### + + // Configuration manager + configuration_manager config_manager ( + .clk_in(sys_clk), + .prog_reset(prog_reset), + .prog_clk(prog_clk), + .ccff_head(ccff_head), + .configuration_done(configuration_done) + ); + + // ############################################################## + + +endmodule \ No newline at end of file