Skip to content

Commit 31a86bd

Browse files
committed
Enable c++ model parameterisation, apply to gpio
1 parent 5e2641c commit 31a86bd

File tree

4 files changed

+50
-46
lines changed

4 files changed

+50
-46
lines changed

chipflow_lib/common/sim/models.cc

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -274,39 +274,6 @@ void uart_model::step(unsigned timestamp) {
274274
}
275275
}
276276

277-
// GPIO
278-
279-
void gpio_model::step(unsigned timestamp) {
280-
uint32_t o_value = o.get<uint32_t>();
281-
uint32_t oe_value = oe.get<uint32_t>();
282-
283-
for (auto action : get_pending_actions(name)) {
284-
if (action.event == "set") {
285-
auto bin = std::string(action.payload);
286-
input_data = 0;
287-
for (unsigned i = 0; i < pin_count; i++) {
288-
if (bin.at((pin_count - 1) - i) == '1')
289-
input_data |= (1U << i);
290-
}
291-
}
292-
}
293-
294-
if (o_value != s.o_last || oe_value != s.oe_last) {
295-
std::string formatted_value;
296-
for (int i = pin_count - 1; i >= 0; i--) {
297-
if (oe_value & (1U << unsigned(i)))
298-
formatted_value += (o_value & (1U << unsigned(i))) ? '1' : '0';
299-
else
300-
formatted_value += 'Z';
301-
}
302-
log_event(timestamp, name, "change", json(formatted_value));
303-
}
304-
305-
i.set((input_data & ~oe_value) | (o_value & oe_value));
306-
s.o_last = o_value;
307-
s.oe_last = oe_value;
308-
}
309-
310277
// Generic SPI model
311278
void spi_model::step(unsigned timestamp) {
312279
for (auto action : get_pending_actions(name)) {

chipflow_lib/common/sim/models.h

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,11 @@ struct uart_model {
8282
} s;
8383
};
8484

85+
template<int pin_count>
8586
struct gpio_model {
8687
std::string name;
87-
struct parameters {
88-
unsigned pin_count;
89-
};
90-
parameters parameters;
9188

92-
gpio_model(const std::string &name, parameters, const value<paramters.pin_count> &o, const value<parameters.pin_count> &oe, value<parameters.pin_count> &i) : name(name), parameters(parameters), o(o), oe(oe), i(i) {};
89+
gpio_model(const std::string &name, const value<pin_count> &o, const value<pin_count> &oe, value<pin_count> &i) : name(name), o(o), oe(oe), i(i) {};
9390

9491
void step(unsigned timestamp);
9592

@@ -105,6 +102,39 @@ struct gpio_model {
105102
};
106103

107104

105+
// GPIO
106+
template<int pin_count>
107+
void gpio_model<pin_count>::step(unsigned timestamp) {
108+
uint32_t o_value = o.template get<uint32_t>();
109+
uint32_t oe_value = oe.template get<uint32_t>();
110+
111+
for (auto action : get_pending_actions(name)) {
112+
if (action.event == "set") {
113+
auto bin = std::string(action.payload);
114+
input_data = 0;
115+
for (unsigned i = 0; i < pin_count; i++) {
116+
if (bin.at((pin_count - 1) - i) == '1')
117+
input_data |= (1U << i);
118+
}
119+
}
120+
}
121+
122+
if (o_value != s.o_last || oe_value != s.oe_last) {
123+
std::string formatted_value;
124+
for (int i = pin_count - 1; i >= 0; i--) {
125+
if (oe_value & (1U << unsigned(i)))
126+
formatted_value += (o_value & (1U << unsigned(i))) ? '1' : '0';
127+
else
128+
formatted_value += 'Z';
129+
}
130+
log_event(timestamp, name, "change", json(formatted_value));
131+
}
132+
133+
i.set((input_data & ~oe_value) | (o_value & oe_value));
134+
s.o_last = o_value;
135+
s.oe_last = oe_value;
136+
}
137+
108138
struct spi_model {
109139
std::string name;
110140
spi_model(const std::string &name, const value<1> &clk, const value<1> &copi, value<1> &cipo, const value<1> &csn) :

chipflow_lib/platforms/_signatures.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ class SimInterface(TypedDict):
1818

1919
_VALID_UID = re.compile('[a-zA-Z_.]').search
2020

21+
"""
22+
Attributes:
23+
__chipflow_parameters__: list of tuples (name, value).
24+
It is expected that a model that takes parameters is implmemted as a template, with the parameters in the order
25+
given.
26+
"""
2127
def sim_annotate(base="com.chipflow.chipflow_lib"):
2228
def decorate(klass):
2329
assert _VALID_UID(base)
@@ -35,7 +41,7 @@ def new_init(self,*args, **kwargs):
3541
klass.__init__ = new_init
3642
klass.__chipflow_uid__ = f"{base}.{klass.__name__}"
3743
if not hasattr(klass, '__chipflow_parameters__'):
38-
klass.__chipflow_parameters__ = lambda self: {}
44+
klass.__chipflow_parameters__ = lambda self: []
3945
return klass
4046
return decorate
4147

@@ -100,7 +106,7 @@ def __init__(self, pin_count=1, **kwargs: Unpack[IOModelOptions]):
100106
})
101107

102108
def __chipflow_parameters__(self):
103-
return {'pin_count': self._pin_count}
109+
return [('pin_count',self._pin_count)]
104110

105111
def __repr__(self) -> str:
106112
return f"GPIOSignature(pin_count={self._pin_count}, {dict(self.members.items())})"

chipflow_lib/platforms/sim.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def instantiate_model(self, interface: str, sim_interface: SimInterface, interfa
110110
logger.warn(f"Unable to find simulation model for '{sim_interface}'")
111111

112112
model = self._table[uid]
113-
sig = model.signature(**parameters)
113+
sig = model.signature(**dict(parameters))
114114
members = list(sig.flatten(sig.create()))
115115

116116
sig_names = [ path for path, _, _ in members ]
@@ -120,12 +120,13 @@ def instantiate_model(self, interface: str, sim_interface: SimInterface, interfa
120120
names = [f"\\io${port_names[str(n)]}${d}" for n,d in sig_names]
121121
params = [f"top.{cxxrtlmangle(n)}" for n in names]
122122

123-
out = f"{model.name} {interface}(\"{interface}\", "
123+
cpp_class = model.name
124124
if len(parameters):
125-
cpp_params = []
126-
for p,v in parameters.items():
127-
cpp_params.append(f"{p} = {v}")
128-
out += '{' + ', '.join(cpp_params) + '}, '
125+
template_params = []
126+
for p,v in parameters:
127+
template_params.append(f"{v}")
128+
cpp_class = cpp_class + '<' + ', '.join(template_params) + '>'
129+
out = f"{cpp_class} {interface}(\"{interface}\", "
129130
out += ', '.join(list(params))
130131
out += ')\n'
131132
return out

0 commit comments

Comments
 (0)