Compare commits

67 Commits

Author SHA1 Message Date
11ec898cf4 THIS REPOSITORY IS DEPRICATED 2024-12-31 13:23:15 -05:00
alexmadison
a86b2fc824 added bufx32 lolol 2022-04-21 14:46:08 +02:00
alexmadison
ec03f8abe4 added reg reset sig 2022-04-21 14:33:41 +02:00
alexmadison
c91a7cad50 added separate reset sig for regs 2022-04-21 14:32:04 +02:00
alexmadison
75a42fff1b texel prs for innovus generated 2022-04-21 14:31:35 +02:00
alexmadison
3443d46b9b completely cut out the neuron and synapse hs from core 2022-04-21 14:07:15 +02:00
alexmadison
41f240726c internal access added 2022-04-21 10:41:37 +02:00
alexmadison
c3b336267b added nrn syn ports to dualcore 2022-04-21 10:35:43 +02:00
alexmadison
1a41c03aeb more renaming 2022-04-21 10:23:58 +02:00
alexmadison
10ecb7f55f exposed pd lines 2022-04-21 10:11:26 +02:00
alexmadison
83ae6a4cc3 adjusted pull up channel names 2022-04-20 19:31:06 +02:00
alexmadison
bb63182694 disentangled neurons and pull downs 2022-04-20 19:21:55 +02:00
alexmadison
351b3ea151 disentangled synapse handshake circuits, passing tests 2022-04-20 18:24:43 +02:00
alexmadison
cd5900d4dc tapeout freeze 2022-04-14 17:51:34 +02:00
alexmadison
f7d2db9ef3 cleaned decoder code 2022-04-14 16:37:53 +02:00
alexmadison
62a87ab99c fixed stupid bug in dualrail decoder refresh 2022-04-14 16:31:16 +02:00
alexmadison
058da32b5b made dualrail decoder en use fewer AND gates 2022-04-13 18:53:39 +02:00
alexmadison
17cbc269a6 altered dly cfg to use not(t) rather than f 2022-04-13 18:44:41 +02:00
alexmadison
57d895c4e7 added dr dec refhresh to decoder en 2022-04-13 17:43:03 +02:00
alexmadison
67f8197e8d added decoder refhres to hybrid hs 2022-04-13 17:41:35 +02:00
alexmadison
bf4af13e04 added decoder dualrail refresh 2022-04-13 17:35:41 +02:00
alexmadison
4cca8c14fe texel dualcore testing wip 2022-04-13 15:22:45 +02:00
alexmadison
300c2effde texel dualcore initial tests passed 2022-04-13 14:16:56 +02:00
alexmadison
a51f2191d6 migrating to core 2022-04-13 11:12:16 +02:00
alexmadison
0abc47f682 Merge branch 'dev' of ssh://git.web.rug.nl:222/bics/actlib_dataflow_neuro into dev 2022-04-12 17:49:23 +02:00
alexmadison
ec6d91127f texel small testt working 2022-04-12 17:48:59 +02:00
4af8fc9008 Merge remote-tracking branch 'origin/dev' into dev 2022-04-12 17:05:26 +02:00
7c18ad3437 fixed naming 2022-04-12 17:05:21 +02:00
alexmadison
4216f8808f added sigbuf in chips 2022-04-12 16:41:30 +02:00
alexmadison
fdf05371f3 added sigbufs to register 2022-04-12 16:37:59 +02:00
alexmadison
9d864117d4 Merge branch 'dev' of ssh://git.web.rug.nl:222/bics/actlib_dataflow_neuro into dev 2022-04-12 15:45:17 +02:00
alexmadison
194f33ec81 fixed minor instability in demux 2022-04-12 15:44:29 +02:00
alexmadison
790622bf95 added nrn/syn output TBUFs, added nrn/syn EFO flag inputs 2022-04-12 15:43:46 +02:00
7661e328ed Merge remote-tracking branch 'origin/dev' into dev 2022-04-12 14:18:09 +02:00
bdea75c6ff changed A_2C2N2N_RB_X1 naming conv 2022-04-12 14:18:06 +02:00
alexmadison
3ed1cd9131 Merge branch 'dev' of ssh://git.web.rug.nl:222/bics/actlib_dataflow_neuro into dev 2022-04-12 12:18:59 +02:00
alexmadison
ca00cce63b fixed minor instab in dropper 2022-04-12 12:18:14 +02:00
fb9787d45f fixed naming conv 2022-04-12 10:34:00 +02:00
alexmadison
276efdede5 ole added no stop on fail 2022-04-12 10:31:50 +02:00
alexmadison
cefe78fa24 added more reset sigbugs 2022-04-12 10:25:05 +02:00
432ea397d1 Merge remote-tracking branch 'origin/dev' into dev 2022-04-12 10:24:44 +02:00
aea3bcae6e fixed pull up/down naming convention 2022-04-12 10:24:39 +02:00
alexmadison
a5a378fe6c trying to fix possible lockup in reg lol 2022-04-12 10:24:26 +02:00
87499f834a added flag for start seed 2022-04-11 20:16:32 +02:00
alexmadison
adc37f8de2 encoder1d passed unit tests 2022-04-11 19:49:22 +02:00
alexmadison
a2ca30cbb7 Merge branch 'dev' of ssh://git.web.rug.nl:222/bics/actlib_dataflow_neuro into dev 2022-04-11 19:43:19 +02:00
4b7179768f pullup/down fixed in coders 2022-04-11 19:36:46 +02:00
alexmadison
ed7dc05d97 Merge branch 'dev' of ssh://git.web.rug.nl:222/bics/actlib_dataflow_neuro into dev 2022-04-11 19:30:09 +02:00
7dedeb47fe Merge remote-tracking branch 'origin/dev' into dev 2022-04-11 19:28:08 +02:00
77edb22bb6 chnaged some a cells 2022-04-11 19:28:05 +02:00
alexmadison
b21e64a22a commented nrn hs timing assumption, added encoder1d not tested 2022-04-11 18:36:30 +02:00
alexmadison
c1ea7be83d minor sigbuf changes 2022-04-11 17:29:15 +02:00
7b2484a8a4 KEEP_X1 out 2022-04-11 17:08:31 +02:00
alexmadison
631df5e837 idk ole did something 2022-04-11 17:00:28 +02:00
alexmadison
19565e7303 fixed doubling of sigs 2022-04-11 17:00:15 +02:00
alexmadison
81032c1296 texel working with replaced encoder 2022-04-11 15:31:05 +02:00
alexmadison
d3614580dd wqMerge branch 'dev' of ssh://git.web.rug.nl:222/bics/actlib_dataflow_neuro into dev 2022-04-10 19:43:18 +02:00
alexmadison
8481d67f26 added sigs 2022-04-10 19:42:55 +02:00
alexmadison
812095840e fixed instability in buffers lol 2022-04-10 19:42:09 +02:00
alexmadison
007859023f fixed timing bug in encoder 2022-04-10 19:23:28 +02:00
alexmadison
5647d4affe added TBUF_X4 2022-04-10 19:02:03 +02:00
alexmadison
1aab499474 added 3p pullup 2022-04-10 19:01:51 +02:00
alexmadison
8c8a2eb9a4 altered neuron handshake design to use pullups without timing delays 2022-04-10 18:27:44 +02:00
alexmadison
3bf7c21c48 adding sigbufs 2022-04-10 18:18:11 +02:00
alexmadison
067b2645ee fixed a possible issue in validation of demux 2022-04-10 17:09:37 +02:00
alexmadison
a33bec178f added TBUFs 2022-04-10 16:40:37 +02:00
alexmadison
eeddc15060 added bool sigbuf 2022-04-10 16:40:11 +02:00
30 changed files with 3495366 additions and 137391 deletions

View File

@@ -1,3 +1,7 @@
# ARCHIVED REPOSITORY
further development and new versions => https://github.com/async-ic/actlib-neurosynaptic-perifery
# A dataflow template library for mixed signal neuromoric processors
the library will be installed in `$ACT_HOME/act/tmpl/dataflow_neuro`.

View File

