Skip to content

Commit 5286fb8

Browse files
Synthesis rework.
Synthesis could only handle relatively simple conditional constructs. This rework aims to make it handle anything the user can throw at it (or output a sensible message as to why it can't).
1 parent 46105e0 commit 5286fb8

File tree

5 files changed

+973
-688
lines changed

5 files changed

+973
-688
lines changed

net_link.cc

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000-2013 Stephen Williams ([email protected])
2+
* Copyright (c) 2000-2016 Stephen Williams ([email protected])
33
*
44
* This source code is free software; you can redistribute it
55
* and/or modify it in source code form under the terms of the GNU
@@ -311,6 +311,20 @@ void Nexus::count_io(unsigned&inp, unsigned&out) const
311311
}
312312
}
313313

314+
bool Nexus::has_floating_input() const
315+
{
316+
bool found_input = false;
317+
for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
318+
if (cur->get_dir() == Link::OUTPUT)
319+
return false;
320+
321+
if (cur->get_dir() == Link::INPUT)
322+
found_input = true;
323+
}
324+
325+
return found_input;
326+
}
327+
314328
bool Nexus::drivers_present() const
315329
{
316330
for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
@@ -467,6 +481,17 @@ NetNet* Nexus::pick_any_net()
467481
return 0;
468482
}
469483

484+
NetNode* Nexus::pick_any_node()
485+
{
486+
for (Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
487+
NetNode*node = dynamic_cast<NetNode*>(cur->get_obj());
488+
if (node != 0)
489+
return node;
490+
}
491+
492+
return 0;
493+
}
494+
470495
const char* Nexus::name() const
471496
{
472497
if (name_)

net_scope.cc

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
2+
* Copyright (c) 2000-2016 Stephen Williams ([email protected])
33
*
44
* This source code is free software; you can redistribute it
55
* and/or modify it in source code form under the terms of the GNU
@@ -23,6 +23,7 @@
2323
# include "netlist.h"
2424
# include "netclass.h"
2525
# include "netenum.h"
26+
# include "netvector.h"
2627
# include <cstring>
2728
# include <cstdlib>
2829
# include <sstream>
@@ -161,6 +162,8 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest,
161162
lineno_ = 0;
162163
def_lineno_ = 0;
163164
genvar_tmp_val = 0;
165+
tie_hi_ = 0;
166+
tie_lo_ = 0;
164167
}
165168

166169
NetScope::~NetScope()
@@ -744,3 +747,33 @@ perm_string NetScope::local_symbol()
744747
res << "_s" << (lcounter_++);
745748
return lex_strings.make(res.str());
746749
}
750+
751+
void NetScope::add_tie_hi(Design*des)
752+
{
753+
if (tie_hi_ == 0) {
754+
NetNet*sig = new NetNet(this, lex_strings.make("_LOGIC1"),
755+
NetNet::WIRE, &netvector_t::scalar_logic);
756+
sig->local_flag(true);
757+
758+
tie_hi_ = new NetLogic(this, local_symbol(),
759+
1, NetLogic::PULLUP, 1);
760+
des->add_node(tie_hi_);
761+
762+
connect(sig->pin(0), tie_hi_->pin(0));
763+
}
764+
}
765+
766+
void NetScope::add_tie_lo(Design*des)
767+
{
768+
if (tie_lo_ == 0) {
769+
NetNet*sig = new NetNet(this, lex_strings.make("_LOGIC0"),
770+
NetNet::WIRE, &netvector_t::scalar_logic);
771+
sig->local_flag(true);
772+
773+
tie_lo_ = new NetLogic(this, local_symbol(),
774+
1, NetLogic::PULLDOWN, 1);
775+
des->add_node(tie_lo_);
776+
777+
connect(sig->pin(0), tie_lo_->pin(0));
778+
}
779+
}

netlist.cc

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998-2015 Stephen Williams ([email protected])
2+
* Copyright (c) 1998-2016 Stephen Williams ([email protected])
33
*
44
* This source code is free software; you can redistribute it
55
* and/or modify it in source code form under the terms of the GNU
@@ -1022,11 +1022,36 @@ NetProc::~NetProc()
10221022
NetProcTop::NetProcTop(NetScope*s, ivl_process_type_t t, NetProc*st)
10231023
: type_(t), statement_(st), scope_(s)
10241024
{
1025+
synthesized_design_ = 0;
10251026
}
10261027

