From 62a87ab99cd610ba187cfc64c17d08ece026a1c5 Mon Sep 17 00:00:00 2001 From: alexmadison Date: Thu, 14 Apr 2022 16:31:16 +0200 Subject: [PATCH] fixed stupid bug in dualrail decoder refresh --- dataflow_neuro/coders.act | 64 +++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/dataflow_neuro/coders.act b/dataflow_neuro/coders.act index bf077d1..a03849c 100644 --- a/dataflow_neuro/coders.act +++ b/dataflow_neuro/coders.act @@ -96,7 +96,9 @@ export template defproc decoder_dualrail_refresh (Mx1of2 in; bool? out[N]; Mx1of2 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 in; bool? out[N]; Mx1of2 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 in; bool? out[N]; Mx1of2 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 in; bool? outx[Nx], outy[Ny], export template defproc and_grid(bool! out[Nx*Ny]; bool? inx[Nx], iny[Ny]; power supply) { // Buffer inputs - sigbuf xbuf[Nx]; - sigbuf ybuf[Ny]; + // sigbuf xbuf[Nx]; + // sigbuf 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 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 -defproc decoder_2d_hybrid (avMx1of2 in; a1of1 out[Nx*Ny]; bool? dly_cfg[N_dly_cfg], hs_en, +defproc decoder_2d_hybrid (avMx1of2 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 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 d_dr_xX[Nx]; - (i:Nx: - d_dr_xX[i].in = d_dr_x.out[i]; - d_dr_xX[i].supply = supply; - ) + sigbuf_boolarray 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 d_dr_yX(.in = d_dr_y.out, .supply = supply); + // Validity - vtree vtree_x (.supply = supply); - vtree 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 vtree_x (.in = d_dr_x.in, .supply = supply); + vtree 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 _and_grid(.inx = d_dr_x.out, .iny = d_dr_y.out, .supply = supply); + + and_grid _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 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 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 in; a1of1 out[Nx*Ny]; bool? dly_cfg .vdd = supply.vdd, .vss = supply.vss); // Programmable delay - delayprog dly(.in = ack_mux.y, .out = addr_buf.out.a, .s = dly_cfg, .supply = supply); + delayprog 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); + }