Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
6adf439081
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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 << ")";
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
|
@ -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);
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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", ""),
|
||||
|
|
|
@ -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=
|
||||
|
|
|
@ -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>
|
||||
|
|
@ -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=
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Reference in New Issue