Merge remote-tracking branch 'upstream/master'

This commit is contained in:
tangxifan 2021-09-01 14:19:00 -07:00
commit 6adf439081
53 changed files with 960 additions and 190 deletions

View File

@ -10,7 +10,7 @@ An example of design constraints is shown as follows.
.. code-block:: xml
<pin_constraints>
<set_io pin="clk[0]" net="clk0"/>
<set_io pin="clk[0]" net="clk0" default_value="1"/>
<set_io pin="clk[1]" net="clk1"/>
<set_io pin="clk[2]" net="OPEN"/>
<set_io pin="clk[3]" net="OPEN"/>
@ -23,3 +23,11 @@ An example of design constraints is shown as follows.
.. option:: net="<string>"
The net name of the pin to be mapped, which should be consistent with net definition in your ``.blif`` file. The reserved word ``OPEN`` means that no net should be mapped to a given pin. Please ensure that it is not conflicted with any net names in your ``.blif`` file.
.. option:: default_value="<string>"
The default value of a net to be constrained. This is mainly used when generating testbenches. Valid value is ``0`` or ``1``. If defined as ``1``, the net is be driven by the inversion of its stimuli.
.. note:: This feature is mainly used to generate the correct stimuli for some pin whose polarity can be configurable. For example, the ``Reset`` pin of an FPGA fabric may be active-low or active-high depending on its configuration.
.. note:: The default value in pin constraint file has a higher priority than the ``default_value`` syntax in the :ref:`circuit_library`.

View File

@ -46,6 +46,11 @@ In particular, OpenFPGA requires specific versions for the following dependencie
:iverilog:
version 10.1+ is required to run Verilog-to-Verification flow
:python dependencies:
python packages are also required:
python3 -m pip install -r requirements.txt
.. _install_dependencies_build: https://github.com/lnis-uofu/OpenFPGA/blob/master/.github/workflows/install_dependencies_build.sh

View File