@@ -26,14 +26,14 @@
namespace tmpl {
namespace dataflow_neuro{
export defcell KEEP_X1 (bool y; bool vdd, vss) {
// bool _y;
// prs{
// y => _y-
export defcell KEEP (bool y; bool vdd, vss) {
bool _y;
prs{
y => _y-
// [weak=1] _y -> y-
// [weak=1] ~_y -> y+
// }
}
}
export defcell A_1C2N_RB_X1 (bool! y; bool? c1,n1,n2,pr_B, sr_B; bool vdd, vss) {
@@ -252,12 +252,12 @@ namespace tmpl {
y {-1}}
}
export defcell A_2C2N2N_RB_X1 (bool ! y; bool? c1, c2, n1, n2, n3, n4, pr_B, sr_B; bool vdd, vss)
export defcell A_2C2N2N_RB_X1 (bool ! y; bool? c1, c2, na1, na2, nb1, nb2, pr_B, sr_B; bool vdd, vss)
{
bool _y;
prs{
(~c1 & ~c2) | ~pr_B -> _y+
c1 & c2 & ((n1 & n2) | (n3 & n4)) & sr_B -> _y-
c1 & c2 & ((na1 & na2) | (nb1 & nb2)) & sr_B -> _y-
_y => y-
}
sizing {
@@ -610,11 +610,11 @@ namespace tmpl {
y {-1}; _y{-1} }
}
export defcell A_4P1N1N_X1 (bool! y; bool? n1, n2, p1, p2, p3, p4; bool? vdd, vss)
export defcell A_4P1N1N_X1 (bool! y; bool? na1, nb1, p1, p2, p3, p4; bool? vdd, vss)
{
prs{
~p1 & ~p2 & ~p3 & ~p4 -> y+
n1 | n2 -> y-
na1 | nb1 -> y-
}
sizing {leak_adjust <- 1;
p_n_mode <- 1;
@@ -653,45 +653,53 @@ namespace tmpl {
}
}
export
defproc A_1N_U_X4(bool? a; bool! y; bool? vdd, vss)
defproc A_1N_U_X4(bool? n1; bool! y; bool? vdd, vss)
{
prs{
[keeper=0] a -> y-
[keeper=0] n1 -> y-
}
}
export
defproc A_2N_U_X4(bool? a, b; bool! y; bool? vdd, vss)
defproc A_2N_U_X4(bool? n1, n2; bool! y; bool? vdd, vss)
{
prs{
[keeper=0] a & b -> y-
[keeper=0] n1 & n2 -> y-
}
}
export
defproc A_1P_U_X4(bool? a; bool! y; bool? vdd, vss)
defproc A_1P_U_X4(bool? p1; bool! y; bool? vdd, vss)
{
prs{
[keeper=0] ~a -> y+
[keeper=0] ~p1 -> y+
}
}
export
defproc A_2P_U_X4(bool? a, b; bool! y; bool? vdd, vss)
defproc A_2P_U_X4(bool? p1, p2; bool! y; bool? vdd, vss)
{
prs{
[keeper=0] ~a & ~b -> y+
[keeper=0] ~p1 & ~p2 -> y+
}
}
export
defproc A_3P_U_X4(bool? p1, p2, p3; bool! y; bool? vdd, vss)
{
prs{
[keeper=0] ~p1 & ~p2 & ~p3-> y+
}
}
export
defproc PULLDOWN_X4(bool? a; bool! y; bool? vdd, vss) {
A_1N_U_X4 cell(.a = a, .y = y, .vdd = vdd, .vss = vss);
A_1N_U_X4 cell(.n1 = a, .y = y, .vdd = vdd, .vss = vss);
}
export
defproc PULLUP_X4(bool? a; bool! y; bool? vdd, vss) {
A_1P_U_X4 cell(.a = a, .y = y, .vdd = vdd, .vss = vss);
A_1P_U_X4 cell(.p1 = a, .y = y, .vdd = vdd, .vss = vss);
}
defproc A_2C2P_RB_X1(bool! y;bool? c1,c2,p1,p2,reset_B,vdd,vss){

View File

@@ -86,15 +86,27 @@ namespace tmpl {
{
sizing { _y {-1.5}; y {-4,2} }
}
export defcell BUF_X6<: buf()
export defcell BUF_X6<: buf()
{
sizing { _y {-3}; y {-6,2} }
}
export defcell BUF_X8<: buf()
export defcell BUF_X8<: buf()
{
sizing { _y {-4,2}; y {-8,4} }
}
export defcell BUF_X12<: buf()
export defcell BUF_X12<: buf()
{
sizing { _y {-6,2}; y {-12,4} }
}
export defcell BUF_X16<: buf()
{
sizing { _y {-6,2}; y {-12,4} }
}
export defcell BUF_X24<: buf()
{
sizing { _y {-6,2}; y {-12,4} }
}
export defcell BUF_X32<: buf()
{
sizing { _y {-6,2}; y {-12,4} }
}
@@ -383,6 +395,19 @@ namespace tmpl {
}
sizing { _en{-2}; y{-2,2} }
}
export defcell TBUF_X4 (bool! y; bool? a, en, vdd, vss)
{
bool _en;
prs {
en => _en-
~a & ~_en -> y+
a & en -> y-
}
sizing { _en{-4}; y{-4,4} }
}
export defproc DFFQ_R_X1 (bool? clk_B, reset_B, d; bool! q,q_B; bool? vdd,vss)
{
bool _clk_B, __clk_B, _mqi,_mqib,_sqi,_sqib;

View File

@@ -42,89 +42,118 @@ open std::channel;
namespace tmpl {
namespace dataflow_neuro {
export template<pint N_IN, // Size of input data from outside world
export template<pint N_IN, // Size of input data from outside world
N_NRN_X, N_NRN_Y, N_SYN_X, N_SYN_Y, // Number of neurons / synapses
NC_NRN_X, NC_NRN_Y, NC_SYN_X, NC_SYN_Y,
N_SYN_DLY_CFG,
N_NRN_MON_X, N_NRN_MON_Y, N_SYN_MON_X, N_SYN_MON_Y,
N_MON_AMZO_PER_SYN, N_MON_AMZO_PER_NRN, // Number of signals that each synapse outputs to be monitored.
N_FLAGS_PER_SYN, N_FLAGS_PER_NRN, // Number of signals that each nrn/syn recieves from the register.
N_BUFFERS,
N_LINE_PD_DLY, // Number of dummy delays to add line pull down
N_BD_DLY_CFG, N_BD_DLY_CFG2,
REG_NCA, REG_NCW, REG_M>
defproc chip_texel (bd<N_IN> in, out;
Mx1of2<REG_NCW> 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? bd_dly_cfg[N_BD_DLY_CFG], bd_dly_cfg2[N_BD_DLY_CFG2];
bool? loopback_en;
power supply;
bool? reset_B){
defproc texel_core (avMx1of2<N_IN> in, out;
Mx1of2<REG_NCW> reg_data[REG_M];
bd2qdi<N_IN, N_BD_DLY_CFG, N_BD_DLY_CFG2> _bd2qdi(.in = in, .dly_cfg = bd_dly_cfg, .dly_cfg2 = bd_dly_cfg2,
.reset_B = reset_B, .supply = supply);
fifo<N_IN,N_BUFFERS> fifo_in2fork(.in = _bd2qdi.out, .reset_B = reset_B, .supply = supply);
// Dummy synapses and neurons in the handshake blocks
// should be removed pre-innovus, else they are floating.
// a1of1 synapses[N_SYN_X * N_SYN_Y];
// a1of1 neurons[N_NRN_X * N_NRN_Y];
fork<N_IN> _fork(.in = fifo_in2fork.out, .reset_B = reset_B, .supply = supply);
// Synapse decoder stuff
// The analogue core and connects to these to replace the above synapses.
bool! dec_req_x[N_SYN_X], dec_req_y[N_SYN_Y];
bool? dec_ackB[N_SYN_X];
a1of1 syn_pu[N_SYN_X];
// Loopback
fifo<N_IN,N_BUFFERS> fifo_fork2drop(.in = _fork.out1, .reset_B = reset_B, .supply = supply);
dropper_static<N_IN, false> _loopback_dropper(.in = fifo_fork2drop.out, .cond = loopback_en,
.supply = supply);
// Neuron encoder stuff
a1of1 enc_inx[N_NRN_X], enc_iny[N_NRN_Y];
a1of1 nrn_pd_x[N_NRN_X], nrn_pd_y[N_NRN_Y];
// Onwards
fifo<N_IN,N_BUFFERS> fifo_fork2dmx(.in = _fork.out2, .reset_B = reset_B, .supply = supply);
demux_bit_msb<N_IN-1> _demux(.in = fifo_fork2dmx.out, .reset_B = reset_B, .supply = supply);
// Monitors and flags to/from core, and selected mon out.
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];
// Register
fifo<N_IN-1,N_BUFFERS> fifo_dmx2reg(.in = _demux.out2, .reset_B = reset_B, .supply = supply);
register_wr_array<REG_NCA, REG_NCW, REG_M> register(.in = fifo_dmx2reg.out, .data = reg_data,
.supply = supply, .reset_B = reset_B);
fifo<N_IN-2,N_BUFFERS> fifo_reg2mrg(.in = register.out, .reset_B = reset_B, .supply = supply);
power supply;
bool? reset_B, reset_reg_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
// Onwards
fifo<N_IN,N_BUFFERS> fifo_in(.in = in, .reset_B = _reset_BX, .supply = supply);
demux_bit_msb<N_IN-1> _demux(.in = fifo_in.out, .reset_B = _reset_BX, .supply = supply);
// Register
fifo<N_IN-1,N_BUFFERS> fifo_dmx2reg(.in = _demux.out2, .reset_B = _reset_BX, .supply = supply);
register_wr_array<REG_NCA, REG_NCW, REG_M> register(.in = fifo_dmx2reg.out, .data = reg_data,
.supply = supply, .reset_B = reset_reg_B);
fifo<N_IN-2,N_BUFFERS> fifo_reg2mrg(.in = register.out, .reset_B = _reset_BX, .supply = supply);
// Spike Decoder
// Spike Decoder
pint NC_SYN;
NC_SYN = NC_SYN_X + NC_SYN_Y;
slice_data<N_IN-1, 0, NC_SYN> slice_pre_dec(.in = _demux.out1, .supply = supply);
fifo<NC_SYN,N_BUFFERS> fifo_dmx2dec(.in = slice_pre_dec.out, .reset_B = reset_B, .supply = supply);
decoder_2d_hybrid<NC_SYN_X, NC_SYN_Y, N_SYN_X, N_SYN_Y, N_SYN_DLY_CFG> decoder(.in = fifo_dmx2dec.out,
.out = synapses,
.hs_en = register.data[0].d[0].t, // Defaults to handshake disable
.supply = supply, .reset_B = reset_B);
(i:N_SYN_DLY_CFG: decoder.dly_cfg[i] = register.data[0].d[1 + i].f;) // Defaults to max delay
fifo<NC_SYN,N_BUFFERS> fifo_dmx2dec(.in = slice_pre_dec.out, .reset_B = _reset_BX, .supply = supply);
decoder_2d_hybrid<NC_SYN_X, NC_SYN_Y, N_SYN_X, N_SYN_Y, N_SYN_DLY_CFG> decoder(.in = fifo_dmx2dec.out,
.hs_en = register.data[0].d[0].t, // Defaults to handshake disable
.ack_disable = register.data[1].d[2].t, // Defaults to ack enabled
.out_req_x = dec_req_x, .out_req_y = dec_req_y,
.to_pu = syn_pu,
.in_ackB_decoder = dec_ackB,
.supply = supply, .reset_B = _reset_BX);
INV_X1 dly_cfg_inverters[N_SYN_DLY_CFG];
(i:N_SYN_DLY_CFG:
dly_cfg_inverters[i].a = register.data[0].d[1+i].t; // iff t is high, is the delay disabled.
dly_cfg_inverters[i].vdd = supply.vdd;
dly_cfg_inverters[i].vss = supply.vss;
decoder.dly_cfg[i] = dly_cfg_inverters[i].y;
)
// Neurons + encoder
// Synapse handshake circuits, to be removed for innovus
// decoder_2d_synapse_hs<N_SYN_X, N_SYN_Y> _synapses(
// .synapses = synapses,
// .in_req_x = dec_req_x, .in_req_y = dec_req_y,
// .to_pu = syn_pu,
// .out_ackB_decoder = dec_ackB,
// .supply = supply);
// Neurons + encoder
pint NC_NRN;
NC_NRN = NC_NRN_X + NC_NRN_Y;
nrn_hs_2d_array<N_NRN_X,N_NRN_Y,N_LINE_PD_DLY> nrn_grid(.in = neurons,
.supply = supply, .reset_B = reset_B);
encoder2d<NC_NRN_X, NC_NRN_Y, N_NRN_X, N_NRN_Y, 16> encoder(
.inx = nrn_grid.outx,
.iny = nrn_grid.outy,
.reset_B = reset_B, .supply = supply
);
fifo<NC_NRN, N_BUFFERS> fifo_enc2mrg(.in = encoder.out,
.reset_B = reset_B, .supply = supply);
encoder2d_simple<NC_NRN_X, NC_NRN_Y, N_NRN_X, N_NRN_Y, N_LINE_PD_DLY> encoder(
.inx = enc_inx, .iny = enc_iny,
.reset_B = _reset_BX, .supply = supply,
.to_pd_x = nrn_pd_x, .to_pd_y = nrn_pd_y);
fifo<NC_NRN, N_BUFFERS> fifo_enc2mrg(.in = encoder.out,
.reset_B = _reset_BX, .supply = supply);
// Neuron handshake circuits, to be removed for innovus
// nrn_hs_2d_array<N_NRN_X,N_NRN_Y> nrn_grid(.in = neurons,
// .outx = enc_inx, .outy = enc_iny,
// .to_pd_x = nrn_pd_x, .to_pd_y = nrn_pd_y,
// .supply = supply, .reset_B = _reset_BX);
// Merge
append<NC_NRN, N_IN-NC_NRN, 0> append_enc(.in = fifo_enc2mrg.out, .supply = supply);
append<N_IN-2, 2, 0> append_reg(.in = fifo_reg2mrg.out, .supply = supply);
append<N_IN-2, 2, 2> append_reg(.in = fifo_reg2mrg.out, .supply = supply);
merge<N_IN> merge_enc8reg(.in1 = append_enc.out, .in2 = append_reg.out,
.supply = supply, .reset_B = reset_B);
.supply = supply, .reset_B = _reset_BX);
merge<N_IN> merge_loop8mrg(.in1 = merge_enc8reg.out, .in2 = _loopback_dropper.out,
.reset_B = reset_B, .supply = supply);
// qdi2bd
fifo<N_IN, N_BUFFERS> fifo_mrg2bd(.in = merge_loop8mrg.out,
.reset_B = reset_B, .supply = supply);
qdi2bd<N_IN, N_BD_DLY_CFG> _qdi2bd(.in = fifo_mrg2bd.out, .out = out, .dly_cfg = bd_dly_cfg,
.reset_B = reset_B, .supply = supply);
// Output
fifo<N_IN, N_BUFFERS> fifo_out(.in = merge_enc8reg.out, .out = out,
.reset_B = _reset_BX, .supply = supply);
// Neuron/synapse monitor targeters
@@ -133,19 +162,19 @@ defproc chip_texel (bd<N_IN> in, out;
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<NC_NRN_MON_X, N_NRN_MON_X> nrn_mon_dec_x(.out = nrn_mon_x,
.supply = supply);
decoder_dualrail_en<NC_NRN_MON_X, N_NRN_MON_X> 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<N_NRN_MON_X, 13> nrn_mon_x_buf(.in = nrn_mon_dec_x.out, .out = nrn_mon_x, .supply = supply);
decoder_dualrail_en<NC_NRN_MON_Y, N_NRN_MON_Y> nrn_mon_dec_y(.out = nrn_mon_y,
.supply = supply);
decoder_dualrail_en<NC_NRN_MON_Y, N_NRN_MON_Y> 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<N_NRN_MON_Y, 48> nrn_mon_y_buf(.in = nrn_mon_dec_y.out, .out = nrn_mon_y, .supply = supply);
decoder_dualrail_en<NC_SYN_MON_X, N_SYN_MON_X> syn_mon_dec_x(
.supply = supply);
@@ -153,13 +182,14 @@ defproc chip_texel (bd<N_IN> in, out;
(i:NC_SYN_MON_X:
syn_mon_dec_x.in.d[i] = register.data[3].d[i];
)
sigbuf_boolarray<N_SYN_MON_X, 13> syn_mon_x_buf(.out = syn_mon_x, .supply = supply);
decoder_dualrail_en<NC_SYN_MON_Y, N_SYN_MON_Y> syn_mon_dec_y(.out = syn_mon_y,
.supply = supply);
decoder_dualrail_en<NC_SYN_MON_Y, N_SYN_MON_Y> 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<N_SYN_MON_Y, 48> 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.
@@ -174,21 +204,307 @@ defproc chip_texel (bd<N_IN> in, out;
(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[1+i*4];
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[i] = syn_mon_dec_x.out[i];
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<N_MON_AMZO_PER_SYN, 40> 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<N_MON_AMZO_PER_NRN, 40> 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<pint N_IN, // Size of input data from outside world
N_NRN_X, N_NRN_Y, N_SYN_X, N_SYN_Y, // Number of neurons / synapses
NC_NRN_X, NC_NRN_Y, NC_SYN_X, NC_SYN_Y,
N_SYN_DLY_CFG,
N_NRN_MON_X, N_NRN_MON_Y, N_SYN_MON_X, N_SYN_MON_Y,
N_MON_AMZO_PER_SYN, N_MON_AMZO_PER_NRN, // Number of signals that each synapse outputs to be monitored.
N_FLAGS_PER_SYN, N_FLAGS_PER_NRN, // Number of signals that each nrn/syn recieves from the register.
N_BUFFERS,
N_LINE_PD_DLY, // Number of dummy delays to add line pull down
N_BD_DLY_CFG, N_BD_DLY_CFG2,
REG_NCA, REG_NCW, REG_M>
defproc texel_singlecore (bd<N_IN> in, out;
Mx1of2<REG_NCW> 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<N_IN, N_BD_DLY_CFG, N_BD_DLY_CFG2> _bd2qdi(.in = in, .dly_cfg = bd_dly_cfg, .dly_cfg2 = bd_dly_cfg2,
.reset_B = _reset_BX, .supply = supply);
fifo<N_IN,N_BUFFERS> fifo_in2fork(.in = _bd2qdi.out, .reset_B = _reset_BX, .supply = supply);
fork<N_IN> _fork(.in = fifo_in2fork.out, .reset_B = _reset_BX, .supply = supply);
// Loopback
fifo<N_IN,N_BUFFERS> fifo_fork2drop(.in = _fork.out1, .reset_B = _reset_BX, .supply = supply);
dropper_static<N_IN, false> _loopback_dropper(.in = fifo_fork2drop.out, .cond = loopback_en,
.supply = supply);
fifo<N_IN,N_BUFFERS> fifo_drop2mrg(.in = _loopback_dropper.out, .reset_B = _reset_BX, .supply = supply);
// Onwards to core
fifo<N_IN,N_BUFFERS> fifo_fork2core(.in = _fork.out2, .reset_B = _reset_BX, .supply = supply);
texel_core<N_IN,N_NRN_X, N_NRN_Y, N_SYN_X, N_SYN_Y,NC_NRN_X, NC_NRN_Y, NC_SYN_X, NC_SYN_Y,N_SYN_DLY_CFG,N_NRN_MON_X, N_NRN_MON_Y, N_SYN_MON_X, N_SYN_MON_Y,N_MON_AMZO_PER_SYN, N_MON_AMZO_PER_NRN,N_FLAGS_PER_SYN, N_FLAGS_PER_NRN,N_BUFFERS,N_LINE_PD_DLY, REG_NCA, REG_NCW, REG_M>
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<N_IN, N_BUFFERS> fifo_core2mrg(.in = core.out,
.reset_B = _reset_BX, .supply = supply);
// merge core output and loopback
merge<N_IN> merge_drop8core(.in1 = fifo_core2mrg.out, .in2 = fifo_drop2mrg.out,
.supply = supply, .reset_B = _reset_BX);
qdi2bd<N_IN, N_BD_DLY_CFG> _qdi2bd(.in = merge_drop8core.out, .out = out, .dly_cfg = bd_dly_cfg,
.reset_B = _reset_BX, .supply = supply);
}
export template<pint N_IN, // Size of input data from outside world
N_NRN_X, N_NRN_Y, N_SYN_X, N_SYN_Y, // Number of neurons / synapses
NC_NRN_X, NC_NRN_Y, NC_SYN_X, NC_SYN_Y,
N_SYN_DLY_CFG,
N_NRN_MON_X, N_NRN_MON_Y, N_SYN_MON_X, N_SYN_MON_Y,
N_MON_AMZO_PER_SYN, N_MON_AMZO_PER_NRN, // Number of signals that each synapse outputs to be monitored.
N_FLAGS_PER_SYN, N_FLAGS_PER_NRN, // Number of signals that each nrn/syn recieves from the register.
N_BUFFERS,
N_LINE_PD_DLY, // Number of dummy delays to add line pull down
N_BD_DLY_CFG, N_BD_DLY_CFG2,
REG_NCA, REG_NCW, REG_M>
defproc texel_dualcore (bd<N_IN> in, out;
Mx1of2<REG_NCW> c1_reg_data[REG_M];
// a1of1 c1_synapses[N_SYN_X * N_SYN_Y];
// a1of1 c1_neurons[N_NRN_X * N_NRN_Y];
bool! c1_dec_req_x[N_SYN_X], c1_dec_req_y[N_SYN_Y];
bool? c1_dec_ackB[N_SYN_X];
a1of1 c1_syn_pu[N_SYN_X];
a1of1 c1_enc_inx[N_NRN_X], c1_enc_iny[N_NRN_Y];
a1of1 c1_nrn_pd_x[N_NRN_X], c1_nrn_pd_y[N_NRN_Y];
bool! c1_nrn_mon_x[N_NRN_MON_X], c1_nrn_mon_y[N_NRN_MON_Y];
bool! c1_syn_mon_x[N_SYN_MON_X], c1_syn_mon_y[N_SYN_MON_Y];
bool? c1_syn_mon_AMZI[N_SYN_X * N_MON_AMZO_PER_SYN], c1_nrn_mon_AMZI[N_NRN_X * N_MON_AMZO_PER_NRN];
bool! c1_syn_mon_AMZO[N_MON_AMZO_PER_SYN], c1_nrn_mon_AMZO[N_MON_AMZO_PER_NRN];
bool! c1_syn_flags_EFO[N_FLAGS_PER_SYN], c1_nrn_flags_EFO[N_FLAGS_PER_NRN];
Mx1of2<REG_NCW> c2_reg_data[REG_M];
// a1of1 c2_synapses[N_SYN_X * N_SYN_Y];
// a1of1 c2_neurons[N_NRN_X * N_NRN_Y];
bool! c2_dec_req_x[N_SYN_X], c2_dec_req_y[N_SYN_Y];
bool? c2_dec_ackB[N_SYN_X];
a1of1 c2_syn_pu[N_SYN_X];
a1of1 c2_enc_inx[N_NRN_X], c2_enc_iny[N_NRN_Y];
a1of1 c2_nrn_pd_x[N_NRN_X], c2_nrn_pd_y[N_NRN_Y];
bool! c2_nrn_mon_x[N_NRN_MON_X], c2_nrn_mon_y[N_NRN_MON_Y];
bool! c2_syn_mon_x[N_SYN_MON_X], c2_syn_mon_y[N_SYN_MON_Y];
bool? c2_syn_mon_AMZI[N_SYN_X * N_MON_AMZO_PER_SYN], c2_nrn_mon_AMZI[N_NRN_X * N_MON_AMZO_PER_NRN];
bool! c2_syn_mon_AMZO[N_MON_AMZO_PER_SYN], c2_nrn_mon_AMZO[N_MON_AMZO_PER_NRN];
bool! c2_syn_flags_EFO[N_FLAGS_PER_SYN], c2_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, reset_reg_B){
// Reset buffers
bool _reset_BX;
BUF_X12 reset_buf(.a = reset_B, .y = _reset_BX, .vdd = supply.vdd, .vss = supply.vss);
bd2qdi<N_IN, N_BD_DLY_CFG, N_BD_DLY_CFG2> _bd2qdi(.in = in, .dly_cfg = bd_dly_cfg, .dly_cfg2 = bd_dly_cfg2,
.reset_B = _reset_BX, .supply = supply);
fifo<N_IN,N_BUFFERS> fifo_in2fork(.in = _bd2qdi.out, .reset_B = _reset_BX, .supply = supply);
fork<N_IN> _fork(.in = fifo_in2fork.out, .reset_B = _reset_BX, .supply = supply);
// Loopback
fifo<N_IN,N_BUFFERS> fifo_fork2drop(.in = _fork.out1, .reset_B = _reset_BX, .supply = supply);
dropper_static<N_IN, false> _loopback_dropper(.in = fifo_fork2drop.out, .cond = loopback_en,
.supply = supply);
fifo<N_IN,N_BUFFERS> fifo_drop2mrg(.in = _loopback_dropper.out, .reset_B = _reset_BX, .supply = supply);
// Onwards to core demux
fifo<N_IN,N_BUFFERS> fifo_fork2dmx(.in = _fork.out2, .reset_B = _reset_BX, .supply = supply);
demux_bit_msb<N_IN-1> core_dmx(.in = fifo_fork2dmx.out, .reset_B = _reset_BX, .supply = supply);
fifo<N_IN-1,N_BUFFERS> fifo_dmx2core1(.in = core_dmx.out1, .reset_B = _reset_BX, .supply = supply);
fifo<N_IN-1,N_BUFFERS> fifo_dmx2core2(.in = core_dmx.out2, .reset_B = _reset_BX, .supply = supply);
// Cores
texel_core<N_IN-1,N_NRN_X, N_NRN_Y, N_SYN_X, N_SYN_Y,NC_NRN_X, NC_NRN_Y, NC_SYN_X, NC_SYN_Y,N_SYN_DLY_CFG,N_NRN_MON_X, N_NRN_MON_Y, N_SYN_MON_X, N_SYN_MON_Y,N_MON_AMZO_PER_SYN, N_MON_AMZO_PER_NRN,N_FLAGS_PER_SYN, N_FLAGS_PER_NRN,N_BUFFERS,N_LINE_PD_DLY, REG_NCA, REG_NCW, REG_M>
core1(.in = fifo_dmx2core1.out,
.reg_data = c1_reg_data,
// .synapses = c1_synapses,
// .neurons = c1_neurons,
.dec_req_x = c1_dec_req_x, .dec_req_y = c1_dec_req_y,
.dec_ackB = c1_dec_ackB,
.syn_pu = c1_syn_pu,
.enc_inx = c1_enc_inx, .enc_iny = c1_enc_iny,
.nrn_pd_x = c1_nrn_pd_x, .nrn_pd_y = c1_nrn_pd_y,
.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, .reset_reg_B = reset_reg_B,
.supply = supply
);
texel_core<N_IN-1,N_NRN_X, N_NRN_Y, N_SYN_X, N_SYN_Y,NC_NRN_X, NC_NRN_Y, NC_SYN_X, NC_SYN_Y,N_SYN_DLY_CFG,N_NRN_MON_X, N_NRN_MON_Y, N_SYN_MON_X, N_SYN_MON_Y,N_MON_AMZO_PER_SYN, N_MON_AMZO_PER_NRN,N_FLAGS_PER_SYN, N_FLAGS_PER_NRN,N_BUFFERS,N_LINE_PD_DLY, REG_NCA, REG_NCW, REG_M>
core2(.in = fifo_dmx2core2.out,
.reg_data = c2_reg_data,
// .synapses = c2_synapses,
// .neurons = c2_neurons,
.dec_req_x = c2_dec_req_x, .dec_req_y = c2_dec_req_y,
.dec_ackB = c2_dec_ackB,
.syn_pu = c2_syn_pu,
.enc_inx = c2_enc_inx, .enc_iny = c2_enc_iny,
.nrn_pd_x = c2_nrn_pd_x, .nrn_pd_y = c2_nrn_pd_y,
.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, .reset_reg_B = reset_reg_B,
.supply = supply
);
fifo<N_IN-1,N_BUFFERS> fifo_core1out(.in = core1.out, .reset_B = _reset_BX, .supply = supply);
fifo<N_IN-1,N_BUFFERS> fifo_core2out(.in = core2.out, .reset_B = _reset_BX, .supply = supply);
// Merge cores
append<N_IN-1, 1, 0> append_core1(.in = fifo_core1out.out, .supply = supply);
append<N_IN-1, 1, 1> append_core2(.in = fifo_core2out.out, .supply = supply);
merge<N_IN> merge_core1x2(.in1 = append_core1.out, .in2 = append_core2.out,
.supply = supply, .reset_B = _reset_BX);
// Merge cores and loopback
merge<N_IN> merge_drop8core(.in1 = merge_core1x2.out, .in2 = fifo_drop2mrg.out,
.reset_B = _reset_BX, .supply = supply);
// qdi2bd
fifo<N_IN, N_BUFFERS> fifo_mrg2bd(.in = merge_drop8core.out,
.reset_B = _reset_BX, .supply = supply);
qdi2bd<N_IN, N_BD_DLY_CFG> _qdi2bd(.in = fifo_mrg2bd.out, .out = out, .dly_cfg = bd_dly_cfg,
.reset_B = _reset_BX, .supply = supply);
}
}
}
}

View File

@@ -86,20 +86,81 @@ defproc decoder_dualrail (Mx1of2<Nc> in; bool? out[N]; power supply) {
)
}
/**
* Dualrail decoder, but the signals to the decoders are refreshed every 48 gates.
* final_refresh is signal at the end of the refresh line.
* Is needed for doing validity checking etc, since it is the laggiest signal.
*/
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_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)];
(i:Nc:
// Connect start
in_tX[i].a = in.d[i].t;
in_fX[i].a = in.d[i].f;
// Connect mid bois
(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
in_tX[i+NUM_REFRESH*Nc].y = final_refresh.d[i].t;
in_fX[i+NUM_REFRESH*Nc].y = final_refresh.d[i].f;
)
(i:Nc*(NUM_REFRESH+1):
in_tX[i].vdd = supply.vdd;
in_tX[i].vss = supply.vss;
in_fX[i].vdd = supply.vdd;
in_fX[i].vss = supply.vss;
)
// AND trees
pint bitval;
andtree<Nc> atree[N];
(k:0..N-1:atree[k].supply = supply;)
(i:0..N-1:
(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/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/NUM_OUTS_PER_BUF)*Nc)].y;
// atree[i].in[j] = addr_buf.out.d.d[j].f;
[]bitval >= 2 -> {false : "fuck"};
]
atree[i].out = out[i];
)
)
}
/**
* Dualrail decoder with buffered outputs.
* Be careful of out[] indexing.
*/
export template<pint Nc, N, OUT_STRENGTH>
defproc decoder_dualrail_x(Mx1of2<Nc> in; bool? out[N*OUT_STRENGTH]; power supply) {
defproc decoder_dualrail_x(Mx1of2<Nc> in; bool? out[N]; power supply) {
decoder_dualrail<Nc, N> decoder(.in = in, .supply = supply);
sigbuf<OUT_STRENGTH> sb[N];
(i:N:
sb[i].in = decoder.out[i];
sb[i].supply = supply;
(j:OUT_STRENGTH:
sb[i].out[j] = out[j + i*OUT_STRENGTH];
)
sb[i].out[0] = out[i];
// (j:OUT_STRENGTH:
// sb[i].out[j] = out[j + i*OUT_STRENGTH];
// )
)
}
@@ -109,57 +170,42 @@ defproc decoder_dualrail_x(Mx1of2<Nc> in; bool? out[N*OUT_STRENGTH]; power suppl
*/
export template<pint Nc, N>
defproc decoder_dualrail_en(Mx1of2<Nc> in; bool? en, out[N]; power supply) {
decoder_dualrail<Nc, N> decoder(.in = in, .supply = supply);
sigbuf<N> sb_en(.in = en, .supply = supply);
AND2_X1 en_ands[N];
(i:N:
en_ands[i].a = decoder.out[i];
en_ands[i].b = sb_en.out[i];
decoder_dualrail_refresh<Nc, N> decoder(.out = out, .supply = supply);
en_ands[i].vdd = supply.vdd;
en_ands[i].vss = supply.vss;
sigbuf<Nc*2> sb_en(.in = en, .supply = supply);
// AND2_X1 en_ands[N];
// (i:N:
// en_ands[i].a = decoder.out[i];
// en_ands[i].b = sb_en.out[i];
en_ands[i].y = out[i];
// en_ands[i].vdd = supply.vdd;
// en_ands[i].vss = supply.vss;
// en_ands[i].y = out[i];
// )
AND2_X1 en_ands_t[Nc];
AND2_X1 en_ands_f[Nc];
(i:Nc:
en_ands_t[i].a = in.d[i].t;
en_ands_f[i].a = in.d[i].f;
en_ands_t[i].b = sb_en.out[i];
en_ands_f[i].b = sb_en.out[i+Nc];
en_ands_t[i].y = decoder.in.d[i].t;
en_ands_f[i].y = decoder.in.d[i].f;
en_ands_t[i].vdd = supply.vdd;
en_ands_t[i].vss = supply.vss;
en_ands_f[i].vdd = supply.vdd;
en_ands_f[i].vss = supply.vss;
)
}
/**
* Dualrail decoder with on/off switch.
* Outputs are buffered.
*/
// export template<pint Nc, N, OUT_STRENGTH>
// defproc decoder_dualrail_en_x(Mx1of2<Nc> in; bool? en, out[N]; power supply) {
// decoder_dualrail<Nc, N> decoder(.in = in, .supply = supply);
// sigbuf<N> sb_en(.in = en, .supply = supply);
// sigbuf<OUT_STRENGTH> sb[N];
// AND2_X1 en_ands[N];
// (i:N:
// en_ands[i].a = decoder.out[i];
// en_ands[i].b = sb_en.out[i];
// en_ands[i].vdd = supply.vdd;
// en_ands[i].vss = supply.vss;
// sb[i].in = en_ands[i].y;
// sb[i].supply = supply;
// // (j:OUT_STRENGTH:
// // sb[i].out[j] = out[j + i*OUT_STRENGTH];
// // )
// sb[i].out[0] = out[i];
// )
// }
/**
@@ -206,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;
@@ -221,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];
)
)
@@ -242,6 +290,9 @@ defproc and_grid(bool! out[Nx*Ny]; bool? inx[Nx], iny[Ny]; power supply) {
export template<pint NxC, NyC, Nx, Ny>
defproc decoder_2d_hs (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? reset_B; power supply) {
bool _reset_BX[Nx];
sigbuf<Nx> reset_sb(.in = reset_B, .out = _reset_BX, .supply = supply);
// Buffer to recieve concat(x,y) address packet
buffer<NxC+NyC> addr_buf(.in = in, .reset_B = reset_B, .supply = supply);
@@ -282,8 +333,8 @@ defproc decoder_2d_hs (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? reset_B; po
(i:Nx:
(j:Ny:
index = i + Nx*j;
ack_pulldowns[index].a = out[index].a;
ack_pulldowns[index].b = d_dr_xX[i].out[j];
ack_pulldowns[index].n1 = out[index].a;
ack_pulldowns[index].n2 = d_dr_xX[i].out[j];
ack_pulldowns[index].y = _out_acksB[i];
ack_pulldowns[index].vss = supply.vss;
ack_pulldowns[index].vdd = supply.vdd;
@@ -298,12 +349,12 @@ defproc decoder_2d_hs (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? reset_B; po
A_1P_U_X4 pu[Nx]; // TODO probably replace this with variable strength PU
A_1P_U_X4 pu_reset[Nx];
(i:Nx:
pu[i].a = d_dr_xX[i].out[Ny];
pu[i].p1 = d_dr_xX[i].out[Ny];
pu[i].y = _out_acksB[i];
pu[i].vdd = supply.vdd;
pu[i].vss = supply.vss;
pu_reset[i].a = reset_B;
pu_reset[i].p1 = _reset_BX[i];
pu_reset[i].y = _out_acksB[i];
pu_reset[i].vdd = supply.vdd;
pu_reset[i].vss = supply.vss;
@@ -331,6 +382,44 @@ defproc decoder_2d_hs (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? reset_B; po
}
/**
* Synapse handshaking stuff which exists in the core, and so will not be spawned in
* when innovusing all the periphery.
*/
export template<pint Nx, Ny>
defproc decoder_2d_synapse_hs (bool? in_req_x[Nx], in_req_y[Ny]; a1of1 synapses[Nx*Ny];
bool out_ackB_decoder[Nx];
a1of1 to_pu[Nx];
power supply) {
// and grid for reqs into synapses
and_grid<Nx, Ny> _and_grid(.inx = in_req_x, .iny = in_req_y, .supply = supply);
(i:Nx*Ny: synapses[i].r = _and_grid.out[i];)
// Pull DOWNs on the ackB lines by synapses (easier to invert).
A_2N_U_X4 ack_pulldowns[Nx*Ny];
pint index;
(i:Nx:
(j:Ny:
index = i + Nx*j;
ack_pulldowns[index].n1 = synapses[index].a;
ack_pulldowns[index].n2 = in_req_x[i]; // GET REFRHRESED IN CORE
ack_pulldowns[index].y = out_ackB_decoder[i];
ack_pulldowns[index].vss = supply.vss;
ack_pulldowns[index].vdd = supply.vdd;
)
)
// Connect the ackB lines together
(i:Nx: out_ackB_decoder[i] = to_pu[i].a;)
// Pipe req x lines down to the ackB pullups
(i:Nx: to_pu[i].r = in_req_x[i];)
}
/**
* 2D decoder which uses either synapse handshaking, or just a delay.
* Controlled by the "hs_en" (handshake_enable) config bit.
@@ -340,10 +429,19 @@ 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,
reset_B; power supply) {
defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; bool! out_req_x[Nx], out_req_y[Ny]; bool? dly_cfg[N_dly_cfg], hs_en, ack_disable;
bool in_ackB_decoder[Nx]; // AckB lines back to the decoder for handshaking
a1of1 to_pu[Nx];
// bool out_ackB_pullups[Nx]; // AckB lines from the line end pull ups
// bool in_req_x_pullups[Nx]; // req x lines going to the line pull ups
bool? reset_B; power supply) {
bool _reset_BX[Nx];
sigbuf<Nx> reset_sb(.in = reset_B, .out = _reset_BX, .supply = supply);
bool hs_enB;
INV_X4 hs_inv(.a = hs_en, .y = hs_enB, .vdd = supply.vdd, .vss = supply.vss);
@@ -352,50 +450,27 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
buffer<NxC+NyC> addr_buf(.in = in, .reset_B = reset_B, .supply = supply);
// Decoder X/Y And trees
decoder_dualrail<NxC,Nx> d_dr_x(.supply = supply);
decoder_dualrail_refresh<NxC,Nx> d_dr_x(.supply = supply);
(i:0..NxC-1:d_dr_x.in.d[i] = addr_buf.out.d.d[i];)
decoder_dualrail<NyC,Ny> d_dr_y(.supply = supply);
decoder_dualrail_refresh<NyC,Ny> d_dr_y(.supply = supply);
(i:0..NyC-1:d_dr_y.in.d[i] = addr_buf.out.d.d[i+NxC];)
// sig buf for reqx lines, since they go to synapse pull down gates.
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;
)
// Signals to the and-grid are buffered therein.
sigbuf_boolarray<Nx,15> d_dr_xX(.in = d_dr_x.out, .supply = supply);
d_dr_xX.out = out_req_x;
sigbuf_boolarray<Ny,47> d_dr_yX(.in = d_dr_y.out, .supply = supply);
d_dr_yX.out = out_req_y;
// Validity
vtree<NxC> vtree_x (.supply = supply);
vtree<NyC> vtree_y (.supply = supply);
(i:0..NxC-1:vtree_x.in.d[i].t = addr_buf.out.d.d[i].t;)
(i:0..NxC-1:vtree_x.in.d[i].f = addr_buf.out.d.d[i].f;)
(i:0..NyC-1:vtree_y.in.d[i].t = addr_buf.out.d.d[i+NxC].t;)
(i:0..NyC-1:vtree_y.in.d[i].f = addr_buf.out.d.d[i+NxC].f;)
vtree<NxC> vtree_x (.in = d_dr_x.final_refresh, .supply = supply);
vtree<NyC> vtree_y (.in = d_dr_y.final_refresh, .supply = supply);
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);
(i:Nx*Ny: out[i].r = _and_grid.out[i];)
// Acknowledge pull down time
// Pull DOWNs on the ackB lines by synapses (easier to invert).
bool _out_acksB[Nx]; // The vertical output ack lines from each syn.
A_2N_U_X4 ack_pulldowns[Nx*Ny];
pint index;
(i:Nx:
(j:Ny:
index = i + Nx*j;
ack_pulldowns[index].a = out[index].a;
ack_pulldowns[index].b = d_dr_xX[i].out[j];
ack_pulldowns[index].y = _out_acksB[i];
ack_pulldowns[index].vss = supply.vss;
ack_pulldowns[index].vdd = supply.vdd;
)
)
// Line end pull UPs (triggered once reqs removed)
// Use two pullups rather than and-pullup
// bc smaller
@@ -404,33 +479,34 @@ 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].a = d_dr_xX[i].out[Ny];
pu[i].b = hs_enB;
pu[i].y = _out_acksB[i];
pu[i].p1 = to_pu[i].r;
pu[i].p2 = hs_enB;
pu[i].y = to_pu[i].a;
pu[i].vdd = supply.vdd;
pu[i].vss = supply.vss;
pu_reset[i].a = reset_B;
pu_reset[i].y = _out_acksB[i];
pu_reset[i].p1 = _reset_BX[i];
pu_reset[i].y = to_pu[i].a;
pu_reset[i].vdd = supply.vdd;
pu_reset[i].vss = supply.vss;
)
// Add keeps (currently don't do anything in ACT)
KEEP_X1 keeps[Nx];
KEEP keeps[Nx];
(i:Nx:
keeps[i].vdd = supply.vdd;
keeps[i].vss = supply.vss;
keeps[i].y = _out_acksB[i];
keeps[i].y = to_pu[i].a;
)
// ORtree from all output acks, back to the buffer ack.
// This is instead of the ack that came from the delayed validity trees,
// in decoder_2d_dly.
ortree<Nx> _ortree(.supply = supply);
INV_X1 out_ack_invs[Nx];
(i:Nx:
out_ack_invs[i].a = _out_acksB[i];
out_ack_invs[i].a = in_ackB_decoder[i];
out_ack_invs[i].vdd = supply.vdd;
out_ack_invs[i].vss = supply.vss;
@@ -449,7 +525,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);
}
@@ -570,10 +652,15 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
(i:Nc:ors_t[i].supply = supply; ors_t[i].out = out.d[i].t;)
(i:Nc:ors_f[i].supply = supply; ors_f[i].out = out.d[i].f;)
bool _inX[N];
sigbuf_boolarray<N, Nc> sb_in(.in = in, .out = _inX, .supply = supply);
pint num_connected_t; // Number of guys already connected to the current OR tree
pint num_connected_f;
TIELO_X1 tielo(.vdd = supply.vdd, .vss = supply.vss); // I'm sorry
TIELO_X1 tielo[Nc]; // I'm sorry
(i:Nc:tielo[i].vdd = supply.vdd; tielo[i].vss = supply.vss;)
pint bitval;
(i:0..Nc-1: // For each output line
num_connected_t = 0;
@@ -581,16 +668,16 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
(j:0.. _N-1:
bitval = (j & ( 1 << i )) >> i; // Get binary digit of integer j, column i
[bitval = 1 & j <= N-1->
ors_t[i].in[num_connected_t] = in[j];
ors_t[i].in[num_connected_t] = _inX[j];
num_connected_t = num_connected_t + 1;
[] bitval = 0 & j <= N-1->
ors_f[i].in[num_connected_f] = in[j];
ors_f[i].in[num_connected_f] = _inX[j];
num_connected_f = num_connected_f + 1;
[] bitval = 1 & j > N-1->
ors_t[i].in[num_connected_t] = tielo.y;
ors_t[i].in[num_connected_t] = tielo[i].y;
num_connected_t = num_connected_t + 1;
[] bitval = 0 & j > N-1->
ors_f[i].in[num_connected_f] = tielo.y;
ors_f[i].in[num_connected_f] = tielo[i].y;
num_connected_f = num_connected_f + 1;
]
@@ -604,24 +691,25 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
/**
* Buffer function code.
* Is the function block ripped from the buffer_s.
* Used in the encoder2d.
*/
/**
* Buffer function code.
* Is the function block ripped from the buffer_s.
* Used in the encoder2d.
*/
export template<pint N>
defproc buffer_s_func (Mx1of2<N> in; avMx1of2<N> out; bool? in_v, en, reset_B; power supply) {
//function
bool _out_a_BX_t[N],_out_a_BX_f[N],_out_a_B,_en_X_t[N],_en_X_f[N], _in_vX, _in_vXX_t[N],_in_vXX_f[N];
bool _out_a_BX_t[N],_out_a_BX_f[N],_out_a_B,_en_X_t[N],_en_X_f[N], _in_vX;
// bool _in_vXX_t[N],_in_vXX_f[N];
A_2C2N_RB_X4 f_buf_func[N];
A_2C2N_RB_X4 t_buf_func[N];
// reset buffers
bool _reset_BX,_reset_BXX[N];
bool _reset_BX,_reset_BXX[N*2];
BUF_X1 reset_buf(.a=reset_B, .y=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
sigbuf<N> reset_bufarray(.in=_reset_BX, .out=_reset_BXX, .supply=supply);
sigbuf<N*2> reset_bufarray(.in=_reset_BX, .out=_reset_BXX, .supply=supply);
// Enable signal buffers
sigbuf<N> en_buf_t(.in=en, .out=_en_X_t, .supply=supply);
@@ -634,8 +722,10 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
// in val signal buffers
BUF_X4 in_v_prebuf(.a = in_v, .y = _in_vX, .vss = supply.vss, .vdd = supply.vdd);
sigbuf<N> in_v_buf_t(.in=_in_vX, .out=_in_vXX_t, .supply=supply);
sigbuf<N> in_v_buf_f(.in=_in_vX, .out=_in_vXX_f, .supply=supply);
// sigbuf<N> in_v_buf_t(.in=_in_vX, .out=_in_vXX_t, .supply=supply);
// sigbuf<N> in_v_buf_f(.in=_in_vX, .out=_in_vXX_f, .supply=supply);
sigbuf<N*2> in_v_buf(.in=_in_vX,.supply=supply);
(i:N:
f_buf_func[i].y=out.d.d[i].f;
@@ -646,28 +736,29 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
t_buf_func[i].c2=_out_a_BX_t[i];
f_buf_func[i].n1=in.d[i].f;
t_buf_func[i].n1=in.d[i].t;
f_buf_func[i].n2=_in_vXX_f[i];
t_buf_func[i].n2=_in_vXX_t[i];
f_buf_func[i].n2=in_v_buf.out[i];
t_buf_func[i].n2=in_v_buf.out[i+N];
f_buf_func[i].vdd=supply.vdd;
t_buf_func[i].vdd=supply.vdd;
f_buf_func[i].vss=supply.vss;
t_buf_func[i].vss=supply.vss;
t_buf_func[i].pr_B = _reset_BXX[i];
t_buf_func[i].sr_B = _reset_BXX[i];
f_buf_func[i].pr_B = _reset_BXX[i];
f_buf_func[i].sr_B = _reset_BXX[i];
f_buf_func[i].pr_B = _reset_BXX[i+N];
f_buf_func[i].sr_B = _reset_BXX[i+N];
)
}
export template<pint NxC, NyC, Nx, Ny, ACK_STRENGTH>
defproc encoder2d(a1of1 inx[Nx]; a1of1 iny[Ny]; avMx1of2<(NxC + NyC)> out; power supply; bool reset_B) {
defproc encoder2d(a1of1 inx[Nx]; a1of1 iny[Ny]; avMx1of2<(NxC + NyC)> out; power supply; bool reset_B) {
// Reset buffers
pint H = 2*(NxC + NyC); //Reset strength? to be investigated
bool _reset_BX,_reset_BXX[H];
BUF_X4 reset_buf(.a=reset_B, .y=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
sigbuf<2*(NxC + NyC)> reset_bufarray(.in=_reset_BX, .out=_reset_BXX,.supply=supply);
BUF_X4 reset_buf(.a=reset_B, .y=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
sigbuf<2*(NxC + NyC)> reset_bufarray(.in=_reset_BX, .out=_reset_BXX,.supply=supply);
// Arbiters
a1of1 _arb_out_x, _arb_out_y;
@@ -723,8 +814,10 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
// X_req ORtree
bool _x_req_array[Nx], _x_v_B;
(i:Nx:_x_req_array[i] = inx[i].r;)
ortree<Nx> x_req_ortree(.in = _x_req_array,.out = _x_v,.supply = supply); //todo BUFF
INV_X1 not_x_req_ortree(.a = _x_v,.y = _x_v_B);
ortree<Nx> x_req_ortree(.in = _x_req_array, .supply = supply); //todo BUFF
INV_X1 not_x_req_ortree(.a = x_req_ortree.out, .y = _x_v_B);
INV_X1 not_x_req_ortree2(.a = _x_v_B,.y = _x_v);
//X_REQ validation
// bool _x_req_array[Nx],_x_v_B, _en;
@@ -735,7 +828,7 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
bool _x_a_B2; // sorry
bool _en;
A_1C3P2P2N_R_X1 x_ack(); // NEEDS BUFFERING TO X4
A_1C3P2P2N_R_X1 x_ack();
//branch1
x_ack.p4 = _in_x_v;
x_ack.p5 = _x_v_B;
@@ -789,6 +882,156 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
}
export
defproc nrn_line_end_pull_down (bool? in; bool? reset_B; power supply; bool! out)
{
INV_X1 inv(.a = reset_B, .vdd=supply.vdd,.vss =supply.vss);
A_1N_U_X4 pull_down(.n1=in, .y=out);
A_1N_U_X4 pull_downR(.n1=inv.y, .y=out);
}
export template<pint NxC, NyC, Nx, Ny, N_dly>
defproc encoder2d_simple(a1of1 inx[Nx]; a1of1 iny[Ny]; avMx1of2<(NxC + NyC)> out;
a1of1 to_pd_x[Nx], to_pd_y[Ny]; // Ports for the line end pull downs to tap into
power supply; bool reset_B) {
bool _a_x, _a_y;
bool _r_x, _r_y;
bool _r_x_B, _r_y_B;
buffer<NxC + NyC> buf(.out = out, .supply = supply, .reset_B = reset_B);
// Arbiters
arbtree<Nx> Xarb(.supply = supply);
arbtree<Ny> Yarb(.supply = supply);
Xarb.out.a = _a_x;
Xarb.out.r = _r_x;
Yarb.out.a = _a_y;
Yarb.out.r = _r_y;
// Encoders
dualrail_encoder<NxC, Nx> Xenc(.supply = supply);
dualrail_encoder<NyC, Ny> Yenc(.supply = supply);
// Wire up inputs to encoders and arb
(i:Nx:
Xarb.in[i].r = inx[i].r;
Xarb.in[i].a = inx[i].a;
Xenc.in[i] = inx[i].a;
)
// Wire up inputs to encoders and arb
(i:Ny:
Yarb.in[i].r = iny[i].r;
Yarb.in[i].a = iny[i].a;
Yenc.in[i] = iny[i].a;
)
INV_X2 inv_buf(.a = buf.in.a, .vdd = supply.vdd, .vss = supply.vss);
A_2C_RB_X1 a_x_Cel(.c1 = inv_buf.y, .c2 = _r_x, .y = _a_x,
.sr_B = reset_B, .pr_B = reset_B, .vdd = supply.vdd, .vss = supply.vss);
A_2C_RB_X1 a_y_Cel(.c1 = inv_buf.y, .c2 = _r_y, .y = _a_y,
.sr_B = reset_B, .pr_B = reset_B, .vdd = supply.vdd, .vss = supply.vss);
// Wire up encoder to buffer
(i:NxC:
Xenc.out.d[i] = buf.in.d.d[i];
)
(i:NyC:
Yenc.out.d[i] = buf.in.d.d[i+NxC];
)
// Line pull down stuff
// Create delay fifos to emulate the fact that the line pull downs
// are at the end of the line, and thus slow.
// Note that if N_dly = 0, delay fifo is just a pipe.
delay_chain<N_dly> dly_x[Nx];
delay_chain<N_dly> dly_y[Ny];
// Create x line req pull downs
nrn_line_end_pull_down pd_x[Nx];
sigbuf<Nx> rsb_pd_x(.in = reset_B, .supply = supply);
(i:0..Nx-1:
dly_x[i].supply = supply;
dly_x[i].in = to_pd_x[i].a;
pd_x[i].in = dly_x[i].out;
pd_x[i].out = to_pd_x[i].r;
pd_x[i].reset_B = rsb_pd_x.out[i];
pd_x[i].supply = supply;
)
// Create y line req pull downs
nrn_line_end_pull_down pd_y[Ny];
sigbuf<Ny> rsb_pd_y(.in = reset_B, .supply = supply);
(j:0..Ny-1:
dly_y[j].supply = supply;
dly_y[j].in = to_pd_y[j].a;
pd_y[j].in = dly_y[j].out;
pd_y[j].out = to_pd_y[j].r;
pd_y[j].reset_B = rsb_pd_y.out[j];
pd_y[j].supply = supply;
)
// Add keeps
KEEP keep_x[Nx];
(i:Nx:
keep_x[i].vdd = supply.vdd;
keep_x[i].vss = supply.vss;
keep_x[i].y = inx[i].r;
)
KEEP keep_y[Ny];
(j:Ny:
keep_y[j].vdd = supply.vdd;
keep_y[j].vss = supply.vss;
keep_y[j].y = iny[j].r;
)
}
export template<pint Nc, N>
defproc encoder1d_simple(a1of1 in[N]; avMx1of2<Nc> out;
power supply; bool reset_B) {
bool _a_x, _r_x;
bool _r_x_B;
buffer<Nc> buf(.out = out, .supply = supply, .reset_B = reset_B);
// Arbiters
arbtree<N> Xarb(.supply = supply);
Xarb.out.a = _a_x;
Xarb.out.r = _r_x;
// Encoders
dualrail_encoder<Nc, N> Xenc(.supply = supply);
// Wire up inputs to encoders and arb
(i:N:
Xarb.in[i].r = in[i].r;
Xarb.in[i].a = in[i].a;
Xenc.in[i] = in[i].a;
)
INV_X2 inv_buf(.a = buf.in.a, .vdd = supply.vdd, .vss = supply.vss);
A_2C_RB_X1 a_x_Cel(.c1 = inv_buf.y, .c2 = _r_x, .y = _a_x,
.sr_B = reset_B, .pr_B = reset_B, .vdd = supply.vdd, .vss = supply.vss);
// Wire up encoder to buffer
(i:Nc:
Xenc.out.d[i] = buf.in.d.d[i];
)
}
/**
* Neuron handshaking.
@@ -801,14 +1044,7 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
BUF_X2 reset_buf(.a = reset_B, .y = _reset_BX, .vdd = supply.vdd, .vss = supply.vss);
bool _en, _req;
// A_1C2N_RB_X1 A_ack(.c1 = _en, .n1 = _req, .n2 = in.r, .y = in.a,
// .pr_B = _reset_BX, .sr_B = _reset_BX, .vss = supply.vss, .vdd = supply.vdd);
// Switched it back
// Because had the problem that if the req was not removed in time,
// it would be recounted as a double spike,
// since in.req is still high after the out has been dealt with.
A_2C1N_RB_X1 A_ack(.c1 = _en, .c2 = in.r, .n1 = _req, .y = in.a,
.pr_B = _reset_BX, .sr_B = _reset_BX, .vss = supply.vss, .vdd = supply.vdd);
@@ -820,35 +1056,36 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
INV_X2 inv_x(.a = outx.a, .y = _x_a_B, .vss = supply.vss, .vdd = supply.vdd);
INV_X2 inv_y(.a = outy.a, .y = _y_a_B, .vss = supply.vss, .vdd = supply.vdd);
// WARNUNG WARNUNG WARNUNG //
// This neuron hs design has a fat timing assumption.
// Say that the neuron has sent out both reqs, and is now receiving the acks.
// _x_a_B and _y_a_B are then low, and _req starts to be pulled down to reset the hs.
// However, if the line pull downs at the end of the neuron row/column are fast enough,
// then seeing the high acks, they will pull the ack lines down. If the arbiter tree
// is sufficiently fast enough, then it will remove the ack lines.
// If this cell were rather tardy, then _req's pd would be cancelled midway,
// it missed its window of opportunity to switch, and would probably make the system hang.
// Or starts oscillating with the line pull down and goes brrrrapppppppp.
// This issue may be somewhat unavoidable, as from a black box perspective,
// we are giving the neuron acks, but then not listening to it at all to check
// that it has had time to act upon these acks.
A_2C1P1N_RB_X1 A_req(.p1 = _x_a_B, .c1 = _en, .c2 = _y_a_B, .n1 = in.r, .y = _req,
.pr_B = _reset_BX, .sr_B = _reset_BX, .vdd = supply.vdd, .vss = supply.vss);
// y_req pull up
NAND2_X1 nand_y(.a = _y_a_B, .b = _req, .vdd = supply.vdd, .vss = supply.vss);
A_1P_U_X4 pu_y(.a = nand_y.y, .y = outy.r, .vdd = supply.vdd, .vss = supply.vss);
bool _reqB;
INV_X1 req_inv(.a = _req, .y = _reqB, .vdd= supply.vdd, .vss = supply.vss);
A_2P_U_X4 pu_y(.p1 = _reqB, .p2 = outy.a, .y = outy.r, .vdd = supply.vdd, .vss = supply.vss);
// x_req pull up
NAND3_X1 nand_x(.a = _x_a_B, .b = _req, .c = outy.a, .vdd = supply.vdd, .vss = supply.vss);
A_1P_U_X4 pu_x(.a = nand_x.y, .y = outx.r, .vdd = supply.vdd, .vss = supply.vss);
A_3P_U_X4 pu_x(.p1 = outx.a, .p2 = _reqB, .p3 = _y_a_B, .y = outx.r,
.vdd = supply.vdd, .vss = supply.vss);
}
export
defproc nrn_line_end_pull_down (bool? in; bool? reset_B; power supply; bool! out)
{
bool _out, __out, nand_out;
BUF_X1 buf1(.a=in, .y=_out, .vdd=supply.vdd,.vss=supply.vss);
BUF_X1 buf2(.a=_out, .y=__out, .vdd=supply.vdd,.vss=supply.vss);
INV_X1 inv(.a = __out, .vdd=supply.vdd,.vss =supply.vss);
NAND2_X1 aenor(.a=inv.y, .b=reset_B, .y = nand_out, .vdd=supply.vdd,.vss=supply.vss);
A_1N_U_X4 pull_down(.a=nand_out, .y=out);
}
/**
* A 2d grid of neuron handshakers.
* Should then slot into the encoder.
@@ -857,8 +1094,9 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
* for the purpose of running ACT sims.
* It should probably be set to 0 though.
*/
export template<pint Nx, Ny, N_dly>
export template<pint Nx, Ny>
defproc nrn_hs_2d_array(a1of1 in[Nx*Ny]; a1of1 outx[Nx], outy[Ny];
a1of1 to_pd_x[Nx], to_pd_y[Ny];
power supply; bool reset_B) {
// Make hella signal buffers
@@ -885,18 +1123,16 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
out_req_buf_y[i].a = _outy[i].r;
out_req_buf_y[i].y = outy[i].r;
)
// Add buffers on output ack lines
// Note that this should be generalised.
// And probably won't even be done by ACT/innovus anwyay
// TODO: do it properly with sigbufs?
BUF_X4 out_ack_buf_x[Nx];
BUF_X12 out_ack_buf_x[Nx];
(i:Nx:
out_ack_buf_x[i].vss = supply.vss;
out_ack_buf_x[i].vdd = supply.vdd;
out_ack_buf_x[i].a = outx[i].a;
out_ack_buf_x[i].y = _outx[i].a;
)
BUF_X4 out_ack_buf_y[Ny];
BUF_X12 out_ack_buf_y[Ny];
(i:Ny:
out_ack_buf_y[i].vss = supply.vss;
out_ack_buf_y[i].vdd = supply.vdd;
@@ -920,55 +1156,14 @@ defproc decoder_2d_hybrid (avMx1of2<NxC+NyC> in; a1of1 out[Nx*Ny]; bool? dly_cfg
)
)
// Create delay fifos to emulate the fact that the line pull downs
// are at the end of the line, and thus slow.
// Note that if N_dly = 0, delay fifo is just a pipe.
delay_chain<N_dly> dly_x[Nx];
delay_chain<N_dly> dly_y[Ny];
// Create x line req pull downs
nrn_line_end_pull_down pd_x[Nx];
sigbuf<Nx> rsb_pd_x(.in = reset_B, .supply = supply);
(i:0..Nx-1:
dly_x[i].supply = supply;
dly_x[i].in = _outx[i].a;
pd_x[i].in = dly_x[i].out;
pd_x[i].out = _outx[i].r;
pd_x[i].reset_B = rsb_pd_x.out[i];
pd_x[i].supply = supply;
)
// Pipe the ack/req lines through to the pulldowns
to_pd_x = _outx;
to_pd_y = _outy;
// Create y line req pull downs
nrn_line_end_pull_down pd_y[Ny];
sigbuf<Ny> rsb_pd_y(.in = reset_B, .supply = supply);
(j:0..Ny-1:
dly_y[j].supply = supply;
dly_y[j].in = _outy[j].a;
pd_y[j].in = dly_y[j].out;
pd_y[j].out = _outy[j].r;
pd_y[j].reset_B = rsb_pd_y.out[j];
pd_y[j].supply = supply;
)
// Add keeps
KEEP_X1 keep_x[Nx];
(i:Nx:
keep_x[i].vdd = supply.vdd;
keep_x[i].vss = supply.vss;
keep_x[i].y = _outx[i].r;
)
KEEP_X1 keep_y[Ny];
(j:Ny:
keep_y[j].vdd = supply.vdd;
keep_y[j].vss = supply.vss;
keep_y[j].y = _outy[j].r;
)
}
}
}
}

View File

@@ -57,14 +57,14 @@ namespace tmpl {
delayprog<N_dly_cfg> dly(.in = in.r, .out = _req, .s = dly_cfg, .supply = supply);
// sig buff the reset signal
bool _reset_BX, _reset_BXX[N];
bool _reset_BX, _reset_BXX[N*2];
BUF_X4 reset_buf(.a=reset_B, .y=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
sigbuf<N> reset_bufarray(.in=_reset_BX, .out=_reset_BXX, .supply=supply);
sigbuf<N*2> reset_bufarray(.in=_reset_BX, .out=_reset_BXX, .supply=supply);
// sig buff the req
bool _reqX, _reqXX[N];
bool _reqX, _reqXX[N*2];
BUF_X4 req_buf(.a=_req, .y=_reqX,.vdd=supply.vdd,.vss=supply.vss);
sigbuf<N> req_bufarray(.in=_reqX, .out=_reqXX, .supply=supply);
sigbuf<N*2> req_bufarray(.in=_reqX, .out=_reqXX, .supply=supply);
// For reasons of pure spice, the control circuitry
// requires a req signal that FALLS SLOWER than the req going to the function block.
@@ -103,38 +103,35 @@ namespace tmpl {
A_1C1P_X1 en_ctl(.c1=in.a,.p1=out.v,.y=_en,.vdd=supply.vdd,.vss=supply.vss);
//function
bool _out_a_BX_t[N],_out_a_BX_f[N],_out_a_B,_en_X_t[N],_en_X_f[N];
bool _out_a_B;
A_2C2N_RB_X4 f_buf_func[N];
A_2C2N_RB_X4 t_buf_func[N];
sigbuf<N> en_buf_t(.in=_en, .out=_en_X_t, .supply=supply);
sigbuf<N> en_buf_f(.in=_en, .out=_en_X_f, .supply=supply);
sigbuf<N*2> en_buf(.in=_en, .supply=supply);
INV_X1 out_a_inv(.a=out.a,.y=_out_a_B, .vss = supply.vss, .vdd = supply.vdd);
sigbuf<N> out_a_B_buf_f(.in=_out_a_B,.out=_out_a_BX_t, .supply=supply);
sigbuf<N> out_a_B_buf_t(.in=_out_a_B,.out=_out_a_BX_f, .supply=supply);
sigbuf<N*2> out_a_B_buf(.in=_out_a_B, .supply=supply);
// check if you can also do single var to array connect a=b[N]
// and remove them from the loop
(i:N:
f_buf_func[i].y=out.d.d[i].f;
t_buf_func[i].y=out.d.d[i].t;
f_buf_func[i].c1=_en_X_f[i];
t_buf_func[i].c1=_en_X_t[i];
f_buf_func[i].c2=_out_a_BX_f[i];
t_buf_func[i].c2=_out_a_BX_t[i];
f_buf_func[i].c1=en_buf.out[i];
t_buf_func[i].c1=en_buf.out[i+N];
f_buf_func[i].c2=out_a_B_buf.out[i];
t_buf_func[i].c2=out_a_B_buf.out[i+N];
f_buf_func[i].n1=_inB[i];
t_buf_func[i].n1=in.d[i];
f_buf_func[i].n2=_reqXX[i];
t_buf_func[i].n2=_reqXX[i];
t_buf_func[i].n2=_reqXX[i+N];
f_buf_func[i].vdd=supply.vdd;
t_buf_func[i].vdd=supply.vdd;
f_buf_func[i].vss=supply.vss;
t_buf_func[i].vss=supply.vss;
t_buf_func[i].pr_B = _reset_BXX[i];
t_buf_func[i].sr_B = _reset_BXX[i];
f_buf_func[i].pr_B = _reset_BXX[i];
f_buf_func[i].sr_B = _reset_BXX[i];
f_buf_func[i].pr_B = _reset_BXX[i+N];
f_buf_func[i].sr_B = _reset_BXX[i+N];
)
}

View File

@@ -125,23 +125,21 @@ namespace tmpl {
BUF_X4 in_v_buf(.a=_in_v, .y=in.v,.vdd=supply.vdd,.vss=supply.vss);
//function
bool _out_a_BX_t[N],_out_a_BX_f[N],_out_a_B,_en_X_t[N],_en_X_f[N];
bool _out_a_BX[N*2],_out_a_B;
A_2C1N_RB_X4 f_buf_func[N];
A_2C1N_RB_X4 t_buf_func[N];
sigbuf<N> en_buf_t(.in=_en, .out=_en_X_t, .supply=supply);
sigbuf<N> en_buf_f(.in=_en, .out=_en_X_f, .supply=supply);
sigbuf<N*2> en_buf(.in=_en, .supply=supply);
INV_X1 out_a_inv(.a=out.a,.y=_out_a_B, .vss = supply.vss, .vdd = supply.vdd);
sigbuf<N> out_a_B_buf_f(.in=_out_a_B,.out=_out_a_BX_t, .supply = supply);
sigbuf<N> out_a_B_buf_t(.in=_out_a_B,.out=_out_a_BX_f, .supply = supply);
sigbuf<N*2> out_a_B_buf(.in=_out_a_B,.out=_out_a_BX, .supply = supply);
// check if you can also do single var to array connect a=b[N]
// and remove them from the loop
(i:N:
f_buf_func[i].y=out.d.d[i].f;
t_buf_func[i].y=out.d.d[i].t;
f_buf_func[i].c1=_en_X_f[i];
t_buf_func[i].c1=_en_X_t[i];
f_buf_func[i].c2=_out_a_BX_f[i];
t_buf_func[i].c2=_out_a_BX_t[i];
f_buf_func[i].c1=en_buf.out[i];
t_buf_func[i].c1=en_buf.out[i+N];
f_buf_func[i].c2=_out_a_BX[i];
t_buf_func[i].c2=_out_a_BX[i+N];
f_buf_func[i].n1=in.d.d[i].f;
t_buf_func[i].n1=in.d.d[i].t;
f_buf_func[i].vdd=supply.vdd;
@@ -196,33 +194,31 @@ namespace tmpl {
sigbuf<N> reset_bufarray(.in=_reset_BX, .out=_reset_BXX, .supply=supply);
//validity
bool _in_v, _in_vX[N];
bool _in_v;
vtree<N> vc(.in=in.d,.out=_in_v,.supply=supply);
BUF_X4 in_v_buf4(.a=_in_v, .y=in.v,.vdd=supply.vdd,.vss=supply.vss);
sigbuf<N> in_v_bufN(.in = in.v, .out = _in_vX, .supply = supply);
sigbuf<N*2> in_v_bufN(.in = in.v, .supply = supply);
//function
bool _out_a_BX_t[N],_out_a_BX_f[N],_out_a_B,_en_X_t[N],_en_X_f[N];
bool _out_a_B;
A_2C2N_RB_X4 f_buf_func[N];
A_2C2N_RB_X4 t_buf_func[N];
sigbuf<N> en_buf_t(.in=_en, .out=_en_X_t, .supply=supply);
sigbuf<N> en_buf_f(.in=_en, .out=_en_X_f, .supply=supply);
sigbuf<N*2> en_buf(.in=_en, .supply=supply);
INV_X1 out_a_inv(.a=out.a,.y=_out_a_B, .vss = supply.vss, .vdd = supply.vdd);
sigbuf<N> out_a_B_buf_f(.in=_out_a_B,.out=_out_a_BX_t, .supply=supply);
sigbuf<N> out_a_B_buf_t(.in=_out_a_B,.out=_out_a_BX_f, .supply=supply);
sigbuf<N*2> out_a_B_buf(.in=_out_a_B, .supply=supply);
// check if you can also do single var to array connect a=b[N]
// and remove them from the loop
(i:N:
f_buf_func[i].y=out.d.d[i].f;
t_buf_func[i].y=out.d.d[i].t;
f_buf_func[i].c1=_en_X_f[i];
t_buf_func[i].c1=_en_X_t[i];
f_buf_func[i].c2=_out_a_BX_f[i];
t_buf_func[i].c2=_out_a_BX_t[i];
f_buf_func[i].c1=en_buf.out[i];
t_buf_func[i].c1=en_buf.out[i+N];
f_buf_func[i].c2=out_a_B_buf.out[i];
t_buf_func[i].c2=out_a_B_buf.out[i+N];
f_buf_func[i].n1=in.d.d[i].f;
t_buf_func[i].n1=in.d.d[i].t;
f_buf_func[i].n2=_in_vX[i];
t_buf_func[i].n2=_in_vX[i];
f_buf_func[i].n2=in_v_bufN.out[i];
t_buf_func[i].n2=in_v_bufN.out[i+N];
f_buf_func[i].vdd=supply.vdd;
t_buf_func[i].vdd=supply.vdd;
f_buf_func[i].vss=supply.vss;
@@ -241,7 +237,7 @@ namespace tmpl {
OR2_X1 out_or(.a=out1.v, .b=out2.v, .y=_out_v,.vdd=supply.vdd,.vss=supply.vss);
A_3C_RB_X4 inack_ctl(.c1=_en,.c2=_in_c_v_,.c3=_out_v,.y=in.a,.pr_B=_reset_BX,.sr_B=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
cond.a = in.a;
cond.a = in.a; // THIS SHOULD BE IMPROVED UPON IN FUTURE VERSIONS
cond.v = _in_c_v_;
A_1C1P_X1 en_ctl(.c1=in.a,.p1=_out_v,.y=_en,.vdd=supply.vdd,.vss=supply.vss);
BUF_X1 reset_buf(.a=reset_B, .y=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
@@ -261,21 +257,19 @@ namespace tmpl {
//function
//func buffer out1
bool _out1_a_BX_t[N],_out1_a_BX_f[N],_out1_a_B,_en1_X_t[N],_en1_X_f[N];
bool _out1_a_B;
A_2C2N_RB_X4 out1_f_buf_func[N];
A_2C2N_RB_X4 out1_t_buf_func[N];
sigbuf<N> out1_en_buf_t(.in=_en, .out=_en1_X_t, .supply=supply);
sigbuf<N> out1_en_buf_f(.in=_en, .out=_en1_X_f, .supply=supply);
INV_X1 out1_a_inv(.a=out1.a,.y=_out1_a_B);
sigbuf<N> out1_a_B_buf_f(.in=_out1_a_B,.out=_out1_a_BX_t, .supply=supply);
sigbuf<N> out1_a_B_buf_t(.in=_out1_a_B,.out=_out1_a_BX_f, .supply=supply);
sigbuf<N*4> out_en_buf(.in=_en, .supply=supply);
INV_X1 out1_a_inv(.a=out1.a,.y=_out1_a_B, .vdd = supply.vdd, .vss = supply.vss);
sigbuf<N*2> out1_a_B_buf(.in=_out1_a_B, .supply=supply);
(i:N:
out1_f_buf_func[i].y=out1.d.d[i].f;
out1_t_buf_func[i].y=out1.d.d[i].t;
out1_f_buf_func[i].c1=_en1_X_f[i];
out1_t_buf_func[i].c1=_en1_X_t[i];
out1_f_buf_func[i].c2=_out1_a_BX_f[i];
out1_t_buf_func[i].c2=_out1_a_BX_t[i];
out1_f_buf_func[i].c1=out_en_buf.out[i];
out1_t_buf_func[i].c1=out_en_buf.out[i+N];
out1_f_buf_func[i].c2=out1_a_B_buf.out[i];
out1_t_buf_func[i].c2=out1_a_B_buf.out[i+N];
out1_f_buf_func[i].n1=in.d.d[i].f;
out1_t_buf_func[i].n1=in.d.d[i].t;
out1_f_buf_func[i].vdd=supply.vdd;
@@ -291,31 +285,29 @@ namespace tmpl {
)
//func buffer out2
bool _out2_a_BX_t[N],_out2_a_BX_f[N],_out2_a_B,_en2_X_t[N],_en2_X_f[N];
bool _out2_a_B;
A_2C2N_RB_X4 out2_f_buf_func[N];
A_2C2N_RB_X4 out2_t_buf_func[N];
sigbuf<N> out2_en_buf_t(.in=_en, .out=_en2_X_t, .supply=supply);
sigbuf<N> out2_en_buf_f(.in=_en, .out=_en2_X_f, .supply=supply);
INV_X1 out2_a_inv(.a=out2.a,.y=_out2_a_B);
sigbuf<N> out2_a_B_buf_f(.in=_out2_a_B,.out=_out2_a_BX_t);
sigbuf<N> out2_a_B_buf_t(.in=_out2_a_B,.out=_out2_a_BX_f);
// sigbuf<N*2> out2_en_buf(.in=_en, .supply=supply);
INV_X1 out2_a_inv(.a=out2.a,.y=_out2_a_B, .vdd = supply.vdd, .vss = supply.vss);
sigbuf<N*2> out2_a_B_buf(.in=_out2_a_B);
(i:N:
out2_f_buf_func[i].y=out2.d.d[i].f;
out2_t_buf_func[i].y=out2.d.d[i].t;
out2_f_buf_func[i].c1=_en2_X_f[i];
out2_t_buf_func[i].c1=_en2_X_t[i];
out2_f_buf_func[i].c2=_out2_a_BX_f[i];
out2_t_buf_func[i].c2=_out2_a_BX_t[i];
out2_f_buf_func[i].c1=out_en_buf.out[i+2*N];
out2_t_buf_func[i].c1=out_en_buf.out[i+3*N];
out2_f_buf_func[i].c2=out2_a_B_buf.out[i];
out2_t_buf_func[i].c2=out2_a_B_buf.out[i+N];
out2_f_buf_func[i].n1=in.d.d[i].f;
out2_t_buf_func[i].n1=in.d.d[i].t;
out2_f_buf_func[i].vdd=supply.vdd;
out2_t_buf_func[i].vdd=supply.vdd;
out2_f_buf_func[i].vss=supply.vss;
out2_t_buf_func[i].vss=supply.vss;
out2_t_buf_func[i].pr_B = _reset_BXX[i+N-1];
out2_t_buf_func[i].sr_B = _reset_BXX[i+N-1];
out2_f_buf_func[i].pr_B = _reset_BXX[i+N-1];
out2_f_buf_func[i].sr_B = _reset_BXX[i+N-1];
out2_t_buf_func[i].pr_B = _reset_BXX[i+N];
out2_t_buf_func[i].sr_B = _reset_BXX[i+N];
out2_f_buf_func[i].pr_B = _reset_BXX[i+N];
out2_f_buf_func[i].sr_B = _reset_BXX[i+N];
out2_f_buf_func[i].n2=_c_t_buf[i];
out2_t_buf_func[i].n2=_c_t_buf[i];
)
@@ -342,21 +334,19 @@ namespace tmpl {
//function
//func buffer out1
bool _out1_a_BX_t[N],_out1_a_BX_f[N],_out1_a_B,_en1_X_t[N],_en1_X_f[N];
bool _out1_a_B;
A_2C1N_RB_X4 out1_f_buf_func[N];
A_2C1N_RB_X4 out1_t_buf_func[N];
sigbuf<N> out1_en_buf_t(.in=_en, .out=_en1_X_t, .supply=supply);
sigbuf<N> out1_en_buf_f(.in=_en, .out=_en1_X_f, .supply=supply);
sigbuf<N*2> out1_en_buf(.in=_en, .supply=supply);
INV_X1 out1_a_inv(.a=out1.a,.y=_out1_a_B);
sigbuf<N> out1_a_B_buf_f(.in=_out1_a_B,.out=_out1_a_BX_t);
sigbuf<N> out1_a_B_buf_t(.in=_out1_a_B,.out=_out1_a_BX_f);
sigbuf<N*2> out1_a_B_buf(.in=_out1_a_B);
(i:N:
out1_f_buf_func[i].y=out1.d.d[i].f;
out1_t_buf_func[i].y=out1.d.d[i].t;
out1_f_buf_func[i].c1=_en1_X_f[i];
out1_t_buf_func[i].c1=_en1_X_t[i];
out1_f_buf_func[i].c2=_out1_a_BX_f[i];
out1_t_buf_func[i].c2=_out1_a_BX_t[i];
out1_f_buf_func[i].c1=out1_en_buf.out[i];
out1_t_buf_func[i].c1=out1_en_buf.out[i+N];
out1_f_buf_func[i].c2=out1_a_B_buf.out[i];
out1_t_buf_func[i].c2=out1_a_B_buf.out[i+N];
out1_f_buf_func[i].n1=in.d.d[i].f;
out1_t_buf_func[i].n1=in.d.d[i].t;
out1_f_buf_func[i].vdd=supply.vdd;
@@ -369,31 +359,29 @@ namespace tmpl {
out1_f_buf_func[i].sr_B = _reset_BXX[i];
)
//func buffer out2
bool _out2_a_BX_t[N],_out2_a_BX_f[N],_out2_a_B,_en2_X_t[N],_en2_X_f[N];
bool _out2_a_B;
A_2C1N_RB_X4 out2_f_buf_func[N];
A_2C1N_RB_X4 out2_t_buf_func[N];
sigbuf<N> out2_en_buf_t(.in=_en, .out=_en2_X_t, .supply=supply);
sigbuf<N> out2_en_buf_f(.in=_en, .out=_en2_X_f, .supply=supply);
sigbuf<N*2> out2_en_buf(.in=_en, .supply=supply);
INV_X1 out2_a_inv(.a=out2.a,.y=_out2_a_B);
sigbuf<N> out2_a_B_buf_f(.in=_out2_a_B,.out=_out2_a_BX_t);
sigbuf<N> out2_a_B_buf_t(.in=_out2_a_B,.out=_out2_a_BX_f);
sigbuf<N*2> out2_a_B_buf(.in=_out2_a_B);
(i:N:
out2_f_buf_func[i].y=out2.d.d[i].f;
out2_t_buf_func[i].y=out2.d.d[i].t;
out2_f_buf_func[i].c1=_en2_X_f[i];
out2_t_buf_func[i].c1=_en2_X_t[i];
out2_f_buf_func[i].c2=_out2_a_BX_f[i];
out2_t_buf_func[i].c2=_out2_a_BX_t[i];
out2_f_buf_func[i].c1=out2_en_buf.out[i];
out2_t_buf_func[i].c1=out2_en_buf.out[i+N];
out2_f_buf_func[i].c2=out2_a_B_buf.out[i];
out2_t_buf_func[i].c2=out2_a_B_buf.out[i+N];
out2_f_buf_func[i].n1=in.d.d[i].f;
out2_t_buf_func[i].n1=in.d.d[i].t;
out2_f_buf_func[i].vdd=supply.vdd;
out2_t_buf_func[i].vdd=supply.vdd;
out2_f_buf_func[i].vss=supply.vss;
out2_t_buf_func[i].vss=supply.vss;
out2_t_buf_func[i].pr_B = _reset_BXX[i+N-1];
out2_t_buf_func[i].sr_B = _reset_BXX[i+N-1];
out2_f_buf_func[i].pr_B = _reset_BXX[i+N-1];
out2_f_buf_func[i].sr_B = _reset_BXX[i+N-1];
out2_t_buf_func[i].pr_B = _reset_BXX[i];
out2_t_buf_func[i].sr_B = _reset_BXX[i];
out2_f_buf_func[i].pr_B = _reset_BXX[i];
out2_f_buf_func[i].sr_B = _reset_BXX[i];
)
}
@@ -439,21 +427,19 @@ namespace tmpl {
//function
//func buffer out1
bool _out1_a_BX_t[N],_out1_a_BX_f[N],_out1_a_B,_en1_X_t[N],_en1_X_f[N];
bool _out1_a_B;
A_2C2N_RB_X4 out1_f_buf_func[N];
A_2C2N_RB_X4 out1_t_buf_func[N];
sigbuf<N> out1_en_buf_t(.in=_en, .out=_en1_X_t, .supply=supply);
sigbuf<N> out1_en_buf_f(.in=_en, .out=_en1_X_f, .supply=supply);
sigbuf<N*2> out1_en_buf(.in=_en, .supply=supply);
INV_X1 out1_a_inv(.a=out1.a,.y=_out1_a_B, .vss = supply.vss, .vdd = supply.vdd);
sigbuf<N> out1_a_B_buf_f(.in=_out1_a_B,.out=_out1_a_BX_t, .supply=supply);
sigbuf<N> out1_a_B_buf_t(.in=_out1_a_B,.out=_out1_a_BX_f, .supply=supply);
sigbuf<N*2> out1_a_B_buf(.in=_out1_a_B, .supply=supply);
(i:N:
out1_f_buf_func[i].y=out1.d.d[i].f;
out1_t_buf_func[i].y=out1.d.d[i].t;
out1_f_buf_func[i].c1=_en1_X_f[i];
out1_t_buf_func[i].c1=_en1_X_t[i];
out1_f_buf_func[i].c2=_out1_a_BX_f[i];
out1_t_buf_func[i].c2=_out1_a_BX_t[i];
out1_f_buf_func[i].c1=out1_en_buf.out[i];
out1_t_buf_func[i].c1=out1_en_buf.out[i+N];
out1_f_buf_func[i].c2=out1_a_B_buf.out[i];
out1_t_buf_func[i].c2=out1_a_B_buf.out[i+N];
out1_f_buf_func[i].n1=in.d.d[i].f;
out1_t_buf_func[i].n1=in.d.d[i].t;
out1_f_buf_func[i].vdd=supply.vdd;
@@ -515,11 +501,12 @@ namespace tmpl {
AND2_X1 and2(.a = _drop, .b = _in_vX, .vss = supply.vss, .vdd = supply.vdd);
OR2_X1 or2(.a = out.a, .b = and2.y, .vss = supply.vss, .vdd = supply.vdd);
A_2C_B_X1 ack_Cel(.c1 = or2.y, .c2 = _in_vX, .y = in.a);
_in_vX = in.v;
// _in_vX = in.v;
// Sigbufs
sigbuf<N*2> sb_dropB(.in = _dropB, .supply = supply);
sigbuf<N*2> sb_in_v(.in = _in_vX, .supply = supply);
sigbuf<N*2+1> sb_in_v(.in = _in_vX, .supply = supply);
sb_in_v.out[2*N] = in.v;
AND3_X1 and_t[N];
AND3_X1 and_f[N];
@@ -557,23 +544,23 @@ namespace tmpl {
}
//The buffer_t_valid doesn't work
export
defproc buffer_t_valid(a1of1 in; a1of1 out; bool? reset_B; power supply)
{
//control
bool _en, _reset_BX;
A_3C_RB_X4 inack_ctl(.c1=_en,.c2=in.r,.c3=out.r,.y=in.a,.pr_B=_reset_BX,.sr_B=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
A_1C1P_X1 en_ctl(.c1=in.a,.p1=out.r,.y=_en,.vdd=supply.vdd,.vss=supply.vss);
// export
// defproc buffer_t_valid(a1of1 in; a1of1 out; bool? reset_B; power supply)
// {
// //control
// bool _en, _reset_BX;
// A_3C_RB_X4 inack_ctl(.c1=_en,.c2=in.r,.c3=out.r,.y=in.a,.pr_B=_reset_BX,.sr_B=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
// A_1C1P_X1 en_ctl(.c1=in.a,.p1=out.r,.y=_en,.vdd=supply.vdd,.vss=supply.vss);
//function
bool _out_a_B;
INV_X1 inv_outa(.a = out.a,.y=_out_a_B,.vdd = supply.vdd,.vss=supply.vss);
A_2C1N_RB_X4 buf_func(.c1 = _en,.c2 = _out_a_B, .n1 = in.r,.y = out.r, .pr_B = _reset_BX, .sr_B = _reset_BX,.vdd = supply.vdd,.vss=supply.vss);
// //function
// bool _out_a_B;
// INV_X1 inv_outa(.a = out.a,.y=_out_a_B,.vdd = supply.vdd,.vss=supply.vss);
// A_2C1N_RB_X4 buf_func(.c1 = _en,.c2 = _out_a_B, .n1 = in.r,.y = out.r, .pr_B = _reset_BX, .sr_B = _reset_BX,.vdd = supply.vdd,.vss=supply.vss);
//reset buffers
BUF_X1 reset_buf(.a=reset_B, .y=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
}
// //reset buffers
// BUF_X1 reset_buf(.a=reset_B, .y=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
// }
@@ -590,7 +577,7 @@ namespace tmpl {
bool _in1_arb,_in2_arb,_in1_arb_X[2*N],_in2_arb_X[2*N];
A_4C_RB_X4 in1ack_ctl(.c1=_in1_arb,.c2=_en,.c3=in1.v,.c4=out.v,.y=in1.a,.pr_B=_reset_BX,.sr_B=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
A_4C_RB_X4 in2ack_ctl(.c1=_in2_arb,.c2=_en,.c3=in2.v,.c4=out.v,.y=in2.a,.pr_B=_reset_BX,.sr_B=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
A_4P1N1N_X1 en_ctl(.p1 = in1.a,.p2=in2.a,.p3=out.a,.p4 = out.v, .n1 = in1.a,.n2 = in2.a,.y = _en,.vdd=supply.vdd,.vss=supply.vss);
A_4P1N1N_X1 en_ctl(.p1 = in1.a,.p2=in2.a,.p3=out.a,.p4 = out.v, .na1 = in1.a,.nb1 = in2.a,.y = _en,.vdd=supply.vdd,.vss=supply.vss);
sigbuf<2*N> en_buffer(.in = _en,.out = _en_X,.supply=supply);
INV_X1 in1ack_ctl_inv(.a=in1.a,.y=_in1_a_B,.vdd=supply.vdd,.vss=supply.vss);
INV_X1 in2ack_ctl_inv(.a=in2.a,.y=_in2_a_B,.vdd=supply.vdd,.vss=supply.vss);
@@ -621,10 +608,10 @@ namespace tmpl {
(i:N:
merge_func_t[i].c1 = _en_X[i];
merge_func_t[i].c2 = _out_a_BX[i];
merge_func_t[i].n1 = _in1_arb_X[i];
merge_func_t[i].n2 = in1.d.d[i].t;
merge_func_t[i].n3 = _in2_arb_X[i];
merge_func_t[i].n4 = in2.d.d[i].t;
merge_func_t[i].na1 = _in1_arb_X[i];
merge_func_t[i].na2 = in1.d.d[i].t;
merge_func_t[i].nb1 = _in2_arb_X[i];
merge_func_t[i].nb2 = in2.d.d[i].t;
merge_func_t[i].y = out.d.d[i].t;
merge_func_t[i].vdd=supply.vdd;
merge_func_t[i].vss=supply.vss;
@@ -633,10 +620,10 @@ namespace tmpl {
merge_func_f[i].c1 = _en_X[i+N];
merge_func_f[i].c2 = _out_a_BX[i+N];
merge_func_f[i].n1 = _in1_arb_X[i+N];
merge_func_f[i].n2 = in1.d.d[i].f;
merge_func_f[i].n3 = _in2_arb_X[i+N];
merge_func_f[i].n4 = in2.d.d[i].f;
merge_func_f[i].na1 = _in1_arb_X[i+N];
merge_func_f[i].na2 = in1.d.d[i].f;
merge_func_f[i].nb1 = _in2_arb_X[i+N];
merge_func_f[i].nb2 = in2.d.d[i].f;
merge_func_f[i].y = out.d.d[i].f;
merge_func_f[i].vdd=supply.vdd;
merge_func_f[i].vss=supply.vss;
@@ -873,9 +860,17 @@ defproc slice_data(avMx1of2<N> in; avMx1of2<std::min(N1,N)-std::max(N0,0)> out;
in.d.d[CONDITION_BIT].f = demux.cond.d.d[0].f;
in.d.d[CONDITION_BIT].t = demux.cond.d.d[0].t;
in.v = demux.in.v;
in.a = demux.in.a;
A_2C_B_X1 val_Cel(.c1 = demux.in.v, .c2 = demux.cond.v, .y = in.v,
.vdd = supply.vdd, .vss = supply.vss);
// Not actually needed bc the current version of demux
// Something like below should be added once the handshakes are properly decoupled.
// wires the data and cond ack lines together anyway.
// A_2C_B_X1 ack_Cel(.c1 = demux.in.a, .c2 = demux.cond.a, .y = in.a,
// .vdd = supply.vdd, .vss = supply.vss);
// in.v = demux.in.v;
in.a = demux.in.a;
(i:0..CONDITION_BIT-1:
in.d.d[i].f = demux.in.d.d[i].f;
@@ -893,5 +888,20 @@ defproc slice_data(avMx1of2<N> in; avMx1of2<std::min(N1,N)-std::max(N0,0)> out;
demux_bit<N,N> demux(.in = in, .out1 = out1, .out2 = out2, .reset_B = reset_B, .out1=out1, .out2=out2);
}
/**
* Create M sigbufs to buffer an M bool array to N strength.
* Done lazily.
**/
export template<pint M, N>
defproc sigbuf_boolarray(bool? in[M]; bool! out[M]; power supply) {
sigbuf<N> sb[M];
(i:M:
sb[i].in = in[i];
sb[i].out[0] = out[i];
sb[i].supply = supply;
)
}
}}

View File

@@ -52,84 +52,72 @@ export template<pint N>
defproc buffer_register(avMx1of2<N> in; Mx1of2<N> out; bool? out_v, flush,
reset_B; power supply) {
// BIG TODO
// I HAVE NOT BOTHERED WITH ANY SIGNAL BUFFERING IN HERE YET
//control
bool _en, _reset_BX,_reset_BXX[N];
bool _en, _reset_BX[N];
bool _in_aB;
bool _reset;
INV_X1 reset_inv(.a = reset_B, .y = _reset);
bool _resetX[N];
// Reset sigs
INV_X1 reset_inv(.a = reset_B, .y = _reset, .vdd = supply.vdd, .vss = supply.vss);
sigbuf<N> reset_sb(.in = _reset, .out = _resetX, .supply = supply);
sigbuf<N> resetB_sb(.in=reset_B, .out=_reset_BX, .supply = supply);
A_2C1N_R_X1 inack_ctl(.c1=_in_aB,.c2=in.v,.n1=out_v,.y=_in_aB,
.pr_B=_reset_BX,.sr_B=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
.pr_B=_reset_BX[0],.sr_B=_reset_BX[0],.vdd=supply.vdd,.vss=supply.vss);
INV_X1 inack_inv(.a = _in_aB, .y = in.a, .vdd = supply.vdd, .vss = supply.vss);
// A_1C1P_X1 en_ctl(.c1=in.a,.p1=out.v,.y=_en,
// .vdd=supply.vdd,.vss=supply.vss);
bool _flushB;
// Flush sigs
bool _flushB, _flushBX[N*2];
INV_X1 flush_inv(.a = flush, .y = _flushB);
// AND2_X1 flush_en(.a = _flushB, .b = _in_aB, .y = _en);
sigbuf<N*2> flushB_sb(.in = _flushB, .out = _flushBX, .supply = supply);
_en = _in_aB;
BUF_X1 reset_buf(.a=reset_B, .y=_reset_BX,.vdd=supply.vdd,.vss=supply.vss);
sigbuf<N> reset_bufarray(.in=_reset_BX, .out=_reset_BXX);
//validity
bool _in_v;
vtree<N> vc(.in=in.d,.out=_in_v,.supply=supply);
BUF_X4 in_v_buf(.a=_in_v, .y=in.v,.vdd=supply.vdd,.vss=supply.vss);
//function
bool _out_a_BX_t[N],_out_a_BX_f[N],_out_a_B,_en_X_t[N],_en_X_f[N];
bool _out_a_BX_t[N],_out_a_BX_f[N],_out_a_B;
A_1C2N_SB_X4 f_buf_func[N];
A_1C2N_RB_X4 t_buf_func[N];
sigbuf<N> en_buf_t(.in=_en, .out=_en_X_t, .supply=supply);
sigbuf<N> en_buf_f(.in=_en, .out=_en_X_f, .supply=supply);
// INV_X1 out_a_inv(.a=out.a,.y=_out_a_B, .vss = supply.vss, .vdd = supply.vdd);
// sigbuf<N> out_a_B_buf_f(.in=_out_a_B,.out=_out_a_BX_t);
// sigbuf<N> out_a_B_buf_t(.in=_out_a_B,.out=_out_a_BX_f);
// check if you can also do single var to array connect a=b[N]
// and remove them from the loop
sigbuf<N*2> en_buf(.in=_en, .supply=supply);
(i:N:
f_buf_func[i].y=out.d[i].f;
t_buf_func[i].y=out.d[i].t;
f_buf_func[i].c1=_flushB;
t_buf_func[i].c1=_flushB;
f_buf_func[i].c1=_flushBX[i];
t_buf_func[i].c1=_flushBX[i+N];
f_buf_func[i].n2=_en_X_f[i];
t_buf_func[i].n2=_en_X_t[i];
// f_buf_func[i].c2=_out_a_BX_f[i];
// t_buf_func[i].c2=_out_a_BX_t[i];
f_buf_func[i].n2=en_buf.out[i];
t_buf_func[i].n2=en_buf.out[i+N];
f_buf_func[i].n1=in.d.d[i].f;
t_buf_func[i].n1=in.d.d[i].t;
f_buf_func[i].vdd=supply.vdd;
t_buf_func[i].vdd=supply.vdd;
f_buf_func[i].vss=supply.vss;
t_buf_func[i].vss=supply.vss;
f_buf_func[i].pr = _reset;
f_buf_func[i].sr = _reset;
t_buf_func[i].pr_B = _reset_BXX[i];
t_buf_func[i].sr_B = _reset_BXX[i];
f_buf_func[i].pr = _resetX[i];
f_buf_func[i].sr = _resetX[i];
t_buf_func[i].pr_B = _reset_BX[i];
t_buf_func[i].sr_B = _reset_BX[i];
)
}
/**
* A single register made out of A cells.
* last bit is whether to read or write.
* MSB is whether to read or write.
* Currently only handles writing.
*/
export template<pint N>
defproc register_acells(avMx1of2<N+1> in; Mx1of2<N> out;
bool? reset_B; power supply) {
// BIG TODO
// I HAVE NOT BOTHERED WITH ANY SIGNAL BUFFERING IN HERE YET
bool _en2;
bool _w;
@@ -163,13 +151,14 @@ A_1C2N_R_X1 A_en2(.c1 = _w, .n1 = _en2, .n2 = _out_vB, .y = _en2,
// Pass to let data into the buffer
NOR2_X1 pass(.a = _en2, .b = _flush, .vss = supply.vss, .vdd = supply.vdd);
sigbuf<N*2> passX(.in = pass.y, .supply = supply);
AND2_X1 gandalf_t[N];
AND2_X1 gandalf_f[N];
(i:0..N-1:
gandalf_t[i].a = in.d.d[i].t;
gandalf_f[i].a = in.d.d[i].f;
gandalf_t[i].b = pass.y;
gandalf_f[i].b = pass.y;
gandalf_t[i].b = passX.out[i];
gandalf_f[i].b = passX.out[i+N];
gandalf_t[i].y = buf.in.d.d[i].t;
gandalf_f[i].y = buf.in.d.d[i].f;
@@ -194,65 +183,71 @@ AND2_X1 gandalf_f[N];
* Input packets should be
* [-addr-][-word-][r/w]
*/
export template<pint NcA, NcW, M>
defproc register_w_array(avMx1of2<NcA + NcW + 1> in; Mx1of2<NcW> data[M];
bool? reset_B; power supply) {
// BIG TODO
// I HAVE NOT BOTHERED WITH ANY SIGNAL BUFFERING IN HERE YET
vtree<NcA + NcW + 1> input_valid(.in = in.d, .out = in.v,
.supply = supply);
// UNUSED
// UNUSED
// UNUSED
// UNUSED
// export template<pint NcA, NcW, M>
// defproc register_w_array(avMx1of2<NcA + NcW + 1> in; Mx1of2<NcW> data[M];
// bool? reset_B; power supply) {
// // BIG TODO
// // I HAVE NOT BOTHERED WITH ANY SIGNAL BUFFERING IN HERE YET
// vtree<NcA + NcW + 1> input_valid(.in = in.d, .out = in.v,
// .supply = supply);
// Address decoder
decoder_dualrail<NcA, M> decoder(.supply = supply);
(i:NcA:
decoder.in.d[i] = in.d.d[i];
)
// // Address decoder
// decoder_dualrail<NcA, M> decoder(.supply = supply);
// (i:NcA:
// decoder.in.d[i] = in.d.d[i];
// )
// OrTree over acks from all registers
ortree<M> ack_ortree(.supply = supply);
// // OrTree over acks from all registers
// ortree<M> ack_ortree(.supply = supply);
// C element handling in ack
A_2C_B_X1 in_ack_Cel(.c1 = ack_ortree.out, .c2 = input_valid.out, .y = in.a,
.vss = supply.vss, .vdd = supply.vdd);
// // C element handling in ack
// A_2C_B_X1 in_ack_Cel(.c1 = ack_ortree.out, .c2 = input_valid.out, .y = in.a,
// .vss = supply.vss, .vdd = supply.vdd);
// Write bit selector
bool _w = in.d.d[NcA+NcW].t;
A_2C_B_X1 write_selectors[M];
(i:M:
write_selectors[i].c1 = _w;
write_selectors[i].c2 = decoder.out[i];
write_selectors[i].vdd = supply.vdd;
write_selectors[i].vss = supply.vss;
)
// // Write bit selector
// bool _w = in.d.d[NcA+NcW].t;
// A_2C_B_X1 write_selectors[M];
// (i:M:
// write_selectors[i].c1 = _w;
// write_selectors[i].c2 = decoder.out[i];
// write_selectors[i].vdd = supply.vdd;
// write_selectors[i].vss = supply.vss;
// )
// Registers
register_acells<NcW> registers[M];
TIELO_X1 tielow_writebit_f[M];
(i:M:
// Connect each register to word inputs.
(j:NcW:
registers[i].in.d.d[j] = in.d.d[j + NcA];
)
// // Registers
// register_acells<NcW> registers[M];
// TIELO_X1 tielow_writebit_f[M];
// (i:M:
// // Connect each register to word inputs.
// (j:NcW:
// registers[i].in.d.d[j] = in.d.d[j + NcA];
// )
// Connect the (selected) write bit
registers[i].in.d.d[NcW].t = write_selectors[i].y;
tielow_writebit_f[i].vdd = supply.vdd;
tielow_writebit_f[i].vss = supply.vss;
registers[i].in.d.d[NcW].f = tielow_writebit_f[i].y;
// // Connect the (selected) write bit
// registers[i].in.d.d[NcW].t = write_selectors[i].y;
// tielow_writebit_f[i].vdd = supply.vdd;
// tielow_writebit_f[i].vss = supply.vss;
// registers[i].in.d.d[NcW].f = tielow_writebit_f[i].y;
// Connect to ack ortree
registers[i].in.a = ack_ortree.in[i];
// // Connect to ack ortree
// registers[i].in.a = ack_ortree.in[i];
// Connect outputs
data[i] = registers[i].out;
// // Connect outputs
// data[i] = registers[i].out;
registers[i].supply = supply;
registers[i].reset_B = reset_B;
)
// registers[i].supply = supply;
// registers[i].reset_B = reset_B;
// )
}
// }
/**
* Array of registers made out of A-cells
@@ -267,8 +262,6 @@ export template<pint NcA, NcW, M>
defproc register_wr_array(avMx1of2<NcA + NcW + 1> in; Mx1of2<NcW> data[M]; avMx1of2<NcA+NcW> out;
bool? reset_B; power supply) {
// BIG TODO
// I HAVE NOT BOTHERED WITH ANY SIGNAL BUFFERING IN HERE YET
// Input valid tree
vtree<NcA + NcW + 1> input_valid(.in = in.d, .out = in.v,
@@ -292,14 +285,17 @@ A_2C_B_X1 in_ack_Cel(.c1 = ack_ortree.out, .c2 = input_valid.out, .y = _write_ac
// Bit to join the acks either from read or write
bool _read_ack;
_read_ack = out.a;
OR2_X1 ack_rw_or(.a = _read_ack, .b = _write_ack, .y = in.a,
OR2_X1 ack_rw_or(.a = _read_ack, .b = _write_ack,
.vdd = supply.vdd, .vss = supply.vss);
A_2C_B_X1 ack_safety(.c1 = ack_rw_or.y, .c2 = in.v, .y = in.a);
// Write bit selector
bool _w = in.d.d[NcA+NcW].t;
bool _wX[M];
sigbuf<M> _w_sb(.in = _w, .out = _wX, .supply = supply);
A_2C_B_X1 write_selectors[M];
(i:M:
write_selectors[i].c1 = _w;
write_selectors[i].c1 = _wX[i];
write_selectors[i].c2 = decoder.out[i];
write_selectors[i].vdd = supply.vdd;
write_selectors[i].vss = supply.vss;
@@ -333,12 +329,17 @@ TIELO_X1 tielow_writebit_f[M];
// Read bit selector
bool _r = in.d.d[NcA+NcW].f;
bool _rX[M+NcA];
sigbuf<M+NcA> _r_sb(.in = _r, .out = _rX, .supply = supply);
A_2C_B_X1 read_selectors[M];
sigbuf_boolarray<M, NcW*2> read_selectorsX(.supply = supply);
(i:M:
read_selectors[i].c1 = _r;
read_selectors[i].c1 = _rX[i];
read_selectors[i].c2 = decoder.out[i];
read_selectors[i].vdd = supply.vdd;
read_selectors[i].vss = supply.vss;
read_selectorsX.in[i] = read_selectors[i].y;
)
// OrTrees for each output word bit on read
@@ -362,9 +363,9 @@ pint index;
index = i + j*NcW;
and_reads_t[index].a = data[j].d[i].t;
and_reads_t[index].b = read_selectors[j].y;
and_reads_t[index].b = read_selectorsX.out[j];
and_reads_f[index].a = data[j].d[i].f;
and_reads_f[index].b = read_selectors[j].y;
and_reads_f[index].b = read_selectorsX.out[j];
and_reads_t[index].y = out_ortrees_t[i].in[j];
and_reads_f[index].y = out_ortrees_f[i].in[j];
@@ -384,8 +385,8 @@ A_2C_B_X1 addr_read_f[NcA];
addr_read_t[i].c1 = in.d.d[i].t;
addr_read_f[i].c1 = in.d.d[i].f;
addr_read_t[i].c2 = _r;
addr_read_f[i].c2 = _r;
addr_read_t[i].c2 = _rX[M+i];
addr_read_f[i].c2 = _rX[M+i];
addr_read_t[i].y = out.d.d[i].t;
addr_read_f[i].y = out.d.d[i].f;

View File

@@ -418,7 +418,7 @@ defproc sigbuf (bool? in; bool! out[N]; power supply)
{
{ N >= 0 : "sigbuf: parameter error" };
{ N <= 43 : "sigbuf: parameter error, N too big" };
{ N <= 128 : "sigbuf: parameter error, N too big" };
/* -- just use in sized driver here -- */
[ N <= 4 ->
@@ -433,8 +433,18 @@ defproc sigbuf (bool? in; bool! out[N]; power supply)
BUF_X6 buf6 (.a = in, .y = out[0], .vdd = supply.vdd, .vss = supply.vss);
[] N >= 19 & N <= 29 ->
BUF_X8 buf8 (.a = in, .y = out[0], .vdd = supply.vdd, .vss = supply.vss);
[] N >= 30 & N <= 42 ->
[] N >= 30 & N <= 48->
BUF_X12 buf12 (.a = in, .y = out[0], .vdd = supply.vdd, .vss = supply.vss);
[] N >= 49 & N <= 64 ->
BUF_X16 buf16 (.a = in, .y = out[0], .vdd = supply.vdd, .vss = supply.vss);
[] N >= 65 & N <= 96 ->
BUF_X24 buf24 (.a = in, .y = out[0], .vdd = supply.vdd, .vss = supply.vss);
[] N >= 97 & N <=128 ->
BUF_X32 buf32 (.a = in, .y = out[0], .vdd = supply.vdd, .vss = supply.vss);
// [] N >= 129 & N <=192 ->
// BUF_X48 buf48 (.a = in, .y = out[0], .vdd = supply.vdd, .vss = supply.vss);
// [] N >= 193 & N <= 256->
// BUF_X64 buf64 (.a = in, .y = out[0], .vdd = supply.vdd, .vss = supply.vss);
]
(i:1..N-1:out[i]=out[0];)
}
@@ -445,7 +455,7 @@ defproc sigbuf_1output (bool? in; bool! out; power supply)
{
{ N >= 0 : "sigbuf: parameter error" };
{ N <= 43 : "sigbuf: parameter error, N too big" };
{ N <= 43 : "sigbuf: parameter error, N too big" };
/* -- just use in sized driver here -- */
[ N <= 4 ->

View File

@@ -29,7 +29,7 @@ run_test () {
cat $1/run/prsim.in | prsim -r $1/run/test.prs > $1/run/prsim.out
if egrep '(WRONG|WARNING|Node)' $1/run/prsim.out >/dev/null; then
echo "${bold}*** simulation failed seed: $2 ***${normal}"
faildirs="${faildirs} ${1}-sim"
faildirs="${faildirs} ${1}-sim($2)"
failed=1
echo
fi
@@ -55,25 +55,29 @@ fi
cd "unit_tests"
# run all test except single one is specified
if [ ! -z $3 ]; then
iteration=$3
fi
if [ ! -z $2 ]; then
$numberofruns = $2
numberofruns=$2
fi
if [ -z $1 ]; then
for i in *
do
if [ -d $i -a -f $i/test.act ]; then
while [ $failed = 0 ] && [ $iteration < $numberofruns ]
while [ $iteration -lt $numberofruns ]
do
run_test $iteration
iteration=$iteration+1
done
fi
done
else
while [ $failed = 0 ] && [ $iteration < $numberofruns ]
while [ $iteration -lt $numberofruns ]
do
run_test $1 $iteration
iteration=$((iteration+1))
done
fi

View File

@@ -0,0 +1,268 @@
random_seed 99
initialize
load-scm "helper.scm"
random
set GND 0
set Vdd 1
set Reset 1
mode reset
cycle
status U
watchall
system "echo '[] Set Reset 1'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.a 0
set e.out.v 0
set Reset 1
cycle
status X
system "echo '[] Set Reset 0'"
set Reset 0
cycle
status X
system "echo '[] Neuron 5 spikes'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 1
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 5
assert e.in[5].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.a 1
set e.out.v 1
cycle
assert e.in[5].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 1 spikes'"
set e.in[0].r 0
set e.in[1].r 1
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 1
assert e.in[1].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.v 1
set e.out.a 1
cycle
assert e.in[1].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 5 spikes'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 1
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 5
assert e.in[5].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.a 1
set e.out.v 1
cycle
assert e.in[5].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 1 spikes'"
set e.in[0].r 0
set e.in[1].r 1
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 1
assert e.in[1].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.v 1
set e.out.a 1
cycle
assert e.in[1].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 5 spikes'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 1
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 5
assert e.in[5].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.a 1
set e.out.v 1
cycle
assert e.in[5].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 1 spikes'"
set e.in[0].r 0
set e.in[1].r 1
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 1
assert e.in[1].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.v 1
set e.out.a 1
cycle
assert e.in[1].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 6 spikes'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 1
cycle
assert-qdi-channel-valid "e.out" 3 6
assert e.in[6].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.a 1
set e.out.v 1
cycle
assert e.in[6].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 1 spikes'"
set e.in[0].r 0
set e.in[1].r 1
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 1
assert e.in[1].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.v 1
set e.out.a 1
cycle
assert e.in[1].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
/*************************************************************************
*
* This file is part of ACT dataflow neuro library.
* It's the testing facility for cell_lib_std.act
*
* Copyright (c) 2022 University of Groningen - Ole Richter
* Copyright (c) 2022 University of Groningen - Hugh Greatorex
* Copyright (c) 2022 University of Groningen - Michele Mastella
* Copyright (c) 2022 University of Groningen - Madison Cotteret
*
* This source describes Open Hardware and is licensed under the CERN-OHL-W v2 or later
*
* You may redistribute and modify this documentation and make products
* using it under the terms of the CERN-OHL-W v2 (https:/cern.ch/cern-ohl).
* This documentation is distributed WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY
* AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN-OHL-W v2
* for applicable conditions.
*
* Source location: https://git.web.rug.nl/bics/actlib_dataflow_neuro
*
* As per CERN-OHL-W v2 section 4.1, should You produce hardware based on
* these sources, You must maintain the Source Location visible in its
* documentation.
*
**************************************************************************
*/
import "../../dataflow_neuro/coders.act";
import globals;
import std::data;
open std::data;
open tmpl::dataflow_neuro;
defproc encoder1d_simple_test(a1of1 in[7]; avMx1of2<3> out){
power supply;
supply.vss = GND;
supply.vdd = Vdd;
bool _reset_B;
prs {
Reset => _reset_B-
}
encoder1d_simple<3,7> e(.in = in, .supply = supply, .reset_B = _reset_B);
fifo<3, 5> fifo_post(.in = e.out, .out = out, .supply = supply, .reset_B = _reset_B);
}
encoder1d_simple_test e;

View File

@@ -0,0 +1,257 @@
watchall
system "echo '[] Set Reset 1'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.a 0
set e.out.v 0
set Reset 1
cycle
status X
system "echo '[] Set Reset 0'"
set Reset 0
cycle
status X
system "echo '[] Neuron 5 spikes'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 1
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 5
assert e.in[5].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.a 1
set e.out.v 1
cycle
assert e.in[5].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 1 spikes'"
set e.in[0].r 0
set e.in[1].r 1
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 1
assert e.in[1].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.v 1
set e.out.a 1
cycle
assert e.in[1].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 5 spikes'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 1
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 5
assert e.in[5].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.a 1
set e.out.v 1
cycle
assert e.in[5].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 1 spikes'"
set e.in[0].r 0
set e.in[1].r 1
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 1
assert e.in[1].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.v 1
set e.out.a 1
cycle
assert e.in[1].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 5 spikes'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 1
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 5
assert e.in[5].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.a 1
set e.out.v 1
cycle
assert e.in[5].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 1 spikes'"
set e.in[0].r 0
set e.in[1].r 1
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 1
assert e.in[1].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.v 1
set e.out.a 1
cycle
assert e.in[1].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 6 spikes'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 1
cycle
assert-qdi-channel-valid "e.out" 3 6
assert e.in[6].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.a 1
set e.out.v 1
cycle
assert e.in[6].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0
system "echo '[] Neuron 1 spikes'"
set e.in[0].r 0
set e.in[1].r 1
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
cycle
assert-qdi-channel-valid "e.out" 3 1
assert e.in[1].a 1
system "echo '[] remove data and give ack'"
set e.in[0].r 0
set e.in[1].r 0
set e.in[2].r 0
set e.in[3].r 0
set e.in[4].r 0
set e.in[5].r 0
set e.in[6].r 0
set e.out.v 1
set e.out.a 1
cycle
assert e.in[1].a 0
assert-qdi-channel-neutral "e.out" 3
set e.out.a 0
set e.out.v 0

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,173 @@
/*************************************************************************
*
* This file is part of ACT dataflow neuro library.
* It's the testing facility for cell_lib_std.act
*
* Copyright (c) 2022 University of Groningen - Ole Richter
* Copyright (c) 2022 University of Groningen - Hugh Greatorex
* Copyright (c) 2022 University of Groningen - Michele Mastella
* Copyright (c) 2022 University of Groningen - Madison Cotteret
*
* This source describes Open Hardware and is licensed under the CERN-OHL-W v2 or later
*
* You may redistribute and modify this documentation and make products
* using it under the terms of the CERN-OHL-W v2 (https:/cern.ch/cern-ohl).
* This documentation is distributed WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY
* AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN-OHL-W v2
* for applicable conditions.
*
* Source location: https://git.web.rug.nl/bics/actlib_dataflow_neuro
*
* As per CERN-OHL-W v2 section 4.1, should You produce hardware based on
* these sources, You must maintain the Source Location visible in its
* documentation.
*
**************************************************************************
*/
import "../../dataflow_neuro/coders.act";
import "../../dataflow_neuro/primitives.act";
import "../../dataflow_neuro/chips.act";
import globals;
import std::data;
open std::data;
open tmpl::dataflow_neuro;
pint N_IN = 32;
pint N_NRN_X = 15;
pint N_NRN_Y = 6;
pint NC_NRN_X = 4;
pint NC_NRN_Y = 3;
pint N_SYN_X = 15;
pint N_SYN_Y = 348;
pint NC_SYN_X = 6;
pint NC_SYN_Y = 9;
pint N_SYN_DLY_CFG = 4;
pint N_BD_DLY_CFG = 4;
pint N_BD_DLY_CFG2 = 2;
pint N_NRN_MON_X = N_NRN_X*2; // [mon,kill]*N
pint N_NRN_MON_Y = N_NRN_Y; // [mon]*N
pint N_SYN_MON_X = N_SYN_X*4; // [mon, dev_mon, set, reset]*N
pint N_SYN_MON_Y = N_SYN_Y; // [mon]*N
pint N_MON_AMZO_PER_SYN = 5;
pint N_MON_AMZO_PER_NRN = 7;
pint N_FLAGS_PER_SYN = 4; // Syn: Must be at least 3 (since those ones have special safety)
pint N_FLAGS_PER_NRN = 9; // and leq than the number of bits in a reg, since have presumed only needs one.
pint N_BUFFERS = 3;
pint N_LINE_PD_DLY = 3;
pint REG_NCA = 6;
pint REG_M = 1<<REG_NCA;
pint REG_NCW = 23;
defproc chip_texel_dualcore (bd<N_IN> in, out;
Mx1of2<REG_NCW> c1_reg_data[REG_M];
a1of1 c1_synapses[N_SYN_X * N_SYN_Y];
a1of1 c1_neurons[N_NRN_X * N_NRN_Y];
bool! c1_dec_req_x[N_SYN_X], c1_dec_req_y[N_SYN_Y];
bool? c1_dec_ackB[N_SYN_X];
a1of1 c1_syn_pu[N_SYN_X];
a1of1 c1_enc_inx[N_NRN_X], c1_enc_iny[N_NRN_Y];
a1of1 c1_nrn_pd_x[N_NRN_X], c1_nrn_pd_y[N_NRN_Y];
bool! c1_nrn_mon_x[N_NRN_MON_X], c1_nrn_mon_y[N_NRN_MON_Y];
bool! c1_syn_mon_x[N_SYN_MON_X], c1_syn_mon_y[N_SYN_MON_Y];
bool? c1_syn_mon_AMZI[N_SYN_X * N_MON_AMZO_PER_SYN], c1_nrn_mon_AMZI[N_NRN_X * N_MON_AMZO_PER_NRN];
bool! c1_syn_mon_AMZO[N_MON_AMZO_PER_SYN], c1_nrn_mon_AMZO[N_MON_AMZO_PER_NRN];
bool! c1_syn_flags_EFO[N_FLAGS_PER_SYN], c1_nrn_flags_EFO[N_FLAGS_PER_NRN];
Mx1of2<REG_NCW> c2_reg_data[REG_M];
a1of1 c2_synapses[N_SYN_X * N_SYN_Y];
a1of1 c2_neurons[N_NRN_X * N_NRN_Y];
bool! c2_dec_req_x[N_SYN_X], c2_dec_req_y[N_SYN_Y];
bool? c2_dec_ackB[N_SYN_X];
a1of1 c2_syn_pu[N_SYN_X];
a1of1 c2_enc_inx[N_NRN_X], c2_enc_iny[N_NRN_Y];
a1of1 c2_nrn_pd_x[N_NRN_X], c2_nrn_pd_y[N_NRN_Y];
bool! c2_nrn_mon_x[N_NRN_MON_X], c2_nrn_mon_y[N_NRN_MON_Y];
bool! c2_syn_mon_x[N_SYN_MON_X], c2_syn_mon_y[N_SYN_MON_Y];
bool? c2_syn_mon_AMZI[N_SYN_X * N_MON_AMZO_PER_SYN], c2_nrn_mon_AMZI[N_NRN_X * N_MON_AMZO_PER_NRN];
bool! c2_syn_mon_AMZO[N_MON_AMZO_PER_SYN], c2_nrn_mon_AMZO[N_MON_AMZO_PER_NRN];
bool! c2_syn_flags_EFO[N_FLAGS_PER_SYN], c2_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){
bool _reset_B;
prs {
Reset => _reset_B-
}
power supply;
supply.vdd = Vdd;
supply.vss = GND;
texel_dualcore<N_IN,
N_NRN_X, N_NRN_Y, N_SYN_X, N_SYN_Y,
NC_NRN_X, NC_NRN_Y, NC_SYN_X, NC_SYN_Y,
N_SYN_DLY_CFG,
N_NRN_MON_X, N_NRN_MON_Y, N_SYN_MON_X, N_SYN_MON_Y,
N_MON_AMZO_PER_SYN, N_MON_AMZO_PER_NRN,
N_FLAGS_PER_SYN, N_FLAGS_PER_NRN,
N_BUFFERS,
N_LINE_PD_DLY,
N_BD_DLY_CFG, N_BD_DLY_CFG2,
REG_NCA, REG_NCW, REG_M> c(.in = in, .out = out,
.c1_reg_data = c1_reg_data, .c1_dec_req_x = c1_dec_req_x, .c1_dec_req_y = c1_dec_req_y, .c1_dec_ackB = c1_dec_ackB, .c1_syn_pu = c1_syn_pu, .c1_enc_inx = c1_enc_inx, .c1_enc_iny = c1_enc_iny, .c1_nrn_pd_x = c1_nrn_pd_x, .c1_nrn_pd_y = c1_nrn_pd_y, .c1_nrn_mon_x = c1_nrn_mon_x, .c1_nrn_mon_y = c1_nrn_mon_y, .c1_syn_mon_x = c1_syn_mon_x, .c1_syn_mon_y = c1_syn_mon_y, .c1_syn_mon_AMZI = c1_syn_mon_AMZI, .c1_nrn_mon_AMZI = c1_nrn_mon_AMZI, .c1_syn_mon_AMZO = c1_syn_mon_AMZO, .c1_nrn_mon_AMZO = c1_nrn_mon_AMZO, .c1_syn_flags_EFO = c1_syn_flags_EFO, .c1_nrn_flags_EFO = c1_nrn_flags_EFO, .c2_reg_data = c2_reg_data, .c2_dec_req_x = c2_dec_req_x, .c2_dec_req_y = c2_dec_req_y, .c2_dec_ackB = c2_dec_ackB, .c2_syn_pu = c2_syn_pu, .c2_enc_inx = c2_enc_inx, .c2_enc_iny = c2_enc_iny, .c2_nrn_pd_x = c2_nrn_pd_x, .c2_nrn_pd_y = c2_nrn_pd_y, .c2_nrn_mon_x = c2_nrn_mon_x, .c2_nrn_mon_y = c2_nrn_mon_y, .c2_syn_mon_x = c2_syn_mon_x, .c2_syn_mon_y = c2_syn_mon_y, .c2_syn_mon_AMZI = c2_syn_mon_AMZI, .c2_nrn_mon_AMZI = c2_nrn_mon_AMZI, .c2_syn_mon_AMZO = c2_syn_mon_AMZO, .c2_nrn_mon_AMZO = c2_nrn_mon_AMZO, .c2_syn_flags_EFO = c2_syn_flags_EFO, .c2_nrn_flags_EFO = c2_nrn_flags_EFO, .bd_dly_cfg = bd_dly_cfg, .bd_dly_cfg2 = bd_dly_cfg2,
.loopback_en = loopback_en,
.reset_B = _reset_B, .reset_reg_B = _reset_B,
.supply = supply);
decoder_2d_synapse_hs<N_SYN_X, N_SYN_Y> c1_syn_grid(
.synapses = c1_synapses,
.in_req_x = c1_dec_req_x, .in_req_y = c1_dec_req_y,
.to_pu = c1_syn_pu,
.out_ackB_decoder = c1_dec_ackB,
.supply = supply);
nrn_hs_2d_array<N_NRN_X,N_NRN_Y> c1_nrn_grid(.in = c1_neurons,
.outx = c1_enc_inx, .outy = c1_enc_iny,
.to_pd_x = c1_nrn_pd_x, .to_pd_y = c1_nrn_pd_y,
.supply = supply, .reset_B = _reset_B);
decoder_2d_synapse_hs<N_SYN_X, N_SYN_Y> c2_syn_grid(
.synapses = c2_synapses,
.in_req_x = c2_dec_req_x, .in_req_y = c2_dec_req_y,
.to_pu = c2_syn_pu,
.out_ackB_decoder = c2_dec_ackB,
.supply = supply);
nrn_hs_2d_array<N_NRN_X,N_NRN_Y> c2_nrn_grid(.in = c2_neurons,
.outx = c2_enc_inx, .outy = c2_enc_iny,
.to_pd_x = c2_nrn_pd_x, .to_pd_y = c2_nrn_pd_y,
.supply = supply, .reset_B = _reset_B);
}
// fifo_decoder_neurons_encoder_fifo e;
chip_texel_dualcore c;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
initialize
load-scm "helper.scm"
random
set GND 0
set Vdd 1
set Reset 1
mode reset
cycle
status U
# watchall
set c.bd_dly_cfg[0] 1
set c.bd_dly_cfg[1] 1
set c.bd_dly_cfg[2] 1
set c.bd_dly_cfg[3] 1
set c.bd_dly_cfg2[0] 1
set c.bd_dly_cfg2[1] 1
set-bd-channel-neutral "c.in" 32
set c.out.a 0
set c.loopback_en 1
# set c.loopback_en 0
# set R
cycle

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,149 @@
/*************************************************************************
*
* This file is part of ACT dataflow neuro library.
* It's the testing facility for cell_lib_std.act
*
* Copyright (c) 2022 University of Groningen - Ole Richter
* Copyright (c) 2022 University of Groningen - Hugh Greatorex
* Copyright (c) 2022 University of Groningen - Michele Mastella
* Copyright (c) 2022 University of Groningen - Madison Cotteret
*
* This source describes Open Hardware and is licensed under the CERN-OHL-W v2 or later
*
* You may redistribute and modify this documentation and make products
* using it under the terms of the CERN-OHL-W v2 (https:/cern.ch/cern-ohl).
* This documentation is distributed WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY
* AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN-OHL-W v2
* for applicable conditions.
*
* Source location: https://git.web.rug.nl/bics/actlib_dataflow_neuro
*
* As per CERN-OHL-W v2 section 4.1, should You produce hardware based on
* these sources, You must maintain the Source Location visible in its
* documentation.
*
**************************************************************************
*/
import "../../dataflow_neuro/coders.act";
import "../../dataflow_neuro/primitives.act";
import "../../dataflow_neuro/chips.act";
import globals;
import std::data;
open std::data;
open tmpl::dataflow_neuro;
pint N_IN = 32;
pint N_NRN_X = 15;
pint N_NRN_Y = 6;
pint NC_NRN_X = 4;
pint NC_NRN_Y = 3;
pint N_SYN_X = 15;
pint N_SYN_Y = 348;
pint NC_SYN_X = 6;
pint NC_SYN_Y = 9;
pint N_SYN_DLY_CFG = 4;
pint N_BD_DLY_CFG = 4;
pint N_BD_DLY_CFG2 = 2;
pint N_NRN_MON_X = N_NRN_X*2; // [mon,kill]*N
pint N_NRN_MON_Y = N_NRN_Y; // [mon]*N
pint N_SYN_MON_X = N_SYN_X*4; // [mon, dev_mon, set, reset]*N
pint N_SYN_MON_Y = N_SYN_Y; // [mon]*N
pint N_MON_AMZO_PER_SYN = 5;
pint N_MON_AMZO_PER_NRN = 7;
pint N_FLAGS_PER_SYN = 4; // Syn: Must be at least 3 (since those ones have special safety)
pint N_FLAGS_PER_NRN = 9; // and leq than the number of bits in a reg, since have presumed only needs one.
pint N_BUFFERS = 3;
pint N_LINE_PD_DLY = 3;
pint REG_NCA = 6;
pint REG_M = 1<<REG_NCA;
pint REG_NCW = 23;
defproc chip_texel_dualcore_innovus (bd<N_IN> in, out;
Mx1of2<REG_NCW> c1_reg_data[REG_M];
// a1of1 c1_synapses[N_SYN_X * N_SYN_Y];
// a1of1 c1_neurons[N_NRN_X * N_NRN_Y];
bool! c1_dec_req_x[N_SYN_X], c1_dec_req_y[N_SYN_Y];
bool? c1_dec_ackB[N_SYN_X];
a1of1 c1_syn_pu[N_SYN_X];
a1of1 c1_enc_inx[N_NRN_X], c1_enc_iny[N_NRN_Y];
a1of1 c1_nrn_pd_x[N_NRN_X], c1_nrn_pd_y[N_NRN_Y];
bool! c1_nrn_mon_x[N_NRN_MON_X], c1_nrn_mon_y[N_NRN_MON_Y];
bool! c1_syn_mon_x[N_SYN_MON_X], c1_syn_mon_y[N_SYN_MON_Y];
bool? c1_syn_mon_AMZI[N_SYN_X * N_MON_AMZO_PER_SYN], c1_nrn_mon_AMZI[N_NRN_X * N_MON_AMZO_PER_NRN];
bool! c1_syn_mon_AMZO[N_MON_AMZO_PER_SYN], c1_nrn_mon_AMZO[N_MON_AMZO_PER_NRN];
bool! c1_syn_flags_EFO[N_FLAGS_PER_SYN], c1_nrn_flags_EFO[N_FLAGS_PER_NRN];
Mx1of2<REG_NCW> c2_reg_data[REG_M];
// a1of1 c2_synapses[N_SYN_X * N_SYN_Y];
// a1of1 c2_neurons[N_NRN_X * N_NRN_Y];
bool! c2_dec_req_x[N_SYN_X], c2_dec_req_y[N_SYN_Y];
bool? c2_dec_ackB[N_SYN_X];
a1of1 c2_syn_pu[N_SYN_X];
a1of1 c2_enc_inx[N_NRN_X], c2_enc_iny[N_NRN_Y];
a1of1 c2_nrn_pd_x[N_NRN_X], c2_nrn_pd_y[N_NRN_Y];
bool! c2_nrn_mon_x[N_NRN_MON_X], c2_nrn_mon_y[N_NRN_MON_Y];
bool! c2_syn_mon_x[N_SYN_MON_X], c2_syn_mon_y[N_SYN_MON_Y];
bool? c2_syn_mon_AMZI[N_SYN_X * N_MON_AMZO_PER_SYN], c2_nrn_mon_AMZI[N_NRN_X * N_MON_AMZO_PER_NRN];
bool! c2_syn_mon_AMZO[N_MON_AMZO_PER_SYN], c2_nrn_mon_AMZO[N_MON_AMZO_PER_NRN];
bool! c2_syn_flags_EFO[N_FLAGS_PER_SYN], c2_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;
bool? reset_B, reset_reg_B
){
// bool _reset_B;
// prs {
// Reset => _reset_B-
// }
power supply;
supply.vdd = Vdd;
supply.vss = GND;
texel_dualcore<N_IN,
N_NRN_X, N_NRN_Y, N_SYN_X, N_SYN_Y,
NC_NRN_X, NC_NRN_Y, NC_SYN_X, NC_SYN_Y,
N_SYN_DLY_CFG,
N_NRN_MON_X, N_NRN_MON_Y, N_SYN_MON_X, N_SYN_MON_Y,
N_MON_AMZO_PER_SYN, N_MON_AMZO_PER_NRN,
N_FLAGS_PER_SYN, N_FLAGS_PER_NRN,
N_BUFFERS,
N_LINE_PD_DLY,
N_BD_DLY_CFG, N_BD_DLY_CFG2,
REG_NCA, REG_NCW, REG_M> c(.in = in, .out = out,
.c1_reg_data = c1_reg_data, .c1_dec_req_x = c1_dec_req_x, .c1_dec_req_y = c1_dec_req_y, .c1_dec_ackB = c1_dec_ackB, .c1_syn_pu = c1_syn_pu, .c1_enc_inx = c1_enc_inx, .c1_enc_iny = c1_enc_iny, .c1_nrn_pd_x = c1_nrn_pd_x, .c1_nrn_pd_y = c1_nrn_pd_y, .c1_nrn_mon_x = c1_nrn_mon_x, .c1_nrn_mon_y = c1_nrn_mon_y, .c1_syn_mon_x = c1_syn_mon_x, .c1_syn_mon_y = c1_syn_mon_y, .c1_syn_mon_AMZI = c1_syn_mon_AMZI, .c1_nrn_mon_AMZI = c1_nrn_mon_AMZI, .c1_syn_mon_AMZO = c1_syn_mon_AMZO, .c1_nrn_mon_AMZO = c1_nrn_mon_AMZO, .c1_syn_flags_EFO = c1_syn_flags_EFO, .c1_nrn_flags_EFO = c1_nrn_flags_EFO, .c2_reg_data = c2_reg_data, .c2_dec_req_x = c2_dec_req_x, .c2_dec_req_y = c2_dec_req_y, .c2_dec_ackB = c2_dec_ackB, .c2_syn_pu = c2_syn_pu, .c2_enc_inx = c2_enc_inx, .c2_enc_iny = c2_enc_iny, .c2_nrn_pd_x = c2_nrn_pd_x, .c2_nrn_pd_y = c2_nrn_pd_y, .c2_nrn_mon_x = c2_nrn_mon_x, .c2_nrn_mon_y = c2_nrn_mon_y, .c2_syn_mon_x = c2_syn_mon_x, .c2_syn_mon_y = c2_syn_mon_y, .c2_syn_mon_AMZI = c2_syn_mon_AMZI, .c2_nrn_mon_AMZI = c2_nrn_mon_AMZI, .c2_syn_mon_AMZO = c2_syn_mon_AMZO, .c2_nrn_mon_AMZO = c2_nrn_mon_AMZO, .c2_syn_flags_EFO = c2_syn_flags_EFO, .c2_nrn_flags_EFO = c2_nrn_flags_EFO, .bd_dly_cfg = bd_dly_cfg, .bd_dly_cfg2 = bd_dly_cfg2,
.loopback_en = loopback_en, .supply = supply, .reset_B = reset_B, .reset_reg_B = reset_reg_B);
}
// fifo_decoder_neurons_encoder_fifo e;
chip_texel_dualcore_innovus c;

View File

@@ -0,0 +1,19 @@
# watchall
set c.bd_dly_cfg[0] 1
set c.bd_dly_cfg[1] 1
set c.bd_dly_cfg[2] 1
set c.bd_dly_cfg[3] 1
set c.bd_dly_cfg2[0] 1
set c.bd_dly_cfg2[1] 1
set-bd-channel-neutral "c.in" 32
set c.out.a 0
set c.loopback_en 1
# set c.loopback_en 0
# set R
cycle

View File

@@ -0,0 +1,391 @@
random_seed 0
initialize
load-scm "helper.scm"
random
set GND 0
set Vdd 1
set Reset 1
mode reset
cycle
status U
watchall
set c.bd_dly_cfg[0] 1
set c.bd_dly_cfg[1] 1
set c.bd_dly_cfg[2] 1
set c.bd_dly_cfg[3] 1
set c.bd_dly_cfg2[0] 1
set c.bd_dly_cfg2[1] 1
set-bd-channel-neutral "c.in" 14
set c.out.a 0
# set c.loopback_en 1
set c.loopback_en 0
set Reset 1
cycle
mode run
status X
system "echo '[] Set reset 0'"
status X
set Reset 0
cycle
# Reading address 0
set-bd-data-valid "c.in" 14 8192
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Should first get loopback
# Receiving output 0 from register 0
# assert-bd-channel-valid "c.out" 14 8192
# set c.out.a 1
# cycle
# assert-bd-channel-neutral "c.out" 14
# set c.out.a 0
# cycle
# Expect register read packet to arrive
# Receiving output 0 from register 0
assert-bd-channel-valid "c.out" 14 0
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# Disable loopback cus it's annoying
set c.loopback_en 0
cycle
# Writing 17 to address 1
set-bd-data-valid "c.in" 14 12561
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Writing 255 to address 5
set-bd-data-valid "c.in" 14 16373
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Reading address 1
system "echo '[] Reading reg 1'"
set-bd-data-valid "c.in" 14 8193
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Reading address 5
system "echo '[] Reading reg 5'"
set-bd-data-valid "c.in" 14 8197
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output 17 from register 1
system "echo '[] Receiving 17'"
assert-bd-channel-valid "c.out" 14 273
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
system "echo '[] Receiving 4085'"
# Receiving output 255 from register 5
assert-bd-channel-valid "c.out" 14 4085
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# SEND PACKET TO CHANGE TO SYNAPSE HANDSHAKING
# Writing 255 to address 0
set-bd-data-valid "c.in" 14 16368
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# SPIKES
# Sending spike to synapse [0,1]
system "echo '[] Spike'"
set-bd-data-valid "c.in" 14 2
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output spike [0,1]
assert-bd-channel-valid "c.out" 14 2
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# Sending spike to synapse [1,3]
system "echo '[] Spike'"
set-bd-data-valid "c.in" 14 7
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output spike [1,3]
assert-bd-channel-valid "c.out" 14 7
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# Sending spike to synapse [1,2]
system "echo '[] Spike'"
set-bd-data-valid "c.in" 14 5
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output spike [1,2]
assert-bd-channel-valid "c.out" 14 5
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# Sending spike to synapse [1,3]
system "echo '[] Spike'"
set-bd-data-valid "c.in" 14 7
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output spike [1,3]
assert-bd-channel-valid "c.out" 14 7
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# Sending spike to synapse [0,2]
set-bd-data-valid "c.in" 14 4
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output spike [0,2]
assert-bd-channel-valid "c.out" 14 4
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# Sending spike to synapse [0,3]
set-bd-data-valid "c.in" 14 6
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output spike [0,3]
assert-bd-channel-valid "c.out" 14 6
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# Sending spike to synapse [0,1]
set-bd-data-valid "c.in" 14 2
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output spike [0,1]
assert-bd-channel-valid "c.out" 14 2
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# Sending spike to synapse [0,0]
set-bd-data-valid "c.in" 14 0
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output spike [0,0]
assert-bd-channel-valid "c.out" 14 0
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# Sending spike to synapse [0,0]
set-bd-data-valid "c.in" 14 0
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output spike [0,0]
assert-bd-channel-valid "c.out" 14 0
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# Sending spike to synapse [0,3]
set-bd-data-valid "c.in" 14 6
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# Receiving output spike [0,3]
assert-bd-channel-valid "c.out" 14 6
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -69,10 +69,18 @@ defproc chip_texel_test (bd<14> in; bd<14> out; Mx1of2<8> reg_data[16];
pint N_BD_DLY_CFG = 4;
pint N_BD_DLY_CFG2 = 2;
pint N_NRN_MON_X = 2;
pint N_NRN_MON_Y = 4;
pint N_SYN_MON_X = 2;
pint N_SYN_MON_Y = 4;
pint N_NRN_MON_X = N_NRN_X*2; // [mon,kill]*N
pint N_NRN_MON_Y = N_NRN_Y; // [mon]*N
// pint N_SYN_MON_X = 2;
// pint N_SYN_MON_Y = 4;
pint N_SYN_MON_X = N_SYN_X*4; // [mon, dev_mon, set, reset]*N
pint N_SYN_MON_Y = N_SYN_Y; // [mon]*N
pint N_MON_AMZO_PER_SYN = 5;
pint N_MON_AMZO_PER_NRN = 7;
pint N_FLAGS_PER_SYN = 5; // Must be at least 3 (since those ones have special safety)
pint N_FLAGS_PER_NRN = 7; // And leq than the number of bits in a reg, since have presumed only needs one.
pint N_BUFFERS = 3;
@@ -87,6 +95,8 @@ defproc chip_texel_test (bd<14> in; bd<14> out; Mx1of2<8> reg_data[16];
NC_NRN_X, NC_NRN_Y, NC_SYN_X, NC_SYN_Y,
N_SYN_DLY_CFG,
N_NRN_MON_X, N_NRN_MON_Y, N_SYN_MON_X, N_SYN_MON_Y,
N_MON_AMZO_PER_SYN, N_MON_AMZO_PER_NRN,
N_FLAGS_PER_SYN, N_FLAGS_PER_NRN,
N_BUFFERS,
N_LINE_PD_DLY,
N_BD_DLY_CFG, N_BD_DLY_CFG2,

View File

@@ -11,7 +11,8 @@ set c.bd_dly_cfg2[1] 1
set-bd-channel-neutral "c.in" 14
set c.out.a 0
set c.loopback_en 1
# set c.loopback_en 1
set c.loopback_en 0
set Reset 1
cycle
@@ -37,12 +38,12 @@ assert c.in.a 0
# Should first get loopback
# Receiving output 0 from register 0
assert-bd-channel-valid "c.out" 14 8192
set c.out.a 1
cycle
assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
# assert-bd-channel-valid "c.out" 14 8192
# set c.out.a 1
# cycle
# assert-bd-channel-neutral "c.out" 14
# set c.out.a 0
# cycle
# Expect register read packet to arrive
@@ -86,6 +87,7 @@ cycle
assert c.in.a 0
# Reading address 1
system "echo '[] Reading reg 1'"
set-bd-data-valid "c.in" 14 8193
cycle
set c.in.r 1
@@ -100,6 +102,7 @@ assert c.in.a 0
# Reading address 5
system "echo '[] Reading reg 5'"
set-bd-data-valid "c.in" 14 8197
cycle
set c.in.r 1
@@ -114,6 +117,7 @@ assert c.in.a 0
# Receiving output 17 from register 1
system "echo '[] Receiving 17'"
assert-bd-channel-valid "c.out" 14 273
set c.out.a 1
cycle
@@ -121,6 +125,7 @@ assert-bd-channel-neutral "c.out" 14
set c.out.a 0
cycle
system "echo '[] Receiving 4085'"
# Receiving output 255 from register 5
assert-bd-channel-valid "c.out" 14 4085
set c.out.a 1
@@ -131,9 +136,18 @@ cycle
# SEND PACKET TO CHANGE TO SYNAPSE HANDSHAKING
# Writing 255 to address 0
set-bd-data-valid "c.in" 14 16368
cycle
set c.in.r 1
cycle
assert c.in.a 1
# Remove input
set-bd-channel-neutral "c.in" 14
cycle
assert c.in.a 0
# SPIKES
@@ -141,6 +155,7 @@ cycle
# Sending spike to synapse [0,1]
system "echo '[] Spike'"
set-bd-data-valid "c.in" 14 2
cycle
set c.in.r 1
@@ -163,6 +178,7 @@ set c.out.a 0
cycle
# Sending spike to synapse [1,3]
system "echo '[] Spike'"
set-bd-data-valid "c.in" 14 7
cycle
set c.in.r 1
@@ -185,6 +201,7 @@ set c.out.a 0
cycle
# Sending spike to synapse [1,2]
system "echo '[] Spike'"
set-bd-data-valid "c.in" 14 5
cycle
set c.in.r 1
@@ -207,6 +224,7 @@ set c.out.a 0
cycle
# Sending spike to synapse [1,3]
system "echo '[] Spike'"
set-bd-data-valid "c.in" 14 7
cycle
set c.in.r 1