yowasp-yosys 0.43.0.0.post751__py3-none-any.whl → 0.45.0.0.post775__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.
- yowasp_yosys/share/gowin/cells_sim.v +68 -1
- yowasp_yosys/share/gowin/cells_xtra.v +0 -10
- yowasp_yosys/share/include/frontends/ast/ast.h +3 -1
- yowasp_yosys/share/include/kernel/bitpattern.h +161 -0
- yowasp_yosys/share/include/kernel/cost.h +24 -41
- yowasp_yosys/share/include/kernel/hashlib.h +20 -1
- yowasp_yosys/share/include/kernel/sigtools.h +12 -0
- yowasp_yosys/share/microchip/LSRAM.txt +191 -0
- yowasp_yosys/share/microchip/LSRAM_map.v +320 -0
- yowasp_yosys/share/microchip/arith_map.v +105 -0
- yowasp_yosys/share/microchip/brams_defs.vh +69 -0
- yowasp_yosys/share/microchip/cells_map.v +104 -0
- yowasp_yosys/share/microchip/cells_sim.v +719 -0
- yowasp_yosys/share/microchip/polarfire_dsp_map.v +95 -0
- yowasp_yosys/share/microchip/uSRAM.txt +69 -0
- yowasp_yosys/share/microchip/uSRAM_map.v +126 -0
- yowasp_yosys/share/nanoxplore/arith_map.v +76 -0
- yowasp_yosys/share/nanoxplore/brams.txt +50 -0
- yowasp_yosys/share/nanoxplore/brams_init.vh +23 -0
- yowasp_yosys/share/nanoxplore/brams_map.v +84 -0
- yowasp_yosys/share/nanoxplore/cells_bb.v +127 -0
- yowasp_yosys/share/nanoxplore/cells_bb_l.v +2156 -0
- yowasp_yosys/share/nanoxplore/cells_bb_m.v +1527 -0
- yowasp_yosys/share/nanoxplore/cells_bb_u.v +2758 -0
- yowasp_yosys/share/nanoxplore/cells_map.v +95 -0
- yowasp_yosys/share/nanoxplore/cells_sim.v +421 -0
- yowasp_yosys/share/nanoxplore/cells_sim_l.v +0 -0
- yowasp_yosys/share/nanoxplore/cells_sim_m.v +0 -0
- yowasp_yosys/share/nanoxplore/cells_sim_u.v +306 -0
- yowasp_yosys/share/nanoxplore/cells_wrap.v +201 -0
- yowasp_yosys/share/nanoxplore/cells_wrap_l.v +1713 -0
- yowasp_yosys/share/nanoxplore/cells_wrap_m.v +1501 -0
- yowasp_yosys/share/nanoxplore/cells_wrap_u.v +3506 -0
- yowasp_yosys/share/nanoxplore/io_map.v +15 -0
- yowasp_yosys/share/nanoxplore/latches_map.v +11 -0
- yowasp_yosys/share/nanoxplore/rf_init.vh +17 -0
- yowasp_yosys/share/nanoxplore/rf_rams_l.txt +15 -0
- yowasp_yosys/share/nanoxplore/rf_rams_m.txt +15 -0
- yowasp_yosys/share/nanoxplore/rf_rams_map_l.v +30 -0
- yowasp_yosys/share/nanoxplore/rf_rams_map_m.v +30 -0
- yowasp_yosys/share/nanoxplore/rf_rams_map_u.v +345 -0
- yowasp_yosys/share/nanoxplore/rf_rams_u.txt +66 -0
- yowasp_yosys/share/quicklogic/qlf_k6n10f/bram_types_sim.v +1 -1
- yowasp_yosys/share/simlib.v +159 -0
- yowasp_yosys/yosys.wasm +0 -0
- {yowasp_yosys-0.43.0.0.post751.dist-info → yowasp_yosys-0.45.0.0.post775.dist-info}/METADATA +3 -3
- {yowasp_yosys-0.43.0.0.post751.dist-info → yowasp_yosys-0.45.0.0.post775.dist-info}/RECORD +50 -14
- {yowasp_yosys-0.43.0.0.post751.dist-info → yowasp_yosys-0.45.0.0.post775.dist-info}/WHEEL +1 -1
- {yowasp_yosys-0.43.0.0.post751.dist-info → yowasp_yosys-0.45.0.0.post775.dist-info}/entry_points.txt +0 -0
- {yowasp_yosys-0.43.0.0.post751.dist-info → yowasp_yosys-0.45.0.0.post775.dist-info}/top_level.txt +0 -0
|
@@ -618,6 +618,21 @@ module OSER4(D3, D2, D1, D0, TX1, TX0, FCLK, PCLK, RESET, Q1, Q0);
|
|
|
618
618
|
parameter HWL = "false";
|
|
619
619
|
endmodule
|
|
620
620
|
|
|
621
|
+
module OSER4_MEM (Q0, Q1, D0, D1, D2, D3, TX0, TX1, PCLK, FCLK, TCLK, RESET) ;
|
|
622
|
+
parameter GSREN = "";
|
|
623
|
+
parameter LSREN = "";
|
|
624
|
+
parameter HWL = "";
|
|
625
|
+
parameter TCLK_SOURCE = "";
|
|
626
|
+
parameter TXCLK_POL = "";
|
|
627
|
+
|
|
628
|
+
input D0, D1, D2, D3;
|
|
629
|
+
input TX0, TX1;
|
|
630
|
+
input PCLK, FCLK, TCLK, RESET;
|
|
631
|
+
output Q0, Q1;
|
|
632
|
+
|
|
633
|
+
parameter ID = "";
|
|
634
|
+
endmodule
|
|
635
|
+
|
|
621
636
|
module OSER8(D7, D6, D5, D4, D3, D2, D1, D0, TX3, TX2, TX1, TX0, FCLK, PCLK, RESET, Q1, Q0);
|
|
622
637
|
output Q1;
|
|
623
638
|
output Q0;
|
|
@@ -729,6 +744,21 @@ RESET, CALIB, D);
|
|
|
729
744
|
parameter LSREN = "true";
|
|
730
745
|
endmodule
|
|
731
746
|
|
|
747
|
+
module IDES4_MEM (Q0, Q1, Q2, Q3, D, WADDR,
|
|
748
|
+
RADDR, CALIB, PCLK, FCLK, ICLK, RESET) ;
|
|
749
|
+
parameter GSREN = "";
|
|
750
|
+
parameter LSREN = "";
|
|
751
|
+
|
|
752
|
+
input D, ICLK, FCLK, PCLK;
|
|
753
|
+
input [2:0] WADDR;
|
|
754
|
+
input [2:0] RADDR;
|
|
755
|
+
input CALIB, RESET;
|
|
756
|
+
|
|
757
|
+
output Q0,Q1,Q2,Q3;
|
|
758
|
+
|
|
759
|
+
parameter ID = "";
|
|
760
|
+
endmodule
|
|
761
|
+
|
|
732
762
|
module IDES8(Q7, Q6, Q5, Q4, Q3, Q2, Q1, Q0, FCLK, PCLK,
|
|
733
763
|
RESET, CALIB, D);
|
|
734
764
|
input D;
|
|
@@ -842,6 +872,28 @@ module IDDRC(D, CLK, CLEAR, Q0, Q1);
|
|
|
842
872
|
parameter Q1_INIT = 1'b0;
|
|
843
873
|
endmodule
|
|
844
874
|
|
|
875
|
+
module DQS(DQSR90, DQSW0, DQSW270, RPOINT, WPOINT, RVALID, RBURST, RFLAG,
|
|
876
|
+
WFLAG, DQSIN, DLLSTEP, WSTEP, READ, RLOADN, RMOVE, RDIR, WLOADN, WMOVE, WDIR,
|
|
877
|
+
HOLD, RCLKSEL, PCLK, FCLK, RESET) ;
|
|
878
|
+
input DQSIN,PCLK,FCLK,RESET;
|
|
879
|
+
input [3:0] READ;
|
|
880
|
+
input [2:0] RCLKSEL;
|
|
881
|
+
input [7:0] DLLSTEP;
|
|
882
|
+
input [7:0] WSTEP;
|
|
883
|
+
input RLOADN, RMOVE, RDIR, WLOADN, WMOVE, WDIR, HOLD;
|
|
884
|
+
|
|
885
|
+
output DQSR90, DQSW0, DQSW270;
|
|
886
|
+
output [2:0] RPOINT, WPOINT;
|
|
887
|
+
output RVALID,RBURST, RFLAG, WFLAG;
|
|
888
|
+
|
|
889
|
+
parameter FIFO_MODE_SEL = "";
|
|
890
|
+
parameter RD_PNTR = "";
|
|
891
|
+
parameter DQS_MODE = "";
|
|
892
|
+
parameter HWL = "";
|
|
893
|
+
parameter GSREN = "";
|
|
894
|
+
parameter ID = "";
|
|
895
|
+
endmodule
|
|
896
|
+
|
|
845
897
|
(* blackbox *)
|
|
846
898
|
module ODDR(D0, D1, TX, CLK, Q0, Q1);
|
|
847
899
|
input D0;
|
|
@@ -867,8 +919,12 @@ module ODDRC(D0, D1, CLEAR, TX, CLK, Q0, Q1);
|
|
|
867
919
|
parameter INIT = 0;
|
|
868
920
|
endmodule
|
|
869
921
|
|
|
922
|
+
(* blackbox, keep *)
|
|
870
923
|
module GSR (input GSRI);
|
|
871
|
-
|
|
924
|
+
endmodule
|
|
925
|
+
|
|
926
|
+
(* blackbox, keep *)
|
|
927
|
+
module BANDGAP (input BGEN);
|
|
872
928
|
endmodule
|
|
873
929
|
|
|
874
930
|
(* abc9_box, lib_whitebox *)
|
|
@@ -1901,3 +1957,14 @@ output OSCOUT;
|
|
|
1901
1957
|
parameter FREQ_DIV = 100;
|
|
1902
1958
|
parameter REGULATOR_EN = 1'b0;
|
|
1903
1959
|
endmodule
|
|
1960
|
+
|
|
1961
|
+
(* blackbox *)
|
|
1962
|
+
module DCS (CLK0, CLK1, CLK2, CLK3, CLKSEL, SELFORCE, CLKOUT);
|
|
1963
|
+
input CLK0, CLK1, CLK2, CLK3, SELFORCE;
|
|
1964
|
+
input [3:0] CLKSEL;
|
|
1965
|
+
output CLKOUT;
|
|
1966
|
+
parameter DCS_MODE = "RISING";
|
|
1967
|
+
endmodule
|
|
1968
|
+
|
|
1969
|
+
|
|
1970
|
+
|
|
@@ -1564,12 +1564,6 @@ parameter IDLE = 4'd0,
|
|
|
1564
1564
|
RD_S2 = 4'd12;
|
|
1565
1565
|
endmodule
|
|
1566
1566
|
|
|
1567
|
-
module DCS (...);
|
|
1568
|
-
input CLK0, CLK1, CLK2, CLK3, SELFORCE;
|
|
1569
|
-
input [3:0] CLKSEL;
|
|
1570
|
-
output CLKOUT;
|
|
1571
|
-
endmodule
|
|
1572
|
-
|
|
1573
1567
|
module DQCE (...);
|
|
1574
1568
|
input CLKIN;
|
|
1575
1569
|
input CE;
|
|
@@ -1687,10 +1681,6 @@ endmodule
|
|
|
1687
1681
|
module ADC (...);
|
|
1688
1682
|
endmodule
|
|
1689
1683
|
|
|
1690
|
-
module BANDGAP (...);
|
|
1691
|
-
input BGEN;
|
|
1692
|
-
endmodule
|
|
1693
|
-
|
|
1694
1684
|
module CLKDIV2 (...);
|
|
1695
1685
|
parameter GSREN = "false";
|
|
1696
1686
|
input HCLKIN, RESETN;
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
*
|
|
18
18
|
* ---
|
|
19
19
|
*
|
|
20
|
-
*
|
|
20
|
+
* The AST frontend library is not a frontend on its own but provides an
|
|
21
|
+
* abstract syntax tree (AST) abstraction for the open source Verilog frontend
|
|
22
|
+
* at frontends/verilog.
|
|
21
23
|
*
|
|
22
24
|
*/
|
|
23
25
|
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* yosys -- Yosys Open SYnthesis Suite
|
|
3
|
+
*
|
|
4
|
+
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
|
5
|
+
*
|
|
6
|
+
* Permission to use, copy, modify, and/or distribute this software for any
|
|
7
|
+
* purpose with or without fee is hereby granted, provided that the above
|
|
8
|
+
* copyright notice and this permission notice appear in all copies.
|
|
9
|
+
*
|
|
10
|
+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
11
|
+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
12
|
+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
13
|
+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
14
|
+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
15
|
+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
16
|
+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#ifndef BITPATTERN_H
|
|
21
|
+
#define BITPATTERN_H
|
|
22
|
+
|
|
23
|
+
#include "kernel/log.h"
|
|
24
|
+
#include "kernel/rtlil.h"
|
|
25
|
+
|
|
26
|
+
YOSYS_NAMESPACE_BEGIN
|
|
27
|
+
|
|
28
|
+
struct BitPatternPool
|
|
29
|
+
{
|
|
30
|
+
int width;
|
|
31
|
+
struct bits_t {
|
|
32
|
+
std::vector<RTLIL::State> bitdata;
|
|
33
|
+
mutable unsigned int cached_hash;
|
|
34
|
+
bits_t(int width = 0) : bitdata(width), cached_hash(0) { }
|
|
35
|
+
RTLIL::State &operator[](int index) {
|
|
36
|
+
return bitdata[index];
|
|
37
|
+
}
|
|
38
|
+
const RTLIL::State &operator[](int index) const {
|
|
39
|
+
return bitdata[index];
|
|
40
|
+
}
|
|
41
|
+
bool operator==(const bits_t &other) const {
|
|
42
|
+
if (hash() != other.hash())
|
|
43
|
+
return false;
|
|
44
|
+
return bitdata == other.bitdata;
|
|
45
|
+
}
|
|
46
|
+
unsigned int hash() const {
|
|
47
|
+
if (!cached_hash)
|
|
48
|
+
cached_hash = hash_ops<std::vector<RTLIL::State>>::hash(bitdata);
|
|
49
|
+
return cached_hash;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
pool<bits_t> database;
|
|
53
|
+
|
|
54
|
+
BitPatternPool(RTLIL::SigSpec sig)
|
|
55
|
+
{
|
|
56
|
+
width = sig.size();
|
|
57
|
+
if (width > 0) {
|
|
58
|
+
bits_t pattern(width);
|
|
59
|
+
for (int i = 0; i < width; i++) {
|
|
60
|
+
if (sig[i].wire == NULL && sig[i].data <= RTLIL::State::S1)
|
|
61
|
+
pattern[i] = sig[i].data;
|
|
62
|
+
else
|
|
63
|
+
pattern[i] = RTLIL::State::Sa;
|
|
64
|
+
}
|
|
65
|
+
database.insert(pattern);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
BitPatternPool(int width)
|
|
70
|
+
{
|
|
71
|
+
this->width = width;
|
|
72
|
+
if (width > 0) {
|
|
73
|
+
bits_t pattern(width);
|
|
74
|
+
for (int i = 0; i < width; i++)
|
|
75
|
+
pattern[i] = RTLIL::State::Sa;
|
|
76
|
+
database.insert(pattern);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
bits_t sig2bits(RTLIL::SigSpec sig)
|
|
81
|
+
{
|
|
82
|
+
bits_t bits;
|
|
83
|
+
bits.bitdata = sig.as_const().bits;
|
|
84
|
+
for (auto &b : bits.bitdata)
|
|
85
|
+
if (b > RTLIL::State::S1)
|
|
86
|
+
b = RTLIL::State::Sa;
|
|
87
|
+
return bits;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
bool match(bits_t a, bits_t b)
|
|
91
|
+
{
|
|
92
|
+
log_assert(int(a.bitdata.size()) == width);
|
|
93
|
+
log_assert(int(b.bitdata.size()) == width);
|
|
94
|
+
for (int i = 0; i < width; i++)
|
|
95
|
+
if (a[i] <= RTLIL::State::S1 && b[i] <= RTLIL::State::S1 && a[i] != b[i])
|
|
96
|
+
return false;
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
bool has_any(RTLIL::SigSpec sig)
|
|
101
|
+
{
|
|
102
|
+
bits_t bits = sig2bits(sig);
|
|
103
|
+
for (auto &it : database)
|
|
104
|
+
if (match(it, bits))
|
|
105
|
+
return true;
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
bool has_all(RTLIL::SigSpec sig)
|
|
110
|
+
{
|
|
111
|
+
bits_t bits = sig2bits(sig);
|
|
112
|
+
for (auto &it : database)
|
|
113
|
+
if (match(it, bits)) {
|
|
114
|
+
for (int i = 0; i < width; i++)
|
|
115
|
+
if (bits[i] > RTLIL::State::S1 && it[i] <= RTLIL::State::S1)
|
|
116
|
+
goto next_database_entry;
|
|
117
|
+
return true;
|
|
118
|
+
next_database_entry:;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
bool take(RTLIL::SigSpec sig)
|
|
124
|
+
{
|
|
125
|
+
bool status = false;
|
|
126
|
+
bits_t bits = sig2bits(sig);
|
|
127
|
+
for (auto it = database.begin(); it != database.end();)
|
|
128
|
+
if (match(*it, bits)) {
|
|
129
|
+
for (int i = 0; i < width; i++) {
|
|
130
|
+
if ((*it)[i] != RTLIL::State::Sa || bits[i] == RTLIL::State::Sa)
|
|
131
|
+
continue;
|
|
132
|
+
bits_t new_pattern;
|
|
133
|
+
new_pattern.bitdata = it->bitdata;
|
|
134
|
+
new_pattern[i] = bits[i] == RTLIL::State::S1 ? RTLIL::State::S0 : RTLIL::State::S1;
|
|
135
|
+
database.insert(new_pattern);
|
|
136
|
+
}
|
|
137
|
+
it = database.erase(it);
|
|
138
|
+
status = true;
|
|
139
|
+
continue;
|
|
140
|
+
} else
|
|
141
|
+
++it;
|
|
142
|
+
return status;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
bool take_all()
|
|
146
|
+
{
|
|
147
|
+
if (database.empty())
|
|
148
|
+
return false;
|
|
149
|
+
database.clear();
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
bool empty()
|
|
154
|
+
{
|
|
155
|
+
return database.empty();
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
YOSYS_NAMESPACE_END
|
|
160
|
+
|
|
161
|
+
#endif
|
|
@@ -26,7 +26,17 @@ YOSYS_NAMESPACE_BEGIN
|
|
|
26
26
|
|
|
27
27
|
struct CellCosts
|
|
28
28
|
{
|
|
29
|
+
|
|
30
|
+
private:
|
|
31
|
+
dict<RTLIL::IdString, int> mod_cost_cache_;
|
|
32
|
+
Design *design_ = nullptr;
|
|
33
|
+
|
|
34
|
+
public:
|
|
35
|
+
CellCosts(RTLIL::Design *design) : design_(design) { }
|
|
36
|
+
|
|
29
37
|
static const dict<RTLIL::IdString, int>& default_gate_cost() {
|
|
38
|
+
// Default size heuristics for several common PDK standard cells
|
|
39
|
+
// used by abc and stat
|
|
30
40
|
static const dict<RTLIL::IdString, int> db = {
|
|
31
41
|
{ ID($_BUF_), 1 },
|
|
32
42
|
{ ID($_NOT_), 2 },
|
|
@@ -43,12 +53,14 @@ struct CellCosts
|
|
|
43
53
|
{ ID($_AOI4_), 7 },
|
|
44
54
|
{ ID($_OAI4_), 7 },
|
|
45
55
|
{ ID($_MUX_), 4 },
|
|
46
|
-
{ ID($_NMUX_), 4 }
|
|
56
|
+
{ ID($_NMUX_), 4 },
|
|
47
57
|
};
|
|
48
58
|
return db;
|
|
49
59
|
}
|
|
50
60
|
|
|
51
61
|
static const dict<RTLIL::IdString, int>& cmos_gate_cost() {
|
|
62
|
+
// Estimated CMOS transistor counts for several common PDK standard cells
|
|
63
|
+
// used by stat and optionally by abc
|
|
52
64
|
static const dict<RTLIL::IdString, int> db = {
|
|
53
65
|
{ ID($_BUF_), 1 },
|
|
54
66
|
{ ID($_NOT_), 2 },
|
|
@@ -65,50 +77,21 @@ struct CellCosts
|
|
|
65
77
|
{ ID($_AOI4_), 8 },
|
|
66
78
|
{ ID($_OAI4_), 8 },
|
|
67
79
|
{ ID($_MUX_), 12 },
|
|
68
|
-
{ ID($_NMUX_), 10 }
|
|
80
|
+
{ ID($_NMUX_), 10 },
|
|
81
|
+
{ ID($_DFF_P_), 16 },
|
|
82
|
+
{ ID($_DFF_N_), 16 },
|
|
69
83
|
};
|
|
70
84
|
return db;
|
|
71
85
|
}
|
|
72
86
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
int get(RTLIL::
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
log_warning("Can't determine cost of %s cell.\n", log_id(type));
|
|
83
|
-
return 1;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
int get(RTLIL::Cell *cell)
|
|
87
|
-
{
|
|
88
|
-
if (gate_cost && gate_cost->count(cell->type))
|
|
89
|
-
return gate_cost->at(cell->type);
|
|
90
|
-
|
|
91
|
-
if (design && design->module(cell->type) && cell->parameters.empty())
|
|
92
|
-
{
|
|
93
|
-
RTLIL::Module *mod = design->module(cell->type);
|
|
94
|
-
|
|
95
|
-
if (mod->attributes.count(ID(cost)))
|
|
96
|
-
return mod->attributes.at(ID(cost)).as_int();
|
|
97
|
-
|
|
98
|
-
if (mod_cost_cache.count(mod->name))
|
|
99
|
-
return mod_cost_cache.at(mod->name);
|
|
100
|
-
|
|
101
|
-
int module_cost = 1;
|
|
102
|
-
for (auto c : mod->cells())
|
|
103
|
-
module_cost += get(c);
|
|
104
|
-
|
|
105
|
-
mod_cost_cache[mod->name] = module_cost;
|
|
106
|
-
return module_cost;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(cell->type), GetSize(cell->parameters));
|
|
110
|
-
return 1;
|
|
111
|
-
}
|
|
87
|
+
// Get the cell cost for a cell based on its parameters.
|
|
88
|
+
// This cost is an *approximate* upper bound for the number of gates that
|
|
89
|
+
// the cell will get mapped to with "opt -fast; techmap"
|
|
90
|
+
// The intended usage is for flattening heuristics and similar situations
|
|
91
|
+
unsigned int get(RTLIL::Cell *cell);
|
|
92
|
+
// Sum up the cell costs of all cells in the module
|
|
93
|
+
// and all its submodules recursively
|
|
94
|
+
unsigned int get(RTLIL::Module *mod);
|
|
112
95
|
};
|
|
113
96
|
|
|
114
97
|
YOSYS_NAMESPACE_END
|
|
@@ -188,6 +188,7 @@ inline unsigned int mkhash(const T &v) {
|
|
|
188
188
|
|
|
189
189
|
inline int hashtable_size(int min_size)
|
|
190
190
|
{
|
|
191
|
+
// Primes as generated by https://oeis.org/A175953
|
|
191
192
|
static std::vector<int> zero_and_some_primes = {
|
|
192
193
|
0, 23, 29, 37, 47, 59, 79, 101, 127, 163, 211, 269, 337, 431, 541, 677,
|
|
193
194
|
853, 1069, 1361, 1709, 2137, 2677, 3347, 4201, 5261, 6577, 8231, 10289,
|
|
@@ -196,7 +197,9 @@ inline int hashtable_size(int min_size)
|
|
|
196
197
|
897133, 1121423, 1401791, 1752239, 2190299, 2737937, 3422429, 4278037,
|
|
197
198
|
5347553, 6684443, 8355563, 10444457, 13055587, 16319519, 20399411,
|
|
198
199
|
25499291, 31874149, 39842687, 49803361, 62254207, 77817767, 97272239,
|
|
199
|
-
121590311, 151987889, 189984863, 237481091, 296851369, 371064217
|
|
200
|
+
121590311, 151987889, 189984863, 237481091, 296851369, 371064217,
|
|
201
|
+
463830313, 579787991, 724735009, 905918777, 1132398479, 1415498113,
|
|
202
|
+
1769372713
|
|
200
203
|
};
|
|
201
204
|
|
|
202
205
|
for (auto p : zero_and_some_primes)
|
|
@@ -1129,6 +1132,11 @@ public:
|
|
|
1129
1132
|
const_iterator end() const { return const_iterator(*this, offset + size()); }
|
|
1130
1133
|
};
|
|
1131
1134
|
|
|
1135
|
+
/**
|
|
1136
|
+
* Union-find data structure with a promotion method
|
|
1137
|
+
* mfp stands for "merge, find, promote"
|
|
1138
|
+
* i-prefixed methods operate on indices in parents
|
|
1139
|
+
*/
|
|
1132
1140
|
template<typename K, typename OPS>
|
|
1133
1141
|
class mfp
|
|
1134
1142
|
{
|
|
@@ -1142,13 +1150,18 @@ public:
|
|
|
1142
1150
|
{
|
|
1143
1151
|
}
|
|
1144
1152
|
|
|
1153
|
+
// Finds a given element's index. If it isn't in the data structure,
|
|
1154
|
+
// it is added as its own set
|
|
1145
1155
|
int operator()(const K &key) const
|
|
1146
1156
|
{
|
|
1147
1157
|
int i = database(key);
|
|
1158
|
+
// If the lookup caused the database to grow,
|
|
1159
|
+
// also add a corresponding entry in parents initialized to -1 (no parent)
|
|
1148
1160
|
parents.resize(database.size(), -1);
|
|
1149
1161
|
return i;
|
|
1150
1162
|
}
|
|
1151
1163
|
|
|
1164
|
+
// Finds an element at given index
|
|
1152
1165
|
const K &operator[](int index) const
|
|
1153
1166
|
{
|
|
1154
1167
|
return database[index];
|
|
@@ -1161,6 +1174,11 @@ public:
|
|
|
1161
1174
|
while (parents[p] != -1)
|
|
1162
1175
|
p = parents[p];
|
|
1163
1176
|
|
|
1177
|
+
// p is now the representative of i
|
|
1178
|
+
// Now we traverse from i up to the representative again
|
|
1179
|
+
// and make p the parent of all the nodes along the way.
|
|
1180
|
+
// This is a side effect and doesn't affect the return value.
|
|
1181
|
+
// It speeds up future find operations
|
|
1164
1182
|
while (k != p) {
|
|
1165
1183
|
int next_k = parents[k];
|
|
1166
1184
|
parents[k] = p;
|
|
@@ -1170,6 +1188,7 @@ public:
|
|
|
1170
1188
|
return p;
|
|
1171
1189
|
}
|
|
1172
1190
|
|
|
1191
|
+
// Merge sets if the given indices belong to different sets
|
|
1173
1192
|
void imerge(int i, int j)
|
|
1174
1193
|
{
|
|
1175
1194
|
i = ifind(i);
|
|
@@ -229,6 +229,13 @@ using sort_by_name_id_guard = typename std::enable_if<std::is_same<T,RTLIL::Cell
|
|
|
229
229
|
template<typename T>
|
|
230
230
|
class SigSet<T, sort_by_name_id_guard<T>> : public SigSet<T, RTLIL::sort_by_name_id<typename std::remove_pointer<T>::type>> {};
|
|
231
231
|
|
|
232
|
+
/**
|
|
233
|
+
* SigMap wraps a union-find "database"
|
|
234
|
+
* to map SigBits of a module to canonical representative SigBits.
|
|
235
|
+
* SigBits that are connected share a set in the underlying database.
|
|
236
|
+
* If a SigBit has a const state (impl: bit.wire is nullptr),
|
|
237
|
+
* it's promoted to a representative.
|
|
238
|
+
*/
|
|
232
239
|
struct SigMap
|
|
233
240
|
{
|
|
234
241
|
mfp<SigBit> database;
|
|
@@ -249,6 +256,7 @@ struct SigMap
|
|
|
249
256
|
database.clear();
|
|
250
257
|
}
|
|
251
258
|
|
|
259
|
+
// Rebuild SigMap for all connections in module
|
|
252
260
|
void set(RTLIL::Module *module)
|
|
253
261
|
{
|
|
254
262
|
int bitcount = 0;
|
|
@@ -262,6 +270,7 @@ struct SigMap
|
|
|
262
270
|
add(it.first, it.second);
|
|
263
271
|
}
|
|
264
272
|
|
|
273
|
+
// Add connections from "from" to "to", bit-by-bit
|
|
265
274
|
void add(const RTLIL::SigSpec& from, const RTLIL::SigSpec& to)
|
|
266
275
|
{
|
|
267
276
|
log_assert(GetSize(from) == GetSize(to));
|
|
@@ -287,6 +296,7 @@ struct SigMap
|
|
|
287
296
|
}
|
|
288
297
|
}
|
|
289
298
|
|
|
299
|
+
// Add sig as disconnected from anything
|
|
290
300
|
void add(const RTLIL::SigBit &bit)
|
|
291
301
|
{
|
|
292
302
|
const auto &b = database.find(bit);
|
|
@@ -302,6 +312,7 @@ struct SigMap
|
|
|
302
312
|
|
|
303
313
|
inline void add(Wire *wire) { return add(RTLIL::SigSpec(wire)); }
|
|
304
314
|
|
|
315
|
+
// Modify bit to its representative
|
|
305
316
|
void apply(RTLIL::SigBit &bit) const
|
|
306
317
|
{
|
|
307
318
|
bit = database.find(bit);
|
|
@@ -332,6 +343,7 @@ struct SigMap
|
|
|
332
343
|
return sig;
|
|
333
344
|
}
|
|
334
345
|
|
|
346
|
+
// All non-const bits
|
|
335
347
|
RTLIL::SigSpec allbits() const
|
|
336
348
|
{
|
|
337
349
|
RTLIL::SigSpec sig;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# ISC License
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
|
|
4
|
+
#
|
|
5
|
+
# Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
# purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
# copyright notice and this permission notice appear in all copies.
|
|
8
|
+
#
|
|
9
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# LSRAM true dual-port
|
|
21
|
+
ram block $__LSRAM_TDP_ {
|
|
22
|
+
|
|
23
|
+
# Cost of a given cell is assumed to be:
|
|
24
|
+
# (cost-widthscale) + [widthscale * (used_bits/14)]
|
|
25
|
+
cost 129;
|
|
26
|
+
|
|
27
|
+
# INIT is supported
|
|
28
|
+
init any;
|
|
29
|
+
|
|
30
|
+
# port A and port B are allowed to have different widths, but they MUST have
|
|
31
|
+
# WIDTH values of the same set.
|
|
32
|
+
# Example: Port A has a Data Width of 1. Then Port B's Data Width must be either
|
|
33
|
+
# 1, 2, 4, 8, or 16 (both values are in the 'WIDTH_1' set).
|
|
34
|
+
# WIDTH_1 = {1, 2, 4, 8, 16}
|
|
35
|
+
# WIDTH_2 = {5, 10, 20}
|
|
36
|
+
|
|
37
|
+
# "byte" specifies how many data bits correspond to one write enable bit.
|
|
38
|
+
# "byte" must be larger than width, or width must be a multipler of "byte"
|
|
39
|
+
# if "byte" > WIDTH, a single enable wire is inferred
|
|
40
|
+
# otherwise, WIDTH/byte number of enable wires are inferred
|
|
41
|
+
#
|
|
42
|
+
# WIDTH = {1, 2, 4, 5, 8, 10} requires 1 enable wire
|
|
43
|
+
# WIDTH = {16, 20} requires 2 enable wire
|
|
44
|
+
|
|
45
|
+
option "WIDTH_CONFIG" "REGULAR" {
|
|
46
|
+
|
|
47
|
+
# Data-Width| Address bits
|
|
48
|
+
# 1 | 14
|
|
49
|
+
# 2 | 13
|
|
50
|
+
# 4 | 12
|
|
51
|
+
# 8 | 11
|
|
52
|
+
# 16 | 10
|
|
53
|
+
|
|
54
|
+
# 14 address bits
|
|
55
|
+
abits 14;
|
|
56
|
+
|
|
57
|
+
widths 1 2 4 8 16 per_port;
|
|
58
|
+
byte 8;
|
|
59
|
+
}
|
|
60
|
+
option "WIDTH_CONFIG" "ALIGN" {
|
|
61
|
+
|
|
62
|
+
# Data-Width| Address bits
|
|
63
|
+
# 5 | 12
|
|
64
|
+
# 10 | 11
|
|
65
|
+
# 20 | 10
|
|
66
|
+
|
|
67
|
+
# Quick "hack" to fix address bit alignment by setting address bits to 12.
|
|
68
|
+
# If abits=14, tool will think there are 14 bits for width=5, 13 bits for width=10, 12 bits for width=20
|
|
69
|
+
# THe LSRAM_map.v file detects if this option is being used, and adjusts the address port alignments accordingly.
|
|
70
|
+
abits 12;
|
|
71
|
+
|
|
72
|
+
widths 5 10 20 per_port;
|
|
73
|
+
byte 10;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
port srsw "A" "B" {
|
|
79
|
+
|
|
80
|
+
# read & write width must be same
|
|
81
|
+
width tied;
|
|
82
|
+
|
|
83
|
+
# clock polarity is rising
|
|
84
|
+
clock posedge;
|
|
85
|
+
|
|
86
|
+
# A/B read-enable
|
|
87
|
+
rden;
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# initial value of read port data (not supported)
|
|
91
|
+
rdinit none;
|
|
92
|
+
|
|
93
|
+
# write modes (<A/B>_WMODE)
|
|
94
|
+
# 1. Simple Write: read-data port holds prev value (similar to "NO_CHANGE" for RAMB18E1)
|
|
95
|
+
# 2. Feed-through: read-data port takes new write value (similar to "WRITE_FIRST" for RAMB18E1)
|
|
96
|
+
# 3. Read-Before-Write: read-data port holds old value while being written (similar to "READ_FIRST" for RAMB18E1)
|
|
97
|
+
|
|
98
|
+
portoption "WRITE_MODE" "NO_CHANGE" {
|
|
99
|
+
|
|
100
|
+
# Read-write interaction
|
|
101
|
+
rdwr no_change;
|
|
102
|
+
|
|
103
|
+
# Write transparency:
|
|
104
|
+
# For write ports, define behaviour when another synchronous read port
|
|
105
|
+
# reads from the same memory cell that said write port is writing to at the same time.
|
|
106
|
+
wrtrans all old;
|
|
107
|
+
}
|
|
108
|
+
portoption "WRITE_MODE" "WRITE_FIRST" {
|
|
109
|
+
# bits corresponding to high A/B_WEN are updated
|
|
110
|
+
rdwr new_only;
|
|
111
|
+
wrtrans all new;
|
|
112
|
+
}
|
|
113
|
+
portoption "WRITE_MODE" "READ_FIRST" {
|
|
114
|
+
rdwr old;
|
|
115
|
+
|
|
116
|
+
wrtrans all old;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# generate params to indicate if read or write is used for each port
|
|
120
|
+
optional_rw;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# two-port configuration
|
|
125
|
+
ram block $__LSRAM_SDP_ {
|
|
126
|
+
|
|
127
|
+
# since two-port configuration is dedicated for wide-read/write,
|
|
128
|
+
# we want to prioritize this configuration over TDP to avoid tool picking multiple TDP RAMs
|
|
129
|
+
# inplace of a single SDP RAM for wide read/write. This means the cost of a single SDP should
|
|
130
|
+
# be less than 2 TDP.
|
|
131
|
+
cost 129;
|
|
132
|
+
init any;
|
|
133
|
+
|
|
134
|
+
option "WIDTH_CONFIG" "REGULAR" {
|
|
135
|
+
|
|
136
|
+
# Data-Width| Address bits
|
|
137
|
+
# 1 | 14
|
|
138
|
+
# 2 | 13
|
|
139
|
+
# 4 | 12
|
|
140
|
+
# 8 | 11
|
|
141
|
+
# 16 | 10
|
|
142
|
+
# 32 | 9
|
|
143
|
+
|
|
144
|
+
abits 14;
|
|
145
|
+
|
|
146
|
+
widths 1 2 4 8 16 32 per_port;
|
|
147
|
+
|
|
148
|
+
# width = 32, byte-write size is 8, ignore other widths
|
|
149
|
+
byte 8;
|
|
150
|
+
|
|
151
|
+
}
|
|
152
|
+
option "WIDTH_CONFIG" "ALIGN" {
|
|
153
|
+
|
|
154
|
+
# Data-Width| Address bits
|
|
155
|
+
# 5 | 12
|
|
156
|
+
# 10 | 11
|
|
157
|
+
# 20 | 10
|
|
158
|
+
# 40 | 9
|
|
159
|
+
|
|
160
|
+
# Same trick as TSP RAM for alignment
|
|
161
|
+
abits 12;
|
|
162
|
+
widths 5 10 20 40 per_port;
|
|
163
|
+
byte 10;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
port sw "W" {
|
|
167
|
+
|
|
168
|
+
# only consider wide write
|
|
169
|
+
|
|
170
|
+
option "WIDTH_CONFIG" "REGULAR" width 32;
|
|
171
|
+
option "WIDTH_CONFIG" "ALIGN" width 40;
|
|
172
|
+
|
|
173
|
+
clock posedge;
|
|
174
|
+
|
|
175
|
+
# only simple write supported for two-port mode
|
|
176
|
+
wrtrans all old;
|
|
177
|
+
|
|
178
|
+
optional;
|
|
179
|
+
}
|
|
180
|
+
port sr "R" {
|
|
181
|
+
|
|
182
|
+
option "WIDTH_CONFIG" "REGULAR" width 32;
|
|
183
|
+
option "WIDTH_CONFIG" "ALIGN" width 40;
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
clock posedge;
|
|
187
|
+
rden;
|
|
188
|
+
rdinit none;
|
|
189
|
+
optional;
|
|
190
|
+
}
|
|
191
|
+
}
|