@ -60,6 +60,36 @@ openfpga::BasicPort PinConstraints::net_pin(const std::string& net) const {
return constrained_pin;
}
PinConstraints::e_logic_level PinConstraints::net_default_value(const std::string& net) const {
PinConstraints::e_logic_level logic_level = PinConstraints::NUM_LOGIC_LEVELS;
for (const PinConstraintId& pin_constraint : pin_constraints()) {
if (net == pin_constraint_nets_[pin_constraint]) {
logic_level = pin_constraint_net_default_values_[pin_constraint];
break;
}
}
return logic_level;
}
std::string PinConstraints::net_default_value_to_string(const PinConstraintId& pin_constraint) const {
VTR_ASSERT(valid_pin_constraint_id(pin_constraint));
if (PinConstraints::LOGIC_HIGH == pin_constraint_net_default_values_[pin_constraint]) {
return std::string("1");
} else if (PinConstraints::LOGIC_LOW == pin_constraint_net_default_values_[pin_constraint]) {
return std::string("0");
}
return std::string();
}
size_t PinConstraints::net_default_value_to_int(const std::string& net) const {
if (PinConstraints::LOGIC_HIGH == net_default_value(net)) {
return 1;
} else if (PinConstraints::LOGIC_LOW == net_default_value(net)) {
return 0;
}
return -1;
}
bool PinConstraints::empty() const {
return 0 == pin_constraint_ids_.size();
}
@ -71,6 +101,7 @@ void PinConstraints::reserve_pin_constraints(const size_t& num_pin_constraints)
pin_constraint_ids_.reserve(num_pin_constraints);
pin_constraint_pins_.reserve(num_pin_constraints);
pin_constraint_nets_.reserve(num_pin_constraints);
pin_constraint_net_default_values_.reserve(num_pin_constraints);
}
PinConstraintId PinConstraints::create_pin_constraint(const openfpga::BasicPort& pin,
@ -81,10 +112,21 @@ PinConstraintId PinConstraints::create_pin_constraint(const openfpga::BasicPort&
pin_constraint_ids_.push_back(pin_constraint_id);
pin_constraint_pins_.push_back(pin);
pin_constraint_nets_.push_back(net);
pin_constraint_net_default_values_.push_back(PinConstraints::NUM_LOGIC_LEVELS);
return pin_constraint_id;
}
void PinConstraints::set_net_default_value(const PinConstraintId& pin_constraint,
const std::string& default_value) {
VTR_ASSERT(valid_pin_constraint_id(pin_constraint));
if (default_value == std::string("1")) {
pin_constraint_net_default_values_[pin_constraint] = PinConstraints::LOGIC_HIGH;
} else if (default_value == std::string("0")) {
pin_constraint_net_default_values_[pin_constraint] = PinConstraints::LOGIC_LOW;
}
}
/************************************************************************
* Internal invalidators/validators
***********************************************************************/
@ -100,3 +142,12 @@ bool PinConstraints::unconstrained_net(const std::string& net) const {
bool PinConstraints::unmapped_net(const std::string& net) const {
return std::string(PIN_CONSTRAINT_OPEN_NET) == net;
}
bool PinConstraints::valid_net_default_value(const PinConstraintId& pin_constraint) const {
VTR_ASSERT(valid_pin_constraint_id(pin_constraint));
return PinConstraints::NUM_LOGIC_LEVELS != pin_constraint_net_default_values_[pin_constraint];
}
bool PinConstraints::valid_net_default_value(const std::string& net) const {
return PinConstraints::NUM_LOGIC_LEVELS != net_default_value(net);
}

View File

@ -41,6 +41,12 @@ class PinConstraints {
typedef vtr::vector<PinConstraintId, PinConstraintId>::const_iterator pin_constraint_iterator;
/* Create range */
typedef vtr::Range<pin_constraint_iterator> pin_constraint_range;
/* Logic value */
enum e_logic_level {
LOGIC_HIGH,
LOGIC_LOW,
NUM_LOGIC_LEVELS
};
public: /* Constructors */
PinConstraints();
public: /* Accessors: aggregates */
@ -63,6 +69,21 @@ class PinConstraints {
*/
openfpga::BasicPort net_pin(const std::string& net) const;
/* Find the default value that a net is constrained to
* If not found, return an invalid value
*/
e_logic_level net_default_value(const std::string& net) const;
/* Generate the string of the default value
* If not found, return an empty string
*/
std::string net_default_value_to_string(const PinConstraintId& pin_constraint) const;
/* Generate the integer representation of the default value
* If not found, return -1
*/
size_t net_default_value_to_int(const std::string& net) const;
/* Check if there are any pin constraints */
bool empty() const;
@ -74,6 +95,10 @@ class PinConstraints {
PinConstraintId create_pin_constraint(const openfpga::BasicPort& pin,
const std::string& net);
/* Set the default value for the net under a given pin constraint */
void set_net_default_value(const PinConstraintId& pin_constraint,
const std::string& default_value);
public: /* Public invalidators/validators */
/* Show if the pin constraint id is a valid for data queries */
bool valid_pin_constraint_id(const PinConstraintId& pin_constraint_id) const;
@ -91,6 +116,16 @@ class PinConstraints {
* - net()
*/
bool unmapped_net(const std::string& net) const;
/* Check if default value is a valid one or not
* This is to check if the default value is constrained or not
*/
bool valid_net_default_value(const PinConstraintId& pin_constraint) const;
/* Check if default value is a valid one or not
* This is to check if the default value is constrained or not
*/
bool valid_net_default_value(const std::string& net) const;
private: /* Internal data */
/* Unique ids for each design constraint */
vtr::vector<PinConstraintId, PinConstraintId> pin_constraint_ids_;
@ -100,6 +135,9 @@ class PinConstraints {
/* Nets to constraint */
vtr::vector<PinConstraintId, std::string> pin_constraint_nets_;
/* Default value of the nets to constraint */
vtr::vector<PinConstraintId, e_logic_level> pin_constraint_net_default_values_;
};
#endif

View File

@ -41,6 +41,14 @@ void read_xml_pin_constraint(pugi::xml_node& xml_pin_constraint,
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_pin_constraint),
"Fail to create pin constraint!\n");
}
/* Set default value if defined */
std::string default_value = get_attribute(xml_pin_constraint, "default_value", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string();
pin_constraints.set_net_default_value(pin_constraint_id, default_value);
if (!default_value.empty() && !pin_constraints.valid_net_default_value(pin_constraint_id)) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_pin_constraint),
"Invalid default value for pin constraints. Expect [0|1]!\n");
}
}
/********************************************************************

View File

@ -44,6 +44,7 @@ int write_xml_pin_constraint(std::fstream& fp,
write_xml_attribute(fp, "pin", generate_xml_port_name(pin_constraints.pin(pin_constraint)).c_str());
write_xml_attribute(fp, "net", pin_constraints.net(pin_constraint).c_str());
write_xml_attribute(fp, "default_value", pin_constraints.net_default_value_to_string(pin_constraint).c_str());
fp << "/>" << "\n";

View File

@ -105,6 +105,7 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp,
const std::string& reference_verilog_top_name,
const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints,
const bool& explicit_port_mapping) {
/* Validate the file stream */
valid_file_stream(fp);
@ -125,6 +126,7 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp,
prefix_to_remove,
std::string(BENCHMARK_PORT_POSTFIX),
atom_ctx, netlist_annotation,
pin_constraints,
explicit_port_mapping);
print_verilog_comment(fp, std::string("----- End reference Benchmark Instanication -------"));
@ -155,6 +157,7 @@ void print_verilog_random_testbench_fpga_instance(std::fstream& fp,
std::vector<std::string>(),
std::string(FPGA_PORT_POSTFIX),
atom_ctx, netlist_annotation,
PinConstraints(),
explicit_port_mapping);
print_verilog_comment(fp, std::string("----- End FPGA Fabric Instanication -------"));
@ -230,7 +233,7 @@ void print_verilog_random_testbench_reset_stimuli(std::fstream& fp,
*/
fp << "\t@(negedge " << generate_verilog_port(VERILOG_PORT_CONKT, clock_port) << ");" << std::endl;
fp << "\t@(negedge " << generate_verilog_port(VERILOG_PORT_CONKT, clock_port) << ");" << std::endl;
print_verilog_wire_connection(fp, reset_port, reset_port, true);
print_verilog_register_connection(fp, reset_port, reset_port, true);
fp << "\tend" << std::endl;
}
@ -304,6 +307,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
if (!options.no_self_checking()) {
print_verilog_top_random_testbench_benchmark_instance(fp, circuit_name,
atom_ctx, netlist_annotation,
pin_constraints,
options.explicit_port_mapping());
}

