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.
- librelane/__init__.py +38 -0
- librelane/__main__.py +470 -0
- librelane/__version__.py +43 -0
- librelane/common/__init__.py +61 -0
- librelane/common/cli.py +75 -0
- librelane/common/drc.py +245 -0
- librelane/common/generic_dict.py +319 -0
- librelane/common/metrics/__init__.py +35 -0
- librelane/common/metrics/__main__.py +413 -0
- librelane/common/metrics/library.py +354 -0
- librelane/common/metrics/metric.py +186 -0
- librelane/common/metrics/util.py +279 -0
- librelane/common/misc.py +402 -0
- librelane/common/ring_buffer.py +63 -0
- librelane/common/tcl.py +80 -0
- librelane/common/toolbox.py +549 -0
- librelane/common/tpe.py +41 -0
- librelane/common/types.py +117 -0
- librelane/config/__init__.py +32 -0
- librelane/config/__main__.py +158 -0
- librelane/config/config.py +1025 -0
- librelane/config/flow.py +490 -0
- librelane/config/pdk_compat.py +255 -0
- librelane/config/preprocessor.py +464 -0
- librelane/config/removals.py +45 -0
- librelane/config/variable.py +722 -0
- librelane/container.py +264 -0
- librelane/env_info.py +306 -0
- librelane/examples/spm/config.yaml +33 -0
- librelane/examples/spm/pin_order.cfg +14 -0
- librelane/examples/spm/src/impl.sdc +73 -0
- librelane/examples/spm/src/signoff.sdc +68 -0
- librelane/examples/spm/src/spm.v +73 -0
- librelane/examples/spm/verify/spm_tb.v +106 -0
- librelane/examples/spm-user_project_wrapper/SPM_example.v +286 -0
- librelane/examples/spm-user_project_wrapper/base_sdc_file.sdc +145 -0
- librelane/examples/spm-user_project_wrapper/config-tut.json +12 -0
- librelane/examples/spm-user_project_wrapper/config.json +13 -0
- librelane/examples/spm-user_project_wrapper/defines.v +66 -0
- librelane/examples/spm-user_project_wrapper/template.def +7656 -0
- librelane/examples/spm-user_project_wrapper/user_project_wrapper.v +123 -0
- librelane/flows/__init__.py +24 -0
- librelane/flows/builtins.py +18 -0
- librelane/flows/classic.py +330 -0
- librelane/flows/cli.py +463 -0
- librelane/flows/flow.py +985 -0
- librelane/flows/misc.py +71 -0
- librelane/flows/optimizing.py +179 -0
- librelane/flows/sequential.py +367 -0
- librelane/flows/synth_explore.py +173 -0
- librelane/logging/__init__.py +40 -0
- librelane/logging/logger.py +323 -0
- librelane/open_pdks_rev +1 -0
- librelane/plugins.py +21 -0
- librelane/py.typed +0 -0
- librelane/scripts/base.sdc +80 -0
- librelane/scripts/klayout/Readme.md +2 -0
- librelane/scripts/klayout/open_design.py +63 -0
- librelane/scripts/klayout/render.py +121 -0
- librelane/scripts/klayout/stream_out.py +176 -0
- librelane/scripts/klayout/xml_drc_report_to_json.py +45 -0
- librelane/scripts/klayout/xor.drc +120 -0
- librelane/scripts/magic/Readme.md +1 -0
- librelane/scripts/magic/common/read.tcl +114 -0
- librelane/scripts/magic/def/antenna_check.tcl +35 -0
- librelane/scripts/magic/def/mag.tcl +19 -0
- librelane/scripts/magic/def/mag_gds.tcl +81 -0
- librelane/scripts/magic/drc.tcl +79 -0
- librelane/scripts/magic/extract_spice.tcl +98 -0
- librelane/scripts/magic/gds/drc_batch.tcl +74 -0
- librelane/scripts/magic/gds/erase_box.tcl +32 -0
- librelane/scripts/magic/gds/extras_mag.tcl +47 -0
- librelane/scripts/magic/gds/mag_with_pointers.tcl +32 -0
- librelane/scripts/magic/get_bbox.tcl +11 -0
- librelane/scripts/magic/lef/extras_maglef.tcl +63 -0
- librelane/scripts/magic/lef/maglef.tcl +27 -0
- librelane/scripts/magic/lef.tcl +57 -0
- librelane/scripts/magic/open.tcl +28 -0
- librelane/scripts/magic/wrapper.tcl +19 -0
- librelane/scripts/netgen/setup.tcl +28 -0
- librelane/scripts/odbpy/apply_def_template.py +49 -0
- librelane/scripts/odbpy/cell_frequency.py +107 -0
- librelane/scripts/odbpy/check_antenna_properties.py +116 -0
- librelane/scripts/odbpy/contextualize.py +109 -0
- librelane/scripts/odbpy/defutil.py +574 -0
- librelane/scripts/odbpy/diodes.py +373 -0
- librelane/scripts/odbpy/disconnected_pins.py +305 -0
- librelane/scripts/odbpy/exception_codes.py +17 -0
- librelane/scripts/odbpy/filter_unannotated.py +100 -0
- librelane/scripts/odbpy/io_place.py +482 -0
- librelane/scripts/odbpy/label_macro_pins.py +277 -0
- librelane/scripts/odbpy/lefutil.py +97 -0
- librelane/scripts/odbpy/placers.py +162 -0
- librelane/scripts/odbpy/power_utils.py +395 -0
- librelane/scripts/odbpy/random_place.py +57 -0
- librelane/scripts/odbpy/reader.py +246 -0
- librelane/scripts/odbpy/remove_buffers.py +173 -0
- librelane/scripts/odbpy/snap_to_grid.py +57 -0
- librelane/scripts/odbpy/wire_lengths.py +93 -0
- librelane/scripts/openroad/antenna_check.tcl +20 -0
- librelane/scripts/openroad/antenna_repair.tcl +31 -0
- librelane/scripts/openroad/basic_mp.tcl +24 -0
- librelane/scripts/openroad/buffer_list.tcl +10 -0
- librelane/scripts/openroad/common/dpl.tcl +24 -0
- librelane/scripts/openroad/common/dpl_cell_pad.tcl +26 -0
- librelane/scripts/openroad/common/grt.tcl +32 -0
- librelane/scripts/openroad/common/io.tcl +476 -0
- librelane/scripts/openroad/common/pdn_cfg.tcl +135 -0
- librelane/scripts/openroad/common/resizer.tcl +103 -0
- librelane/scripts/openroad/common/set_global_connections.tcl +78 -0
- librelane/scripts/openroad/common/set_layer_adjustments.tcl +31 -0
- librelane/scripts/openroad/common/set_power_nets.tcl +30 -0
- librelane/scripts/openroad/common/set_rc.tcl +75 -0
- librelane/scripts/openroad/common/set_routing_layers.tcl +30 -0
- librelane/scripts/openroad/cts.tcl +80 -0
- librelane/scripts/openroad/cut_rows.tcl +24 -0
- librelane/scripts/openroad/dpl.tcl +24 -0
- librelane/scripts/openroad/drt.tcl +37 -0
- librelane/scripts/openroad/fill.tcl +30 -0
- librelane/scripts/openroad/floorplan.tcl +145 -0
- librelane/scripts/openroad/gpl.tcl +88 -0
- librelane/scripts/openroad/grt.tcl +30 -0
- librelane/scripts/openroad/gui.tcl +15 -0
- librelane/scripts/openroad/insert_buffer.tcl +127 -0
- librelane/scripts/openroad/ioplacer.tcl +67 -0
- librelane/scripts/openroad/irdrop.tcl +51 -0
- librelane/scripts/openroad/pdn.tcl +52 -0
- librelane/scripts/openroad/rcx.tcl +32 -0
- librelane/scripts/openroad/repair_design.tcl +70 -0
- librelane/scripts/openroad/repair_design_postgrt.tcl +48 -0
- librelane/scripts/openroad/rsz_timing_postcts.tcl +68 -0
- librelane/scripts/openroad/rsz_timing_postgrt.tcl +70 -0
- librelane/scripts/openroad/sta/check_macro_instances.tcl +53 -0
- librelane/scripts/openroad/sta/corner.tcl +393 -0
- librelane/scripts/openroad/tapcell.tcl +25 -0
- librelane/scripts/openroad/write_views.tcl +27 -0
- librelane/scripts/pyosys/construct_abc_script.py +177 -0
- librelane/scripts/pyosys/json_header.py +84 -0
- librelane/scripts/pyosys/synthesize.py +493 -0
- librelane/scripts/pyosys/ys_common.py +153 -0
- librelane/scripts/tclsh/hello.tcl +1 -0
- librelane/state/__init__.py +24 -0
- librelane/state/__main__.py +61 -0
- librelane/state/design_format.py +180 -0
- librelane/state/state.py +351 -0
- librelane/steps/__init__.py +61 -0
- librelane/steps/__main__.py +511 -0
- librelane/steps/checker.py +637 -0
- librelane/steps/common_variables.py +340 -0
- librelane/steps/cvc_rv.py +169 -0
- librelane/steps/klayout.py +509 -0
- librelane/steps/magic.py +566 -0
- librelane/steps/misc.py +160 -0
- librelane/steps/netgen.py +253 -0
- librelane/steps/odb.py +955 -0
- librelane/steps/openroad.py +2433 -0
- librelane/steps/openroad_alerts.py +102 -0
- librelane/steps/pyosys.py +629 -0
- librelane/steps/step.py +1547 -0
- librelane/steps/tclstep.py +288 -0
- librelane/steps/verilator.py +222 -0
- librelane/steps/yosys.py +371 -0
- librelane-2.4.0.dev0.dist-info/METADATA +151 -0
- librelane-2.4.0.dev0.dist-info/RECORD +166 -0
- librelane-2.4.0.dev0.dist-info/WHEEL +4 -0
- 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]
|