def test_combinational(self): ir_file = self.create_tempfile(content=NOT_ADD_IR) signature_path = test_base.create_named_output_text_file( 'combinational_sig.textproto') verilog_path = test_base.create_named_output_text_file('combinational.v') subprocess.check_call([ CODEGEN_MAIN_PATH, '--generator=combinational', '--alsologtostderr', '--entry=not_add', '--output_signature_path=' + signature_path, '--output_verilog_path=' + verilog_path, ir_file.full_path ]) with open(verilog_path, 'r') as f: self.assertIn('module not_add(', f.read()) with open(signature_path, 'r') as f: sig_proto = text_format.Parse(f.read(), module_signature_pb2.ModuleSignatureProto()) self.assertEqual(sig_proto.module_name, 'not_add') self.assertTrue(sig_proto.HasField('combinational'))
def test_fixed_pipeline_length(self, pipeline_stages): signature_path = test_base.create_named_output_text_file( f'sha256.{pipeline_stages}_stage.sig.textproto') verilog_path = test_base.create_named_output_text_file( f'sha256.{pipeline_stages}_stage.v') subprocess.check_call([ CODEGEN_MAIN_PATH, '--generator=pipeline', '--delay_model=unit', '--pipeline_stages=' + str(pipeline_stages), '--alsologtostderr', '--output_signature_path=' + signature_path, '--output_verilog_path=' + verilog_path, SHA256_IR_PATH ]) with open(verilog_path, 'r') as f: verilog = f.read() self.assertIn(f'// ===== Pipe stage {pipeline_stages}', verilog) self.assertNotIn(f'// ===== Pipe stage {pipeline_stages + 1}', verilog) with open(signature_path, 'r') as f: sig_proto = text_format.Parse(f.read(), module_signature_pb2.ModuleSignatureProto()) self.assertTrue(sig_proto.HasField('pipeline')) self.assertEqual(sig_proto.pipeline.latency, pipeline_stages + 1)
def generate_parallel_module(modules: Sequence[ module_signature_mod.ModuleGeneratorResult], module_name: str) -> str: """Generates a module composed of instantiated instances of the given modules. Each module in 'modules' is instantiated exactly once in a enclosing, composite module. Inputs to each instantiation are provided by inputs to the enclosing module. For example, if given two modules, add8_module and add16_module, the generated module might look like: module add8_module( input wire clk, input wire [7:0] op0, input wire [7:0] op1, output wire [7:0] out ); // contents of module elided... endmodule module add16_module( input wire clk, input wire [15:0] op0, input wire [15:0] op1, output wire [15:0] out ); // contents of module elided... endmodule module foo( input wire clk, input wire [7:0] add8_module_op0, input wire [7:0] add8_module_op1, output wire [7:0] add8_module_out, input wire [15:0] add16_module_op0, input wire [15:0] add16_module_op1, output wire [15:0] add16_module_out, ); add8_module add8_module_inst( .clk(clk), .op0(add8_module_op0), .op1(add8_module_op1), .out(add8_module_out) ); add16_module add16_module_inst( .clk(clk), .op0(add16_module_op0), .op1(add16_module_op1), .out(add16_module_out) ); endmodule Arguments: modules: Modules to include instantiate. module_name: Name of the module containing the instantiated input modules. Returns: Verilog text containing the composite module and component modules. """ module_protos = [ text_format.Parse(m.signature.as_text_proto(), module_signature_pb2.ModuleSignatureProto()) for m in modules ] ports = ['input wire clk'] for module in module_protos: for data_port in module.data_ports: width_str = f'[{data_port.width - 1}:0]' signal_name = f'{module.module_name}_{data_port.name}' if data_port.direction == module_signature_pb2.DIRECTION_INPUT: ports.append(f'input wire {width_str} {signal_name}') elif data_port.direction == module_signature_pb2.DIRECTION_OUTPUT: ports.append(f'output wire {width_str} {signal_name}') header = """module {module_name}(\n{ports}\n);""".format( module_name=module_name, ports=',\n'.join(f' {p}' for p in ports)) instantiations = [] for module in module_protos: connections = ['.clk(clk)'] for data_port in module.data_ports: connections.append( f'.{data_port.name}({module.module_name}_{data_port.name})') instantiations.append(' {name} {name}_inst(\n{connections}\n );'.format( name=module.module_name, connections=',\n'.join(f' {c}' for c in connections))) return '{modules}\n\n{header}\n{instantiations}\nendmodule\n'.format( modules='\n\n'.join(m.verilog_text for m in modules), header=header, instantiations='\n'.join(instantiations))