View File

@ -69,6 +69,7 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
const std::string& output_port_postfix,
const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints,
const bool& use_explicit_port_map) {
/* Validate the file stream */
valid_file_stream(fp);
@ -99,6 +100,15 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
if (true == use_explicit_port_map) {
fp << "." << block_name << module_input_port_postfix << "(";
}
/* Polarity of some input may have to be inverted, as defined in pin constraints
* For example, the reset signal of the benchmark is active low
* while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted)
* However, to ensure correct stimuli to the benchmark, we have to invert the signal
*/
if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(block_name)) {
fp << "~";
}
fp << block_name;
if (true == use_explicit_port_map) {
fp << ")";

View File

@ -38,6 +38,7 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
const std::string& output_port_postfix,
const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints,
const bool& use_explicit_port_map);
void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,

View File

@ -912,6 +912,7 @@ void print_verilog_top_testbench_benchmark_instance(std::fstream& fp,
const std::string& reference_verilog_top_name,
const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints,
const bool& explicit_port_mapping) {
/* Validate the file stream */
valid_file_stream(fp);
@ -932,6 +933,7 @@ void print_verilog_top_testbench_benchmark_instance(std::fstream& fp,
prefix_to_remove,
std::string(TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX),
atom_ctx, netlist_annotation,
pin_constraints,
explicit_port_mapping);
print_verilog_comment(fp, std::string("----- End reference Benchmark Instanication -------"));
@ -1789,11 +1791,13 @@ void print_verilog_top_testbench_reset_stimuli(std::fstream& fp,
continue;
}
size_t initial_value = global_ports.global_port_default_value(find_fabric_global_port(global_ports, module_manager, pin_constraints.net_pin(block_name)));
/* Connect stimuli to greset with an optional inversion, depending on the default value */
BasicPort reset_port(block_name, 1);
print_verilog_wire_connection(fp, reset_port,
BasicPort(TOP_TB_RESET_PORT_NAME, 1),
1 == global_ports.global_port_default_value(find_fabric_global_port(global_ports, module_manager, pin_constraints.net_pin(block_name))));
1 == initial_value);
}
}
@ -1998,6 +2002,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
circuit_name,
atom_ctx,
netlist_annotation,
pin_constraints,
explicit_port_mapping);
}

View File

@ -0,0 +1,21 @@
// Creating a scaleable adder
module adder_16(cout, sum, a, b, cin);
parameter size = 6; /* declare a parameter. default required */
output cout;
output [size-1:0] sum; // sum uses the size parameter
input cin;
input [size-1:0] a, b; // 'a' and 'b' use the size parameter
assign {cout, sum} = a + b + cin;
endmodule

View File

@ -0,0 +1,21 @@
// Creating a scaleable adder
module adder_4(cout, sum, a, b, cin);
parameter size = 4; /* declare a parameter. default required */
output cout;
output [size-1:0] sum; // sum uses the size parameter
input cin;
input [size-1:0] a, b; // 'a' and 'b' use the size parameter
assign {cout, sum} = a + b + cin;
endmodule

View File

@ -0,0 +1,21 @@
// Creating a scaleable adder
module adder_6(cout, sum, a, b, cin);
parameter size = 6; /* declare a parameter. default required */
output cout;
output [size-1:0] sum; // sum uses the size parameter
input cin;
input [size-1:0] a, b; // 'a' and 'b' use the size parameter
assign {cout, sum} = a + b + cin;
endmodule

View File

@ -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

View File

@ -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

View File

@ -1,22 +0,0 @@
clk0 0.505000 0.204400
rst0 0.491000 0.206000
clk1 0.472000 0.204400
rst1 0.501400 0.204600
q1[0] 0.278800 0.557400
q1[1] 0.240600 0.268800
q1[2] 0.178200 0.120000
q1[3] 0.098400 0.041600
q0[0] 0.283400 0.566600
q0[1] 0.246800 0.272000
q0[2] 0.181000 0.122200
q0[3] 0.093200 0.048800
n34 0.178200 0.068356
n38 0.098400 0.002698
$abc$226$new_n22_ 0.880800 0.004943
n42 0.283400 0.129291
n46 0.246800 0.084119
n50 0.181000 0.067113
n54 0.093200 0.002644
$abc$226$new_n27_ 0.883200 0.005398
n26 0.278800 0.038636
n30 0.240600 0.082416

View File