10271028
NetProcTop::~NetProcTop()
10281029
{
1030+
if (!synthesized_design_) {
1031+
delete statement_;
1032+
return;
1033+
}
1034+
1035+
NexusSet nex_set;
1036+
statement_->nex_output(nex_set);
1037+
10291038
delete statement_;
1039+
1040+
bool flag = false;
1041+
for (unsigned idx = 0 ; idx < nex_set.size() ; idx += 1) {
1042+
1043+
NetNet*net = nex_set[idx].lnk.nexus()->pick_any_net();
1044+
if (net->peek_lref() > 0) {
1045+
cerr << get_fileline() << ": warning: '" << net->name()
1046+
<< "' is driven by more than one process." << endl;
1047+
flag = true;
1048+
}
1049+
}
1050+
if (flag) {
1051+
cerr << get_fileline() << ": sorry: Cannot synthesize signals "
1052+
"that are driven by more than one process." << endl;
1053+
synthesized_design_->errors += 1;
1054+
}
10301055
}
10311056

10321057
NetProc* NetProcTop::statement()

netlist.h

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef IVL_netlist_H
22
#define IVL_netlist_H
33
/*
4-
* Copyright (c) 1998-2015 Stephen Williams ([email protected])
4+
* Copyright (c) 1998-2016 Stephen Williams ([email protected])
55
* Copyright CERN 2013 / Stephen Williams ([email protected])
66
*
77
* This source code is free software; you can redistribute it
@@ -379,6 +379,8 @@ class Nexus {
379379

380380
NetNet* pick_any_net();
381381

382+
NetNode* pick_any_node();
383+
382384
/* This method counts the number of input and output links for
383385
this nexus, and assigns the results to the output arguments. */
384386
void count_io(unsigned&inp, unsigned&out) const;
@@ -388,6 +390,10 @@ class Nexus {
388390
is a variable, but also if this is a net with a force. */
389391
bool assign_lval() const;
390392

393+
/* This method returns true if there are any inputs
394+
attached to this nexus but no drivers. */
395+
bool has_floating_input() const;
396+
391397
/* This method returns true if there are any drivers
392398
(including variables) attached to this nexus. */
393399
bool drivers_present() const;
@@ -1146,6 +1152,12 @@ class NetScope : public Definitions, public Attrib {
11461152
children of this node as well. */
11471153
void run_functor(Design*des, functor_t*fun);
11481154

1155+
/* These are used in synthesis. They provide shared pullup and
1156+
pulldown nodes for this scope. */
1157+
void add_tie_hi(Design*des);
1158+
void add_tie_lo(Design*des);
1159+
Link&tie_hi() const { return tie_hi_->pin(0); };
1160+
Link&tie_lo() const { return tie_lo_->pin(0); };
11491161

11501162
/* This member is used during elaboration to pass defparam
11511163
assignments from the scope pass to the parameter evaluation
@@ -1267,6 +1279,9 @@ class NetScope : public Definitions, public Attrib {
12671279
/* Final procedures sets this to notify statements that
12681280
they are part of a final procedure. */
12691281
bool in_final_;
1282+
1283+
NetNode*tie_hi_;
1284+
NetNode*tie_lo_;
12701285
};
12711286

12721287
/*
@@ -2605,12 +2620,11 @@ class NetProc : public virtual LineInfo {
26052620

26062621
// Synthesize as asynchronous logic, and return true. The
26072622
// nex_out is where this function attaches its output
2608-
// results. The accumulated_nex_out is used by sequential
2609-
// blocks to show outputs from the previous code.
2623+
// results.
2624+
typedef vector<bool> mask_t;
26102625
virtual bool synth_async(Design*des, NetScope*scope,
2611-
NexusSet&nex_map,
2612-
NetBus&nex_out,
2613-
NetBus&accumulated_nex_out);
2626+
NexusSet&nex_map, NetBus&nex_out,
2627+
NetBus&enables, vector<mask_t>&bitmasks);
26142628

26152629
// Synthesize as synchronous logic, and return true. That
26162630
// means binding the outputs to the data port of a FF, and the
@@ -2630,6 +2644,7 @@ class NetProc : public virtual LineInfo {
26302644
NetBus&ff_aclr, NetBus&ff_aset,
26312645
vector<verinum>&ff_aset_value,
26322646
NexusSet&nex_map, NetBus&nex_out,
2647+
vector<mask_t>&bitmasks,
26332648
const std::vector<NetEvProbe*>&events);
26342649

26352650
virtual void dump(ostream&, unsigned ind) const;
@@ -2640,7 +2655,9 @@ class NetProc : public virtual LineInfo {
26402655
protected:
26412656
bool synth_async_block_substatement_(Design*des, NetScope*scope,
26422657
NexusSet&nex_map,
2643-
NetBus&accumulated_nex_out,
2658+
NetBus&nex_out,
2659+
NetBus&enables,
2660+
vector<mask_t>&bitmasks,
26442661
NetProc*substmt);
26452662
private:
26462663
friend class NetBlock;
@@ -2819,7 +2836,7 @@ class NetAssignBase : public NetProc {
28192836

28202837
bool synth_async(Design*des, NetScope*scope,
28212838
NexusSet&nex_map, NetBus&nex_out,
2822-
NetBus&accumulated_nex_out);
2839+
NetBus&enables, vector<mask_t>&bitmasks);
28232840

28242841
// This dumps all the lval structures.
28252842
void dump_lval(ostream&) const;
@@ -2905,14 +2922,15 @@ class NetBlock : public NetProc {
29052922
// synthesize as asynchronous logic, and return true.
29062923
bool synth_async(Design*des, NetScope*scope,
29072924
NexusSet&nex_map, NetBus&nex_out,
2908-
NetBus&accumulated_nex_out);
2925+
NetBus&enables, vector<mask_t>&bitmasks);
29092926

29102927
bool synth_sync(Design*des, NetScope*scope,
29112928
bool&ff_negedge,
29122929
NetNet*ff_clk, NetBus&ff_ce,
29132930
NetBus&ff_aclr,NetBus&ff_aset,
29142931
vector<verinum>&ff_aset_value,
29152932
NexusSet&nex_map, NetBus&nex_out,
2933+
vector<mask_t>&bitmasks,
29162934
const std::vector<NetEvProbe*>&events);
29172935

29182936
// This version of emit_recurse scans all the statements of
@@ -2968,7 +2986,7 @@ class NetCase : public NetProc {
29682986

29692987
bool synth_async(Design*des, NetScope*scope,
29702988
NexusSet&nex_map, NetBus&nex_out,
2971-
NetBus&accumulated_nex_out);
2989+
NetBus&enables, vector<mask_t>&bitmasks);
29722990

29732991
virtual bool emit_proc(struct target_t*) const;
29742992
virtual void dump(ostream&, unsigned ind) const;
@@ -2984,7 +3002,7 @@ class NetCase : public NetProc {
29843002

29853003
bool synth_async_casez_(Design*des, NetScope*scope,
29863004
NexusSet&nex_map, NetBus&nex_out,
2987-
NetBus&accumulated_nex_out);
3005+
NetBus&enables, vector<mask_t>&bitmasks);
29883006

29893007
TYPE type_;
29903008

@@ -3048,14 +3066,15 @@ class NetCondit : public NetProc {
30483066
bool is_asynchronous();
30493067
bool synth_async(Design*des, NetScope*scope,
30503068
NexusSet&nex_map, NetBus&nex_out,
3051-
NetBus&accumulated_nex_out);
3069+
NetBus&enables, vector<mask_t>&bitmasks);
30523070

30533071
bool synth_sync(Design*des, NetScope*scope,
30543072
bool&ff_negedge,
30553073
NetNet*ff_clk, NetBus&ff_ce,
30563074
NetBus&ff_aclr,NetBus&ff_aset,
30573075
vector<verinum>&ff_aset_value,
30583076
NexusSet&nex_map, NetBus&nex_out,
3077+
vector<mask_t>&bitmasks,
30593078
const std::vector<NetEvProbe*>&events);
30603079

30613080
virtual bool emit_proc(struct target_t*) const;
@@ -3327,14 +3346,15 @@ class NetEvWait : public NetProc {
33273346

33283347
virtual bool synth_async(Design*des, NetScope*scope,
33293348
NexusSet&nex_map, NetBus&nex_out,
3330-
NetBus&accumulated_nex_out);
3349+
NetBus&enables, vector<mask_t>&bitmasks);
33313350

33323351
virtual bool synth_sync(Design*des, NetScope*scope,
33333352
bool&ff_negedge,
33343353
NetNet*ff_clk, NetBus&ff_ce,
33353354
NetBus&ff_aclr,NetBus&ff_aset,
33363355
vector<verinum>&ff_aset_value,
33373356
NexusSet&nex_map, NetBus&nex_out,
3357+
vector<mask_t>&bitmasks,
33383358
const std::vector<NetEvProbe*>&events);
33393359

33403360
virtual void dump(ostream&, unsigned ind) const;
@@ -3439,7 +3459,7 @@ class NetForLoop : public NetProc {
34393459
// synthesize as asynchronous logic, and return true.
34403460
bool synth_async(Design*des, NetScope*scope,
34413461
NexusSet&nex_map, NetBus&nex_out,
3442-
NetBus&accumulated_nex_out);
3462+
NetBus&enables, vector<mask_t>&bitmasks);
34433463

34443464
private:
34453465
NetNet*index_;
@@ -3827,8 +3847,14 @@ class NetProcTop : public LineInfo, public Attrib {
38273847
bool emit(struct target_t*tgt) const;
38283848

38293849
private:
3850+
bool tie_off_floating_inputs_(Design*des,
3851+
NexusSet&nex_map, NetBus&nex_in,
3852+
vector<NetProc::mask_t>&bitmasks,
3853+
bool is_ff_input);
3854+
38303855
const ivl_process_type_t type_;
38313856
NetProc*const statement_;
3857+
Design*synthesized_design_;
38323858

38333859
NetScope*scope_;
38343860
friend class Design;

0 commit comments

Comments
 (0)