diff --git a/dataflow_neuro/chips.act b/dataflow_neuro/chips.act index 95b3d49..6083a5a 100644 --- a/dataflow_neuro/chips.act +++ b/dataflow_neuro/chips.act @@ -42,223 +42,6 @@ open std::channel; namespace tmpl { namespace dataflow_neuro { -export template - -defproc chip_texel (bd in, out; - Mx1of2 reg_data[REG_M]; - a1of1 synapses[N_SYN_X * N_SYN_Y]; - a1of1 neurons[N_NRN_X * N_NRN_Y]; - - bool! nrn_mon_x[N_NRN_MON_X], nrn_mon_y[N_NRN_MON_Y]; - bool! syn_mon_x[N_SYN_MON_X], syn_mon_y[N_SYN_MON_Y]; - bool? syn_mon_AMZI[N_SYN_X * N_MON_AMZO_PER_SYN], nrn_mon_AMZI[N_NRN_X * N_MON_AMZO_PER_NRN]; - bool! syn_mon_AMZO[N_MON_AMZO_PER_SYN], nrn_mon_AMZO[N_MON_AMZO_PER_NRN]; - bool! syn_flags_EFO[N_FLAGS_PER_SYN], nrn_flags_EFO[N_FLAGS_PER_NRN]; - - bool? bd_dly_cfg[N_BD_DLY_CFG], bd_dly_cfg2[N_BD_DLY_CFG2]; - bool? loopback_en; - power supply; - bool? reset_B){ - - bool _reset_BX; - BUF_X12 reset_buf(.a = reset_B, .y = _reset_BX, .vdd = supply.vdd, .vss = supply.vss); - - pint index = 0; // Just useful - - bd2qdi _bd2qdi(.in = in, .dly_cfg = bd_dly_cfg, .dly_cfg2 = bd_dly_cfg2, - .reset_B = _reset_BX, .supply = supply); - fifo fifo_in2fork(.in = _bd2qdi.out, .reset_B = _reset_BX, .supply = supply); - - fork _fork(.in = fifo_in2fork.out, .reset_B = _reset_BX, .supply = supply); - - // Loopback - fifo fifo_fork2drop(.in = _fork.out1, .reset_B = _reset_BX, .supply = supply); - dropper_static _loopback_dropper(.in = fifo_fork2drop.out, .cond = loopback_en, - .supply = supply); - - // Onwards - fifo fifo_fork2dmx(.in = _fork.out2, .reset_B = _reset_BX, .supply = supply); - demux_bit_msb _demux(.in = fifo_fork2dmx.out, .reset_B = _reset_BX, .supply = supply); - - // Register - fifo fifo_dmx2reg(.in = _demux.out2, .reset_B = _reset_BX, .supply = supply); - register_wr_array register(.in = fifo_dmx2reg.out, .data = reg_data, - .supply = supply, .reset_B = _reset_BX); - fifo fifo_reg2mrg(.in = register.out, .reset_B = _reset_BX, .supply = supply); - - - // Spike Decoder - pint NC_SYN; - NC_SYN = NC_SYN_X + NC_SYN_Y; - slice_data slice_pre_dec(.in = _demux.out1, .supply = supply); - fifo fifo_dmx2dec(.in = slice_pre_dec.out, .reset_B = _reset_BX, .supply = supply); - decoder_2d_hybrid decoder(.in = fifo_dmx2dec.out, - .out = synapses, - .hs_en = register.data[0].d[0].t, // Defaults to handshake disable - .supply = supply, .reset_B = _reset_BX); - (i:N_SYN_DLY_CFG: decoder.dly_cfg[i] = register.data[0].d[1 + i].f;) // Defaults to max delay - - // Neurons + encoder - pint NC_NRN; - NC_NRN = NC_NRN_X + NC_NRN_Y; - nrn_hs_2d_array nrn_grid(.in = neurons, - .supply = supply, .reset_B = _reset_BX); - encoder2d_simple encoder( - .inx = nrn_grid.outx, - .iny = nrn_grid.outy, - .reset_B = _reset_BX, .supply = supply - ); - fifo fifo_enc2mrg(.in = encoder.out, - .reset_B = _reset_BX, .supply = supply); - - - // Merge - append append_enc(.in = fifo_enc2mrg.out, .supply = supply); - append append_reg(.in = fifo_reg2mrg.out, .supply = supply); - merge merge_enc8reg(.in1 = append_enc.out, .in2 = append_reg.out, - .supply = supply, .reset_B = _reset_BX); - - merge merge_loop8mrg(.in1 = merge_enc8reg.out, .in2 = _loopback_dropper.out, - .reset_B = _reset_BX, .supply = supply); - - // qdi2bd - fifo fifo_mrg2bd(.in = merge_loop8mrg.out, - .reset_B = _reset_BX, .supply = supply); - qdi2bd _qdi2bd(.in = fifo_mrg2bd.out, .out = out, .dly_cfg = bd_dly_cfg, - .reset_B = _reset_BX, .supply = supply); - - - - // Neuron/synapse monitor targeters - pint NC_NRN_MON_X = std::ceil_log2(N_NRN_MON_X); - pint NC_NRN_MON_Y = std::ceil_log2(N_NRN_MON_Y); - pint NC_SYN_MON_X = std::ceil_log2(N_SYN_MON_X); - pint NC_SYN_MON_Y = std::ceil_log2(N_SYN_MON_Y); - - decoder_dualrail_en nrn_mon_dec_x(.supply = supply); - nrn_mon_dec_x.en = register.data[1].d[0].t; - (i:NC_NRN_MON_X: - nrn_mon_dec_x.in.d[i] = register.data[2].d[i]; - ) - sigbuf_boolarray nrn_mon_x_buf(.in = nrn_mon_dec_x.out, .out = nrn_mon_x, .supply = supply); - - decoder_dualrail_en nrn_mon_dec_y(.supply = supply); - nrn_mon_dec_y.en = register.data[1].d[0].t; - (i:NC_NRN_MON_Y: - nrn_mon_dec_y.in.d[i] = register.data[2].d[i+NC_NRN_MON_X]; - ) - sigbuf_boolarray nrn_mon_y_buf(.in = nrn_mon_dec_y.out, .out = nrn_mon_y, .supply = supply); - - decoder_dualrail_en syn_mon_dec_x( - .supply = supply); - syn_mon_dec_x.en = register.data[1].d[1].t; - (i:NC_SYN_MON_X: - syn_mon_dec_x.in.d[i] = register.data[3].d[i]; - ) - sigbuf_boolarray syn_mon_x_buf(.out = syn_mon_x, .supply = supply); - - decoder_dualrail_en syn_mon_dec_y(.supply = supply); - syn_mon_dec_y.en = register.data[1].d[1].t; - (i:NC_SYN_MON_Y: - syn_mon_dec_y.in.d[i] = register.data[3].d[i+NC_SYN_MON_X]; - ) - sigbuf_boolarray syn_mon_y_buf(.out = syn_mon_y, .in = syn_mon_dec_y.out, .supply = supply); - - // Device debug hard-wired safety (reg0, b05 = DEV_DEBUG) - // Stops the possibility of dev_mon being high while some other sig is high. - // Otherwise boom. - bool DEV_DEBUG; - pint NSMX4 = N_SYN_MON_X/4; // Self explanatory - sigbuf sb_DEV_DEBUG(.in = register.data[0].d[5].t, - .supply = supply); - DEV_DEBUG = sb_DEV_DEBUG.out[0]; - [NSMX4 >= 1 -> - AND2_X1 ands_devmon[NSMX4]; - (i:NSMX4: - ands_devmon[i].a = syn_mon_dec_x.out[1+i*4]; - ands_devmon[i].b = DEV_DEBUG; - ands_devmon[i].y = syn_mon_x_buf.in[1+i*4]; - ands_devmon[i].vdd = supply.vdd; - ands_devmon[i].vss = supply.vss; - ) - // Wire up the non-ANDed lines. - (i:N_SYN_MON_X: - [~(i%4 = 1) -> - syn_mon_x_buf.in[i] = syn_mon_dec_x.out[i]; - ] - ) - ] - - // Create TBUFs for each synapse column, - // ctrl wired to mon line (first in each 4). - TBUF_X4 syn_x_AMZI_tbuf[N_SYN_X * N_MON_AMZO_PER_SYN]; - sigbuf_boolarray syn_mon_AMZO_sb(.out = syn_mon_AMZO, .supply = supply); - (j:N_MON_AMZO_PER_SYN: - (i:N_SYN_X: - index = i*N_MON_AMZO_PER_SYN + j; - syn_x_AMZI_tbuf[index].a = syn_mon_AMZI[index]; - syn_x_AMZI_tbuf[index].en = syn_mon_x[i*4]; - syn_x_AMZI_tbuf[index].y = syn_mon_AMZO_sb.in[j]; - ) - ) - - - // Create TBUFs for each neuron column, - // ctrl wired to mon line (first in each 4). - TBUF_X4 nrn_x_AMZI_tbuf[N_NRN_X * N_MON_AMZO_PER_NRN]; - sigbuf_boolarray nrn_mon_AMZO_sb(.out = nrn_mon_AMZO, .supply = supply); - (j:N_MON_AMZO_PER_NRN: - (i:N_NRN_X: - index = i*N_MON_AMZO_PER_NRN + j; - nrn_x_AMZI_tbuf[index].a = nrn_mon_AMZI[index]; - nrn_x_AMZI_tbuf[index].en = nrn_mon_x[i*2]; - nrn_x_AMZI_tbuf[index].y = nrn_mon_AMZO_sb.in[j]; - ) - ) - - // Create NON buffered signals from register to nrns. - (i:N_FLAGS_PER_NRN: - nrn_flags_EFO[i] = register.data[5].d[i].t; - ) - - // Create NON buffered signals from register to synapses. - // Includes safety on the first 3 flags with dev mon. - (i:3..N_FLAGS_PER_SYN-1: - syn_flags_EFO[i] = register.data[4].d[i].t; - ) - AND2_X1 syn_flags_dev_safety[3]; - BUF_X4 syn_flags_dev_safety_sb[3]; - (i:0..2: - syn_flags_dev_safety[i].a = register.data[4].d[i].t; // syn flag bit - syn_flags_dev_safety[i].b = register.data[0].d[5].f; // no device is being monitored. - syn_flags_dev_safety_sb[i].a = syn_flags_dev_safety[i].y; - syn_flags_dev_safety_sb[i].y = syn_flags_EFO[i]; - - syn_flags_dev_safety[i].vdd = supply.vdd; - syn_flags_dev_safety[i].vss = supply.vss; - syn_flags_dev_safety_sb[i].vdd = supply.vdd; - syn_flags_dev_safety_sb[i].vss = supply.vss; - ) - - - - - - - - -} - export template in, out; pint index = 0; // Just useful // Onwards - fifo fifo_fork2dmx(.in = in, .reset_B = _reset_BX, .supply = supply); - demux_bit_msb _demux(.in = fifo_fork2dmx.out, .reset_B = _reset_BX, .supply = supply); + fifo fifo_in(.in = in, .reset_B = _reset_BX, .supply = supply); + demux_bit_msb _demux(.in = fifo_in.out, .reset_B = _reset_BX, .supply = supply); // Register fifo fifo_dmx2reg(.in = _demux.out2, .reset_B = _reset_BX, .supply = supply); @@ -455,6 +238,93 @@ defproc texel_core (avMx1of2 in, out; } + + + +export template + +defproc texel_singlecore (bd in, out; + Mx1of2 reg_data[REG_M]; + a1of1 synapses[N_SYN_X * N_SYN_Y]; + a1of1 neurons[N_NRN_X * N_NRN_Y]; + + bool! nrn_mon_x[N_NRN_MON_X], nrn_mon_y[N_NRN_MON_Y]; + bool! syn_mon_x[N_SYN_MON_X], syn_mon_y[N_SYN_MON_Y]; + bool? syn_mon_AMZI[N_SYN_X * N_MON_AMZO_PER_SYN], nrn_mon_AMZI[N_NRN_X * N_MON_AMZO_PER_NRN]; + bool! syn_mon_AMZO[N_MON_AMZO_PER_SYN], nrn_mon_AMZO[N_MON_AMZO_PER_NRN]; + bool! syn_flags_EFO[N_FLAGS_PER_SYN], nrn_flags_EFO[N_FLAGS_PER_NRN]; + + bool? bd_dly_cfg[N_BD_DLY_CFG], bd_dly_cfg2[N_BD_DLY_CFG2]; + bool? loopback_en; + power supply; + bool? reset_B){ + + bool _reset_BX; + BUF_X12 reset_buf(.a = reset_B, .y = _reset_BX, .vdd = supply.vdd, .vss = supply.vss); + + pint index = 0; // Just useful + + bd2qdi _bd2qdi(.in = in, .dly_cfg = bd_dly_cfg, .dly_cfg2 = bd_dly_cfg2, + .reset_B = _reset_BX, .supply = supply); + fifo fifo_in2fork(.in = _bd2qdi.out, .reset_B = _reset_BX, .supply = supply); + + fork _fork(.in = fifo_in2fork.out, .reset_B = _reset_BX, .supply = supply); + + // Loopback + fifo fifo_fork2drop(.in = _fork.out1, .reset_B = _reset_BX, .supply = supply); + dropper_static _loopback_dropper(.in = fifo_fork2drop.out, .cond = loopback_en, + .supply = supply); + fifo fifo_drop2mrg(.in = _loopback_dropper.out, .reset_B = _reset_BX, .supply = supply); + + + // Onwards to core + fifo fifo_fork2core(.in = _fork.out2, .reset_B = _reset_BX, .supply = supply); + + texel_core + core(.in = fifo_fork2core.out, + .reg_data = reg_data, + .synapses = synapses, + .neurons = neurons, + .nrn_mon_x = nrn_mon_x, .nrn_mon_y = nrn_mon_y, + .syn_mon_x = syn_mon_x, .syn_mon_y = syn_mon_y, + .syn_mon_AMZI = syn_mon_AMZI, .nrn_mon_AMZI = nrn_mon_AMZI, + .syn_mon_AMZO = syn_mon_AMZO, .nrn_mon_AMZO = nrn_mon_AMZO, + .syn_flags_EFO = syn_flags_EFO, .nrn_flags_EFO = nrn_flags_EFO, + + .reset_B = _reset_BX, + .supply = supply + ); + + // qdi2bd + fifo fifo_core2mrg(.in = core.out, + .reset_B = _reset_BX, .supply = supply); + + + // merge core output and loopback + merge merge_drop8core(.in1 = fifo_core2mrg.out, .in2 = fifo_drop2mrg.out, + .supply = supply, .reset_B = _reset_BX); + + + qdi2bd _qdi2bd(.in = merge_drop8core.out, .out = out, .dly_cfg = bd_dly_cfg, + .reset_B = _reset_BX, .supply = supply); + + + + +} + + + export template in, out; power supply; bool? reset_B){ + // Reset buffers bool _reset_BX; BUF_X12 reset_buf(.a = reset_B, .y = _reset_BX, .vdd = supply.vdd, .vss = supply.vss); @@ -506,32 +377,65 @@ defproc texel_dualcore (bd in, out; fifo fifo_fork2drop(.in = _fork.out1, .reset_B = _reset_BX, .supply = supply); dropper_static _loopback_dropper(.in = fifo_fork2drop.out, .cond = loopback_en, .supply = supply); + fifo fifo_drop2mrg(.in = _loopback_dropper.out, .reset_B = _reset_BX, .supply = supply); + // Onwards to core demux fifo fifo_fork2dmx(.in = _fork.out2, .reset_B = _reset_BX, .supply = supply); - demux_bit_msb _demux(.in = fifo_fork2dmx.out, .reset_B = _reset_BX, .supply = supply); + demux_bit_msb core_dmx(.in = fifo_fork2dmx.out, .reset_B = _reset_BX, .supply = supply); + fifo fifo_dmx2core1(.in = core_dmx.out1, .reset_B = _reset_BX, .supply = supply); + fifo fifo_dmx2core2(.in = core_dmx.out2, .reset_B = _reset_BX, .supply = supply); // Cores texel_core - core1(); + core1(.in = fifo_dmx2core1.out, + + .reg_data = c1_reg_data, + .synapses = c1_synapses, + .neurons = c1_neurons, + .nrn_mon_x = c1_nrn_mon_x, .nrn_mon_y = c1_nrn_mon_y, + .syn_mon_x = c1_syn_mon_x, .syn_mon_y = c1_syn_mon_y, + .syn_mon_AMZI = c1_syn_mon_AMZI, .nrn_mon_AMZI = c1_nrn_mon_AMZI, + .syn_mon_AMZO = c1_syn_mon_AMZO, .nrn_mon_AMZO = c1_nrn_mon_AMZO, + .syn_flags_EFO = c1_syn_flags_EFO, .nrn_flags_EFO = c1_nrn_flags_EFO, + + .reset_B = _reset_BX, + .supply = supply + ); + + + texel_core + core2(.in = fifo_dmx2core2.out, + + .reg_data = c2_reg_data, + .synapses = c2_synapses, + .neurons = c2_neurons, + .nrn_mon_x = c2_nrn_mon_x, .nrn_mon_y = c2_nrn_mon_y, + .syn_mon_x = c2_syn_mon_x, .syn_mon_y = c2_syn_mon_y, + .syn_mon_AMZI = c2_syn_mon_AMZI, .nrn_mon_AMZI = c2_nrn_mon_AMZI, + .syn_mon_AMZO = c2_syn_mon_AMZO, .nrn_mon_AMZO = c2_nrn_mon_AMZO, + .syn_flags_EFO = c2_syn_flags_EFO, .nrn_flags_EFO = c2_nrn_flags_EFO, + + .reset_B = _reset_BX, + .supply = supply + ); - // Merge - // pint NC_NRN = NC_NRN_X + NC_NRN_Y; - // append append_enc(.in = fifo_enc2mrg.out, .supply = supply); - // append append_reg(.in = fifo_reg2mrg.out, .supply = supply); - // merge merge_enc8reg(.in1 = append_enc.out, .in2 = append_reg.out, - // .supply = supply, .reset_B = _reset_BX); + // Merge cores + append append_core1(.in = core1.out, .supply = supply); + append append_core2(.in = core2.out, .supply = supply); + merge merge_core1x2(.in1 = append_core1.out, .in2 = append_core2.out, + .supply = supply, .reset_B = _reset_BX); - // merge merge_loop8mrg(.in1 = merge_enc8reg.out, .in2 = _loopback_dropper.out, - // .reset_B = _reset_BX, .supply = supply); - - // // qdi2bd - // fifo fifo_mrg2bd(.in = merge_loop8mrg.out, - // .reset_B = _reset_BX, .supply = supply); - // qdi2bd _qdi2bd(.in = fifo_mrg2bd.out, .out = out, .dly_cfg = bd_dly_cfg, - // .reset_B = _reset_BX, .supply = supply); + // Merge cores and loopback + merge merge_drop8core(.in1 = merge_core1x2.out, .in2 = fifo_drop2mrg.out, + .reset_B = _reset_BX, .supply = supply); + // qdi2bd + fifo fifo_mrg2bd(.in = merge_drop8core.out, + .reset_B = _reset_BX, .supply = supply); + qdi2bd _qdi2bd(.in = fifo_mrg2bd.out, .out = out, .dly_cfg = bd_dly_cfg, + .reset_B = _reset_BX, .supply = supply); }