@ -1,48 +0,0 @@
# Benchmark "counter4bit_2clock" written by ABC on Wed Jan 13 13:27:00 2021
.model counter4bit_2clock
.inputs clk0 rst0 clk1 rst1
.outputs q0[0] q0[1] q0[2] q0[3] q1[0] q1[1] \
q1[2] q1[3]
.latch n26 q1[0] re clk1 2
.latch n30 q1[1] re clk1 2
.latch n34 q1[2] re clk1 2
.latch n38 q1[3] re clk1 2
.latch n42 q0[0] re clk0 2
.latch n46 q0[1] re clk0 2
.latch n50 q0[2] re clk0 2
.latch n54 q0[3] re clk0 2
.names q1[0] q1[1] rst1 q1[2] n34
-001 1
0-01 1
1100 1
.names rst1 $abc$226$new_n22_ n38
00 1
.names q1[2] q1[0] q1[1] q1[3] $abc$226$new_n22_
--00 1
-0-0 1
0--0 1
1111 1
.names rst0 q0[0] n42
00 1
.names rst0 q0[1] q0[0] n46
001 1
010 1
.names q0[1] q0[0] rst0 q0[2] n50
-001 1
0-01 1
1100 1
.names rst0 $abc$226$new_n27_ n54
00 1
.names q0[2] q0[1] q0[0] q0[3] $abc$226$new_n27_
--00 1
-0-0 1
0--0 1
1111 1
.names q1[0] rst1 n26
00 1
.names rst1 q1[0] q1[1] n30
001 1
010 1
.end

View File

@ -1,60 +0,0 @@
/* Generated by Yosys 0.9+2406 (git sha1 a0606e09, gcc 8.4.0 -fPIC -Os) */
module counter4bit_2clock(clk0, rst0, clk1, rst1, \q0[0] , \q0[1] , \q0[2] , \q0[3] , \q1[0] , \q1[1] , \q1[2] , \q1[3] );
wire _00_;
wire _01_;
input clk0;
input clk1;
wire n26;
wire n30;
wire n34;
wire n38;
wire n42;
wire n46;
wire n50;
wire n54;
output \q0[0] ;
reg \q0[0] ;
output \q0[1] ;
reg \q0[1] ;
output \q0[2] ;
reg \q0[2] ;
output \q0[3] ;
reg \q0[3] ;
output \q1[0] ;
reg \q1[0] ;
output \q1[1] ;
reg \q1[1] ;
output \q1[2] ;
reg \q1[2] ;
output \q1[3] ;
reg \q1[3] ;
input rst0;
input rst1;
always @(posedge clk1)
\q1[0] <= n26;
always @(posedge clk1)
\q1[1] <= n30;
always @(posedge clk1)
\q1[2] <= n34;
always @(posedge clk1)
\q1[3] <= n38;
always @(posedge clk1)
\q0[0] <= n42;
always @(posedge clk1)
\q0[1] <= n46;
always @(posedge clk1)
\q0[2] <= n50;
always @(posedge clk1)
\q0[3] <= n54;
assign n38 = 4'h1 >> { _00_, rst1 };
assign _00_ = 16'h807f >> { \q1[3] , \q1[1] , \q1[0] , \q1[2] };
assign n42 = 4'h1 >> { \q0[0] , rst0 };
assign n46 = 8'h14 >> { \q0[0] , \q0[1] , rst0 };
assign n50 = 16'h0708 >> { \q0[2] , rst0, \q0[0] , \q0[1] };
assign n54 = 4'h1 >> { _01_, rst0 };
assign _01_ = 16'h807f >> { \q0[3] , \q0[0] , \q0[1] , \q0[2] };
assign n26 = 4'h1 >> { rst1, \q1[0] };
assign n30 = 8'h14 >> { \q1[1] , \q1[0] , rst1 };
assign n34 = 16'h0708 >> { \q1[2] , rst1, \q1[1] , \q1[0] };
endmodule

View File

@ -1,4 +1,4 @@
module counter4bit_2clock(clk0, rst0, clk1, rst1, q0, q1);
module counter_4bit_2clock(clk0, rst0, clk1, rst1, q0, q1);
input clk0;
input rst0;

View File

