vastly improved lazy synapse handshakes
This commit is contained in:
parent
cd5d41d7f8
commit
2e4cdd5029
@ -190,89 +190,52 @@ namespace tmpl {
|
|||||||
|
|
||||||
// Acknowledge pull down time
|
// Acknowledge pull down time
|
||||||
|
|
||||||
// Pull DOWNs on the reqB lines by synapses (easier to invert).
|
// Pull DOWNs on the ackB lines by synapses (easier to invert).
|
||||||
bool _out_reqsB[Nx], _out_acksB[Nx]; // The vertical output ack lines from each syn.
|
bool _out_acksB[Nx]; // The vertical output ack lines from each syn.
|
||||||
PULLDOWN2_X4 req_pulldowns[Nx*Ny];
|
PULLDOWN2_X4 ack_pulldowns[Nx*Ny];
|
||||||
pint index;
|
pint index;
|
||||||
(i:Nx:
|
(i:Nx:
|
||||||
(j:Ny:
|
(j:Ny:
|
||||||
index = i + Nx*j;
|
index = i + Nx*j;
|
||||||
req_pulldowns[index].a = out[index].a;
|
ack_pulldowns[index].a = out[index].a;
|
||||||
req_pulldowns[index].b = _out_acksB[i];
|
ack_pulldowns[index].b = d_dr_x.out[i];
|
||||||
req_pulldowns[index].y = _out_reqsB[i];
|
ack_pulldowns[index].y = _out_acksB[i];
|
||||||
req_pulldowns[index].vss = supply.vss;
|
ack_pulldowns[index].vss = supply.vss;
|
||||||
req_pulldowns[index].vdd = supply.vdd;
|
ack_pulldowns[index].vdd = supply.vdd;
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReqB keep cells
|
// Line end pull UPs (triggered once reqs removed)
|
||||||
KEEP_X1 req_keeps[Nx];
|
|
||||||
(i:Nx:
|
|
||||||
req_keeps[i].y = _out_reqsB[i];
|
|
||||||
req_keeps[i].vdd = supply.vdd;
|
|
||||||
req_keeps[i].vss = supply.vss;
|
|
||||||
)
|
|
||||||
|
|
||||||
// req-ack buffers
|
|
||||||
// Delay needed here, since otherwise the pull up of reqB happens too quickly.
|
|
||||||
// Means that the pull up may start fighting the synapse,
|
|
||||||
// since the synapse has not yet retracted its ack.
|
|
||||||
// Also there is the possibility, if really fast, that the line pull up block
|
|
||||||
// doesn't yet see that the input is valid, and starts pulling up.
|
|
||||||
// In any case, this delay is important.
|
|
||||||
sigbuf<Ny> req_bufs[Nx];
|
|
||||||
delay_chain<N_dly> ack_delays[Nx];
|
|
||||||
(i:Nx:
|
|
||||||
ack_delays[i].in = _out_reqsB[i];
|
|
||||||
ack_delays[i].supply = supply;
|
|
||||||
|
|
||||||
// req_bufs[i].in = _out_reqsB[i];
|
|
||||||
req_bufs[i].in = ack_delays[i].out;
|
|
||||||
req_bufs[i].out[0] = _out_acksB[i]; // DANGER DANGER
|
|
||||||
req_bufs[i].supply = supply;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
// Line end pull UPs (triggered once synapse reqs removed)
|
|
||||||
OR2_X1 pu_ORs[Nx];
|
|
||||||
PULLUP_X4 pu[Nx]; // TODO probably replace this with variable strength PU
|
PULLUP_X4 pu[Nx]; // TODO probably replace this with variable strength PU
|
||||||
AND2_X1 pu_ANDs[Nx];
|
AND2_X1 pu_ANDs[Nx];
|
||||||
(i:Nx:
|
(i:Nx:
|
||||||
pu_ORs[i].a = _out_acksB[i];
|
pu_ANDs[i].a = d_dr_x.out[i];
|
||||||
pu_ORs[i].b = d_dr_x.out[i];
|
|
||||||
pu_ORs[i].vdd = supply.vdd;
|
|
||||||
pu_ORs[i].vss = supply.vss;
|
|
||||||
|
|
||||||
pu_ANDs[i].a = pu_ORs[i].y;
|
|
||||||
pu_ANDs[i].b = reset_B; // TODO buffer
|
pu_ANDs[i].b = reset_B; // TODO buffer
|
||||||
pu_ANDs[i].vdd = supply.vdd;
|
pu_ANDs[i].vdd = supply.vdd;
|
||||||
pu_ANDs[i].vss = supply.vss;
|
pu_ANDs[i].vss = supply.vss;
|
||||||
|
|
||||||
pu[i].a = pu_ANDs[i].y;
|
pu[i].a = pu_ANDs[i].y;
|
||||||
pu[i].y = _out_reqsB[i];
|
pu[i].y = _out_acksB[i];
|
||||||
pu[i].vdd = supply.vdd;
|
pu[i].vdd = supply.vdd;
|
||||||
pu[i].vss = supply.vss;
|
pu[i].vss = supply.vss;
|
||||||
)
|
)
|
||||||
|
|
||||||
// ORtree from all output reqs, back to the buffer ack.
|
// ORtree from all output acks, back to the buffer ack.
|
||||||
// This is instead of the ack that came from the delayed validity trees,
|
// This is instead of the ack that came from the delayed validity trees,
|
||||||
// in decoder_2d_dly.
|
// in decoder_2d_dly.
|
||||||
ortree<Nx> _ortree(.out = addr_buf.out.a, .supply = supply);
|
ortree<Nx> _ortree(.out = addr_buf.out.a, .supply = supply);
|
||||||
INV_X1 out_req_invs[Nx];
|
INV_X1 out_ack_invs[Nx];
|
||||||
(i:Nx:
|
(i:Nx:
|
||||||
out_req_invs[i].a = _out_reqsB[i];
|
out_ack_invs[i].a = _out_acksB[i];
|
||||||
out_req_invs[i].vdd = supply.vdd;
|
out_ack_invs[i].vdd = supply.vdd;
|
||||||
out_req_invs[i].vss = supply.vss;
|
out_ack_invs[i].vss = supply.vss;
|
||||||
|
|
||||||
_ortree.in[i] = out_req_invs[i].y;
|
_ortree.in[i] = out_ack_invs[i].y;
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build an arbiter_handshake tree.
|
* Build an arbiter_handshake tree.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user