librelane 2.4.0.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of librelane might be problematic. Click here for more details.

Files changed (166) hide show
  1. librelane/__init__.py +38 -0
  2. librelane/__main__.py +470 -0
  3. librelane/__version__.py +43 -0
  4. librelane/common/__init__.py +61 -0
  5. librelane/common/cli.py +75 -0
  6. librelane/common/drc.py +245 -0
  7. librelane/common/generic_dict.py +319 -0
  8. librelane/common/metrics/__init__.py +35 -0
  9. librelane/common/metrics/__main__.py +413 -0
  10. librelane/common/metrics/library.py +354 -0
  11. librelane/common/metrics/metric.py +186 -0
  12. librelane/common/metrics/util.py +279 -0
  13. librelane/common/misc.py +402 -0
  14. librelane/common/ring_buffer.py +63 -0
  15. librelane/common/tcl.py +80 -0
  16. librelane/common/toolbox.py +549 -0
  17. librelane/common/tpe.py +41 -0
  18. librelane/common/types.py +117 -0
  19. librelane/config/__init__.py +32 -0
  20. librelane/config/__main__.py +158 -0
  21. librelane/config/config.py +1025 -0
  22. librelane/config/flow.py +490 -0
  23. librelane/config/pdk_compat.py +255 -0
  24. librelane/config/preprocessor.py +464 -0
  25. librelane/config/removals.py +45 -0
  26. librelane/config/variable.py +722 -0
  27. librelane/container.py +264 -0
  28. librelane/env_info.py +306 -0
  29. librelane/examples/spm/config.yaml +33 -0
  30. librelane/examples/spm/pin_order.cfg +14 -0
  31. librelane/examples/spm/src/impl.sdc +73 -0
  32. librelane/examples/spm/src/signoff.sdc +68 -0
  33. librelane/examples/spm/src/spm.v +73 -0
  34. librelane/examples/spm/verify/spm_tb.v +106 -0
  35. librelane/examples/spm-user_project_wrapper/SPM_example.v +286 -0
  36. librelane/examples/spm-user_project_wrapper/base_sdc_file.sdc +145 -0
  37. librelane/examples/spm-user_project_wrapper/config-tut.json +12 -0
  38. librelane/examples/spm-user_project_wrapper/config.json +13 -0
  39. librelane/examples/spm-user_project_wrapper/defines.v +66 -0
  40. librelane/examples/spm-user_project_wrapper/template.def +7656 -0
  41. librelane/examples/spm-user_project_wrapper/user_project_wrapper.v +123 -0
  42. librelane/flows/__init__.py +24 -0
  43. librelane/flows/builtins.py +18 -0
  44. librelane/flows/classic.py +330 -0
  45. librelane/flows/cli.py +463 -0
  46. librelane/flows/flow.py +985 -0
  47. librelane/flows/misc.py +71 -0
  48. librelane/flows/optimizing.py +179 -0
  49. librelane/flows/sequential.py +367 -0
  50. librelane/flows/synth_explore.py +173 -0
  51. librelane/logging/__init__.py +40 -0
  52. librelane/logging/logger.py +323 -0
  53. librelane/open_pdks_rev +1 -0
  54. librelane/plugins.py +21 -0
  55. librelane/py.typed +0 -0
  56. librelane/scripts/base.sdc +80 -0
  57. librelane/scripts/klayout/Readme.md +2 -0
  58. librelane/scripts/klayout/open_design.py +63 -0
  59. librelane/scripts/klayout/render.py +121 -0
  60. librelane/scripts/klayout/stream_out.py +176 -0
  61. librelane/scripts/klayout/xml_drc_report_to_json.py +45 -0
  62. librelane/scripts/klayout/xor.drc +120 -0
  63. librelane/scripts/magic/Readme.md +1 -0
  64. librelane/scripts/magic/common/read.tcl +114 -0
  65. librelane/scripts/magic/def/antenna_check.tcl +35 -0
  66. librelane/scripts/magic/def/mag.tcl +19 -0
  67. librelane/scripts/magic/def/mag_gds.tcl +81 -0
  68. librelane/scripts/magic/drc.tcl +79 -0
  69. librelane/scripts/magic/extract_spice.tcl +98 -0
  70. librelane/scripts/magic/gds/drc_batch.tcl +74 -0
  71. librelane/scripts/magic/gds/erase_box.tcl +32 -0
  72. librelane/scripts/magic/gds/extras_mag.tcl +47 -0
  73. librelane/scripts/magic/gds/mag_with_pointers.tcl +32 -0
  74. librelane/scripts/magic/get_bbox.tcl +11 -0
  75. librelane/scripts/magic/lef/extras_maglef.tcl +63 -0
  76. librelane/scripts/magic/lef/maglef.tcl +27 -0
  77. librelane/scripts/magic/lef.tcl +57 -0
  78. librelane/scripts/magic/open.tcl +28 -0
  79. librelane/scripts/magic/wrapper.tcl +19 -0
  80. librelane/scripts/netgen/setup.tcl +28 -0
  81. librelane/scripts/odbpy/apply_def_template.py +49 -0
  82. librelane/scripts/odbpy/cell_frequency.py +107 -0
  83. librelane/scripts/odbpy/check_antenna_properties.py +116 -0
  84. librelane/scripts/odbpy/contextualize.py +109 -0
  85. librelane/scripts/odbpy/defutil.py +574 -0
  86. librelane/scripts/odbpy/diodes.py +373 -0
  87. librelane/scripts/odbpy/disconnected_pins.py +305 -0
  88. librelane/scripts/odbpy/exception_codes.py +17 -0
  89. librelane/scripts/odbpy/filter_unannotated.py +100 -0
  90. librelane/scripts/odbpy/io_place.py +482 -0
  91. librelane/scripts/odbpy/label_macro_pins.py +277 -0
  92. librelane/scripts/odbpy/lefutil.py +97 -0
  93. librelane/scripts/odbpy/placers.py +162 -0
  94. librelane/scripts/odbpy/power_utils.py +395 -0
  95. librelane/scripts/odbpy/random_place.py +57 -0
  96. librelane/scripts/odbpy/reader.py +246 -0
  97. librelane/scripts/odbpy/remove_buffers.py +173 -0
  98. librelane/scripts/odbpy/snap_to_grid.py +57 -0
  99. librelane/scripts/odbpy/wire_lengths.py +93 -0
  100. librelane/scripts/openroad/antenna_check.tcl +20 -0
  101. librelane/scripts/openroad/antenna_repair.tcl +31 -0
  102. librelane/scripts/openroad/basic_mp.tcl +24 -0
  103. librelane/scripts/openroad/buffer_list.tcl +10 -0
  104. librelane/scripts/openroad/common/dpl.tcl +24 -0
  105. librelane/scripts/openroad/common/dpl_cell_pad.tcl +26 -0
  106. librelane/scripts/openroad/common/grt.tcl +32 -0
  107. librelane/scripts/openroad/common/io.tcl +476 -0
  108. librelane/scripts/openroad/common/pdn_cfg.tcl +135 -0
  109. librelane/scripts/openroad/common/resizer.tcl +103 -0
  110. librelane/scripts/openroad/common/set_global_connections.tcl +78 -0
  111. librelane/scripts/openroad/common/set_layer_adjustments.tcl +31 -0
  112. librelane/scripts/openroad/common/set_power_nets.tcl +30 -0
  113. librelane/scripts/openroad/common/set_rc.tcl +75 -0
  114. librelane/scripts/openroad/common/set_routing_layers.tcl +30 -0
  115. librelane/scripts/openroad/cts.tcl +80 -0
  116. librelane/scripts/openroad/cut_rows.tcl +24 -0
  117. librelane/scripts/openroad/dpl.tcl +24 -0
  118. librelane/scripts/openroad/drt.tcl +37 -0
  119. librelane/scripts/openroad/fill.tcl +30 -0
  120. librelane/scripts/openroad/floorplan.tcl +145 -0
  121. librelane/scripts/openroad/gpl.tcl +88 -0
  122. librelane/scripts/openroad/grt.tcl +30 -0
  123. librelane/scripts/openroad/gui.tcl +15 -0
  124. librelane/scripts/openroad/insert_buffer.tcl +127 -0
  125. librelane/scripts/openroad/ioplacer.tcl +67 -0
  126. librelane/scripts/openroad/irdrop.tcl +51 -0
  127. librelane/scripts/openroad/pdn.tcl +52 -0
  128. librelane/scripts/openroad/rcx.tcl +32 -0
  129. librelane/scripts/openroad/repair_design.tcl +70 -0
  130. librelane/scripts/openroad/repair_design_postgrt.tcl +48 -0
  131. librelane/scripts/openroad/rsz_timing_postcts.tcl +68 -0
  132. librelane/scripts/openroad/rsz_timing_postgrt.tcl +70 -0
  133. librelane/scripts/openroad/sta/check_macro_instances.tcl +53 -0
  134. librelane/scripts/openroad/sta/corner.tcl +393 -0
  135. librelane/scripts/openroad/tapcell.tcl +25 -0
  136. librelane/scripts/openroad/write_views.tcl +27 -0
  137. librelane/scripts/pyosys/construct_abc_script.py +177 -0
  138. librelane/scripts/pyosys/json_header.py +84 -0
  139. librelane/scripts/pyosys/synthesize.py +493 -0
  140. librelane/scripts/pyosys/ys_common.py +153 -0
  141. librelane/scripts/tclsh/hello.tcl +1 -0
  142. librelane/state/__init__.py +24 -0
  143. librelane/state/__main__.py +61 -0
  144. librelane/state/design_format.py +180 -0
  145. librelane/state/state.py +351 -0
  146. librelane/steps/__init__.py +61 -0
  147. librelane/steps/__main__.py +511 -0
  148. librelane/steps/checker.py +637 -0
  149. librelane/steps/common_variables.py +340 -0
  150. librelane/steps/cvc_rv.py +169 -0
  151. librelane/steps/klayout.py +509 -0
  152. librelane/steps/magic.py +566 -0
  153. librelane/steps/misc.py +160 -0
  154. librelane/steps/netgen.py +253 -0
  155. librelane/steps/odb.py +955 -0
  156. librelane/steps/openroad.py +2433 -0
  157. librelane/steps/openroad_alerts.py +102 -0
  158. librelane/steps/pyosys.py +629 -0
  159. librelane/steps/step.py +1547 -0
  160. librelane/steps/tclstep.py +288 -0
  161. librelane/steps/verilator.py +222 -0
  162. librelane/steps/yosys.py +371 -0
  163. librelane-2.4.0.dev0.dist-info/METADATA +151 -0
  164. librelane-2.4.0.dev0.dist-info/RECORD +166 -0
  165. librelane-2.4.0.dev0.dist-info/WHEEL +4 -0
  166. librelane-2.4.0.dev0.dist-info/entry_points.txt +8 -0
