fixed stupid bug in dualrail decoder refresh

This commit is contained in:
alexmadison 2022-04-14 16:31:16 +02:00
parent 058da32b5b
commit 62a87ab99c
1 changed files with 41 additions and 23 deletions

View File

@ -96,7 +96,9 @@ export template<pint Nc, N>
defproc decoder_dualrail_refresh (Mx1of2<Nc> in; bool? out[N]; Mx1of2<Nc> final_refresh; power supply) {
// signal buffers
pint index;
pint NUM_REFRESH = N/(48*2); // x2 bc only half the output bits look for it.
pint NUM_OUTS_PER_BUF = 96;
pint NUM_REFRESH = N/(NUM_OUTS_PER_BUF); // x2 bc only half the output bits look for it.
// NUM_REFRESH = 0;
BUF_X12 in_tX[Nc*(NUM_REFRESH+1)];
BUF_X12 in_fX[Nc*(NUM_REFRESH+1)];
@ -109,6 +111,7 @@ defproc decoder_dualrail_refresh (Mx1of2<Nc> in; bool? out[N]; Mx1of2<Nc> final_
(j:NUM_REFRESH:
index = i + (1+j)*Nc;
in_tX[index].a = in_tX[index-Nc].y;
in_fX[index].a = in_fX[index-Nc].y;
)
// Connect end
@ -131,10 +134,10 @@ defproc decoder_dualrail_refresh (Mx1of2<Nc> in; bool? out[N]; Mx1of2<Nc> final_
(j:0..Nc-1:
bitval = (i & ( 1 << j )) >> j; // Get binary digit of integer i, column j
[bitval = 1 ->
atree[i].in[j] = in_tX[j+(i/96)*Nc].y;
atree[i].in[j] = in_tX[j+((i/NUM_OUTS_PER_BUF)*Nc)].y;
// atree[i].in[j] = addr_buf.out.d.d[j].t;
[]bitval = 0 ->
atree[i].in[j] = in_fX[j+(i/96)*Nc].y;
atree[i].in[j] = in_fX[j+((i/NUM_OUTS_PER_BUF)*Nc)].y;
// atree[i].in[j] = addr_buf.out.d.d[j].f;
[]bitval >= 2 -> {false : "fuck"};
]
@ -249,8 +252,10 @@ defproc decoder_2d_dly (avMx1of2<NxC+NyC> in; bool? outx[Nx], outy[Ny],
export template<pint Nx, Ny>
defproc and_grid(bool! out[Nx*Ny]; bool? inx[Nx], iny[Ny]; power supply) {
// Buffer inputs
sigbuf<Ny> xbuf[Nx];
sigbuf<Nx> ybuf[Ny];
// sigbuf<Ny> xbuf[Nx];
// sigbuf<Nx> ybuf[Ny];
sigbuf<47> xbuf[Nx]; // BUFFERING DISABLED FOR NOW
sigbuf<47> ybuf[Ny]; // CUS GET BUFFERED IN THE CORE
(i:Nx:
xbuf[i].in = inx[i];
xbuf[i].supply = supply;
@ -264,8 +269,8 @@ defproc and_grid(bool! out[Nx*Ny]; bool? inx[Nx], iny[Ny]; power supply) {
(i:0..Nx*Ny-1:ands[i].vss = supply.vss; ands[i].vdd = supply.vdd;)
(x:0..Nx-1:
(y:0..Ny-1:
ands[x + y*Nx].a = xbuf[x].out[y];
ands[x + y*Nx].b = ybuf[y].out[x];
ands[x + y*Nx].a = xbuf[x].out[0];
ands[x + y*Nx].b = ybuf[y].out[0];
ands[x + y*Nx].y = out[x + y*Nx];
)
)
@ -386,9 +391,11 @@ defproc decoder_2d_hs (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? reset_B; po
* goes through the prog_delay block.
* Thus, for the handshaking version to be used "correctly",
* dly_cfg should be set to all zeros.
* ack_disable blocks the ack being returned to the buffer.
* Is needed in case there are instabilities while we fiddle with delays.
*/
export template<pint NxC, NyC, Nx, Ny, N_dly_cfg>
defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg[N_dly_cfg], hs_en,
defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg[N_dly_cfg], hs_en, ack_disable,
reset_B; power supply) {
bool _reset_BX[Nx];
@ -408,25 +415,30 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
// sig buf for reqx lines, since they go to synapse pull down gates.
// Signals to the and-grid are buffered therein.
sigbuf<Ny+1> d_dr_xX[Nx];
(i:Nx:
d_dr_xX[i].in = d_dr_x.out[i];
d_dr_xX[i].supply = supply;
)
sigbuf_boolarray<Nx,15> d_dr_xX(.in = d_dr_x.out, .supply = supply);
// sigbuf<15> d_dr_xX[Nx]; // GET REFRESHED IN CORE
// (i:Nx:
// d_dr_xX[i].in = d_dr_x.out[i];
// d_dr_xX[i].supply = supply;
// )
sigbuf_boolarray<Ny,47> d_dr_yX(.in = d_dr_y.out, .supply = supply);
// Validity
vtree<NxC> vtree_x (.supply = supply);
vtree<NyC> vtree_y (.supply = supply);
(i:0..NxC-1:vtree_x.in.d[i].t = d_dr_x.final_refresh.d[i].t;)
(i:0..NxC-1:vtree_x.in.d[i].f = d_dr_x.final_refresh.d[i].f;)
(i:0..NyC-1:vtree_y.in.d[i].t = d_dr_y.final_refresh.d[i].t;)
(i:0..NyC-1:vtree_y.in.d[i].f = d_dr_y.final_refresh.d[i].f;)
vtree<NxC> vtree_x (.in = d_dr_x.in, .supply = supply);
vtree<NyC> vtree_y (.in = d_dr_y.in, .supply = supply);
// (i:0..NxC-1:vtree_x.in.d[i].t = d_dr_x.in.d[i].t;)
// (i:0..NxC-1:vtree_x.in.d[i].f = d_dr_x.in.d[i].f;)
// (i:0..NyC-1:vtree_y.in.d[i].t = d_dr_y.in.d[i].t;)
// (i:0..NyC-1:vtree_y.in.d[i].f = d_dr_y.in.d[i].f;)
A_2C_B_X1 valid_Cel(.c1 = vtree_x.out, .c2 = vtree_y.out, .y = addr_buf.out.v,
.vdd = supply.vdd, .vss = supply.vss);
// and grid for reqs into synapses
and_grid<Nx, Ny> _and_grid(.inx = d_dr_x.out, .iny = d_dr_y.out, .supply = supply);
and_grid<Nx, Ny> _and_grid(.inx = d_dr_xX.out, .iny = d_dr_yX.out, .supply = supply);
(i:Nx*Ny: out[i].r = _and_grid.out[i];)
// Acknowledge pull down time
@ -439,7 +451,7 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
(j:Ny:
index = i + Nx*j;
ack_pulldowns[index].n1 = out[index].a;
ack_pulldowns[index].n2 = d_dr_xX[i].out[j];
ack_pulldowns[index].n2 = d_dr_xX.out[i]; // GET REFRHRESED IN CORE
ack_pulldowns[index].y = _out_acksB[i];
ack_pulldowns[index].vss = supply.vss;
ack_pulldowns[index].vdd = supply.vdd;
@ -454,7 +466,7 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
A_2P_U_X4 pu[Nx]; // TODO probably replace this with variable strength PU
A_1P_U_X4 pu_reset[Nx];
(i:Nx:
pu[i].p1 = d_dr_xX[i].out[Ny];
pu[i].p1 = d_dr_xX.out[i];
pu[i].p2 = hs_enB;
pu[i].y = _out_acksB[i];
pu[i].vdd = supply.vdd;
@ -499,7 +511,13 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
.vdd = supply.vdd, .vss = supply.vss);
// Programmable delay
delayprog<N_dly_cfg> dly(.in = ack_mux.y, .out = addr_buf.out.a, .s = dly_cfg, .supply = supply);
delayprog<N_dly_cfg> dly(.in = ack_mux.y, .s = dly_cfg, .supply = supply);
// Final switch from register to maybe block the ack
INV_X1 ack_disableB(.a = ack_disable, .vdd = supply.vdd, .vss = supply.vss);
AND2_X1 ack_block(.a = dly.out, .b = ack_disableB.y, .y = addr_buf.out.a,
.vdd = supply.vdd, .vss = supply.vss);
}