diff --git a/dataflow_neuro/registers.act b/dataflow_neuro/registers.act new file mode 100644 index 0000000..b7808e3 --- /dev/null +++ b/dataflow_neuro/registers.act @@ -0,0 +1,113 @@ +/************************************************************************* + * + * This file is part of ACT dataflow neuro library + * + * Copyright (c) 2022 University of Groningen - Ole Richter + * Copyright (c) 2022 University of Groningen - Michele Mastella + * Copyright (c) 2022 University of Groningen - Hugh Greatorex + * 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/cell_lib_async.act"; +import "../../dataflow_neuro/cell_lib_std.act"; +import "../../dataflow_neuro/treegates.act"; +import "../../dataflow_neuro/primitives.act"; +import "../../dataflow_neuro/coders.act"; +// import tmpl::dataflow_neuro; +// import tmpl::dataflow_neuro; +import std::channel; +open std::channel; + +namespace tmpl { + namespace dataflow_neuro { +// Circuit for storing, reading and writing registers using AER +// The block has the parameters: +// log_nw -> log2(number of words), parameters you can store +// wl -> word length, length of each word +// N_dly_cfg -> the number of config bits in the ACK delay line +// The block has the pins: +// in -> input data, +// - the first bit is write/read_B +// - the next log_nw bits describe the location, +// - the last wl the word to write +// data -> the data saved in the flip flop, sized wl x nw +export template +defproc register_rw (avMx1of2<1+log_nw+wl> in, d1of data[2< val_input_X(.in = _in_v_temp,.out = in.v,.supply = supply); + in.v = _in_v_temp; + // Generation of the clock pulse + delayprog dly(.in = _in_v_temp, .s = _clock_temp, .supply = supply); + sigbuf_1output<4> val_input_X(.in = _clock_temp,.out = _clock,.supply = supply); + // Sending back to the ackowledge + delayprog dly(.in = _clock, .s = _in_a_temp, .supply = supply); + sigbuf_1output<4> val_input_X(.in = _in_a_temp,.out = in.a,.supply = supply); + //Reset Buffers + bool _reset_BX,_reset_BXX[_nw*w]; + BUF_X1 reset_buf(.a=reset_B, .y=_reset_BX,.vdd=supply.vdd,.vss=supply.vss); + sigbuf<_nw*wl> reset_bufarray(.in=_reset_BX, .out=_reset_BXX,.vdd=supply.vdd,.vss=supply.vss); + // Creating the different flip flop arrays + bool _nw = 2< atree[_nw]; + AND2_X1 and_encoder[_nw] + sigbuf clock_buffer; + DFQ_R_X1 ff[_nw*wl]; + (k:_nw:atree_x[k].supply = supply;) + (_word_idx:_nw: + // Decoding the bit pattern to understand which word we are looking at + (pin_idx:log_nw: + bitval = (_word_idx & ( 1 << pin_idx )) >> pin_idx; // Get binary digit of integer i, column j + [bitval = 1 -> + atree[_word_idx].in[pin_idx] = in.d.d[pin_idx+1].t; + [] bitval = 0 -> + atree[_word_idx].in[pin_idx] = in.d.d[pin_idx+1].f; + []bitval >= 2 -> {false : "fuck"}; + ] + ) + // Activating the fake clock for the right word + atree_x[_word_idx].out = _out_encoder[_word_idx]; + and_encoder[_word_idx].a = _out_encoder[_word_idx]; + and_encoder[_word_idx].b = _clock + and_encoder[_word_idx].y = _clock_word_temp[_word_idx]; + and_encoder[_word_idx].vdd = supply.vdd; + and_encoder[_word_idx].vss = supply.vss; + clock_buffer[_word_idx].in = _clock_word_temp[_word_idx]; + clock_buffer[_word_idx].out = _clock_word[_word_idx]; + clock_buffer[_word_idx].vdd = supply.vdd; + clock_buffer[_word_idx].vss = supply.vss; + // Describing all the FF and their connection + (_bit_idx:wl: + ff[_bit_idx*(1+_word_idx)].clk = _clock_word[_word_idx]; + ff[_bit_idx*(1+_word_idx)].d = in.d.d[_bit_idx+1+log_nw]; + ff[_bit_idx*(1+_word_idx)].q = data[_word_idx].d[_bit_idx]; + ff[_bit_idx*(1+_word_idx)].reset_B = reset_BXX[_bit_idx*(1+_word_idx)]; + ff[_bit_idx*(1+_word_idx)].vdd = supply.vdd; + ff[_bit_idx*(1+_word_idx)].vss = supply.vss; + ) + ) +} +}} +