@@ -0,0 +1,68 @@
1
+ # Compared to the implementation SDC, the signoff SDC relaxes
2
+ # max capacitance and transition constraints. (Which are intentionally over-
3
+ # constrained for implementation to yield better results.)
4
+
5
+ set clock_port __VIRTUAL_CLK__
6
+ if { [info exists ::env(CLOCK_PORT)] } {
7
+ set port_count [llength $::env(CLOCK_PORT)]
8
+
9
+ if { $port_count == "0" } {
10
+ puts stderr "\[WARNING] No CLOCK_PORT found. A dummy clock will be used."
11
+ } elseif { $port_count != "1" } {
12
+ puts stderr "\[WARNING] Multi-clock files are not currently supported by the base SDC file. Only the first clock will be constrained."
13
+ }
14
+
15
+ if { $port_count > "0" } {
16
+ set ::clock_port [lindex $::env(CLOCK_PORT) 0]
17
+ }
18
+ }
19
+ set port_args [get_ports $clock_port]
20
+ puts "\[INFO] Using clock $clock_port…"
21
+ create_clock {*}$port_args -name $clock_port -period $::env(CLOCK_PERIOD)
22
+
23
+ set input_delay_value [expr $::env(CLOCK_PERIOD) * $::env(IO_DELAY_CONSTRAINT) / 100]
24
+ set output_delay_value [expr $::env(CLOCK_PERIOD) * $::env(IO_DELAY_CONSTRAINT) / 100]
25
+ puts "\[INFO] Setting output delay to: $output_delay_value"
26
+ puts "\[INFO] Setting input delay to: $input_delay_value"
27
+
28
+ set_max_fanout $::env(MAX_FANOUT_CONSTRAINT) [current_design]
29
+
30
+ set clk_input [get_port $clock_port]
31
+ set clk_indx [lsearch [all_inputs] $clk_input]
32
+ set all_inputs_wo_clk [lreplace [all_inputs] $clk_indx $clk_indx ""]
33
+
34
+ #set rst_input [get_port resetn]
35
+ #set rst_indx [lsearch [all_inputs] $rst_input]
36
+ #set all_inputs_wo_clk_rst [lreplace $all_inputs_wo_clk $rst_indx $rst_indx ""]
37
+ set all_inputs_wo_clk_rst $all_inputs_wo_clk
38
+
39
+ # correct resetn
40
+ set clocks [get_clocks $clock_port]
41
+
42
+ set_input_delay $input_delay_value -clock $clocks $all_inputs_wo_clk_rst
43
+ set_output_delay $output_delay_value -clock $clocks [all_outputs]
44
+
45
+ if { ![info exists ::env(SYNTH_CLK_DRIVING_CELL)] } {
46
+ set ::env(SYNTH_CLK_DRIVING_CELL) $::env(SYNTH_DRIVING_CELL)
47
+ }
48
+
49
+ set_driving_cell \
50
+ -lib_cell [lindex [split $::env(SYNTH_DRIVING_CELL) "/"] 0] \
51
+ -pin [lindex [split $::env(SYNTH_DRIVING_CELL) "/"] 1] \
52
+ $all_inputs_wo_clk_rst
53
+
54
+ set_driving_cell \
55
+ -lib_cell [lindex [split $::env(SYNTH_CLK_DRIVING_CELL) "/"] 0] \
56
+ -pin [lindex [split $::env(SYNTH_CLK_DRIVING_CELL) "/"] 1] \
57
+ $clk_input
58
+
59
+ set cap_load [expr $::env(OUTPUT_CAP_LOAD) / 1000.0]
60
+ puts "\[INFO] Setting load to: $cap_load"
61
+ set_load $cap_load [all_outputs]
62
+
63
+ puts "\[INFO] Setting clock uncertainty to: 0.1"
64
+ set_clock_uncertainty 0.1 $clocks
65
+
66
+ puts "\[INFO] Setting timing derate to: $::env(TIME_DERATING_CONSTRAINT)%"
67
+ set_timing_derate -early [expr 1-[expr $::env(TIME_DERATING_CONSTRAINT) / 100]]
68
+ set_timing_derate -late [expr 1+[expr $::env(TIME_DERATING_CONSTRAINT) / 100]]
@@ -0,0 +1,73 @@
1
+ // Copyright 2023 Efabless Corporation
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // (Parameterized) Unsigned Serial/Parallel Multiplier:
16
+ // - Multiplicand x (Input bit-serially)
17
+ // - Multiplier a (All bits at the same time/Parallel)
18
+ // - Product y (Output bit-serial)
19
+ module spm #(parameter bits=32) (
20
+ input clk,
21
+ input rst,
22
+ input x,
23
+ input[bits-1: 0] a,
24
+ output y
25
+ );
26
+ wire[bits: 0] y_chain;
27
+ assign y_chain[0] = 0;
28
+ assign y = y_chain[bits];
29
+
30
+ wire[bits-1:0] a_flip;
31
+ genvar i;
32
+ generate
33
+ for (i = 0; i < bits; i = i + 1) begin : flip_block
34
+ assign a_flip[i] = a[bits - i - 1];
35
+ end
36
+ endgenerate
37
+
38
+ delayed_serial_adder dsa[bits-1:0](
39
+ .clk(clk),
40
+ .rst(rst),
41
+ .x(x),
42
+ .a(a_flip),
43
+ .y_in(y_chain[bits-1:0]),
44
+ .y_out(y_chain[bits:1])
45
+ );
46
+
47
+ endmodule
48
+
49
+ module delayed_serial_adder(
50
+ input clk,
51
+ input rst,
52
+ input x,
53
+ input a,
54
+ input y_in,
55
+ output reg y_out
56
+ );
57
+ reg last_carry;
58
+ wire last_carry_next;
59
+ wire y_out_next;
60
+
61
+ wire g = x & a;
62
+ assign {last_carry_next, y_out_next} = g + y_in + last_carry;
63
+
64
+ always @ (posedge clk or negedge rst) begin
65
+ if (!rst) begin
66
+ last_carry <= 1'b0;
67
+ y_out <= 1'b0;
68
+ end else begin
69
+ last_carry <= last_carry_next;
70
+ y_out <= y_out_next;
71
+ end
72
+ end
73
+ endmodule
@@ -0,0 +1,106 @@
1
+ // Copyright 2023 Efabless Corporation
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ module spm_tb;
16
+ localparam bits = 32;
17
+ reg clk;
18
+ reg rst;
19
+ reg load;
20
+ reg[bits-1:0] x;
21
+ reg[bits-1:0] a;
22
+
23
+ wire[bits-1:0] srx_value;
24
+ sreg #(bits) srx(
25
+ .clk(clk),
26
+ .rst(rst),
27
+ .direction(1'b1),
28
+ .serial_msb(1'b0),
29
+ .serial_lsb(1'b0),
30
+ .load(load),
31
+ .load_value(x),
32
+ .value(srx_value)
33
+ );
34
+
35
+ wire y;
36
+ wire [bits*2-1:0] y_value;
37
+ sreg #(bits * 2) sry(
38
+ .clk(clk),
39
+ .rst(rst),
40
+ .direction(1'b1),
41
+ .serial_msb(y),
42
+ .serial_lsb(1'b0),
43
+ .load(1'b0),
44
+ .load_value({(bits*2){1'b0}}),
45
+ .value(y_value)
46
+ );
47
+
48
+ spm dut(
49
+ .clk(clk),
50
+ .rst(rst),
51
+ .x(srx_value[0]),
52
+ .a(a),
53
+ .y(y)
54
+ );
55
+
56
+ always #1 clk = ~clk;
57
+
58
+ reg [bits*2-1:0] expected;
59
+
60
+ initial begin
61
+ $dumpvars(0, spm_tb);
62
+ for (integer i = 0; i < 20; i = i + 1) begin
63
+ clk = 0;
64
+ rst = 0;
65
+ load = 0;
66
+ x = $random;
67
+ a = $random;
68
+ expected = x * a;
69
+ #2;
70
+ load = 1;
71
+ rst = 1;
72
+ #2;
73
+ load = 0;
74
+ #2; // No useful bit at the first clock cycle
75
+ #(bits * 2 * 2); // 2 * bits * clock cycle duration
76
+ $display("%h * %h", x, a);
77
+ $display("expected %h, got %h (%s)", expected, y_value, expected==y_value ? "ok " : "err");
78
+ end
79
+ $finish;
80
+ end
81
+ endmodule
82
+
83
+ module sreg #(parameter width = 32) (
84
+ input clk,
85
+ input rst,
86
+ input direction, // 0 -> load from lsb side; 1 -> load from msb side
87
+ input serial_msb,
88
+ input serial_lsb,
89
+ input load,
90
+ input[width-1:0] load_value,
91
+ output[width-1:0] value
92
+ );
93
+ reg[width-1:0] store;
94
+
95
+ assign value = store;
96
+
97
+ always @ (posedge clk or negedge rst) begin
98
+ if (!rst) begin
99
+ store <= {(width){1'b0}};
100
+ end else begin
101
+ store <= load ? load_value :
102
+ direction ? {serial_msb, store[width-1:1]}:
103
+ {store[width-2:0], serial_lsb};
104
+ end
105
+ end
106
+ endmodule
@@ -0,0 +1,286 @@
1
+ // Copyright 2023 Efabless Corporation
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // (Parameterized) Unsigned Serial/Parallel Multiplier:
16
+ // - Multiplicand x (Input bit-serially)
17
+ // - Multiplier a (All bits at the same time/Parallel)
18
+ // - Product y (Output bit-serial)
19
+
20
+ `default_nettype none
21
+ /*
22
+ *-------------------------------------------------------------
23
+ *
24
+ * user_proj_example
25
+ *
26
+ * This is an example of a (trivially simple) user project,
27
+ * showing how the user project can connect to the logic
28
+ * analyzer, the wishbone bus, and the I/O pads.
29
+ *
30
+ * This project generates an integer count, which is output
31
+ * on the user area GPIO pads (digital output only). The
32
+ * wishbone connection allows the project to be controlled
33
+ * (start and stop) from the management SoC program.
34
+ *
35
+ * See the testbenches in directory "mprj_counter" for the
36
+ * example programs that drive this user project. The three
37
+ * testbenches are "io_ports", "la_test1", and "la_test2".
38
+ *
39
+ *-------------------------------------------------------------
40
+ */
41
+
42
+ module SPM_example #(
43
+ parameter BITS = 32
44
+ )(
45
+ `ifdef USE_POWER_PINS
46
+ inout vccd1, // User area 1 1.8V supply
47
+ inout vssd1, // User area 1 digital ground
48
+ // inout vdda2,
49
+ // inout vssd2,
50
+ `endif
51
+
52
+ // Wishbone Slave ports (WB MI A)
53
+ input wb_clk_i,
54
+ input wb_rst_i,
55
+ input wbs_stb_i,
56
+ input wbs_cyc_i,
57
+ input wbs_we_i,
58
+ input [3:0] wbs_sel_i,
59
+ input [31:0] wbs_dat_i,
60
+ input [31:0] wbs_adr_i,
61
+ output reg wbs_ack_o,
62
+ output reg [31:0] wbs_dat_o,
63
+
64
+ // Logic Analyzer Signals
65
+ input [127:0] la_data_in,
66
+ output [127:0] la_data_out,
67
+ input [127:0] la_oenb,
68
+
69
+ // IOs
70
+ input wire [`MPRJ_IO_PADS-1:0] io_in,
71
+ output wire [`MPRJ_IO_PADS-1:0] io_out,
72
+ output wire [`MPRJ_IO_PADS-1:0] io_oeb,
73
+
74
+ // IRQ
75
+ output [2:0] irq
76
+ );
77
+ wire clk;
78
+ wire rst;
79
+
80
+
81
+ wire [31:0] rdata;
82
+ wire [31:0] wdata;
83
+ wire [BITS-1:0] count;
84
+
85
+ wire valid;
86
+ wire [3:0] wstrb;
87
+ wire [31:0] la_write;
88
+
89
+ //addresses for registers
90
+ localparam X_OFF = 805306368, Y_OFF = 805306372, Y0_OFF = 805306376, Y1_OFF = 805306380, STAT_OFF = 32'h30000010;
91
+ //states of the state machine
92
+ localparam S0 = 0, S1 = 1, S2 = 2, S3 = 3;
93
+ reg [3:0] STATE, nstate;
94
+ reg [7:0] CNT, ncnt;
95
+ //Registers for the multiplicand, multiplier, product
96
+ reg [31:0] A, X;
97
+ reg [63:0] Y0;
98
+ wire status; // status register
99
+ assign status = STATE == S0 ? 1:0; // if status reg == 1 means data is ready to be read or change the existing data
100
+ //wire for the current product bit
101
+ wire y;
102
+ //Registers for the WB bus
103
+ reg [7:0] WB_address;
104
+ reg WB_Read, WB_Write;
105
+
106
+ // WB MI A
107
+ assign valid = wbs_cyc_i && wbs_stb_i;
108
+ assign wstrb = wbs_sel_i & {4{wbs_we_i}};
109
+ //assign wbs_dat_o = rdata;
110
+ assign wdata = wbs_dat_i;
111
+
112
+ // IO
113
+ assign io_out = {(`MPRJ_IO_PADS){1'b0}};
114
+ assign io_oeb = {(`MPRJ_IO_PADS){rst}};
115
+
116
+ // IRQ
117
+ assign irq = 3'b000; // Unused
118
+
119
+ // LA
120
+ assign la_data_out = {(127){1'b0}};
121
+ // Assuming LA probes [63:32] are for controlling the count register
122
+ assign la_write = ~la_oenb[63:32] & ~{BITS{valid}};
123
+ // Assuming LA probes [65:64] are for controlling the count clk & reset
124
+ // assign clk = (~la_oenb[64]) ? la_data_in[64]: wb_clk_i;
125
+ // assign rst = (~la_oenb[65]) ? la_data_in[65]: wb_rst_i;
126
+ assign clk = wb_clk_i;
127
+ assign rst = wb_rst_i;
128
+
129
+ always @(posedge clk or posedge rst) begin //assuming that we have posedge rst
130
+
131
+ if(rst) begin
132
+ A <= 32'b0;
133
+ //wbs_ack_o <= 1'b0;
134
+ end
135
+ else if(valid && wbs_we_i && (wbs_adr_i==X_OFF)) begin
136
+ A <= wbs_dat_i;
137
+ // wbs_dat_o <= A;
138
+ // wbs_ack_o <= 1'b1;
139
+ end
140
+ end
141
+
142
+ always @(posedge clk or posedge rst) begin //assuming that we have posedge rst
143
+ // wbs_ack_o <= 1'b0;
144
+ if(rst) begin
145
+ //wbs_ack_o <= 1'b0;
146
+ X <= 32'b0;
147
+ end
148
+ else if(STATE==S1) X <= X >>1; //shift right for the X since we always take the least significant bit in the multiplication
149
+ else if(valid && wbs_we_i && (wbs_adr_i==Y_OFF)) begin //the reason we have a separate always block for the X is the shift right action
150
+ X <= wbs_dat_i;
151
+ // wbs_dat_o <= X;
152
+ // wbs_ack_o <= 1'b1;
153
+ end
154
+
155
+ end
156
+
157
+ always@(posedge clk) begin //a signal such as wbs_dat_o can be manipulated within one always block only
158
+ if(valid && wbs_we_i && (wbs_adr_i==Y_OFF)) begin
159
+ wbs_dat_o <= X;
160
+ end
161
+ else if(valid && wbs_we_i && (wbs_adr_i==X_OFF)) begin
162
+ wbs_dat_o <= A;
163
+ end
164
+ else if(valid && !wbs_we_i && (wbs_adr_i==Y0_OFF)) begin
165
+ wbs_dat_o <= Y0[31:0];
166
+ // wbs_ack_o <= 1'b1;
167
+ end
168
+ else if(valid && !wbs_we_i && (wbs_adr_i==Y1_OFF)) begin
169
+ wbs_dat_o <= Y0[63:32];
170
+ end
171
+ else if(valid && !wbs_we_i && (wbs_adr_i==STAT_OFF)) begin
172
+ wbs_dat_o <= status;
173
+ end
174
+ end
175
+
176
+ always@(posedge clk) begin
177
+ if(wbs_ack_o) begin
178
+ wbs_ack_o <= 1'b0;
179
+ end
180
+ else if((valid && !wbs_we_i && (wbs_adr_i==Y1_OFF)) || (valid && !wbs_we_i && (wbs_adr_i==Y0_OFF)) || (valid && wbs_we_i && (wbs_adr_i==Y_OFF)) || (valid && wbs_we_i && (wbs_adr_i==X_OFF)) || (valid && !wbs_we_i && (wbs_adr_i==STAT_OFF))) begin
181
+ wbs_ack_o <= 1'b1;
182
+ end
183
+ end
184
+
185
+ always @(posedge clk or posedge rst) begin
186
+ if(rst) begin
187
+ Y0 <= 64'b0;
188
+ end
189
+ else if(STATE==S1)
190
+ Y0 <= {y, Y0[63:1]}; //taking the result from the SPM and shifting it right one bit at a time
191
+
192
+ end
193
+
194
+ always @(posedge clk or posedge rst) begin
195
+ if(rst) begin
196
+ STATE <= S0;
197
+ end
198
+ else
199
+ STATE <=nstate; //moving to the next state each clk cycle or on rst
200
+ end
201
+
202
+ always @(*) begin
203
+ case(STATE)
204
+ S0: if(valid && wbs_we_i && (wbs_adr_i==Y_OFF)) nstate=S1; else nstate=S0;
205
+ S1: if(CNT==64) nstate=S0; else nstate=S1; //state 1 means that both numbers are ready now.
206
+ default: nstate=S0;
207
+ endcase
208
+ end
209
+
210
+ always @(posedge clk or posedge rst) begin
211
+ if(rst) begin
212
+ CNT <= 8'b0;
213
+ end
214
+ else
215
+ CNT <= ncnt;
216
+ end
217
+
218
+ always @(*) begin
219
+ ncnt = 0;
220
+ if(CNT==64) ncnt <=0;
221
+ else if(STATE==S1) ncnt = CNT + 1;
222
+ end
223
+ spm spm(.clk(clk), .rst(!rst), .a(A), .x(X[0]), .y(y));
224
+
225
+
226
+ endmodule
227
+
228
+ // (Parameterized) Unsigned Serial/Parallel Multiplier:
229
+ // - Multiplicand x (Input bit-serially)
230
+ // - Multiplier a (All bits at the same time/Parallel)
231
+ // - Product y (Output bit-serial)
232
+ module spm #(parameter bits=32) (
233
+ input clk,
234
+ input rst,
235
+ input x,
236
+ input[bits-1: 0] a,
237
+ output y
238
+ );
239
+ wire[bits: 0] y_chain;
240
+ assign y_chain[0] = 0;
241
+ assign y = y_chain[bits];
242
+
243
+ wire[bits-1:0] a_flip;
244
+ genvar i;
245
+ generate
246
+ for (i = 0; i < bits; i = i + 1) begin : flip_block
247
+ assign a_flip[i] = a[bits - i - 1];
248
+ end
249
+ endgenerate
250
+
251
+ delayed_serial_adder dsa[bits-1:0](
252
+ .clk(clk),
253
+ .rst(rst),
254
+ .x(x),
255
+ .a(a_flip),
256
+ .y_in(y_chain[bits-1:0]),
257
+ .y_out(y_chain[bits:1])
258
+ );
259
+
260
+ endmodule
261
+
262
+ module delayed_serial_adder(
263
+ input clk,
264
+ input rst,
265
+ input x,
266
+ input a,
267
+ input y_in,
268
+ output reg y_out
269
+ );
270
+ reg last_carry;
271
+ wire last_carry_next;
272
+ wire y_out_next;
273
+
274
+ wire g = x & a;
275
+ assign {last_carry_next, y_out_next} = g + y_in + last_carry;
276
+
277
+ always @ (posedge clk or negedge rst) begin
278
+ if (!rst) begin
279
+ last_carry <= 1'b0;
280
+ y_out <= 1'b0;
281
+ end else begin
282
+ last_carry <= last_carry_next;
283
+ y_out <= y_out_next;
284
+ end
285
+ end
286
+ endmodule
@@ -0,0 +1,145 @@
1
+ # generated by get_cup_sdc.py
2
+ # Date: 2023/06/20
3
+
4
+ ### Note:
5
+ # - input clock transition and latency are set for wb_clk_i port.
6
+ # If your design is using the user_clock2, update the clock constraints to reflect that and use usr_* variables.
7
+ # - IO ports are assumed to be asynchronous. If they're synchronous to the clock, update the variable IO_SYNC to 1.
8
+ # As well, update in_ext_delay and out_ext_delay with the required I/O external delays.
9
+
10
+ #------------------------------------------#
11
+ # Pre-defined Constraints
12
+ #------------------------------------------#
13
+
14
+ # Clock network
15
+ set ::env(IO_SYNC) 0
16
+ if {[info exists ::env(CLOCK_PORT)] && $::env(CLOCK_PORT) != ""} {
17
+ set clk_input $::env(CLOCK_PORT)
18
+ create_clock [get_ports $clk_input] -name clk -period $::env(CLOCK_PERIOD)
19
+ puts "\[INFO\]: Creating clock {clk} for port $clk_input with period: $::env(CLOCK_PERIOD)"
20
+ } else {
21
+ set clk_input __VIRTUAL_CLK__
22
+ create_clock -name clk -period $::env(CLOCK_PERIOD)
23
+ puts "\[INFO\]: Creating virtual clock with period: $::env(CLOCK_PERIOD)"
24
+ }
25
+ if { ![info exists ::env(SYNTH_CLK_DRIVING_CELL)] } {
26
+ set ::env(SYNTH_CLK_DRIVING_CELL) $::env(SYNTH_DRIVING_CELL)
27
+ }
28
+ if { ![info exists ::env(SYNTH_CLK_DRIVING_CELL_PIN)] } {
29
+ set ::env(SYNTH_CLK_DRIVING_CELL_PIN) $::env(SYNTH_DRIVING_CELL_PIN)
30
+ }
31
+
32
+ # Clock non-idealities
33
+ set_propagated_clock [all_clocks]
34
+ set_clock_uncertainty $::env(SYNTH_CLOCK_UNCERTAINTY) [get_clocks {clk}]
35
+ puts "\[INFO\]: Setting clock uncertainity to: $::env(SYNTH_CLOCK_UNCERTAINTY)"
36
+ set_clock_transition $::env(SYNTH_CLOCK_TRANSITION) [get_clocks {clk}]
37
+ puts "\[INFO\]: Setting clock transition to: $::env(SYNTH_CLOCK_TRANSITION)"
38
+
39
+ # Maximum transition time for the design nets
40
+ set_max_transition $::env(MAX_TRANSITION_CONSTRAINT) [current_design]
41
+ puts "\[INFO\]: Setting maximum transition to: $::env(MAX_TRANSITION_CONSTRAINT)"
42
+
43
+ # Maximum fanout
44
+ set_max_fanout $::env(MAX_FANOUT_CONSTRAINT) [current_design]
45
+ puts "\[INFO\]: Setting maximum fanout to: $::env(MAX_FANOUT_CONSTRAINT)"
46
+
47
+ # Timing paths delays derate
48
+ set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
49
+ set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
50
+ puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 100}] %"
51
+
52
+ # Reset input delay
53
+ set_input_delay [expr $::env(CLOCK_PERIOD) * 0.5] -clock [get_clocks {clk}] [get_ports {wb_rst_i}]
54
+
55
+ # Multicycle paths
56
+ set_multicycle_path -setup 2 -through [get_ports {wbs_ack_o}]
57
+ set_multicycle_path -hold 1 -through [get_ports {wbs_ack_o}]
58
+ set_multicycle_path -setup 2 -through [get_ports {wbs_cyc_i}]
59
+ set_multicycle_path -hold 1 -through [get_ports {wbs_cyc_i}]
60
+ set_multicycle_path -setup 2 -through [get_ports {wbs_stb_i}]
61
+ set_multicycle_path -hold 1 -through [get_ports {wbs_stb_i}]
62
+
63
+ #------------------------------------------#
64
+ # Retrieved Constraints
65
+ #------------------------------------------#
66
+
67
+ # Clock source latency
68
+ set usr_clk_max_latency 4.57
69
+ set usr_clk_min_latency 4.11
70
+ set clk_max_latency 5.57
71
+ set clk_min_latency 4.65
72
+ set_clock_latency -source -max $clk_max_latency [get_clocks {clk}]
73
+ set_clock_latency -source -min $clk_min_latency [get_clocks {clk}]
74
+ puts "\[INFO\]: Setting clock latency range: $clk_min_latency : $clk_max_latency"
75
+
76
+ # Clock input Transition
77
+ set usr_clk_tran 0.13
78
+ set clk_tran 0.61
79
+ set_input_transition $clk_tran [get_ports $clk_input]
80
+ puts "\[INFO\]: Setting clock transition: $clk_tran"
81
+
82
+ # Input delays
83
+ set_input_delay -max 1.87 -clock [get_clocks {clk}] [get_ports {la_data_in[*]}]
84
+ set_input_delay -max 1.89 -clock [get_clocks {clk}] [get_ports {la_oenb[*]}]
85
+ set_input_delay -max 3.17 -clock [get_clocks {clk}] [get_ports {wbs_sel_i[*]}]
86
+ set_input_delay -max 3.74 -clock [get_clocks {clk}] [get_ports {wbs_we_i}]
87
+ set_input_delay -max 3.89 -clock [get_clocks {clk}] [get_ports {wbs_adr_i[*]}]
88
+ set_input_delay -max 4.13 -clock [get_clocks {clk}] [get_ports {wbs_stb_i}]
89
+ set_input_delay -max 4.61 -clock [get_clocks {clk}] [get_ports {wbs_dat_i[*]}]
90
+ set_input_delay -max 4.74 -clock [get_clocks {clk}] [get_ports {wbs_cyc_i}]
91
+ set_input_delay -min 0.18 -clock [get_clocks {clk}] [get_ports {la_data_in[*]}]
92
+ set_input_delay -min 0.3 -clock [get_clocks {clk}] [get_ports {la_oenb[*]}]
93
+ set_input_delay -min 0.79 -clock [get_clocks {clk}] [get_ports {wbs_adr_i[*]}]
94
+ set_input_delay -min 1.04 -clock [get_clocks {clk}] [get_ports {wbs_dat_i[*]}]
95
+ set_input_delay -min 1.19 -clock [get_clocks {clk}] [get_ports {wbs_sel_i[*]}]
96
+ set_input_delay -min 1.65 -clock [get_clocks {clk}] [get_ports {wbs_we_i}]
97
+ set_input_delay -min 1.69 -clock [get_clocks {clk}] [get_ports {wbs_cyc_i}]
98
+ set_input_delay -min 1.86 -clock [get_clocks {clk}] [get_ports {wbs_stb_i}]
99
+ if { $::env(IO_SYNC) } {
100
+ set in_ext_delay 4
101
+ puts "\[INFO\]: Setting input ports external delay to: $in_ext_delay"
102
+ set_input_delay -max [expr $in_ext_delay + 4.55] -clock [get_clocks {clk}] [get_ports {io_in[*]}]
103
+ set_input_delay -min [expr $in_ext_delay + 1.26] -clock [get_clocks {clk}] [get_ports {io_in[*]}]
104
+ }
105
+
106
+ # Input Transition
107
+ set_input_transition -max 0.14 [get_ports {wbs_we_i}]
108
+ set_input_transition -max 0.15 [get_ports {wbs_stb_i}]
109
+ set_input_transition -max 0.17 [get_ports {wbs_cyc_i}]
110
+ set_input_transition -max 0.18 [get_ports {wbs_sel_i[*]}]
111
+ set_input_transition -max 0.38 [get_ports {io_in[*]}]
112
+ set_input_transition -max 0.84 [get_ports {wbs_dat_i[*]}]
113
+ set_input_transition -max 0.86 [get_ports {la_data_in[*]}]
114
+ set_input_transition -max 0.92 [get_ports {wbs_adr_i[*]}]
115
+ set_input_transition -max 0.97 [get_ports {la_oenb[*]}]
116
+ set_input_transition -min 0.05 [get_ports {io_in[*]}]
117
+ set_input_transition -min 0.06 [get_ports {la_oenb[*]}]
118
+ set_input_transition -min 0.07 [get_ports {la_data_in[*]}]
119
+ set_input_transition -min 0.07 [get_ports {wbs_adr_i[*]}]
120
+ set_input_transition -min 0.07 [get_ports {wbs_dat_i[*]}]
121
+ set_input_transition -min 0.09 [get_ports {wbs_cyc_i}]
122
+ set_input_transition -min 0.09 [get_ports {wbs_sel_i[*]}]
123
+ set_input_transition -min 0.09 [get_ports {wbs_we_i}]
124
+ set_input_transition -min 0.15 [get_ports {wbs_stb_i}]
125
+
126
+ # Output delays
127
+ set_output_delay -max 0.7 -clock [get_clocks {clk}] [get_ports {user_irq[*]}]
128
+ set_output_delay -max 1.0 -clock [get_clocks {clk}] [get_ports {la_data_out[*]}]
129
+ set_output_delay -max 3.62 -clock [get_clocks {clk}] [get_ports {wbs_dat_o[*]}]
130
+ set_output_delay -max 8.41 -clock [get_clocks {clk}] [get_ports {wbs_ack_o}]
131
+ set_output_delay -min 0 -clock [get_clocks {clk}] [get_ports {la_data_out[*]}]
132
+ set_output_delay -min 0 -clock [get_clocks {clk}] [get_ports {user_irq[*]}]
133
+ set_output_delay -min 1.13 -clock [get_clocks {clk}] [get_ports {wbs_dat_o[*]}]
134
+ set_output_delay -min 1.37 -clock [get_clocks {clk}] [get_ports {wbs_ack_o}]
135
+ if { $::env(IO_SYNC) } {
136
+ set out_ext_delay 4
137
+ puts "\[INFO\]: Setting output ports external delay to: $out_ext_delay"
138
+ set_output_delay -max [expr $out_ext_delay + 9.12] -clock [get_clocks {clk}] [get_ports {io_out[*]}]
139
+ set_output_delay -max [expr $out_ext_delay + 9.32] -clock [get_clocks {clk}] [get_ports {io_oeb[*]}]
140
+ set_output_delay -min [expr $out_ext_delay + 2.34] -clock [get_clocks {clk}] [get_ports {io_oeb[*]}]
141
+ set_output_delay -min [expr $out_ext_delay + 3.9] -clock [get_clocks {clk}] [get_ports {io_out[*]}]
142
+ }
143
+
144
+ # Output loads
145
+ set_load 0.19 [all_outputs]
@@ -0,0 +1,12 @@
1
+ {
2
+ "DESIGN_NAME": "user_project_wrapper",
3
+ "VERILOG_FILES": [
4
+ "dir::./defines.v",
5
+ "dir::./SPM_example.v",
6
+ "dir::./user_project_wrapper.v"
7
+ ],
8
+ "CLOCK_PERIOD": 25,
9
+ "CLOCK_PORT": "wb_clk_i",
10
+ "FP_CORE_UTIL": 5
11
+ }
12
+