From 47e30c3e4b4dc36fe8606d80220b8eb450a2e369 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 18 Sep 2024 17:26:44 -0700 Subject: [PATCH 1/9] [core] support last stage mux --- libs/libarchopenfpga/src/circuit_library.cpp | 59 ++++++++++ libs/libarchopenfpga/src/circuit_library.h | 5 + .../src/read_xml_circuit_library.cpp | 14 +++ .../src/write_xml_circuit_library.cpp | 7 ++ openfpga/src/fabric/build_mux_modules.cpp | 101 ++++++++++++++++-- 5 files changed, 175 insertions(+), 11 deletions(-) diff --git a/libs/libarchopenfpga/src/circuit_library.cpp b/libs/libarchopenfpga/src/circuit_library.cpp index 241f63c7a..e39366aec 100644 --- a/libs/libarchopenfpga/src/circuit_library.cpp +++ b/libs/libarchopenfpga/src/circuit_library.cpp @@ -259,6 +259,28 @@ CircuitModelId CircuitLibrary::pass_gate_logic_model( return pgl_model_id; } +/* Find the id of pass-gate circuit model + * Two cases to be considered: + * 1. this is a pass-gate circuit model, just find the data and return + * 2. this circuit model includes a pass-gate, find the link to pass-gate + * circuit model and go recursively + */ +CircuitModelId CircuitLibrary::last_stage_pass_gate_logic_model( + const CircuitModelId& model_id) const { + /* validate the model_id */ + VTR_ASSERT(valid_model_id(model_id)); + + /* Return the data if this is a pass-gate circuit model */ + if (CIRCUIT_MODEL_PASSGATE == model_type(model_id)) { + return model_ids_[model_id]; + } + + /* Otherwise, we need to make sure this circuit model contains a pass-gate */ + CircuitModelId pgl_model_id = last_stage_pass_gate_logic_model_ids_[model_id]; + VTR_ASSERT(CircuitModelId::INVALID() != pgl_model_id); + return pgl_model_id; +} + /* Find the name of pass-gate circuit model * Two cases to be considered: * 1. this is a pass-gate circuit model, just find the data and return @@ -279,6 +301,26 @@ std::string CircuitLibrary::pass_gate_logic_model_name( return pass_gate_logic_model_names_[model_id]; } +/* Find the name of pass-gate circuit model + * Two cases to be considered: + * 1. this is a pass-gate circuit model, just find the data and return + * 2. this circuit model includes a pass-gate, find the link to pass-gate + * circuit model and go recursively + */ +std::string CircuitLibrary::last_stage_pass_gate_logic_model_name( + const CircuitModelId& model_id) const { + /* validate the model_id */ + VTR_ASSERT(valid_model_id(model_id)); + + /* Return the data if this is a pass-gate circuit model */ + if (CIRCUIT_MODEL_PASSGATE == model_type(model_id)) { + return model_names_[model_id]; + } + + /* Otherwise, we need to make sure this circuit model contains a pass-gate */ + return last_stage_pass_gate_logic_model_names_[model_id]; +} + /* Return the type of pass gate logic module, only applicable to circuit model * whose type is pass-gate logic */ enum e_circuit_model_pass_gate_logic_type CircuitLibrary::pass_gate_logic_type( @@ -1262,6 +1304,8 @@ CircuitModelId CircuitLibrary::add_model( /* Pass-gate-related parameters */ pass_gate_logic_model_names_.emplace_back(); pass_gate_logic_model_ids_.emplace_back(CircuitModelId::INVALID()); + last_stage_pass_gate_logic_model_names_.emplace_back(); + last_stage_pass_gate_logic_model_ids_.emplace_back(CircuitModelId::INVALID()); /* Delay information */ delay_types_.emplace_back(); @@ -1485,6 +1529,15 @@ void CircuitLibrary::set_model_pass_gate_logic(const CircuitModelId& model_id, return; } +/* Set pass-gate logic information of a circuit model */ +void CircuitLibrary::set_model_last_stage_pass_gate_logic(const CircuitModelId& model_id, + const std::string& model_name) { + /* validate the model_id */ + VTR_ASSERT(valid_model_id(model_id)); + last_stage_pass_gate_logic_model_names_[model_id] = model_name; + return; +} + /* Add a port to a circuit model */ CircuitPortId CircuitLibrary::add_model_port( const CircuitModelId& model_id, @@ -2174,6 +2227,12 @@ void CircuitLibrary::link_pass_gate_logic_model( } pass_gate_logic_model_ids_[model_id] = model(pass_gate_logic_model_names_[model_id]); + /* Get the circuit model id by name, skip those with empty names*/ + if (true == last_stage_pass_gate_logic_model_names_[model_id].empty()) { + return; + } + last_stage_pass_gate_logic_model_ids_[model_id] = + model(last_stage_pass_gate_logic_model_names_[model_id]); return; } diff --git a/libs/libarchopenfpga/src/circuit_library.h b/libs/libarchopenfpga/src/circuit_library.h index 30caef09c..75613628c 100644 --- a/libs/libarchopenfpga/src/circuit_library.h +++ b/libs/libarchopenfpga/src/circuit_library.h @@ -272,6 +272,7 @@ class CircuitLibrary { const CircuitModelId& model_id) const; /* Pass-gate-logic information */ CircuitModelId pass_gate_logic_model(const CircuitModelId& model_id) const; + CircuitModelId last_stage_pass_gate_logic_model(const CircuitModelId& model_id) const; std::string pass_gate_logic_model_name(const CircuitModelId& model_id) const; enum e_circuit_model_pass_gate_logic_type pass_gate_logic_type( const CircuitModelId& model_id) const; @@ -448,6 +449,8 @@ class CircuitLibrary { /* Pass-gate-related parameters */ void set_model_pass_gate_logic(const CircuitModelId& model_id, const std::string& model_name); + void set_model_last_stage_pass_gate_logic(const CircuitModelId& model_id, + const std::string& model_name); /* Port information */ CircuitPortId add_model_port(const CircuitModelId& model_id, const enum e_circuit_model_port_type& port_type); @@ -664,6 +667,8 @@ class CircuitLibrary { /* Pass-gate-related parameters */ vtr::vector pass_gate_logic_model_names_; vtr::vector pass_gate_logic_model_ids_; + vtr::vector last_stage_pass_gate_logic_model_names_; + vtr::vector last_stage_pass_gate_logic_model_ids_; /* Port information */ vtr::vector port_ids_; diff --git a/libs/libarchopenfpga/src/read_xml_circuit_library.cpp b/libs/libarchopenfpga/src/read_xml_circuit_library.cpp index 13ff84800..bd534779f 100644 --- a/libs/libarchopenfpga/src/read_xml_circuit_library.cpp +++ b/libs/libarchopenfpga/src/read_xml_circuit_library.cpp @@ -832,6 +832,20 @@ static void read_xml_circuit_model(pugi::xml_node& xml_model, circuit_lib.set_model_pass_gate_logic( model, get_attribute(xml_pass_gate_logic, "circuit_model_name", loc_data) .as_string()); + /* Last stage pass gate is optional */ + size_t num_last_stage_pgl = count_children(xml_model, "last_stage_pass_gate_logic", loc_data, pugiutil::ReqOpt::OPTIONAL); + if (0 < num_last_stage_pgl) { + auto xml_last_stage_pass_gate_logic = + get_single_child(xml_model, "last_stage_pass_gate_logic", loc_data); + circuit_lib.set_model_last_stage_pass_gate_logic( + model, get_attribute(xml_last_stage_pass_gate_logic, "circuit_model_name", loc_data) + .as_string()); + } else { + /* By default, assume the last stage circuit model is the same as others */ + circuit_lib.set_model_last_stage_pass_gate_logic( + model, get_attribute(xml_pass_gate_logic, "circuit_model_name", loc_data) + .as_string()); + } } /* Parse all the ports belonging to this circuit model diff --git a/libs/libarchopenfpga/src/write_xml_circuit_library.cpp b/libs/libarchopenfpga/src/write_xml_circuit_library.cpp index ac6867cea..56da46d77 100644 --- a/libs/libarchopenfpga/src/write_xml_circuit_library.cpp +++ b/libs/libarchopenfpga/src/write_xml_circuit_library.cpp @@ -593,6 +593,13 @@ static void write_xml_circuit_model(std::fstream& fp, const char* fname, circuit_lib.model_name(circuit_lib.pass_gate_logic_model(model)).c_str()); fp << "/>" << "\n"; + fp << "\t\t\t" + << "" + << "\n"; } /* Write the ports of circuit model */ diff --git a/openfpga/src/fabric/build_mux_modules.cpp b/openfpga/src/fabric/build_mux_modules.cpp index 3233db768..e7828eb86 100644 --- a/openfpga/src/fabric/build_mux_modules.cpp +++ b/openfpga/src/fabric/build_mux_modules.cpp @@ -461,6 +461,7 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( /* We must have one */ VTR_ASSERT(ModuleId::INVALID() != std_cell_module_id); + /* Find the module ports of the standard cell MUX2 module */ std::vector std_cell_module_inputs; std::vector std_cell_module_input_ports; @@ -496,6 +497,61 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( module_manager.module_port(std_cell_module_id, std_cell_module_output); VTR_ASSERT(1 == std_cell_module_output_port.get_width()); + /* Find module information of the standard cell MUX2 */ + CircuitModelId last_stage_std_cell_model = circuit_lib.model_last_stage_pass_gate_model(mux_model); + std::string last_stage_std_cell_module_name = circuit_lib.model_name(last_stage_std_cell_model); + /* Get the moduleId for the submodule */ + ModuleId last_stage_std_cell_module_id = + module_manager.find_module(last_stage_std_cell_module_name); + /* We must have one */ + VTR_ASSERT(ModuleId::INVALID() != last_stage_std_cell_module_id); + + /* Find the input ports and output ports of the standard cell */ + std::vector last_stage_std_cell_input_ports = + circuit_lib.model_ports_by_type(last_stage_std_cell_model, CIRCUIT_MODEL_PORT_INPUT, + true); + std::vector last_stage_std_cell_output_ports = + circuit_lib.model_ports_by_type(last_stage_std_cell_model, CIRCUIT_MODEL_PORT_OUTPUT, + true); + /* Quick check the requirements on port map */ + VTR_ASSERT(3 == last_stage_std_cell_input_ports.size()); + VTR_ASSERT(1 == last_stage_std_cell_output_ports.size()); + + /* Find the module ports of the standard cell MUX2 module */ + std::vector last_stage_std_cell_module_inputs; + std::vector last_stage_std_cell_module_input_ports; + /* Input 0 port is the first data path input of the tgate, whose size must be + * 1 ! */ + for (size_t port_id = 0; port_id < 2; ++port_id) { + last_stage_std_cell_module_inputs.push_back(module_manager.find_module_port( + last_stage_std_cell_module_id, + circuit_lib.port_prefix(last_stage_std_cell_input_ports[port_id]))); + VTR_ASSERT(true == module_manager.valid_module_port_id( + last_stage_std_cell_module_id, last_stage_std_cell_module_inputs[port_id])); + last_stage_std_cell_module_input_ports.push_back(module_manager.module_port( + last_stage_std_cell_module_id, last_stage_std_cell_module_inputs[port_id])); + VTR_ASSERT(1 == last_stage_std_cell_module_input_ports[port_id].get_width()); + } + + /* Mem port is the memory of the standard cell MUX2, whose size must be 1 ! */ + ModulePortId last_stage_std_cell_module_mem = module_manager.find_module_port( + last_stage_std_cell_module_id, circuit_lib.port_prefix(last_stage_std_cell_input_ports[2])); + VTR_ASSERT(true == module_manager.valid_module_port_id(last_stage_std_cell_module_id, + last_stage_std_cell_module_mem)); + BasicPort last_stage_std_cell_module_mem_port = + module_manager.module_port(last_stage_std_cell_module_id, last_stage_std_cell_module_mem); + VTR_ASSERT(1 == last_stage_std_cell_module_mem_port.get_width()); + + /* Output port is the data path output of the standard cell MUX2, whose size + * must be 1 ! */ + ModulePortId last_stage_std_cell_module_output = module_manager.find_module_port( + last_stage_std_cell_module_id, circuit_lib.port_prefix(last_stage_std_cell_output_ports[0])); + VTR_ASSERT(true == module_manager.valid_module_port_id( + last_stage_std_cell_module_id, last_stage_std_cell_module_output)); + BasicPort last_stage_std_cell_module_output_port = + module_manager.module_port(last_stage_std_cell_module_id, last_stage_std_cell_module_output); + VTR_ASSERT(1 == last_stage_std_cell_module_output_port.get_width()); + /* Cache Net ids for each level of the multiplexer */ std::vector> module_nets_by_level; module_nets_by_level.resize(mux_graph.num_node_levels()); @@ -518,11 +574,17 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( /* To match the standard cell MUX2: We should have only 2 input_nodes */ VTR_ASSERT(2 == branch_size); + + /* Last stage MUX model may have a different name */ + ModuleId curr_stage_std_cell_module_id = std_cell_module_id; + if (true == mux_graph.is_node_output(node)) { + curr_stage_std_cell_module_id = last_stage_std_cell_module_id; + } /* Find the instance id */ size_t std_cell_instance_id = - module_manager.num_instance(mux_module, std_cell_module_id); + module_manager.num_instance(mux_module, curr_stage_std_cell_module_id); /* Add the module to mux_module */ - module_manager.add_child_module(mux_module, std_cell_module_id); + module_manager.add_child_module(mux_module, curr_stage_std_cell_module_id); /* Get the node level and index in the current level */ size_t output_node_level = mux_graph.node_level(node); @@ -530,7 +592,7 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( /* Set a name for the instance */ std::string std_cell_instance_name = generate_mux_branch_instance_name( output_node_level, output_node_index_at_level, false); - module_manager.set_child_instance_name(mux_module, std_cell_module_id, + module_manager.set_child_instance_name(mux_module, curr_stage_std_cell_module_id, std_cell_instance_id, std_cell_instance_name); @@ -540,13 +602,16 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( /* This is an output node, we should use existing output nets */ MuxOutputId output_id = mux_graph.output_id(node); branch_net = mux_module_output_nets[output_id]; + module_manager.add_module_net_source( + mux_module, branch_net, curr_stage_std_cell_module_id, std_cell_instance_id, + last_stage_std_cell_module_output, last_stage_std_cell_module_output_port.get_lsb()); } else { VTR_ASSERT(false == mux_graph.is_node_output(node)); branch_net = module_manager.create_module_net(mux_module); + module_manager.add_module_net_source( + mux_module, branch_net, curr_stage_std_cell_module_id, std_cell_instance_id, + std_cell_module_output, std_cell_module_output_port.get_lsb()); } - module_manager.add_module_net_source( - mux_module, branch_net, std_cell_module_id, std_cell_instance_id, - std_cell_module_output, std_cell_module_output_port.get_lsb()); /* Record the module net id in the cache */ module_nets_by_level[output_node_level][output_node_index_at_level] = @@ -567,10 +632,17 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( * Note that standard cell MUX2 only needs mem but NOT mem_inv */ for (const MuxMemId& mem : mems) { - module_manager.add_module_net_sink( - mux_module, mux_module_mem_nets[mem], std_cell_module_id, - std_cell_instance_id, std_cell_module_mem, - std_cell_module_mem_port.get_lsb()); + if (true == mux_graph.is_node_output(node)) { + module_manager.add_module_net_sink( + mux_module, mux_module_mem_nets[mem], std_cell_module_id, + std_cell_instance_id, std_cell_module_mem, + std_cell_module_mem_port.get_lsb()); + } else { + module_manager.add_module_net_sink( + mux_module, mux_module_mem_nets[mem], last_stage_std_cell_module_id, + last_stage_std_cell_instance_id, last_stage_std_cell_module_mem, + last_stage_std_cell_module_mem_port.get_lsb()); + } } /* Wire the branch module inputs to the nets in previous stage */ @@ -602,8 +674,15 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( mux_module, mux_module_input_nets[input_id], std_cell_module_id, std_cell_instance_id, std_cell_module_inputs[node_id], std_cell_module_input_ports[node_id].get_lsb()); + } else if (true == mux_graph.is_node_output(node)) { + /* Find the input port of standard cell */ + module_manager.add_module_net_sink( + mux_module, + module_nets_by_level[input_node_level][input_node_index_at_level], + last_stage_std_cell_module_id, std_cell_instance_id, + last_stage_std_cell_module_inputs[node_id], + last_stage_std_cell_module_input_ports[node_id].get_lsb()); } else { - VTR_ASSERT(false == mux_graph.is_node_input(input_nodes[node_id])); /* Find the input port of standard cell */ module_manager.add_module_net_sink( mux_module, From 82878063c14b456eb6fbd5d58004636cc024b799 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 18 Sep 2024 17:32:04 -0700 Subject: [PATCH 2/9] [core] syntax --- libs/libarchopenfpga/src/circuit_library.h | 1 + openfpga/src/fabric/build_mux_modules.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/libarchopenfpga/src/circuit_library.h b/libs/libarchopenfpga/src/circuit_library.h index 75613628c..58824d8da 100644 --- a/libs/libarchopenfpga/src/circuit_library.h +++ b/libs/libarchopenfpga/src/circuit_library.h @@ -274,6 +274,7 @@ class CircuitLibrary { CircuitModelId pass_gate_logic_model(const CircuitModelId& model_id) const; CircuitModelId last_stage_pass_gate_logic_model(const CircuitModelId& model_id) const; std::string pass_gate_logic_model_name(const CircuitModelId& model_id) const; + std::string last_stage_pass_gate_logic_model_name(const CircuitModelId& model_id) const; enum e_circuit_model_pass_gate_logic_type pass_gate_logic_type( const CircuitModelId& model_id) const; float pass_gate_logic_pmos_size(const CircuitModelId& model_id) const; diff --git a/openfpga/src/fabric/build_mux_modules.cpp b/openfpga/src/fabric/build_mux_modules.cpp index e7828eb86..07cea6507 100644 --- a/openfpga/src/fabric/build_mux_modules.cpp +++ b/openfpga/src/fabric/build_mux_modules.cpp @@ -498,7 +498,7 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( VTR_ASSERT(1 == std_cell_module_output_port.get_width()); /* Find module information of the standard cell MUX2 */ - CircuitModelId last_stage_std_cell_model = circuit_lib.model_last_stage_pass_gate_model(mux_model); + CircuitModelId last_stage_std_cell_model = circuit_lib.last_stage_pass_gate_logic_model(mux_model); std::string last_stage_std_cell_module_name = circuit_lib.model_name(last_stage_std_cell_model); /* Get the moduleId for the submodule */ ModuleId last_stage_std_cell_module_id = @@ -640,7 +640,7 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( } else { module_manager.add_module_net_sink( mux_module, mux_module_mem_nets[mem], last_stage_std_cell_module_id, - last_stage_std_cell_instance_id, last_stage_std_cell_module_mem, + std_cell_instance_id, last_stage_std_cell_module_mem, last_stage_std_cell_module_mem_port.get_lsb()); } } From 7b4f06ed7d83afd7b7b73fdc5ef0a88d6030fbeb Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 18 Sep 2024 17:40:13 -0700 Subject: [PATCH 3/9] [test] validate mux2 at last stage --- openfpga_flow/openfpga_arch/README.md | 1 + ...N8_stdcell_laststage_mux_40nm_openfpga.xml | 236 ++++++++++++++++++ .../openfpga_cell_library/verilog/mux2.v | 49 ++++ .../fpga_verilog_reg_test.sh | 1 + .../stdcell_mux2_last_stage/config/task.conf | 37 +++ 5 files changed, 324 insertions(+) create mode 100644 openfpga_flow/openfpga_arch/k6_frac_N8_stdcell_laststage_mux_40nm_openfpga.xml create mode 100644 openfpga_flow/tasks/fpga_verilog/mux_design/stdcell_mux2_last_stage/config/task.conf diff --git a/openfpga_flow/openfpga_arch/README.md b/openfpga_flow/openfpga_arch/README.md index a2cc2f6ee..6bd3535ed 100644 --- a/openfpga_flow/openfpga_arch/README.md +++ b/openfpga_flow/openfpga_arch/README.md @@ -29,6 +29,7 @@ Note that an OpenFPGA architecture can be applied to multiple VPR architecture f - registerable\_io: If I/Os are registerable (can be either combinational or sequential) - IoSubtile: If I/O block contains sub tiles (more compact with a higher density of I/Os) - stdcell: If circuit designs are built with standard cells only +- stdcell_laststage: If circuit designs are built with standard cells only. And the last stage uses a different standard cell - tree\_mux: If routing multiplexers are built with a tree-like structure - localClkGen: The clock signal of CLB can be generated by internal programmable resources - : The technology node which the delay numbers are extracted from. diff --git a/openfpga_flow/openfpga_arch/k6_frac_N8_stdcell_laststage_mux_40nm_openfpga.xml b/openfpga_flow/openfpga_arch/k6_frac_N8_stdcell_laststage_mux_40nm_openfpga.xml new file mode 100644 index 000000000..024b4fc13 --- /dev/null +++ b/openfpga_flow/openfpga_arch/k6_frac_N8_stdcell_laststage_mux_40nm_openfpga.xml @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + + + + 10e-12 5e-12 + + + 10e-12 5e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/openfpga_cell_library/verilog/mux2.v b/openfpga_flow/openfpga_cell_library/verilog/mux2.v index fed7858ba..4326a0017 100644 --- a/openfpga_flow/openfpga_cell_library/verilog/mux2.v +++ b/openfpga_flow/openfpga_cell_library/verilog/mux2.v @@ -54,6 +54,55 @@ module MUX2( endmodule +module MUX2D2( + // iVerilog is buggy on the 'input A' declaration when deposit initial + // values + input [0:0] AA, // Data input 0 + input [0:0] BB, // Data input 1 + input [0:0] SS0, // Select port + output [0:0] YY // Data output + ); + + assign YY = SS0 ? BB : AA; + +// Note: +// MUX2 appears will appear in LUTs, routing multiplexers, +// being a component in combinational loops +// To help convergence in simulation +// i.e., to avoid the X (undetermined) signals, +// the following timing constraints and signal initialization +// has to be added! + +`ifdef ENABLE_TIMING +// ------ BEGIN Pin-to-pin Timing constraints ----- + specify + (AA => YY) = (0.001, 0.001); + (BB => YY) = (0.001, 0.001); + (SS0 => YY) = (0.001, 0.001); + endspecify +// ------ END Pin-to-pin Timing constraints ----- +`endif + +`ifdef ENABLE_SIGNAL_INITIALIZATION +// ------ BEGIN driver initialization ----- + initial begin + `ifdef ENABLE_FORMAL_VERIFICATION + $deposit(AA, 1'b0); + $deposit(BB, 1'b0); + $deposit(SS0, 1'b0); + `else + $deposit(AA, $random); + $deposit(BB, $random); + $deposit(SS0, $random); + `endif + + end +// ------ END driver initialization ----- +`endif + +endmodule + + //----------------------------------------------------- // Design Name : CARRY_MUX2 // File Name : mux2.v diff --git a/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh b/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh index 7f418b15d..6d6cb4829 100755 --- a/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh @@ -84,6 +84,7 @@ run-task fpga_verilog/mux_design/tree_structure $@ echo -e "Testing Verilog generation with routing multiplexers implemented by standard cell MUX2"; run-task fpga_verilog/mux_design/stdcell_mux2 $@ +run-task fpga_verilog/mux_design/stdcell_mux2_last_stage $@ echo -e "Testing Verilog generation with routing multiplexers implemented by local encoders"; run-task fpga_verilog/mux_design/local_encoder $@ diff --git a/openfpga_flow/tasks/fpga_verilog/mux_design/stdcell_mux2_last_stage/config/task.conf b/openfpga_flow/tasks/fpga_verilog/mux_design/stdcell_mux2_last_stage/config/task.conf new file mode 100644 index 000000000..a70315f2d --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/mux_design/stdcell_mux2_last_stage/config/task.conf @@ -0,0 +1,37 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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=vpr_blif + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N8_stdcell_laststage_mux_40nm_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N8_tileable_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif + +[SYNTHESIS_PARAM] +bench0_top = and2 +bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act +bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v +bench0_chan_width = 300 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= From 1673d9b919003f97534de01b17031cda72e7cd37 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 18 Sep 2024 17:43:41 -0700 Subject: [PATCH 4/9] [core] fixed a bug --- openfpga/src/fabric/build_mux_modules.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openfpga/src/fabric/build_mux_modules.cpp b/openfpga/src/fabric/build_mux_modules.cpp index 07cea6507..0efd9a590 100644 --- a/openfpga/src/fabric/build_mux_modules.cpp +++ b/openfpga/src/fabric/build_mux_modules.cpp @@ -633,15 +633,15 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( */ for (const MuxMemId& mem : mems) { if (true == mux_graph.is_node_output(node)) { - module_manager.add_module_net_sink( - mux_module, mux_module_mem_nets[mem], std_cell_module_id, - std_cell_instance_id, std_cell_module_mem, - std_cell_module_mem_port.get_lsb()); - } else { module_manager.add_module_net_sink( mux_module, mux_module_mem_nets[mem], last_stage_std_cell_module_id, std_cell_instance_id, last_stage_std_cell_module_mem, last_stage_std_cell_module_mem_port.get_lsb()); + } else { + module_manager.add_module_net_sink( + mux_module, mux_module_mem_nets[mem], std_cell_module_id, + std_cell_instance_id, std_cell_module_mem, + std_cell_module_mem_port.get_lsb()); } } From f6b645fd259586840c8571e160ebb020adfa05a7 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 18 Sep 2024 17:44:55 -0700 Subject: [PATCH 5/9] [core] code format --- libs/libarchopenfpga/src/circuit_library.cpp | 4 +- libs/libarchopenfpga/src/circuit_library.h | 14 ++-- .../src/read_xml_circuit_library.cpp | 15 ++-- .../src/write_xml_circuit_library.cpp | 4 +- openfpga/src/fabric/build_mux_modules.cpp | 68 +++++++++++-------- 5 files changed, 63 insertions(+), 42 deletions(-) diff --git a/libs/libarchopenfpga/src/circuit_library.cpp b/libs/libarchopenfpga/src/circuit_library.cpp index e39366aec..28c00aa7b 100644 --- a/libs/libarchopenfpga/src/circuit_library.cpp +++ b/libs/libarchopenfpga/src/circuit_library.cpp @@ -1530,8 +1530,8 @@ void CircuitLibrary::set_model_pass_gate_logic(const CircuitModelId& model_id, } /* Set pass-gate logic information of a circuit model */ -void CircuitLibrary::set_model_last_stage_pass_gate_logic(const CircuitModelId& model_id, - const std::string& model_name) { +void CircuitLibrary::set_model_last_stage_pass_gate_logic( + const CircuitModelId& model_id, const std::string& model_name) { /* validate the model_id */ VTR_ASSERT(valid_model_id(model_id)); last_stage_pass_gate_logic_model_names_[model_id] = model_name; diff --git a/libs/libarchopenfpga/src/circuit_library.h b/libs/libarchopenfpga/src/circuit_library.h index 58824d8da..2c511d59c 100644 --- a/libs/libarchopenfpga/src/circuit_library.h +++ b/libs/libarchopenfpga/src/circuit_library.h @@ -272,9 +272,11 @@ class CircuitLibrary { const CircuitModelId& model_id) const; /* Pass-gate-logic information */ CircuitModelId pass_gate_logic_model(const CircuitModelId& model_id) const; - CircuitModelId last_stage_pass_gate_logic_model(const CircuitModelId& model_id) const; + CircuitModelId last_stage_pass_gate_logic_model( + const CircuitModelId& model_id) const; std::string pass_gate_logic_model_name(const CircuitModelId& model_id) const; - std::string last_stage_pass_gate_logic_model_name(const CircuitModelId& model_id) const; + std::string last_stage_pass_gate_logic_model_name( + const CircuitModelId& model_id) const; enum e_circuit_model_pass_gate_logic_type pass_gate_logic_type( const CircuitModelId& model_id) const; float pass_gate_logic_pmos_size(const CircuitModelId& model_id) const; @@ -451,7 +453,7 @@ class CircuitLibrary { void set_model_pass_gate_logic(const CircuitModelId& model_id, const std::string& model_name); void set_model_last_stage_pass_gate_logic(const CircuitModelId& model_id, - const std::string& model_name); + const std::string& model_name); /* Port information */ CircuitPortId add_model_port(const CircuitModelId& model_id, const enum e_circuit_model_port_type& port_type); @@ -668,8 +670,10 @@ class CircuitLibrary { /* Pass-gate-related parameters */ vtr::vector pass_gate_logic_model_names_; vtr::vector pass_gate_logic_model_ids_; - vtr::vector last_stage_pass_gate_logic_model_names_; - vtr::vector last_stage_pass_gate_logic_model_ids_; + vtr::vector + last_stage_pass_gate_logic_model_names_; + vtr::vector + last_stage_pass_gate_logic_model_ids_; /* Port information */ vtr::vector port_ids_; diff --git a/libs/libarchopenfpga/src/read_xml_circuit_library.cpp b/libs/libarchopenfpga/src/read_xml_circuit_library.cpp index bd534779f..9fdc05265 100644 --- a/libs/libarchopenfpga/src/read_xml_circuit_library.cpp +++ b/libs/libarchopenfpga/src/read_xml_circuit_library.cpp @@ -833,18 +833,23 @@ static void read_xml_circuit_model(pugi::xml_node& xml_model, model, get_attribute(xml_pass_gate_logic, "circuit_model_name", loc_data) .as_string()); /* Last stage pass gate is optional */ - size_t num_last_stage_pgl = count_children(xml_model, "last_stage_pass_gate_logic", loc_data, pugiutil::ReqOpt::OPTIONAL); + size_t num_last_stage_pgl = + count_children(xml_model, "last_stage_pass_gate_logic", loc_data, + pugiutil::ReqOpt::OPTIONAL); if (0 < num_last_stage_pgl) { auto xml_last_stage_pass_gate_logic = get_single_child(xml_model, "last_stage_pass_gate_logic", loc_data); circuit_lib.set_model_last_stage_pass_gate_logic( - model, get_attribute(xml_last_stage_pass_gate_logic, "circuit_model_name", loc_data) + model, get_attribute(xml_last_stage_pass_gate_logic, + "circuit_model_name", loc_data) .as_string()); } else { - /* By default, assume the last stage circuit model is the same as others */ + /* By default, assume the last stage circuit model is the same as others + */ circuit_lib.set_model_last_stage_pass_gate_logic( - model, get_attribute(xml_pass_gate_logic, "circuit_model_name", loc_data) - .as_string()); + model, + get_attribute(xml_pass_gate_logic, "circuit_model_name", loc_data) + .as_string()); } } diff --git a/libs/libarchopenfpga/src/write_xml_circuit_library.cpp b/libs/libarchopenfpga/src/write_xml_circuit_library.cpp index 56da46d77..42e392685 100644 --- a/libs/libarchopenfpga/src/write_xml_circuit_library.cpp +++ b/libs/libarchopenfpga/src/write_xml_circuit_library.cpp @@ -597,7 +597,9 @@ static void write_xml_circuit_model(std::fstream& fp, const char* fname, << "" << "\n"; } diff --git a/openfpga/src/fabric/build_mux_modules.cpp b/openfpga/src/fabric/build_mux_modules.cpp index 0efd9a590..5d9fb93d7 100644 --- a/openfpga/src/fabric/build_mux_modules.cpp +++ b/openfpga/src/fabric/build_mux_modules.cpp @@ -461,7 +461,6 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( /* We must have one */ VTR_ASSERT(ModuleId::INVALID() != std_cell_module_id); - /* Find the module ports of the standard cell MUX2 module */ std::vector std_cell_module_inputs; std::vector std_cell_module_input_ports; @@ -498,8 +497,10 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( VTR_ASSERT(1 == std_cell_module_output_port.get_width()); /* Find module information of the standard cell MUX2 */ - CircuitModelId last_stage_std_cell_model = circuit_lib.last_stage_pass_gate_logic_model(mux_model); - std::string last_stage_std_cell_module_name = circuit_lib.model_name(last_stage_std_cell_model); + CircuitModelId last_stage_std_cell_model = + circuit_lib.last_stage_pass_gate_logic_model(mux_model); + std::string last_stage_std_cell_module_name = + circuit_lib.model_name(last_stage_std_cell_model); /* Get the moduleId for the submodule */ ModuleId last_stage_std_cell_module_id = module_manager.find_module(last_stage_std_cell_module_name); @@ -508,11 +509,11 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( /* Find the input ports and output ports of the standard cell */ std::vector last_stage_std_cell_input_ports = - circuit_lib.model_ports_by_type(last_stage_std_cell_model, CIRCUIT_MODEL_PORT_INPUT, - true); + circuit_lib.model_ports_by_type(last_stage_std_cell_model, + CIRCUIT_MODEL_PORT_INPUT, true); std::vector last_stage_std_cell_output_ports = - circuit_lib.model_ports_by_type(last_stage_std_cell_model, CIRCUIT_MODEL_PORT_OUTPUT, - true); + circuit_lib.model_ports_by_type(last_stage_std_cell_model, + CIRCUIT_MODEL_PORT_OUTPUT, true); /* Quick check the requirements on port map */ VTR_ASSERT(3 == last_stage_std_cell_input_ports.size()); VTR_ASSERT(1 == last_stage_std_cell_output_ports.size()); @@ -527,29 +528,37 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( last_stage_std_cell_module_id, circuit_lib.port_prefix(last_stage_std_cell_input_ports[port_id]))); VTR_ASSERT(true == module_manager.valid_module_port_id( - last_stage_std_cell_module_id, last_stage_std_cell_module_inputs[port_id])); - last_stage_std_cell_module_input_ports.push_back(module_manager.module_port( - last_stage_std_cell_module_id, last_stage_std_cell_module_inputs[port_id])); - VTR_ASSERT(1 == last_stage_std_cell_module_input_ports[port_id].get_width()); + last_stage_std_cell_module_id, + last_stage_std_cell_module_inputs[port_id])); + last_stage_std_cell_module_input_ports.push_back( + module_manager.module_port(last_stage_std_cell_module_id, + last_stage_std_cell_module_inputs[port_id])); + VTR_ASSERT(1 == + last_stage_std_cell_module_input_ports[port_id].get_width()); } /* Mem port is the memory of the standard cell MUX2, whose size must be 1 ! */ ModulePortId last_stage_std_cell_module_mem = module_manager.find_module_port( - last_stage_std_cell_module_id, circuit_lib.port_prefix(last_stage_std_cell_input_ports[2])); - VTR_ASSERT(true == module_manager.valid_module_port_id(last_stage_std_cell_module_id, - last_stage_std_cell_module_mem)); - BasicPort last_stage_std_cell_module_mem_port = - module_manager.module_port(last_stage_std_cell_module_id, last_stage_std_cell_module_mem); + last_stage_std_cell_module_id, + circuit_lib.port_prefix(last_stage_std_cell_input_ports[2])); + VTR_ASSERT(true == + module_manager.valid_module_port_id( + last_stage_std_cell_module_id, last_stage_std_cell_module_mem)); + BasicPort last_stage_std_cell_module_mem_port = module_manager.module_port( + last_stage_std_cell_module_id, last_stage_std_cell_module_mem); VTR_ASSERT(1 == last_stage_std_cell_module_mem_port.get_width()); /* Output port is the data path output of the standard cell MUX2, whose size * must be 1 ! */ - ModulePortId last_stage_std_cell_module_output = module_manager.find_module_port( - last_stage_std_cell_module_id, circuit_lib.port_prefix(last_stage_std_cell_output_ports[0])); + ModulePortId last_stage_std_cell_module_output = + module_manager.find_module_port( + last_stage_std_cell_module_id, + circuit_lib.port_prefix(last_stage_std_cell_output_ports[0])); VTR_ASSERT(true == module_manager.valid_module_port_id( - last_stage_std_cell_module_id, last_stage_std_cell_module_output)); - BasicPort last_stage_std_cell_module_output_port = - module_manager.module_port(last_stage_std_cell_module_id, last_stage_std_cell_module_output); + last_stage_std_cell_module_id, + last_stage_std_cell_module_output)); + BasicPort last_stage_std_cell_module_output_port = module_manager.module_port( + last_stage_std_cell_module_id, last_stage_std_cell_module_output); VTR_ASSERT(1 == last_stage_std_cell_module_output_port.get_width()); /* Cache Net ids for each level of the multiplexer */ @@ -574,7 +583,6 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( /* To match the standard cell MUX2: We should have only 2 input_nodes */ VTR_ASSERT(2 == branch_size); - /* Last stage MUX model may have a different name */ ModuleId curr_stage_std_cell_module_id = std_cell_module_id; if (true == mux_graph.is_node_output(node)) { @@ -592,9 +600,9 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( /* Set a name for the instance */ std::string std_cell_instance_name = generate_mux_branch_instance_name( output_node_level, output_node_index_at_level, false); - module_manager.set_child_instance_name(mux_module, curr_stage_std_cell_module_id, - std_cell_instance_id, - std_cell_instance_name); + module_manager.set_child_instance_name( + mux_module, curr_stage_std_cell_module_id, std_cell_instance_id, + std_cell_instance_name); /* Add module nets to wire to next stage modules */ ModuleNetId branch_net; @@ -603,14 +611,16 @@ static void build_cmos_mux_module_mux2_multiplexing_structure( MuxOutputId output_id = mux_graph.output_id(node); branch_net = mux_module_output_nets[output_id]; module_manager.add_module_net_source( - mux_module, branch_net, curr_stage_std_cell_module_id, std_cell_instance_id, - last_stage_std_cell_module_output, last_stage_std_cell_module_output_port.get_lsb()); + mux_module, branch_net, curr_stage_std_cell_module_id, + std_cell_instance_id, last_stage_std_cell_module_output, + last_stage_std_cell_module_output_port.get_lsb()); } else { VTR_ASSERT(false == mux_graph.is_node_output(node)); branch_net = module_manager.create_module_net(mux_module); module_manager.add_module_net_source( - mux_module, branch_net, curr_stage_std_cell_module_id, std_cell_instance_id, - std_cell_module_output, std_cell_module_output_port.get_lsb()); + mux_module, branch_net, curr_stage_std_cell_module_id, + std_cell_instance_id, std_cell_module_output, + std_cell_module_output_port.get_lsb()); } /* Record the module net id in the cache */ From 1789ce06c45c4f33de7b65a853d51167ef3079cc Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 18 Sep 2024 17:55:05 -0700 Subject: [PATCH 6/9] [doc] update new syntax with example --- .../manual/arch_lang/circuit_library.rst | 7 +++- .../arch_lang/circuit_model_examples.rst | 32 +++++++++++++++++- .../manual/arch_lang/figures/stdcellmux.png | Bin 0 -> 10983 bytes 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 docs/source/manual/arch_lang/figures/stdcellmux.png diff --git a/docs/source/manual/arch_lang/circuit_library.rst b/docs/source/manual/arch_lang/circuit_library.rst index 4ec803f99..0e515b84b 100644 --- a/docs/source/manual/arch_lang/circuit_library.rst +++ b/docs/source/manual/arch_lang/circuit_library.rst @@ -53,6 +53,7 @@ Here, we focus these common syntax and we will detail special syntax in :ref:`ci + @@ -129,12 +130,16 @@ Input and Output Buffers Pass Gate Logic ^^^^^^^^^^^^^^^ +.. note:: pass-gate logic are used in building multiplexers and LUTs. + .. option:: - ``circuit_model_name=""`` Specify the name of the circuit model which is used to implement pass-gate logic, the type of specified circuit model should be ``pass_gate``. -.. note:: pass-gate logic are used in building multiplexers and LUTs. +.. option:: + + - ``circuit_model_name=""`` Specify the name of the circuit model which is used to implement the pass-gate logic at last stage of multiplexer, the type of specified circuit model should be ``pass_gate``. The type of the pass-gate logic circuit model must be a standard cell MUX2! .. _circuit_library_circuit_port: diff --git a/docs/source/manual/arch_lang/circuit_model_examples.rst b/docs/source/manual/arch_lang/circuit_model_examples.rst index 94f1d5e02..a2a64715c 100644 --- a/docs/source/manual/arch_lang/circuit_model_examples.rst +++ b/docs/source/manual/arch_lang/circuit_model_examples.rst @@ -619,6 +619,14 @@ This example shows: Standard Cell Multiplexer ````````````````````````` +.. _fig_stdcellmux: + +.. figure:: ./figures/stdcellmux.png + :width: 100% + :alt: Examples of MUX built with standard cells + + An example of a multiplexer built with standard cells: (a) all the MUX2 are the same; (b) the MUX2 at the last stage is a different one + .. code-block:: xml @@ -631,12 +639,34 @@ Standard Cell Multiplexer -This example shows: +This example shows (see an illustative example in :numref:`fig_stdcellmux`(a)): - A tree-like 4-input CMOS multiplexer built by the standard cell ``MUX2`` - All the inputs will be buffered using the circuit model ``inv1x`` - All the outputs will be buffered using the circuit model ``tapbuf4`` - The multiplexer will have 4 inputs and 3 SRAMs to control which datapath to propagate +Alternatively, user can specify a different standard cell MUX2 at the last stage. + +.. code-block:: xml + + + + + + + + + + + + +This example shows (see an illustative example in :numref:`fig_stdcellmux`(b)): + - A tree-like 4-input CMOS multiplexer built by the standard cell ``MUX2`` + - The last stage A tree-like 4-input CMOS multiplexer built by the standard cell ``MUX2`` + - All the inputs will be buffered using the circuit model ``inv1x`` + - All the outputs will be buffered using the circuit model ``tapbuf4`` + - The multiplexer will have 4 inputs and 3 SRAMs to control which datapath to propagate + .. _circuit_model_mux_multilevel_example: Multi-level Multiplexer diff --git a/docs/source/manual/arch_lang/figures/stdcellmux.png b/docs/source/manual/arch_lang/figures/stdcellmux.png new file mode 100644 index 0000000000000000000000000000000000000000..d2d08c7b1b57619dba3d9b92a09339d558c5a6a7 GIT binary patch literal 10983 zcmch72{@GB`}a&3WJ?NBrjjUY$yUr*lHJIXvMWVoSF(&5R7zROR<ZaPfgf_Q0g@C!p+w*xIMC8S7gXAPcn-K>ch@n~0f9aw@NBzs z0Chzcrq=p^9QYkQ>H=K%DOmv5gR(ZjRrF6;Oy25`WLGYt05ky-mHSKQGEf$l|09>( zE$`mS?G{92{|M!G%c63-CL(_nMCAW6|I6@?{4f1KI--B{MgArE8kiy`y+~o6H15^XArW=Wm@B?Q*9$_JwrQv16RXKzGfHiT3igb)Qz&%d2Fkla1EB?0LydLEONV0e(QYAZH>k| z>aE^toqnplfht3H&ynsclS9w`MxNov8yElsGYGOYw*ql-?b|0Rdi1D_jFOVNy0*5V zp@qfOt1ccMet!4wqtP)j2?=Rw7))VdSy^>84%gO(#}5vYNM!Qz@(Pu@#ro@~@=G@Z zaLMgwcr6f^C&Ar6aQn%1I0z&YXmnA>`o7cetT@yKgXc5y5B7Z(b$#|h>C&0_GnZaI z5xgX`cQ1E+7?Svb$ma)c)=5osOOj*XO!FX7Q%7!+_Ruh8b@id=K3>Xu-rpyQ&>{)6 zPCw5KhplT8Mr`_&D>#9M|I6Q@@J!U6+$PZVCm5QNf%XX{^wkM<)*`1mWKSfxb$=V_ z32t+ay6UTac(-QjJ7Qw1_$@tu58Gp@_`*JCrcykPA_xPyf!QAGo4~UgS1k{tBy2Dj zT|ghM&J`|iPkh;;69tr(!m`OP?>A@dUOEV4MacNzdlsEGXy89>|6S@B+UAh+1Gd#YUHh$khypBj8is9%#=VRs?><6+IA@OB;;Gh zG0i<}?9us9|CgU%UDoQQBkaQ8J4hJAvsiQk|Ly67wYDa;>Jv&ahi2dD@V!363_Nga zCI%e!V`(Ebfqvx0_9aCwgweK1Sf`?U+hKL#0*pCnJK``3Y~!qPn9`k=FfZ+f_VPwA zU3{ku=qNS$^uDICnjeXrTOIzUIOwUQ7?Dcpn=2;i6KuhZPV{iPx6}gqd`LZHx&NhG4Q#YhQal-(jJF^_5pU@-sK)t`j(M>J5kAMaMZ?7fgD|=zkFO9xa)VQg0+r!2ddYrx* znXZJj_Nffgt%rd^ro`r%g==wu82&UCC(EdM!E9U2n-z?m>_)UndrG86@B4$Nmzq5f9JjRPCPrm zWCq*?jn216`YiDCQEyR~{OfAswZ!6%n@gdvLQ%G zO&f4UM)+BV77PtO9pzS)QJK^Am$Kzk=Q;XH&N3q(VU0uB$TxGt=S=~aC)gdJAP_+A)sE)6J-SVTkP&=#uqQfO)wif;12ISrJ2u7 za>@QF%w-5oY`6l=l@4#wH#+Dn3^<4n)2dH4iNa!&oD>D?{C_=t{WQt%1`IsMrh9$Z zRg2r>%+Cu5-kwFLi?2n{01HpdJ+(S0D#~i&poItG3 z7vbkUDr~5DSX5gs(MkRPyTLV+&oA{IEJR^4B;B){A!Z#6@IzQ<$~5Gp1O-4-~Wr5;=H;yU!WZe1YeV%I7iyS zvL;YuPEufp>&dRC+{o!iC?0UWfYDR)9|zlBRVr*;YnUSGg4oz6oZ{9}!$+QLpxn2; zxQ-$X#q?B&WcBE;w4a$@tXNv?N=*uWN;!eSdO|zxu|1NB5y7*(8;A0DpevF404M+z zMC|04k;}ew8jmfy77O++^YYnkj8qCFr>{hwMT74>PmT3xhAUJPf=eLl6MFQlTr)kK zMnZ6S4zCM3R{iPmFy@ln>%jiH2CKSy|(UEPdWW!pL<62%ZMXz*c{IpJIdwTpE@y@crtku-_5yk7rG% ze-95Mm;SNfGqY{K>{pP2ds@jqlNe3Be5)95jM)$E<#cm?_nb$85mfhDpRMPa#jRoi z$lFJffVTE)XVuNkx}dt=`Wj=O4XIvfp#SJh8A33)Ygy~8c7l1jMr$&0J{o*_f|wF; zV5Qxh92%O9_uiPptvwb5Tt65H)e?F8{YkvcpiQWNTGrR;5?Ej?6U_D?`btPua$g6Q zN9eXjUoW|e-uZol`w7&7p0JLn?YWLOuL^yK@;NT=89Hu|*Sr>onmNE=2cm8fp>XLo z*1%%A?2g-a?~PYU3u&LLn~k9Gb=UZO-A@f&fqU=cVK%HA;@93Dm<_0Ttnmd{?NNz7 z8>cG9lua6IRU&+f@tF=d(?**2z$ehKF|-ZC1hpMM_QAUtp-7?qQaBhA=(SC}g8AFh z?Ec5)?y}W&d*sX%-7R2fZ_U)x$>mmO28FSu7TI&^V+m~UqmxSdPV|6ApN)dS$n}?2 zi%C6@Ex0A0-;%M$UgD{`bmvL(^1QP2AoN7TK=fVtrh#5K&FC=7#)pvRv*BNFAQCdy zK?@QlE7H1L%|F1K#m7c)LZ0YG*=dT%Dl|DzYg+H5AL_QEO zjP?u}p3iIgJ^T8&BK9lr@M$@AYz@>=+)j!i8-NxK&ntAM9Yf=s*Gd~-QRKo`h`>hZ z{;7DlV#PcVlds-Ay*8sj24*1Kq69oD$=bkAAJPV5^{F(<_Q0JDT9Yw`%UNd$L85(m zy1I_weor^NV?QnZIlTl1we|vKF_xL*7}mvfaJ<8=iD@zZ9!l=!@_a>a;e)c{)WSaL zvewlK%vfGPj&gD(J#*gc)1RhHmvGe4dX!=(2#C;qjMGCCt}--;(?qD#mS+I!JaXY? zqz#m?c4hH|l76-q(_{9;OywU#bt)-r8P2jx2KSc0Z2R~e`U?Gz21h-a?yT$0*K`}-zz}%NTORoS7*hye z`)~W#oc&Q^=p@)UdPOhSAfj+-r@@l(gKwH)q*E6?HrNvTX{nkb6rffQgq41L`ZA$nB3xBx{aE4JcG8rK7! z5(_`>aQbh55m=>a8v@-7L_Q}mrFi#crt~hHFZ(7WQq|6!qo~mFnsG&nnmT+r?AxE3aqyey#qnY3T{| zgEGfLWl_ycXvV_2P;a8a|a(Dm;ftMT`Rr%NdWo!F&G%FrI4Lbwwp@ znw(+T^7~=87=q=T(CXkf=Jtgzkp{riP_737wVH_$>lfxrC?-l1lGNbmfbUiX5U&L+ zus6egUNt~_!aLPF1@jL&S-mwhNI!EK!(uRzfG0r zs>2_28_zMZzYqQC$Oj$}TXI4YtHc|cRjo_^yh`M)*!%AmS3=j{Wd6>6nJ%lvjmdVs z!ZxQT_`lmTFmdh{U%Qod|Jlkn=E&~2{~9V3w0{a^ z6B*4qOHVm!6%S7}Uj4thkw7j%HyJU9qxkMqYDsfcss_8)>TDpctp8Mu3mZ^tV64?( z06sABgUqsc$HxB|qDd!0WeGF;-ha7)XQo;T@qa$4xk)71dbS?Bn$S~=s`^TQPtaJ% zCsUZ_PxG+R=6x)6+xbSlmw7HoT{0^aqK;7p6_;u(zEq1n5)^7Y@|-nGdykkU;v%*d z9~T4}%&b}_@kpNae{J15{tnqj{6Kp&-WmZKkP2E7QENIRK1Mu*wi)b6MCrrpX2c<) zF5b;#RT6DRHINxf8^xCoAWVhqw?_kOg&=$wxSy zoI#wb%~S+<)jofFD{3Hs&Pdz*SwgVaV`~v)sxNMwr1+N&UZ`mM{LA_|gM+t6!s-ah z9CDOkgO|8LP$7>0rg(fWQ}_m|8K{5}rdX#}#ZRm^2~*DvBNl5AK7L=IHycW}d*+8z zfpDDyru;;CNxc~wH6|Kble|v8(JuB4ENW+lui_0aH~RJEl%*&8N{22Vu{h=;S+uo$ zhg~(Vh=^Bfk}9ES;EjTBz5!c~6wm~jpW@7u=ZCr8ci7eXs;qytTouo=UVd~7BxIFd zFSOpu=gF{?nMn$9J5qUJbg!Sd#k;z3M6SgTdT zccfKkfgSRMx*D>)*w?NzZ9+fa-KS{N^4NE#wPggDcMRY#SG7D8LJWDdf zcy5eHnL*d|>3fu}W_Sjoo`7ZY+(+!`FK$mH%`epx=Ow=#`TjaShUwF0B`8x!m^)6Q&*WWYJ^8Tjx_P<`wM{-R-Gr3hf3{ znJ|AruNV&{%tTay`Dcar&A|7|P`x@g*rVFvsYgm0<=>vARy|tIH~4zy z*9}r?ah)K8xuMLxO+3t`uW0+gCOO)*dzJJmml7g1^ojecm9VfQ^u!kI$r4H@9X0Sv zN+^dwj{6hx{Y3&!zjIGgLr2FoprgY$qlRZn4n>L`= zIYr+>+Tt(YE~};=;UlcTt_k+;N5gzdwgw{)7ky)=Y1={rL&@ZG=m#= z4R$Kpf|i0^(R|z(hU`PK%?L8cU?-@3ft4VppS+mYV$?fa5P;xYeoQO4A;%=FSbo9qp>fkcpjH?$oS}d+lYs z9?iP@dczeSOTT}oMfgECGwK}vJE(dcGJBql=p;315EDPr1QP#{S1X{qduiwktI@o) z)N#D!uNW_({5*E%i^0DO>YUF?!vdUz5B-G?D=$A_dy}`mA+NcK{wv4=3?V(HEUB~A zU}^a{0LD)oL83X~6Yj9i=f0VgCtKf`j(-Pl#Nj_XUi;7X(2r;Si97z=SzBJ12T^cDApoe?ML-Z4jC#ack~(XC(}uK*JaGM`<)eQ$L~+|LhJIa5gEe!i-YlR@ z?yTZ=f#TnQq)nmq&!!XSNB}^{zwC+1&VQg+r(e~^xs-Aud<}D&Jzqfo z@3v1I!!+z~!$(9V_@Glpu{AGWI!>JVCw9Dh5WX<&UDR06Tk#L5!aL}u@A8%3)8(GS z1SM*5834XZ-vhg#*IpqE9XF7F_Im@zt?0@Bv}<_~zGhWKhkb{Z>OBIuhkqc|Q*PP< z^vh}*yd5gyu0v-v{KFP;MYoa0RA)8U*^r_rJV*Z>+K0Gl^TC6q^h8F&e*mA!{xxr) zE3r5$t|`{!-!p~peb8@1vW0ymodyN$`2UTa($dFB+d79)t9skml%rIr^q+}9+ll26 zhTf@#O`V+bB0Zff|{i2koE&a?ep}Dwi?c>CK0-g%nFeS za;y!Yd3~0On{GJWF6wgF5h4!#3&3~HMi$nnHJJLemZ4w}r;Cj)Yo?8(7&aAg#%ESe zzKeMYk3HtKsTYZL^Y%1N zgM?b&B`Gqz=t#+uQFM#`S5H4PcPSiS4 z0%t`WExMmL2c1>bpz-cp7LEuYUA^-(rfpHP%e-ygEYfKt32d%xhe~D$@iQ$;!0On* z`_yGmFSK$&sj0U6{Qc$5$_?qK%j<PD&p3%};Grd<~@&41QvoQr0+6BXDV%SW`5vWRM4?H@<^s+D_;@lFl(w$X-W-$0f7 zEd*>Mst-*@LW_W%^nKO3p0W>Mv7meJ-w3H(zOf#wE4J-@D6#xbzZ&p0d}-V9I}-b_ zwWY)LURG-HWX6HF&tGvai3o?#9TbG4RFpvOA;LQw)hcRD$Flr{W^J?(AQ1t?)r^@( zo!5cycue9}{d2~x1rIC_vg5<>P+xA6$_H=f^jLBrPRl9ac-N^-BM&yeY{fMO>b-xi zuSTG>0Y+xD$|Pln2pNSCI9fUn;xuX_4uyM(1nhkBZC&jPQCz|Al&~N<$41-3Rb*#9x-d>8mA3=p?#{!&XcUutBQoyFYa7*; zQJ)FpY$*OoJ{z^N8s`S;zh=C7*Tza0Lt8PyJDX|yc>!uu#xF@re#O$hI^*1dXK8n) zRiy`|lRB$0-Wh>EKPL; zY1wp1EN}ZoKUH3f8y9}I`}G5&^Q6R&^8n>h8<)XZ$zJ*VO^G}6ml(QF>)|Pil;~K` zNUK3;eb`;|-Z-pkN@&Yj-;wOycxs!)D4W+s<*Dgtn#Ws~z^bQ~PZP+A&vLz(iyXM! z*_7UXMw-`kegN)Ht~&#s^JeRtuNZ+&pa*uSH&0^>@y)gw4Ep6B%e}~skRk$EVbQ7J z*Y=UKO(SazO)Y?4P@g=4WAJD|0AAd|OAXlmyfHp{+9o6wCfL|cB&{6Wmyn)MFwhxf z4=ic4I@@HX5f*xw0DOCnu3=D;-$5rThPst`Op6mlXqBQCw$rD5^AX(6j!PNt+P-V^ zg$8^jv)=L;_BR_Xli1OTYn$uoK%d>QGt`}yPNqOwu~6}i{3c$ek9zfHe00e zBN4R$q`$hHXj?CTWYAuq4QSUE3`h-g5@Qx(K-25lTfZ^i&T0d^ummxsk{&egeD83_ zdF*h2iek8aE$+t!jHh<*e4a}#q0nk4YC1SLlu-zTlZgyn=TvZNCB5@(nRmBC^O`$7 zyviSwhMA{J>TGWAOcu589K3wx0*DAc{G9kIubxlwnoTA*x0lo+GeHR8b&nMoWK~B495lBKlWal$eH37t_ZSP@6Z~&E z-~WcFelNwutVK(GtU*%}_5;qmjC}jMIC|l#{{`#aVb{Au^*A`AA~YrlBsBl9%F9u0 z|07QM{{eNbtt6KA!|ds#DZhCbHc5|F5PlTtA~yKLEE*8ixuMwri3{2#D8=$fyvXg% zN1OhI!MPs+O7xAve3gb%{#}iakeU&)&9*X zZ0EgXS5hfN{M@#H=~TupkU@Kw_up9J_#{JJHk}d|bulnX4Y93Mn(9%kn|djW_kd|RAzNL5?*vIN-P*xPQZEPCY@8K}~}d6+*1>GfmWk2vJDxn%Ts;Y(?^ z_B&aA=Jf)^6M?ywfOF}YuX2>de%rH|mJ0JJS1wH4Zbb)##;K@FnJaC`Fp zGRbg8KoX$0c}iyEP4~Tf-o3&q=-%PH06U+wsEQ+Wi7RPa7`7!WIWp-jx^{_il-q9LQj@MdZ0wDtK4VllK3W2 zZjSC~mG51BczNIj8%R<#(3kE-$ zWR$-xQeGv516GoRc`LP(KZom4J@dC6dq1KM4|;BBMpEpPfE;4V=bSK<&2CMq|J%CWgJ)-ofvOsQgS}DItwL5If3lcQ82+3h-$M zMa*ZCN8eq+=m{`*?yW?p!lc5_%we`q#N+7PEVgnE>+jMfu)*PFyd9F?4tf$A2GFLD z?QN%%Mwj-pT7Z08*^Zm@*hu<9$oNykoo>AIW6Ul`&u|f6a!5f$T5Y)&C-iJY7zy}9 z0m;zRfXync-i&3Ei5;?nLHkAd)Ct3Jmd-p>Jc=z{hdn)y7XWgEdxUkXBTSXVL7Q`Z z0X~xtz(v4JRYcz2IP@xGX*3pVWz78ehN*wWuxz0L_}n6K*aNc_XX;`HpShA<6Co6Wr_0PeD}bes9okdD$9$ae~zL?##4VlaZM??y8ezgy4%G1sK>- z`4Vmsd+li;v3RVEFgV6+NcS(l2DhbGqaK~dD~6ObrbZ;QDeqNXXaPmmSm?=m?w=j) z(6Xf$BC!Kjc`PHNPZ1|O3Q)hr{kPA}YhoN~yM7tvFmP<8O<7={RCq@Py9@frczGtL z>QuQY-I;YX9=COjwVz9$69UTpmg+PZvP%zh^dADE^0nTK^T5#t4hvr(EV~)*6qT+6 z2RowEfkfm@9l9DW;XGnLfCv(XJOBD5!hpd5SiDMN{l=sw+CBxLRkN705NOV^BNgb6VxvVe0bbl@4@KJ@GQj zQ2t(Y(~UQ0#D5zRc~>P1ejScFuUFit$FHnmJ^x70g2$s0H@)KU&Wqp5A+J*iY{Q^^ zakPK;c(>*kd|au%%cM5p5)L#&SRUmij1^T>L-l>83W+%KzWzwIg0H1t3)@*PWk@sl zek^x8(~4gQncG>Fp?R+4!p)bNnO&Dy$bv^eo7%5_D~zk$7X4XY`MU5;DE(4`o`tjF zR(`r~!gp}+pdMYCNs8k-G8IwcVRkER!*G}-KfS}pl)Rgp7SS=Z0-o2ok?gr}v9fNE zIijZpdA4|_Z(q&izJ8EhuN0p|Y>emYL2CZmoh(EL{5{PJ5o#$d`E2p#2%9mh@yTN= z3f+?uBJs7m? zUct06o}t)kJLVcS+1v~DQjDSd_0np;j%J_Nk;S@6J11F^9OnwJHBCok@Za!7{5FbP zK?Zw?=)@$=09&-n+XPO#uToOPV^TC&+q)%r*Pa{vI^G(FW_zqB>s`?^kKDL($Pm*# z8yBvC3uj33j1OB{_Si;N*6+yI0dVX% zr+tIx#ZXD8K{+0= zP-<9OXqfX_tNERoG;qp2qb2Bb!E-Hac06@gpi8qwhq|sU^-VOQ+Fv8~r`%?yQKzn0 zh$!^l*gn>^?HM$Xb8sxt{&VQEzsOZh_UF_GADFA%8Ia#Hi{=!VO>Lq@-^Q+w zt-hZ#bIB3rbw@_b00%_^QBgmfAlBW|VOz>Q3}iX0SfsM1qr+S5_v*!af;}GQt5EuTFk$jpnqODWk5R2=k^anuOttcJmpr2`Y|UR% z_8pXn+q^FleZV~M3VJSvivE>Y(VzDt;=v`1==rRIX~+5`E77Pn<9g-#9BQIDCy&;D i8ejg;h1z0aVLQ<4BGF!N&-8HZ+8ODaUo6#iiTYoK87Yqd literal 0 HcmV?d00001 From 44a07704ffe8788e12aefc32650e3d48bc0a9445 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 18 Sep 2024 21:10:02 -0700 Subject: [PATCH 7/9] [core] add check codes for last stage pgl model --- .../src/check_circuit_library.cpp | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/libs/libarchopenfpga/src/check_circuit_library.cpp b/libs/libarchopenfpga/src/check_circuit_library.cpp index 62a71a3a1..35e84f416 100644 --- a/libs/libarchopenfpga/src/check_circuit_library.cpp +++ b/libs/libarchopenfpga/src/check_circuit_library.cpp @@ -800,6 +800,50 @@ static size_t check_io_circuit_model(const CircuitLibrary& circuit_lib) { return num_err; } +/************************************************************************ + * Check the last stage pass gate logic model is the same type as default + ***********************************************************************/ +static +size_t check_pass_gate_circuit_model_consistency(const CircuitLibrary& circuit_lib) { + size_t num_err = 0; + + for (const CircuitModelId& mux_model : circuit_lib.models_by_type(CIRCUIT_MODEL_MUX)) { + CircuitModelId pgl_model = circuit_lib.pass_gate_logic_model(mux_model); + CircuitModelId last_stage_pgl_model = circuit_lib.last_stage_pass_gate_logic_model(mux_model); + if (!circuit_lib.valid_model_id(pgl_model)) { + VTR_LOGF_ERROR(__FILE__, __LINE__, + "The pass-gate logic circuit model '%s' of '%s' is not valid!\n", + circuit_lib.pass_gate_logic_model_name(mux_model).c_str(), + circuit_lib.model_name(mux_model).c_str()); + num_err++; + } + if (!circuit_lib.valid_model_id(last_stage_pgl_model)) { + VTR_LOGF_ERROR(__FILE__, __LINE__, + "The last stage pass-gate logic circuit model '%s' of '%s' is not valid!\n", + circuit_lib.last_stage_pass_gate_logic_model_name(mux_model).c_str(), + circuit_lib.model_name(mux_model).c_str()); + num_err++; + } + if (circuit_lib.model_type(pgl_model) != circuit_lib.model_type(last_stage_pgl_model)) { + VTR_LOGF_ERROR(__FILE__, __LINE__, + "The last stage pass-gate logic circuit model '%s' of '%s' should be the same type as its regular pass-gate logic model '%s'!\n", + circuit_lib.model_name(last_stage_pgl_model).c_str(), + circuit_lib.model_name(mux_model).c_str(), + circuit_lib.model_name(pgl_model).c_str()); + num_err++; + } + if (pgl_model != last_stage_pgl_model && circuit_lib.gate_type(pgl_model) != CIRCUIT_MODEL_GATE_MUX2) { + VTR_LOGF_ERROR(__FILE__, __LINE__, + "The last stage pass-gate logic circuit model '%s' of '%s' should be a MUX2 gate!\n", + circuit_lib.model_name(last_stage_pgl_model).c_str(), + circuit_lib.model_name(mux_model).c_str()); + num_err++; + } + } + + return num_err; +} + /************************************************************************ * Check points to make sure we have a valid circuit library * Detailed checkpoints: @@ -920,6 +964,9 @@ bool check_circuit_library(const CircuitLibrary& circuit_lib) { /* 11. Check power-gated inverter/buffer models */ num_err += check_power_gated_circuit_models(circuit_lib); + /* 12. Check pass-gate logic model consistency */ + num_err += check_pass_gate_circuit_model_consistency(circuit_lib); + /* If we have any errors, exit */ if (0 < num_err) { From 8e04d473f2bad4de7d457ee43e7ad40233d8d00f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 18 Sep 2024 21:10:31 -0700 Subject: [PATCH 8/9] [core] code format --- .../src/check_circuit_library.cpp | 50 +++++++++++-------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/libs/libarchopenfpga/src/check_circuit_library.cpp b/libs/libarchopenfpga/src/check_circuit_library.cpp index 35e84f416..a9852a7e5 100644 --- a/libs/libarchopenfpga/src/check_circuit_library.cpp +++ b/libs/libarchopenfpga/src/check_circuit_library.cpp @@ -803,38 +803,48 @@ static size_t check_io_circuit_model(const CircuitLibrary& circuit_lib) { /************************************************************************ * Check the last stage pass gate logic model is the same type as default ***********************************************************************/ -static -size_t check_pass_gate_circuit_model_consistency(const CircuitLibrary& circuit_lib) { +static size_t check_pass_gate_circuit_model_consistency( + const CircuitLibrary& circuit_lib) { size_t num_err = 0; - for (const CircuitModelId& mux_model : circuit_lib.models_by_type(CIRCUIT_MODEL_MUX)) { + for (const CircuitModelId& mux_model : + circuit_lib.models_by_type(CIRCUIT_MODEL_MUX)) { CircuitModelId pgl_model = circuit_lib.pass_gate_logic_model(mux_model); - CircuitModelId last_stage_pgl_model = circuit_lib.last_stage_pass_gate_logic_model(mux_model); + CircuitModelId last_stage_pgl_model = + circuit_lib.last_stage_pass_gate_logic_model(mux_model); if (!circuit_lib.valid_model_id(pgl_model)) { - VTR_LOGF_ERROR(__FILE__, __LINE__, - "The pass-gate logic circuit model '%s' of '%s' is not valid!\n", - circuit_lib.pass_gate_logic_model_name(mux_model).c_str(), - circuit_lib.model_name(mux_model).c_str()); + VTR_LOGF_ERROR( + __FILE__, __LINE__, + "The pass-gate logic circuit model '%s' of '%s' is not valid!\n", + circuit_lib.pass_gate_logic_model_name(mux_model).c_str(), + circuit_lib.model_name(mux_model).c_str()); num_err++; } if (!circuit_lib.valid_model_id(last_stage_pgl_model)) { - VTR_LOGF_ERROR(__FILE__, __LINE__, - "The last stage pass-gate logic circuit model '%s' of '%s' is not valid!\n", - circuit_lib.last_stage_pass_gate_logic_model_name(mux_model).c_str(), - circuit_lib.model_name(mux_model).c_str()); + VTR_LOGF_ERROR( + __FILE__, __LINE__, + "The last stage pass-gate logic circuit model '%s' of '%s' is not " + "valid!\n", + circuit_lib.last_stage_pass_gate_logic_model_name(mux_model).c_str(), + circuit_lib.model_name(mux_model).c_str()); num_err++; } - if (circuit_lib.model_type(pgl_model) != circuit_lib.model_type(last_stage_pgl_model)) { - VTR_LOGF_ERROR(__FILE__, __LINE__, - "The last stage pass-gate logic circuit model '%s' of '%s' should be the same type as its regular pass-gate logic model '%s'!\n", - circuit_lib.model_name(last_stage_pgl_model).c_str(), - circuit_lib.model_name(mux_model).c_str(), - circuit_lib.model_name(pgl_model).c_str()); + if (circuit_lib.model_type(pgl_model) != + circuit_lib.model_type(last_stage_pgl_model)) { + VTR_LOGF_ERROR( + __FILE__, __LINE__, + "The last stage pass-gate logic circuit model '%s' of '%s' should be " + "the same type as its regular pass-gate logic model '%s'!\n", + circuit_lib.model_name(last_stage_pgl_model).c_str(), + circuit_lib.model_name(mux_model).c_str(), + circuit_lib.model_name(pgl_model).c_str()); num_err++; } - if (pgl_model != last_stage_pgl_model && circuit_lib.gate_type(pgl_model) != CIRCUIT_MODEL_GATE_MUX2) { + if (pgl_model != last_stage_pgl_model && + circuit_lib.gate_type(pgl_model) != CIRCUIT_MODEL_GATE_MUX2) { VTR_LOGF_ERROR(__FILE__, __LINE__, - "The last stage pass-gate logic circuit model '%s' of '%s' should be a MUX2 gate!\n", + "The last stage pass-gate logic circuit model '%s' of " + "'%s' should be a MUX2 gate!\n", circuit_lib.model_name(last_stage_pgl_model).c_str(), circuit_lib.model_name(mux_model).c_str()); num_err++; From 4905e694abe15f5774b91adb5020c8a12ec7154a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 18 Sep 2024 21:59:06 -0700 Subject: [PATCH 9/9] [doc] typo --- docs/source/manual/arch_lang/circuit_model_examples.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/manual/arch_lang/circuit_model_examples.rst b/docs/source/manual/arch_lang/circuit_model_examples.rst index a2a64715c..5bc928c6c 100644 --- a/docs/source/manual/arch_lang/circuit_model_examples.rst +++ b/docs/source/manual/arch_lang/circuit_model_examples.rst @@ -639,7 +639,7 @@ Standard Cell Multiplexer -This example shows (see an illustative example in :numref:`fig_stdcellmux`(a)): +This example shows (see an illustative example in :numref:`fig_stdcellmux` (a)): - A tree-like 4-input CMOS multiplexer built by the standard cell ``MUX2`` - All the inputs will be buffered using the circuit model ``inv1x`` - All the outputs will be buffered using the circuit model ``tapbuf4`` @@ -660,7 +660,7 @@ Alternatively, user can specify a different standard cell MUX2 at the last stage -This example shows (see an illustative example in :numref:`fig_stdcellmux`(b)): +This example shows (see an illustative example in :numref:`fig_stdcellmux` (b)): - A tree-like 4-input CMOS multiplexer built by the standard cell ``MUX2`` - The last stage A tree-like 4-input CMOS multiplexer built by the standard cell ``MUX2`` - All the inputs will be buffered using the circuit model ``inv1x``