@ -1,4 +1,4 @@
module counter4bit_2clock_tb;
module counter_4bit_2clock_tb;
reg clk0, rst0;
wire [3:0] q0;
@ -6,12 +6,12 @@ module counter4bit_2clock_tb;
reg clk1, rst1;
wire [3:0] q1;
counter_2clock C_1(
counter_4bit_2clock C_1(
clk0,
q0,
rst0);
counter_2clock C_1(
counter_4bit_2clock C_1(
clk1,
q1,
rst1);

View File

@ -0,0 +1,25 @@
///////////////////////////////////////////
// Functionality: Counter with asynchronous reset
// Author: Xifan Tang
////////////////////////////////////////
module counter (
clk,
resetb,
result
);
input clk;
input resetb;
output [7:0] result;
reg [7:0] result;
always @(posedge clk or negedge resetb)
begin
if (!resetb)
result = 0;
else
result = result + 1;
end
endmodule

View File

@ -0,0 +1,25 @@
module counter_tb;
reg clk, resetb;
wire [7:0] result;
counter DUT(
.clk(clk),
.resetb(resetb),
.result(result)
);
initial begin
#0 resetb = 1'b0; clk = 1'b0;
#100 resetb = 1'b1;
end
always begin
#10 clk = ~clk;
end
initial begin
#5000 $stop;
end
endmodule

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -139,15 +139,15 @@
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<!--DFF subckt ports should be defined as <D> <Q> <CLK> <RESET> <SET> -->
<circuit_model type="ff" name="DFFSRQ" prefix="DFFSRQ" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/dff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/dff.v">
<circuit_model type="ff" name="MULTI_MODE_DFFRQ" prefix="MULTI_MODE_DFFRQ" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/dff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/dff.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="D" size="1"/>
<port type="input" prefix="set" lib_name="SET" size="1" is_global="true" default_val="0" is_set="true"/>
<port type="input" prefix="R" lib_name="RST" size="1" default_val="0"/>
<port type="output" prefix="Q" size="1"/>
<port type="clock" prefix="C" lib_name="CK" size="1" default_val="0"/>
<port type="sram" prefix="mode" size="1" mode_select="true" circuit_model_name="DFFR" default_val="0"/>
</circuit_model>
<circuit_model type="lut" name="frac_lut4" prefix="frac_lut4" dump_structural_verilog="true">
<design_technology type="cmos" fracturable_lut="true"/>
@ -220,20 +220,34 @@
</pb_type>
<pb_type name="clb.fle" physical_mode_name="physical"/>
<pb_type name="clb.fle[physical].fabric.frac_logic.frac_lut4" circuit_model_name="frac_lut4" mode_bits="0"/>
<pb_type name="clb.fle[physical].fabric.ff" circuit_model_name="DFFSRQ"/>
<pb_type name="clb.fle[physical].fabric.ff" circuit_model_name="MULTI_MODE_DFFRQ" mode_bits="0"/>
<!-- Binding operating pb_type to physical pb_type -->
<pb_type name="clb.fle[n2_lut3].lut3inter.ble3.lut3" physical_pb_type_name="clb.fle[physical].fabric.frac_logic.frac_lut4" mode_bits="1" physical_pb_type_index_factor="0.5">
<!-- Binding the lut3 to the first 3 inputs of fracturable lut4 -->
<port name="in" physical_mode_port="in[0:2]"/>
<port name="out" physical_mode_port="lut3_out[0:0]" physical_mode_pin_rotate_offset="1"/>
</pb_type>
<pb_type name="clb.fle[n2_lut3].lut3inter.ble3.ff" physical_pb_type_name="clb.fle[physical].fabric.ff"/>
<pb_type name="clb.fle[n2_lut3].lut3inter.ble3.ff[latch].latch" physical_pb_type_name="clb.fle[physical].fabric.ff" mode_bits="0">
<port name="clk" physical_mode_port="C"/>
</pb_type>
<pb_type name="clb.fle[n2_lut3].lut3inter.ble3.ff[dff].dff" physical_pb_type_name="clb.fle[physical].fabric.ff" mode_bits="0"/>
<pb_type name="clb.fle[n2_lut3].lut3inter.ble3.ff[dffr].dffr" physical_pb_type_name="clb.fle[physical].fabric.ff" mode_bits="0"/>
<pb_type name="clb.fle[n2_lut3].lut3inter.ble3.ff[dffrn].dffrn" physical_pb_type_name="clb.fle[physical].fabric.ff" mode_bits="1">
<port name="RN" physical_mode_port="R"/>
</pb_type>
<pb_type name="clb.fle[n1_lut4].ble4.lut4" physical_pb_type_name="clb.fle[physical].fabric.frac_logic.frac_lut4" mode_bits="0">
<!-- Binding the lut4 to the first 4 inputs of fracturable lut4 -->
<port name="in" physical_mode_port="in[0:3]"/>
<port name="out" physical_mode_port="lut4_out"/>
</pb_type>
<pb_type name="clb.fle[n1_lut4].ble4.ff" physical_pb_type_name="clb.fle[physical].fabric.ff" physical_pb_type_index_factor="2" physical_pb_type_index_offset="0"/>
<pb_type name="clb.fle[n1_lut4].ble4.ff[latch].latch" physical_pb_type_name="clb.fle[physical].fabric.ff" mode_bits="0" physical_pb_type_index_factor="2" physical_pb_type_index_offset="0">
<port name="clk" physical_mode_port="C"/>
</pb_type>
<pb_type name="clb.fle[n1_lut4].ble4.ff[dff].dff" physical_pb_type_name="clb.fle[physical].fabric.ff" mode_bits="0" physical_pb_type_index_factor="2" physical_pb_type_index_offset="0"/>
<pb_type name="clb.fle[n1_lut4].ble4.ff[dffr].dffr" physical_pb_type_name="clb.fle[physical].fabric.ff" mode_bits="0" physical_pb_type_index_factor="2" physical_pb_type_index_offset="0"/>
<pb_type name="clb.fle[n1_lut4].ble4.ff[dffrn].dffrn" physical_pb_type_name="clb.fle[physical].fabric.ff" mode_bits="1" physical_pb_type_index_factor="2" physical_pb_type_index_offset="0">
<port name="RN" physical_mode_port="R"/>
</pb_type>
<!-- End physical pb_type binding in complex block IO -->
</pb_type_annotations>
</openfpga_architecture>

View File

@ -246,9 +246,9 @@ endmodule //End Of Module
//-----------------------------------------------------
// Function : A multi-functional D-type flip-flop with
// - asynchronous reset
// which can be switched between active-low and active hight
// - asynchronous set which can be switched
// which can be switched between active-low and active hight
// which can be switched between active-low and active high
// - asynchronous set
// which can be switched between active-low and active high
//-----------------------------------------------------
module MULTI_MODE_DFFSRQ (
input SET, // Set input
@ -259,8 +259,8 @@ module MULTI_MODE_DFFSRQ (
input [0:1] mode // mode-selection bits: bit0 for reset polarity; bit1 for set polarity
);
wire post_set = mode ? ~SET : SET;
wire post_reset = mode ? ~RST : RST;
wire post_set = mode[1] ? ~SET : SET;
wire post_reset = mode[0] ? ~RST : RST;
DFFSRQ FF_CORE (.SET(post_set),
.RST(post_rst),
@ -271,6 +271,29 @@ DFFSRQ FF_CORE (.SET(post_set),
endmodule //End Of Module
//-----------------------------------------------------
// Function : A multi-functional D-type flip-flop with
// - asynchronous reset
// which can be switched between active-low and active high
//-----------------------------------------------------
module MULTI_MODE_DFFRQ (
input RST, // Reset input
input CK, // Clock Input
input D, // Data Input
output Q, // Q output
input mode // mode-selection bits: bit0 for reset polarity; bit1 for set polarity
);
wire post_reset = mode ? ~RST : RST;
DFFRQ FF_CORE (.RST(post_rst),
.CK(CK),
.D(D),
.Q(Q)
);
endmodule //End Of Module
//-----------------------------------------------------
// Function : D-type flip-flop with
// - asynchronous active high reset

View File

@ -17,6 +17,16 @@ module \$_DFF_PP0_ (D, C, R, Q);
dffr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R));
endmodule
// Async active-low reset
module \$_DFF_PN0_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dffrn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .RN(R));
endmodule
// Async reset, enable
module \$_DFFE_PP0P_ (D, C, E, R, Q);
input D;

View File

@ -76,6 +76,37 @@ module dffre(
endcase
endmodule
//-----------------------------
// D-type flip-flop with active-low asynchronous reset
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dffrn(
output reg Q,
input D,
input RN,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C or negedge RN)
if (RN == 1'b0)
Q <= 1'b0;
else
Q <= D;
1'b1:
always @(negedge C or negedge RN)
if (RN == 1'b0)
Q <= 1'b0;
else
Q <= D;
endcase
endmodule
(* abc9_flop, lib_whitebox *)
module latchre (
output reg Q,

View File

@ -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

View File

@ -168,13 +168,19 @@ def generate_each_task_actions(taskname):
# Check if task directory exists and consistent
local_tasks = os.path.join(*(taskname))
repo_tasks = os.path.join(gc["task_dir"], *(taskname))
abs_tasks = os.path.abspath('/' + local_tasks)
if os.path.isdir(local_tasks):
os.chdir(local_tasks)
curr_task_dir = os.path.abspath(os.getcwd())
elif os.path.isdir(abs_tasks):
curr_task_dir = abs_tasks
elif os.path.isdir(repo_tasks):
curr_task_dir = repo_tasks
else:
clean_up_and_exit("Task directory [%s] not found" % taskname + " locally at [%s]" % local_tasks + " or in OpenFPGA task directory [%s]" % repo_tasks)
clean_up_and_exit("Task directory [%s] not found" % taskname +
" locally at [%s]" % local_tasks +
", absolutely at [%s]" % abs_tasks +
", or in OpenFPGA task directory [%s]" % repo_tasks)
os.chdir(curr_task_dir)
@ -271,6 +277,11 @@ def generate_each_task_actions(taskname):
fallback=ys_rewrite_for_task_common)
CurrBenchPara["chan_width"] = SynthSection.get(bech_name+"_chan_width",
fallback=chan_width_common)
CurrBenchPara["benchVariable"] = []
for eachKey, eachValue in SynthSection.items():
if bech_name in eachKey:
eachKey = eachKey.replace(bech_name+"_", "").upper()
CurrBenchPara["benchVariable"] += [f"--{eachKey}", eachValue]
if GeneralSection.get("fpga_flow") == "vpr_blif":
# Check if activity file exist
@ -320,7 +331,7 @@ def generate_each_task_actions(taskname):
flow_run_dir = get_flow_rundir(arch, "bench" + str(benchmark_list.index(bench)) + "_" + bench["top_module"], lbl)
else:
flow_run_dir = get_flow_rundir(arch, bench["top_module"], lbl)
command = create_run_command(
curr_job_dir=flow_run_dir,
archfile=arch,
@ -332,7 +343,7 @@ def generate_each_task_actions(taskname):
"bench": bench,
"name": "%02d_%s_%s" % (indx, bench["top_module"], lbl),
"run_dir": flow_run_dir,
"commands": command,
"commands": command + bench["benchVariable"],
"finished": False,
"status": False})
@ -343,6 +354,8 @@ def generate_each_task_actions(taskname):
# Make the directory name unique by including the benchmark index in the list.
# This is because benchmarks may share the same top module names
def get_flow_rundir(arch, top_module, flow_params=None):
path = [
os.path.basename(arch).replace(".xml", ""),

View File

@ -20,18 +20,19 @@ openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scrip
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTile4Clk_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_4clock_sim_openfpga.xml
openfpga_repack_design_constraints_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock/config/repack_pin_constraints.xml
openfpga_pin_constraints_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock/config/pin_constraints.xml
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTile4Clk_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counter4bit_2clock/counter4bit_2clock.v
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_4bit_2clock/counter_4bit_2clock.v
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch_2clock/and2_latch_2clock.v
[SYNTHESIS_PARAM]
bench0_top = counter4bit_2clock
bench0_top = counter_4bit_2clock
bench0_openfpga_pin_constraints_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock/config/pin_constraints.xml
bench1_top = and2_latch_2clock
bench1_openfpga_pin_constraints_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock/config/pin_constraints.xml
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

View File

@ -0,0 +1,7 @@
<pin_constraints>
<!-- For a given .blif file, we want to assign
- the reset signal to the op_reset[0] port of the FPGA fabric
-->
<set_io pin="op_reset[0]" net="resetb" default_value="1"/>
</pin_constraints>

View File

@ -19,7 +19,6 @@ fpga_flow=yosys_vpr
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_without_ace_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N4_fracff_40nm_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
openfpga_pin_constraints_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/k4_series/k4n4_fracff/config/pin_constraints.xml
# Yosys script parameters
yosys_cell_sim_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_sim.v
yosys_dff_map_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_map.v
@ -28,13 +27,18 @@ yosys_dff_map_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N4_tileable_fracff_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counter_async_reset/counter.v
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_resetb/counter.v
[SYNTHESIS_PARAM]
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys
bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys
bench0_top = counter
bench0_openfpga_pin_constraints_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/k4_series/k4n4_fracff/config/pin_constraints_reset.xml
bench1_top = counter
bench1_openfpga_pin_constraints_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/k4_series/k4n4_fracff/config/pin_constraints_resetb.xml
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

View File

@ -34,10 +34,10 @@ vpr_route_chan_width=50
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counter/counter.v
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counter_async_reset/counter.v
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counter_128bit_async_reset/counter.v
bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counter_128bit_async_resetb/counter.v
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_sync_reset/counter.v
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_128bit_async_reset/counter.v
bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_128bit_async_resetb/counter.v
[SYNTHESIS_PARAM]
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_bram_dsp_dff_flow.ys

View File

@ -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=

View File

@ -25,7 +25,7 @@ openfpga_verilog_default_net_type=none
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counter/counter.v
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_sync_reset/counter.v
[SYNTHESIS_PARAM]
bench0_top = counter

View File

@ -25,7 +25,7 @@ openfpga_verilog_default_net_type=wire
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counter/counter.v
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_sync_reset/counter.v
[SYNTHESIS_PARAM]
bench0_top = counter

View File

@ -27,18 +27,20 @@ yosys_args = -family qlf_k4n8 -no_ff_map
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadderSuperLUT_register_scan_chain_nonLR_caravel_io_skywater130nm.xml
[BENCHMARKS]
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/adder_8/adder_8.v
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/adder/adder_4/adder_4.v
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/adder/adder_6/adder_6.v
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/adder/adder_8/adder_8.v
bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/adder/adder_16/adder_16.v
[SYNTHESIS_PARAM]
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/qlf_yosys.ys
bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys
bench1_top = adder_8
bench0_top = adder_4
bench1_top = adder_6
bench2_top = adder_8
bench3_top = adder_16
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
##########################
# The output verilog of yosys is not synthesizable!!!
# Turn off verification for now
# SHOULD focus on fixing the Verilog problem and run verification at the end of the flow
end_flow_with_test=
vpr_fpga_verilog_formal_verification_top_netlist=

View File

@ -7,11 +7,7 @@
with optionally registered outputs
- Routing architecture: L = 4, fc_in = 0.15, Fc_out = 0.1
Details on Modelling:
Based on flagship k4_frac_N4_mem32K_40nm.xml architecture.
Authors: Jason Luu, Jeff Goeders, Vaughn Betz
Authors: Xifan Tang
-->
<architecture>
<!--
@ -44,6 +40,16 @@
</output_ports>
</model>
<!-- A virtual model for scan-chain flip-flop to be used in the physical mode of FF -->
<model name="dff">
<input_ports>
<port name="D" clock="C"/>
<port name="C" is_clock="1"/>
</input_ports>
<output_ports>
<port name="Q" clock="C"/>
</output_ports>
</model>
<!-- A virtual model for scan-chain flip-flop to be used in the physical mode of FF -->
<model name="dffr">
<input_ports>
<port name="D" clock="C"/>
@ -54,6 +60,17 @@
<port name="Q" clock="C"/>
</output_ports>
</model>
<!-- A virtual model for scan-chain flip-flop to be used in the physical mode of FF -->
<model name="dffrn">
<input_ports>
<port name="D" clock="C"/>
<port name="RN" clock="C"/>
<port name="C" is_clock="1"/>
</input_ports>
<output_ports>
<port name="Q" clock="C"/>
</output_ports>
</model>
</models>
<tiles>
<!-- Do NOT add clock pins to I/O here!!! VPR does not build clock network in the way that OpenFPGA can support
@ -348,15 +365,74 @@
</delay_matrix>
</pb_type>
<!-- Define the flip-flop -->
<pb_type name="ff" blif_model=".subckt dffr" num_pb="1">
<input name="D" num_pins="1" port_class="D"/>
<pb_type name="ff" num_pb="1">
<input name="D" num_pins="1"/>
<input name="R" num_pins="1"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="C" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="C"/>
<T_setup value="66e-12" port="ff.R" clock="C"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="C"/>
</pb_type>
<output name="Q" num_pins="1"/>
<clock name="C" num_pins="1"/>
<mode name="latch">
<pb_type name="latch" blif_model=".latch" num_pb="1">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="latch.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="latch.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ff.D" output="latch.D"/>
<direct name="direct2" input="ff.C" output="latch.clk"/>
<direct name="direct3" input="latch.Q" output="ff.Q"/>
</interconnect>
</mode>
<mode name="dff">
<pb_type name="dff" blif_model=".subckt dff" num_pb="1">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="C" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="dff.D" clock="C"/>
<T_clock_to_Q max="124e-12" port="dff.Q" clock="C"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ff.D" output="dff.D"/>
<direct name="direct2" input="ff.C" output="dff.C"/>
<direct name="direct3" input="dff.Q" output="ff.Q"/>
</interconnect>
</mode>
<mode name="dffr">
<pb_type name="dffr" blif_model=".subckt dffr" num_pb="1">
<input name="D" num_pins="1" port_class="D"/>
<input name="R" num_pins="1"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="C" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="dffr.D" clock="C"/>
<T_setup value="66e-12" port="dffr.R" clock="C"/>
<T_clock_to_Q max="124e-12" port="dffr.Q" clock="C"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ff.D" output="dffr.D"/>
<direct name="direct2" input="ff.C" output="dffr.C"/>
<direct name="direct3" input="ff.R" output="dffr.R"/>
<direct name="direct4" input="dffr.Q" output="ff.Q"/>
</interconnect>
</mode>
<mode name="dffrn">
<pb_type name="dffrn" blif_model=".subckt dffrn" num_pb="1">
<input name="D" num_pins="1" port_class="D"/>
<input name="RN" num_pins="1"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="C" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="dffrn.D" clock="C"/>
<T_setup value="66e-12" port="dffrn.RN" clock="C"/>
<T_clock_to_Q max="124e-12" port="dffrn.Q" clock="C"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ff.D" output="dffrn.D"/>
<direct name="direct2" input="ff.C" output="dffrn.C"/>
<direct name="direct3" input="ff.R" output="dffrn.RN"/>
<direct name="direct4" input="dffrn.Q" output="ff.Q"/>
</interconnect>
</mode>
</pb_type>
<interconnect>
<direct name="direct1" input="ble3.in[2:0]" output="lut3[0:0].in[2:0]"/>
<direct name="direct2" input="lut3[0:0].out" output="ff[0:0].D">
@ -417,16 +493,75 @@
261e-12
</delay_matrix>
</pb_type>
<!-- Define flip-flop -->
<pb_type name="ff" blif_model=".subckt dffr" num_pb="1">
<input name="D" num_pins="1" port_class="D"/>
<input name="R" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="C" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="C"/>
<T_setup value="66e-12" port="ff.R" clock="C"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="C"/>
</pb_type>
<!-- Define the flip-flop -->
<pb_type name="ff" num_pb="1">
<input name="D" num_pins="1"/>
<input name="R" num_pins="1"/>
<output name="Q" num_pins="1"/>
<clock name="C" num_pins="1"/>
<mode name="latch">
<pb_type name="latch" blif_model=".latch" num_pb="1">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="latch.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="latch.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ff.D" output="latch.D"/>
<direct name="direct2" input="ff.C" output="latch.clk"/>
<direct name="direct3" input="latch.Q" output="ff.Q"/>
</interconnect>
</mode>
<mode name="dff">
<pb_type name="dff" blif_model=".subckt dff" num_pb="1">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="C" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="dff.D" clock="C"/>
<T_clock_to_Q max="124e-12" port="dff.Q" clock="C"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ff.D" output="dff.D"/>
<direct name="direct2" input="ff.C" output="dff.C"/>
<direct name="direct3" input="dff.Q" output="ff.Q"/>
</interconnect>
</mode>
<mode name="dffr">
<pb_type name="dffr" blif_model=".subckt dffr" num_pb="1">
<input name="D" num_pins="1" port_class="D"/>
<input name="R" num_pins="1"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="C" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="dffr.D" clock="C"/>
<T_setup value="66e-12" port="dffr.R" clock="C"/>
<T_clock_to_Q max="124e-12" port="dffr.Q" clock="C"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ff.D" output="dffr.D"/>
<direct name="direct2" input="ff.C" output="dffr.C"/>
<direct name="direct3" input="ff.R" output="dffr.R"/>
<direct name="direct4" input="dffr.Q" output="ff.Q"/>
</interconnect>
</mode>
<mode name="dffrn">
<pb_type name="dffrn" blif_model=".subckt dffrn" num_pb="1">
<input name="D" num_pins="1" port_class="D"/>
<input name="RN" num_pins="1"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="C" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="dffrn.D" clock="C"/>
<T_setup value="66e-12" port="dffrn.RN" clock="C"/>
<T_clock_to_Q max="124e-12" port="dffrn.Q" clock="C"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ff.D" output="dffrn.D"/>
<direct name="direct2" input="ff.C" output="dffrn.C"/>
<direct name="direct3" input="ff.R" output="dffrn.RN"/>
<direct name="direct4" input="dffrn.Q" output="ff.Q"/>
</interconnect>
</mode>
</pb_type>
<interconnect>
<direct name="direct1" input="ble4.in" output="lut4[0:0].in"/>
<direct name="direct2" input="lut4.out" output="ff.D">