From 3a0939c40299a1a65a78b4147a8c91979d571de7 Mon Sep 17 00:00:00 2001 From: Andres AG Date: Tue, 23 Jun 2020 11:50:02 +0100 Subject: [PATCH 01/10] Update minimum required Magic version --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 82fe75ed..d6b948ef 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ The OpenRAM compiler has very few dependencies: If you want to perform DRC and LVS, you will need either: + Calibre (for [FreePDK45]) -+ [Magic] 8.2.79 or higher (for [SCMOS]) ++ [Magic] 8.3.27 or higher (for [SCMOS]) + [Netgen] 1.5 (for [SCMOS]) You must set two environment variables: @@ -81,6 +81,8 @@ We have included the most recent SCN4M_SUBM design rules from [Qflow]. ## Docker Image +**WARNING! Some OpenRAM dependency tools installed in the Docker image are out-of-date.** + We have a pre-configured Ubuntu [Docker](https://www.docker.com/) image available that has all tools installed for the [SCMOS] process. It is available at [docker hub](https://hub.docker.com/r/vlsida/openram-ubuntu). From ed9d32c7bc105db2a438d36d4b2d852152a79e3b Mon Sep 17 00:00:00 2001 From: mrg Date: Mon, 13 Jul 2020 16:26:25 -0700 Subject: [PATCH 02/10] OpenRAM 1.1.6 --- compiler/globals.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/globals.py b/compiler/globals.py index a192ebc9..dd4ac177 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -19,7 +19,7 @@ import re import copy import importlib -VERSION = "1.1.5" +VERSION = "1.1.6" NAME = "OpenRAM v{}".format(VERSION) USAGE = "openram.py [options] \nUse -h for help.\n" From ee3da912321b87369e3aa742cc6ba607d17ce759 Mon Sep 17 00:00:00 2001 From: Bob Vanhoof Date: Wed, 15 Jul 2020 11:50:21 +0200 Subject: [PATCH 03/10] calibrepex: file copy fix --- compiler/sram/sram.py | 1 + compiler/verify/calibre.py | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/compiler/sram/sram.py b/compiler/sram/sram.py index 1ec7d636..b2ab1124 100644 --- a/compiler/sram/sram.py +++ b/compiler/sram/sram.py @@ -101,6 +101,7 @@ class sram(): start_time = datetime.datetime.now() # Output the extracted design if requested sp_file = OPTS.output_path + "temp_pex.sp" + spname = OPTS.output_path + self.s.name + ".sp" verify.run_pex(self.s.name, gdsname, spname, output=sp_file) print_time("Extraction", datetime.datetime.now(), start_time) else: diff --git a/compiler/verify/calibre.py b/compiler/verify/calibre.py index 443c91ca..6d1786c9 100644 --- a/compiler/verify/calibre.py +++ b/compiler/verify/calibre.py @@ -135,11 +135,11 @@ def write_calibre_lvs_script(cell_name, final_verification): def write_calibre_pex_script(cell_name, extract, output, final_verification): """ Write a pex script that can either just extract the netlist or the netlist+parasitics """ if output == None: - output = name + ".pex.netlist" + output = cell_name + ".pex.netlist" # check if lvs report has been done # if not run drc and lvs - if not os.path.isfile(cell_name + ".lvs.report"): + if not os.path.isfile(OPTS.openram_temp + cell_name + ".lvs.report"): gds_name = OPTS.openram_temp +"/"+ cell_name + ".gds" sp_name = OPTS.openram_temp +"/"+ cell_name + ".sp" run_drc(cell_name, gds_name) @@ -155,7 +155,7 @@ def write_calibre_pex_script(cell_name, extract, output, final_verification): 'pexSourcePath': cell_name + ".sp", 'pexSourcePrimary': cell_name, 'pexReportFile': cell_name + ".pex.report", - 'pexPexNetlistFile': cell_name + ".pex.netlist", + 'pexPexNetlistFile': output, 'pexPexReportFile': cell_name + ".pex.report", 'pexMaskDBFile': cell_name + ".maskdb", 'cmnFDIDEFLayoutPath': cell_name + ".def", @@ -195,8 +195,8 @@ def run_drc(cell_name, gds_name, extract=False, final_verification=False): filter_gds(cell_name, OPTS.openram_temp + "temp.gds", OPTS.openram_temp + cell_name + ".gds") else: # Copy file to local dir if it isn't already - if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): - shutil.copy(gds_name, OPTS.openram_temp) + if not os.path.isfile(gds_name): + shutil.copy(OPTS.output_path+os.path.basename(gds_name),gds_name) drc_runset = write_calibre_drc_script(cell_name, extract, final_verification) @@ -241,10 +241,14 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False): lvs_runset = write_calibre_lvs_script(cell_name, final_verification) # Copy file to local dir if it isn't already - if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): - shutil.copy(gds_name, OPTS.openram_temp) - if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'): - shutil.copy(sp_name, OPTS.openram_temp) +# if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): +# shutil.copy(gds_name, OPTS.openram_temp) +# if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'): +# shutil.copy(sp_name, OPTS.openram_temp) + if not os.path.isfile(gds_name): + shutil.copy(OPTS.output_path+os.path.basename(gds_name), gds_name) + if not os.path.isfile(sp_name): + shutil.copy(OPTS.output_path+os.path.basename(sp_name), sp_name) (outfile, errfile, resultsfile) = run_script(cell_name, "lvs") @@ -327,6 +331,11 @@ def run_pex(cell_name, gds_name, sp_name, output=None, final_verification=False) write_calibre_pex_script(cell_name,True,output,final_verification) + if not os.path.isfile(OPTS.openram_temp + os.path.basename(gds_name)): + shutil.copy(gds_name, OPTS.openram_temp + os.path.basename(gds_name)) + if not os.path.isfile(OPTS.openram_temp + os.path.basename(sp_name)): + shutil.copy(sp_name, OPTS.openram_temp + os.path.basename(sp_name)) + (outfile, errfile, resultsfile) = run_script(cell_name, "pex") From b7c43ae674bb1876e6136e3d4bc55b6886860fb6 Mon Sep 17 00:00:00 2001 From: mrg Date: Thu, 23 Jul 2020 14:17:13 -0700 Subject: [PATCH 04/10] Fix 1w/1r example --- compiler/example_configs/example_config_1w_1r_scn4m_subm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/example_configs/example_config_1w_1r_scn4m_subm.py b/compiler/example_configs/example_config_1w_1r_scn4m_subm.py index 55ac4016..7698f1a3 100644 --- a/compiler/example_configs/example_config_1w_1r_scn4m_subm.py +++ b/compiler/example_configs/example_config_1w_1r_scn4m_subm.py @@ -1,9 +1,9 @@ word_size = 2 num_words = 16 -num_rw_ports = 1 +num_rw_ports = 0 num_r_ports = 1 -num_w_ports = 0 +num_w_ports = 1 tech_name = "scn4m_subm" nominal_corners_only = False From c65178f86c14cbbef87293019a7030fa232ffa94 Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Mon, 27 Jul 2020 15:43:50 -0700 Subject: [PATCH 05/10] Fixed issue with sen delay measure getting mixed with voltage checks --- compiler/characterizer/delay.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index b7faaec3..9d36fce7 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -185,8 +185,7 @@ class delay(simulation): self.sen_meas = delay_measure("delay_sen", self.clk_frmt, self.sen_name+"{}", "FALL", "RISE", measure_scale=1e9) self.sen_meas.meta_str = sram_op.READ_ZERO self.sen_meas.meta_add_delay = True - self.dout_volt_meas.append(self.sen_meas) - + return self.dout_volt_meas def create_read_bit_measures(self): From 9ea3616260820c2010316047a29916235d5ad0b8 Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Mon, 27 Jul 2020 15:47:02 -0700 Subject: [PATCH 06/10] Changed multiport characterization warning to better fit --- compiler/characterizer/delay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 9d36fce7..1fcd86f4 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -1350,7 +1350,7 @@ class delay(simulation): Return the analytical model results for the SRAM. """ if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0: - debug.warning("Analytical characterization results are not supported for multiport.") + debug.warning("Analytical characterization for multiple read ports may be inaccurate.") # Probe set to 0th bit, does not matter for analytical delay. self.set_probe('0'*self.addr_size, 0) From b4dafac489d4f618bcb3fc080a97f5688e5f1fac Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Mon, 27 Jul 2020 23:55:03 -0700 Subject: [PATCH 07/10] Fixed issue with sen measurement not being added --- compiler/characterizer/delay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 1fcd86f4..afb9c7f6 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -186,7 +186,7 @@ class delay(simulation): self.sen_meas.meta_str = sram_op.READ_ZERO self.sen_meas.meta_add_delay = True - return self.dout_volt_meas + return self.dout_volt_meas + [self.sen_meas] def create_read_bit_measures(self): """ Adds bit measurements for read0 and read1 cycles """ From f23d2e36a798685c3d0795f6c4c711da0229afd7 Mon Sep 17 00:00:00 2001 From: mrg Date: Wed, 29 Jul 2020 10:31:18 -0700 Subject: [PATCH 08/10] Don't obstruct control logic signals with dffs when no column mux. --- compiler/sram/sram_1bank.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/sram/sram_1bank.py b/compiler/sram/sram_1bank.py index a5dfb0e5..fc390f37 100644 --- a/compiler/sram/sram_1bank.py +++ b/compiler/sram/sram_1bank.py @@ -160,7 +160,10 @@ class sram_1bank(sram_base): port = 0 # Add the col address flops below the bank to the right of the control logic x_offset = self.control_logic_insts[port].rx() + self.dff.width - y_offset = - self.data_bus_size[port] - self.dff.height + # Place it a data bus below the x-axis, but at least as low as the control logic to not block + # the control logic signals + y_offset = min(-self.data_bus_size[port] - self.dff.height, + self.control_logic_insts[port].by()) if self.col_addr_dff: self.col_addr_pos[port] = vector(x_offset, y_offset) @@ -201,7 +204,10 @@ class sram_1bank(sram_base): # Add the col address flops below the bank to the right of the control logic x_offset = self.control_logic_insts[port].lx() - 2 * self.dff.width - y_offset = self.bank.height + self.data_bus_size[port] + self.dff.height + # Place it a data bus below the x-axis, but at least as high as the control logic to not block + # the control logic signals + y_offset = max(self.bank.height + self.data_bus_size[port] + self.dff.height, + self.control_logic_insts[port].uy() - self.dff.height) if self.col_addr_dff: self.col_addr_pos[port] = vector(x_offset, y_offset) From c6f2edc20d03f292ff19b1f709761f84d6a6eba6 Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Wed, 29 Jul 2020 19:50:06 -0700 Subject: [PATCH 09/10] Changed warning message for multiport analytical characterization. --- compiler/characterizer/delay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index afb9c7f6..3f5d61af 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -1350,7 +1350,7 @@ class delay(simulation): Return the analytical model results for the SRAM. """ if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0: - debug.warning("Analytical characterization for multiple read ports may be inaccurate.") + debug.warning("In analytical mode, all ports have the timing of the first read port.") # Probe set to 0th bit, does not matter for analytical delay. self.set_probe('0'*self.addr_size, 0) From 8fa0065aafb8e98f3b275d2508fb51ee13059cb7 Mon Sep 17 00:00:00 2001 From: mrg Date: Thu, 30 Jul 2020 11:09:19 -0700 Subject: [PATCH 10/10] Undo PR 82 changes -- broke unit test. --- compiler/verify/calibre.py | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/compiler/verify/calibre.py b/compiler/verify/calibre.py index 6d1786c9..443c91ca 100644 --- a/compiler/verify/calibre.py +++ b/compiler/verify/calibre.py @@ -135,11 +135,11 @@ def write_calibre_lvs_script(cell_name, final_verification): def write_calibre_pex_script(cell_name, extract, output, final_verification): """ Write a pex script that can either just extract the netlist or the netlist+parasitics """ if output == None: - output = cell_name + ".pex.netlist" + output = name + ".pex.netlist" # check if lvs report has been done # if not run drc and lvs - if not os.path.isfile(OPTS.openram_temp + cell_name + ".lvs.report"): + if not os.path.isfile(cell_name + ".lvs.report"): gds_name = OPTS.openram_temp +"/"+ cell_name + ".gds" sp_name = OPTS.openram_temp +"/"+ cell_name + ".sp" run_drc(cell_name, gds_name) @@ -155,7 +155,7 @@ def write_calibre_pex_script(cell_name, extract, output, final_verification): 'pexSourcePath': cell_name + ".sp", 'pexSourcePrimary': cell_name, 'pexReportFile': cell_name + ".pex.report", - 'pexPexNetlistFile': output, + 'pexPexNetlistFile': cell_name + ".pex.netlist", 'pexPexReportFile': cell_name + ".pex.report", 'pexMaskDBFile': cell_name + ".maskdb", 'cmnFDIDEFLayoutPath': cell_name + ".def", @@ -195,8 +195,8 @@ def run_drc(cell_name, gds_name, extract=False, final_verification=False): filter_gds(cell_name, OPTS.openram_temp + "temp.gds", OPTS.openram_temp + cell_name + ".gds") else: # Copy file to local dir if it isn't already - if not os.path.isfile(gds_name): - shutil.copy(OPTS.output_path+os.path.basename(gds_name),gds_name) + if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): + shutil.copy(gds_name, OPTS.openram_temp) drc_runset = write_calibre_drc_script(cell_name, extract, final_verification) @@ -241,14 +241,10 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False): lvs_runset = write_calibre_lvs_script(cell_name, final_verification) # Copy file to local dir if it isn't already -# if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): -# shutil.copy(gds_name, OPTS.openram_temp) -# if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'): -# shutil.copy(sp_name, OPTS.openram_temp) - if not os.path.isfile(gds_name): - shutil.copy(OPTS.output_path+os.path.basename(gds_name), gds_name) - if not os.path.isfile(sp_name): - shutil.copy(OPTS.output_path+os.path.basename(sp_name), sp_name) + if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): + shutil.copy(gds_name, OPTS.openram_temp) + if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'): + shutil.copy(sp_name, OPTS.openram_temp) (outfile, errfile, resultsfile) = run_script(cell_name, "lvs") @@ -331,11 +327,6 @@ def run_pex(cell_name, gds_name, sp_name, output=None, final_verification=False) write_calibre_pex_script(cell_name,True,output,final_verification) - if not os.path.isfile(OPTS.openram_temp + os.path.basename(gds_name)): - shutil.copy(gds_name, OPTS.openram_temp + os.path.basename(gds_name)) - if not os.path.isfile(OPTS.openram_temp + os.path.basename(sp_name)): - shutil.copy(sp_name, OPTS.openram_temp + os.path.basename(sp_name)) - (outfile, errfile, resultsfile) = run_script(cell_name, "pex")