def MultShifter(shifted, data, direction, num): WIDTH = len(data) MAX_SHIFT = 2**len(num) line_in_bits = [Signal(bool(0)) for k in range(WIDTH)] @always_comb def line_in_conn(): for k in range(WIDTH): line_in_bits[k].next = data[k] line_in_origin = ConcatSignal(*reversed(line_in_bits)) line_in_reversed = ConcatSignal(*line_in_bits) line_in = Signal(modbv(0)[WIDTH:]) @always_comb def line_in_mux(): if direction == LEFT: line_in.next = line_in_origin else: line_in.next = line_in_reversed line_out = Signal(modbv(0)[WIDTH:]) line_out_bits = [Signal(bool(0)) for k in range(WIDTH)] @always_comb def line_out_conn(): for k in range(WIDTH): line_out_bits[k].next = line_out[k] line_out_origin = ConcatSignal(*reversed(line_out_bits)) line_out_reversed = ConcatSignal(*line_out_bits) @always_comb def shifted_mux(): if direction == LEFT: shifted.next = line_out_origin else: shifted.next = line_out_reversed m = Signal(modbv(0)[WIDTH:]) @always_comb def num_to_pow(): temp = modbv(0)[WIDTH:] for k in range(WIDTH): if k == num: temp[k] = 1 m.next = temp @always_comb def shift(): if num > WIDTH - 1: line_out.next = 0 else: line_out.next = line_in * m return instances()
def convert(): clk = Signal(bool(False)) reset = ResetSignal(bool(False), bool(True), async=True) en = Signal(bool(True)) count = [Signal(intbv(0)[4:]) for i in range(6)] count_vec = ConcatSignal(*reversed(count)) pm = Signal(bool(False)) LED = [Signal(intbv(0)[7:]) for i in range(6)] LED_vec = ConcatSignal(*reversed(LED)) toVerilog.timescale = "500ms/1ms" toVerilog(clock, clk, reset, en, count_vec, pm, LED_vec) toVHDL(clock, clk, reset, en, count_vec, pm, LED_vec)
def variable_width_and(output, input_signals): ''' This block will AND all of the input signals onto the output. The `output` arg should be a boolean signal. The `input_signals` arg should be a list of boolean signals. ''' if len(input_signals) < 1: raise ValueError('input_signals must contain at least one signal') if output._type != bool: raise ValueError('output must be a boolean signal') for input_signal in input_signals: if input_signal._type != bool: raise ValueError('All input_signals must be boolean signals') return_objects = [] n_signals = len(input_signals) if n_signals == 1: # Only one input signal return_objects.append(signal_assigner(input_signals[0], output)) else: # Combine all of the input signals into one signal combined_input = ConcatSignal(*reversed(input_signals)) return_objects.append(reducing_and(output, combined_input)) return return_objects
def UIntToFloat( float_output, uint_input, exponent_width, fraction_width, exponent_bias ): # Calculating unbiased and biased exponent. unbiased_exponent = Signal(modbv(0)[exponent_width:]) biased_exponent = Signal(modbv(0)[exponent_width:]) nz_flag = Signal(bool(0)) unbiased_exponent_calculator = PriorityEncoder( unbiased_exponent, nz_flag, uint_input) @always_comb def biased_exponent_calculator(): biased_exponent.next = unbiased_exponent + exponent_bias # Calculating fraction part. fraction = Signal(modbv(0)[fraction_width:]) fraction_calculator = UIntToFraction( fraction, uint_input, unbiased_exponent) float_sig = ConcatSignal(bool(0), biased_exponent, fraction) @always_comb def make_output(): if uint_input == 0: float_output.next = 0 else: float_output.next = float_sig return instances()
def gen(self): system = self.system bus = self.bus() insts = [] for field in self.fields: field_inst = field.gen(system) insts.append(field_inst) connect_inst = self.connect(bus, field) # connect_inst = field.port.connect(bus) insts.append(connect_inst) if not self.MULTI_ASSIGN: # This does not work in simulation, but the verilog looks decent if len(self.fields) > 1: rd_data_array = [] for field in self.fields: rd_data_array.append(field.port.RD_DATA) rd_data = ConcatSignal(*reversed(rd_data_array)) else: rd_data = self.fields[0].port.RD_DATA @always_comb def in_comb(): bus.RD_DATA.next = rd_data insts.append(in_comb) return insts
def IntToFloat( float_output, int_input, exponent_width, fraction_width, exponent_bias): INT_WIDTH = len(int_input) FLOAT_WIDTH = len(float_output) sign = Signal(bool(0)) sign_getter = SignGetter(sign, int_input) abs_int = Signal(modbv(0)[INT_WIDTH:]) abs_calculator = Abs(abs_int, int_input) abs_float = Signal(modbv(0)[(1+exponent_width+fraction_width):]) float_calculator = UIntToFloat( abs_float, abs_int, exponent_width, fraction_width, exponent_bias) signed_float = ConcatSignal(sign, abs_float(FLOAT_WIDTH-1, 0)) @always_comb def make_output(): float_output.next = signed_float return instances()
def keep_port_names(**ports): """ touch the top-level ports so they are persevered """ gens, width, catsig = [], 0, None # walk through all the ports for name, port in ports.items(): if isinstance(port, ( int, str, list, tuple, )): pass elif isinstance(port, SignalType): width += len(port) if catsig is None: catsig = port else: catsig = ConcatSignal(catsig, port) else: g = keep_port_names(**vars(port)) gens.append(g) if width > 0: monsig = Signal(intbv(0)[width:]) @always_comb def mon(): monsig.next = catsig gens.append(mon) return gens
def convert(target=toVerilog, directory="./ex-target"): """Convert design to Verilog or VHDL.""" embedding_dim = 3 leaky_val = 0.01 rate_val = 0.1 fix_min = -2**7 fix_max = -fix_min fix_res = 2**-8 fix_width = 1 + 7 + 8 # signals y = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) error = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) new_word_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_context_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] new_context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] for j in range(embedding_dim): new_word_emb[j].assign( new_word_embv((j + 1) * fix_width, j * fix_width)) new_context_emb[j].assign( new_context_embv((j + 1) * fix_width, j * fix_width)) y_actual = Signal(fixbv(1.0, min=fix_min, max=fix_max, res=fix_res)) word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] word_embv = ConcatSignal(*reversed(word_emb)) context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] context_embv = ConcatSignal(*reversed(context_emb)) # covert to HDL code target.directory = directory target(WordContextUpdated, y, error, new_word_embv, new_context_embv, y_actual, word_embv, context_embv, embedding_dim, leaky_val, rate_val, fix_min, fix_max, fix_res)
def gen(self): adc_data = ConcatSignal(self.sample_data_0, self.sample_data_1) enable_0 = Signal(False) enable_1 = Signal(False) enable_cnt = Signal(intbv(0, 0, self.chunk)) assert self.chunk % 2 == 0 half_chunk = self.chunk / 2 @always_comb def enable_comb(): enable_0.next = 0 enable_1.next = 0 if self.sample_enable: sel = enable_cnt < half_chunk enable_0.next = sel enable_1.next = not sel @always_seq(self.sample_clk.posedge, None) def enable_seq(): if not self.sample_enable: enable_cnt.next = 0 else: enable_cnt.next = 0 if enable_cnt != self.chunk - 1: enable_cnt.next = enable_cnt + 1 sampler_0 = MigSampler(sample_clk=self.sample_clk, sample_data=adc_data, sample_enable=enable_0, mig_port=self.mig_port_0, overflow=self.overflow_0, count=self.count, fifo_depth=self.fifo_depth, base=0, chunk=self.chunk, stride=2 * self.chunk, split=True) sampler_0_inst = sampler_0.gen() sampler_1 = MigSampler(sample_clk=self.sample_clk, sample_data=adc_data, sample_enable=enable_1, mig_port=self.mig_port_1, overflow=self.overflow_1, count=self.count, fifo_depth=self.fifo_depth, base=self.chunk, chunk=self.chunk, stride=2 * self.chunk, split=True) sampler_1_inst = sampler_1.gen() return instances()
def __init__(self, access=0, write=0, datamode=2, ctrlmode=0, dstaddr=0, data=0, srcaddr=0): """ PACKET FIELD | BITS | DESCRIPTION --------------|---------|---------- access | [0] | Indicates a valid transaction write | [1] | Indicates a write transaction datamode[1:0] | [3:2] | Datasize (00=8b,01=16b,10=32b,11=64b) ctrlmode[3:0] | [7:4] | Various special modes for the Epiphany chip dstaddr[31:0] | [39:8] | Address for write, read-request, or read-responses data[31:0] | [71:40] | Data for write transaction, data for read response srcaddr[31:0] | [103:72]| Return address for read-request, upper data for write Arguments: access: Indicates a valid transaction, initial value write: Indicates a write transaction, initial value datamode: Data size (0=8b, 1=16b, 2=32b, 3=64b), initial value ctrlmode: Various special modes for the Epiphany chip, initial value dstaddr: Address for write, read-request, or read-response, initial value data: Data for a write transaction, data for read response, initial value srcaddr: Return addres for read-request upper data for write, initial value """ # set the packet fields self.access = Signal(bool(access)) self.write = Signal(bool(write)) self.datamode = Signal(intbv(datamode)[2:]) self.ctrlmode = Signal(intbv(ctrlmode)[4:]) self.dstaddr = Signal(intbv(dstaddr)[32:]) self.data = Signal(intbv(data)[32:]) self.srcaddr = Signal(intbv(srcaddr)[32:]) # all the above a flattened into a signal bus self.bits = ConcatSignal(self.srcaddr, self.data, self.dstaddr, self.ctrlmode, self.datamode, self.write, self.access) # flow control ... self.wait = Signal(bool(0)) # some extra signals used for modeling and testing self.finished = Signal(bool(0))
def parallella_serdes( clock, # porcupine board breakout serial_tx_p, serial_tx_n, serial_rx_p, serial_rx_n, led, reset=None): """ """ assert len(led) == 8 nbanks = len(serial_tx_p) assert (len(serial_tx_p) == len(serial_tx_n) == len(serial_rx_p) == len(serial_rx_n)) glbl = Global(clock, reset) # signal interface to the prbs generate / check locked = [Signal(bool(0)) for _ in range(nbanks)] inject_error = [Signal(bool(0)) for _ in range(nbanks)] word_count = [Signal(intbv(0)[64:]) for _ in range(nbanks)] error_count = [Signal(intbv(0)[64:]) for _ in range(nbanks)] prbsi = [Signal(intbv(0)[1:]) for _ in range(nbanks)] prbso = [Signal(intbv(0)[1:]) for _ in range(nbanks)] # diff buffers for the diff signals obuf = output_diff_buffer(prbso, serial_tx_p, serial_tx_n) ibuf = input_diff_buffer(serial_rx_p, serial_rx_n, prbsi) insts = [] for bank in range(nbanks): gg = prbs_generate(glbl, prbso[bank], inject_error[bank], order=23) gc = prbs_check(glbl, prbsi[bank], locked[bank], word_count[bank], error_count[bank], order=23) for gg in ( gg, gc, ): insts.append(gg) locks = ConcatSignal(*reversed(locked)) @always_comb def led_assign(): led.next = concat("1010", locks[4:]) return ibuf, obuf, insts, led_assign
def convert(target=toVerilog, directory="./ex-target"): """Convert design to Verilog or VHDL.""" embedding_dim = 3 leaky_val = 0.01 fix_min = -2**7 fix_max = -fix_min fix_res = 2**-8 fix_width = 1 + 7 + 8 # signals y = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) y_dword_vec = Signal(intbv(0)[embedding_dim * fix_width:]) y_dcontext_vec = Signal(intbv(0)[embedding_dim * fix_width:]) y_dword_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] y_dcontext_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] for j in range(embedding_dim): y_dword_list[j].assign(y_dword_vec((j + 1) * fix_width, j * fix_width)) y_dcontext_list[j].assign( y_dcontext_vec((j + 1) * fix_width, j * fix_width)) word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] word_embv = ConcatSignal(*reversed(word_emb)) context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] context_embv = ConcatSignal(*reversed(context_emb)) # covert to HDL code target.directory = directory target(WordContextProduct, y, y_dword_vec, y_dcontext_vec, word_embv, context_embv, embedding_dim, leaky_val, fix_min, fix_max, fix_res)
def flatten(self, flat): """ """ nbits = self.nbits shadowbits = [col(nbits, 0) for row in self.mat for col in row] flats = ConcatSignal(*shadowbits) @always_comb def beh_assign(): flat.next = flats return beh_assign
def convert(target=toVerilog, directory="./ex-target"): """Convert design to Verilog or VHDL.""" dim = 3 fix_min = -2**7 fix_max = -fix_min fix_res = 2**-8 fix_width = 1 + 7 + 8 # signals y = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) y_da_vec = Signal(intbv(0)[dim * fix_width:]) y_db_vec = Signal(intbv(0)[dim * fix_width:]) y_da_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(dim) ] y_db_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(dim) ] for j in range(dim): y_da_list[j].assign(y_da_vec((j + 1) * fix_width, j * fix_width)) y_db_list[j].assign(y_db_vec((j + 1) * fix_width, j * fix_width)) a_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(dim) ] a_vec = ConcatSignal(*reversed(a_list)) b_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(dim) ] b_vec = ConcatSignal(*reversed(b_list)) # covert to HDL code target.directory = directory target(DotProduct, y, y_da_vec, y_db_vec, a_vec, b_vec, dim, fix_min, fix_max, fix_res)
def bitfield_connector(self): if self._reg_type in ('axi_read_write', 'axi_write_only'): instances = [] for bitfield_start in self._bitfield_starts: bitfield = getattr(self, self._bitfield_starts[bitfield_start]) instances.append( assign_bitfield_from_register(self.register, bitfield, bitfield_start)) return instances elif self._reg_type in ('axi_read_only'): if len(self._concat_list) == 1: # This is a hack to allow a concat signal to work in # all cases. An alternative would be to special case single # signals, but that doesn't work well with constants, which # themselves would require a special case, and some hackery to # have the constant read (and requiring initial_values to be # turned on). keep = Signal(True) keep.driven = True reg_signal = ConcatSignal(keep, self._concat_list[0]) else: reg_signal = ConcatSignal(*self._concat_list) @always_comb def assign_register(): self.register.next = reg_signal[self._register_width:] return assign_register
def combined_signal_assigner(input_signals, signal_out): ''' The `input_signals` argument should be a list of signals. This block combines these signals and uses them to drive signal_out. ''' n_input_signals = len(input_signals) if n_input_signals < 1: raise ValueError( 'combined_signal_assigner: input_signals should contain at least ' 'one signal.') if n_input_signals > 1: for n in range(1, n_input_signals): if len(input_signals[n]) != len(input_signals[0]): raise ValueError( 'combined_signal_assigner: All signals in the ' 'input_signals list should be the same bitwidth.') # Calculate the total bitwidth of the signals in input_signals signal_in_bitwidth = n_input_signals*len(input_signals[0]) signal_out_bitwidth = len(signal_out) if signal_in_bitwidth > signal_out_bitwidth: raise ValueError( 'combined_signal_assigner: The signal_out is not wide enough ' 'for all of the input_signals.') return_objects = [] if n_input_signals == 1: # Only one input_signal signal_in = input_signals[0] else: # Combine the input_signals onto a single signal signal_in = ConcatSignal(*reversed(input_signals)) # Drive the signal_out with the combined input_signals return_objects.append( signal_assigner( signal_in, signal_out, offset=0, convert_to_signed=False)) return return_objects
def PS2Keyboard( code, finish, kb_dat, kb_clk, rst ): States = enum('READ', 'FINISH') state = Signal(States.FINISH) # Eight Data bits and One Parity. bits = [Signal(bool(0)) for k in range(9)] code_reg = ConcatSignal(*bits) bit_counter = Signal(intbv(0, min=0, max=10)) @always_seq(kb_clk.posedge, reset=rst) def receiving(): if state == States.FINISH: if not kb_dat: # kb_dat=0, device starts a new transmission. state.next = States.READ finish.next = 0 else: # kb_dat=1, the stop bit. code.next = code_reg finish.next = 1 elif state == States.READ: # Shift Register. bits[0].next = kb_dat for k in range(1, 9): bits[k].next = bits[k-1] # End Shift Register. if bit_counter == 8: # Have got all the 8bits and parity. state.next = States.FINISH bit_counter.next = 0 else: bit_counter.next = bit_counter + 1 else: raise ValueError('Undefined state.') return instances()
def test(bus): freqs = [100E6, 133E6, 233E6] pin_array = [] pin_insts = [] for freq in freqs: pin = Clk(freq, False) pin_inst = pin.gen() pin_array.append(pin) pin_insts.append(pin_inst) pins = ConcatSignal(*pin_array) clk = bus.CLK_I rst = bus.RST_I rst_inst = rstgen(rst, 100 * nsec, clk) hc = HybridCounter(data_width=16, async_width=8) hc_inst = hc.gen(bus, pins) return pin_insts, rst_inst, hc_inst
def atlys_blinky_host(clock, reset, led, sw, pmod, uart_tx, uart_rx): """ This example is similar to the other examples in this directory but the LEDs are controlled externally via command packets sent from a host via the UART on the icestick. """ glbl = Global(clock, reset) ledreg = Signal(intbv(0)[8:]) # create the timer tick instance tick_inst = glbl_timer_ticks(glbl, include_seconds=True) # create the interfaces to the UART fbustx = FIFOBus(width=8, size=32) fbusrx = FIFOBus(width=8, size=32) # create the memmap (CSR) interface memmap = Barebone(glbl, data_width=32, address_width=32) # create the UART instance. cmd_tx = Signal(bool(0)) uart_inst = uartlite(glbl, fbustx, fbusrx, uart_rx, cmd_tx) # create the packet command instance cmd_inst = memmap_command_bridge(glbl, fbusrx, fbustx, memmap) @always_seq(clock.posedge, reset=reset) def beh_led_control(): memmap.done.next = not (memmap.write or memmap.read) if memmap.write: # and memmap.mem_addr == 0x20: ledreg.next = memmap.write_data @always_comb def beh_led_read(): if memmap.read and memmap.mem_addr == 0x20: memmap.read_data.next = ledreg else: memmap.read_data.next = 0 # blink one of the LEDs status = [Signal(bool(0)) for _ in range(8)] statusbv = ConcatSignal(*reversed(status)) @always_seq(clock.posedge, reset=reset) def beh_assign(): # status / debug signals if glbl.tick_sec: status[0].next = not status[0] status[1].next = memmap.mem_addr == 0x20 status[2].next = uart_rx status[3].next = uart_tx led.next = ledreg | statusbv | sw pmod.next = 0 if sw[0]: uart_tx.next = uart_rx else: uart_tx.next = cmd_tx # @todo: PMOD OLED memmap control return (tick_inst, uart_inst, cmd_inst, beh_led_control, beh_led_read, beh_assign)
def test_dim0(n=10, step_word=0.5, step_context=0.5): """Testing bench around zero in dimension 0.""" embedding_dim = 3 leaky_val = 0.01 rate_val = 0.1 fix_min = -2**7 fix_max = -fix_min fix_res = 2**-8 fix_width = 1 + 7 + 8 # signals y = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) error = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) new_word_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_context_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] new_context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] for j in range(embedding_dim): new_word_emb[j].assign( new_word_embv((j + 1) * fix_width, j * fix_width)) new_context_emb[j].assign( new_context_embv((j + 1) * fix_width, j * fix_width)) y_actual = Signal(fixbv(1.0, min=fix_min, max=fix_max, res=fix_res)) word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] word_embv = ConcatSignal(*reversed(word_emb)) context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] context_embv = ConcatSignal(*reversed(context_emb)) clk = Signal(bool(False)) # modules wcupdated = WordContextUpdated(y, error, new_word_embv, new_context_embv, y_actual, word_embv, context_embv, embedding_dim, leaky_val, rate_val, fix_min, fix_max, fix_res) # test stimulus HALF_PERIOD = delay(5) @always(HALF_PERIOD) def clk_gen(): clk.next = not clk @instance def stimulus(): yield clk.negedge for i in range(n): # new values word_emb[0].next = fixbv(step_word * i - step_word * n // 2, min=fix_min, max=fix_max, res=fix_res) context_emb[0].next = fixbv(step_context * i, min=fix_min, max=fix_max, res=fix_res) yield clk.negedge print "%3s word: %s, context: %s, mse: %f, y: %f, new_word: %s, new_context: %s" % ( now(), [float(el.val) for el in word_emb], [ float(el.val) for el in context_emb ], error, y, [float(el.val) for el in new_word_emb ], [float(el.val) for el in new_context_emb]) raise StopSimulation() return clk_gen, stimulus, wcupdated
def test_converge(n=50, emb_spread=0.1, rand_seed=42): """Testing bench for covergence.""" embedding_dim = 3 leaky_val = 0.01 rate_val = 0.1 fix_min = -2**7 fix_max = -fix_min fix_res = 2**-8 fix_width = 1 + 7 + 8 # signals y = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) error = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) new_word_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_context_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] new_context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] for j in range(embedding_dim): new_word_emb[j].assign( new_word_embv((j + 1) * fix_width, j * fix_width)) new_context_emb[j].assign( new_context_embv((j + 1) * fix_width, j * fix_width)) y_actual = Signal(fixbv(1.0, min=fix_min, max=fix_max, res=fix_res)) word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] word_embv = ConcatSignal(*reversed(word_emb)) context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] context_embv = ConcatSignal(*reversed(context_emb)) clk = Signal(bool(False)) # modules wcupdated = WordContextUpdated(y, error, new_word_embv, new_context_embv, y_actual, word_embv, context_embv, embedding_dim, leaky_val, rate_val, fix_min, fix_max, fix_res) # test stimulus random.seed(rand_seed) HALF_PERIOD = delay(5) @always(HALF_PERIOD) def clk_gen(): clk.next = not clk @instance def stimulus(): zero = fixbv(0.0, min=fix_min, max=fix_max, res=fix_res) yield clk.posedge # random initialization for j in range(embedding_dim): word_emb[j].next = fixbv(random.uniform(0.0, emb_spread), min=fix_min, max=fix_max, res=fix_res) context_emb[j].next = fixbv(random.uniform(0.0, emb_spread), min=fix_min, max=fix_max, res=fix_res) # iterate to converge for i in range(n): yield clk.negedge print "%4s mse: %f, y: %f, word: %s, context: %s" % ( now(), error, y, [float(el.val) for el in word_emb ], [float(el.val) for el in context_emb]) if error == zero: break # transfer new values for j in range(embedding_dim): word_emb[j].next = new_word_emb[j] context_emb[j].next = new_context_emb[j] raise StopSimulation() return clk_gen, stimulus, wcupdated
def pack(self, obj): signals = [] for k, lo, hi in self._items: signals.append(getattr(obj, k)) return ConcatSignal(*reversed(signals))
def memmap_command_bridge(glbl, fifobusi, fifobuso, mmbus): """ Convert a command packet to a memory-mapped bus transaction This module will decode the incomming packet and start a bus transaction, the memmap_controller_basic is used to generate the bus transactions, it convertes the Barebone interface to the MemoryMapped interface being used. The variable length command packet is: 00: 0xDE 01: command byte (response msb indicates error) 02: address high byte 03: address byte 04: address byte 05: address low byte 06: length of data (max length 256 bytes) 07: 0xCA # sequence number, fixed for now 08: data high byte 09: data byte 10: data byte 11: data low byte Fixed 12 byte packet currently supported, future to support block write/reads up to 256-8-4 12 - 253: write / read (big-endian) @todo: last 2 bytes crc The total packet length is 16 + data_length Ports: glbl: global signals and control fifobusi: input fifobus, host packets to device (interface) fifobuso: output fifobus, device responses to host (interface) mmbus: memory-mapped bus (interface) this module is convertible """ assert isinstance(fifobusi, FIFOBus) assert isinstance(fifobuso, FIFOBus) assert isinstance(mmbus, MemoryMapped) fbrx, fbtx = fifobusi, fifobuso clock, reset = glbl.clock, glbl.reset bb = Barebone(glbl, data_width=mmbus.data_width, address_width=mmbus.address_width) states = enum( 'idle', 'wait_for_packet', # receive a command packet 'check_packet', # basic command check 'write', # bus write 'write_end', # end of the write cycle 'read', # read bus cycles for response 'read_end', # end of the read cycle 'response', # send response packet 'response_full', # check of RX FIFO full 'error', # error occurred 'end' # end state ) state = Signal(states.idle) ready = Signal(bool(0)) error = Signal(bool(0)) bytecnt = intbv(0, min=0, max=256) # known knows pidx = ( 0, 7, ) pval = ( 0xDE, 0xCA, ) assert len(pidx) == len(pval) nknown = len(pidx) bytemon = Signal(intbv(0)[8:]) # only supporting 12byte packets (single read/write) for now packet_length = 12 data_offset = 8 packet = [Signal(intbv(0)[8:]) for _ in range(packet_length)] command = packet[1] address = ConcatSignal(*packet[2:6]) data = ConcatSignal(*packet[8:12]) datalen = packet[6] # convert generic memory-mapped bus to the memory-mapped interface # passed to the controller mmc_inst = memmap_controller_basic(bb, mmbus) @always_comb def beh_fifo_read(): if ready and not fbrx.empty: fbrx.rd.next = True else: fbrx.rd.next = False @always_seq(clock.posedge, reset=reset) def beh_state_machine(): if state == states.idle: state.next = states.wait_for_packet ready.next = True bytecnt[:] = 0 elif state == states.wait_for_packet: if fbrx.rvld: # check the known bytes, if the values is unexpected # goto the error state and flush all received bytes. for ii in range(nknown): idx = pidx[ii] val = pval[ii] if bytecnt == idx: if fbrx.rdata != val: error.next = True state.next = states.error packet[bytecnt].next = fbrx.rdata bytecnt[:] = bytecnt + 1 # @todo: replace 20 with len(CommandPacket().header) if bytecnt == packet_length: ready.next = False state.next = states.check_packet elif state == states.check_packet: # @todo: some packet checking # @todo: need to support different address widths, use # @todo: `bb` attributes to determine which bits to assign bb.per_addr.next = address[32:28] bb.mem_addr.next = address[28:0] assert bb.done bytecnt[:] = 0 if command == 1: state.next = states.read elif command == 2: bb.write_data.next = data state.next = states.write else: error.next = True state.next = states.error elif state == states.write: # @todo: add timeout if bb.done: bb.write.next = True state.next = states.write_end elif state == states.write_end: bb.write.next = False if bb.done: state.next = states.read elif state == states.read: # @todo: add timeout if bb.done: bb.read.next = True state.next = states.read_end elif state == states.read_end: bb.read.next = False if bb.done: # @todo: support different data_width bus packet[data_offset + 0].next = bb.read_data[32:24] packet[data_offset + 1].next = bb.read_data[24:16] packet[data_offset + 2].next = bb.read_data[16:8] packet[data_offset + 3].next = bb.read_data[8:0] state.next = states.response elif state == states.response: fbtx.wr.next = False if bytecnt < packet_length: if not fbtx.full: fbtx.wr.next = True fbtx.wdata.next = packet[bytecnt] bytecnt[:] = bytecnt + 1 state.next = states.response_full else: state.next = states.end elif state == states.response_full: fbtx.wr.next = False state.next = states.response elif state == states.error: if not fbrx.rvld: state.next = states.end ready.next = False elif state == states.end: error.next = False ready.next = False state.next = states.idle else: assert False, "Invalid state %s" % (state, ) bytemon.next = bytecnt return beh_fifo_read, mmc_inst, beh_state_machine
def PyDHT11( dat, # Received data, Output valid, # Output inout_state, # Output, low for input, high for output line_out, # Output line line_in, # Input line read_dev, # INPUT clk, reset, clk_freq, # Parameter Hz state_out=None # Output, for debugging. ): States = enum('START_SIGNAL_LOW', 'START_SIGNAL_HIGH', 'WAIT_RESPONSE_LOW', 'WAIT_RESPONSE_HIGH', 'WAIT_BIT_LOW', 'WAIT_BIT_HIGH', 'WAIT_BIT_DAT', 'OUTPUT_DAT', 'IDLE') state = Signal(States.IDLE) if state_out is not None: @always_comb def set_state_out(): state_out.next = state timeout_20ms = Signal(bool(0)) timeout_40us = Signal(bool(0)) delayer_rst = Signal(bool(0)) read_dev_tap = [Signal(bool(0)), Signal(bool(0))] read_dev_posedge = Signal(bool(0)) @always_comb def read_dev_posedge_detector(): read_dev_posedge.next = read_dev_tap[0] & (~read_dev_tap[1]) @always(clk.posedge) def connect_read_dev_tap(): read_dev_tap[0].next = read_dev read_dev_tap[1].next = read_dev_tap[0] delayer = DualDelayer(timeout_short=timeout_40us, timeout_long=timeout_20ms, clk=clk, rst=delayer_rst, interval_short=40e-6, interval_long=20e-3, clk_freq=clk_freq) shift_reg = [Signal(bool(0)) for k in range(40)] bit_counter = Signal(intbv(0, min=0, max=41)) shift_reg_sig = ConcatSignal(*shift_reg) @always(clk.posedge) def transmitting(): if reset: state.next = States.IDLE elif state == States.IDLE: if not read_dev_posedge: inout_state.next = READ_LINE else: bit_counter.next = 0 delayer_rst.next = 1 inout_state.next = WRITE_LINE valid.next = 0 state.next = States.START_SIGNAL_LOW elif state == States.START_SIGNAL_LOW: if not timeout_20ms: delayer_rst.next = 0 line_out.next = 0 else: delayer_rst.next = 1 inout_state.next = READ_LINE state.next = States.START_SIGNAL_HIGH elif state == States.START_SIGNAL_HIGH: if not timeout_40us: delayer_rst.next = 0 else: state.next = States.WAIT_RESPONSE_LOW elif state == States.WAIT_RESPONSE_LOW: if line_in == 0: state.next = States.WAIT_RESPONSE_HIGH elif state == States.WAIT_RESPONSE_HIGH: if line_in == 1: state.next = States.WAIT_BIT_LOW elif state == States.WAIT_BIT_LOW: if line_in == 0: state.next = States.WAIT_BIT_HIGH elif state == States.WAIT_BIT_HIGH: if line_in == 1: delayer_rst.next = 1 state.next = States.WAIT_BIT_DAT elif state == States.WAIT_BIT_DAT: if not timeout_40us: delayer_rst.next = 0 else: for k in range(39): shift_reg[k].next = shift_reg[k + 1] shift_reg[39].next = line_in if bit_counter == 39: state.next = States.OUTPUT_DAT else: bit_counter.next = bit_counter + 1 state.next = States.WAIT_BIT_LOW elif state == States.OUTPUT_DAT: valid.next = 1 dat.next = shift_reg_sig state.next = States.IDLE else: state.next = States.IDLE return instances()
def RobotIO( clk25, sspi_clk, sspi_cs, sspi_miso, sspi_mosi, rc1_cha, rc1_chb, rc2_cha, rc2_chb, rc3_cha, rc3_chb, rc4_cha, rc4_chb, mot1_brake, mot1_dir, mot1_pwm, mot2_brake, mot2_dir, mot2_pwm, mot3_brake, mot3_dir, mot3_pwm, mot4_brake, mot4_dir, mot4_pwm, mot5_brake, mot5_dir, mot5_pwm, mot6_brake, mot6_dir, mot6_pwm, mot7_brake, mot7_dir, mot7_pwm, mot8_brake, mot8_dir, mot8_pwm, adc1_clk, adc1_cs, adc1_miso, adc1_mosi, pwm1_ch0, pwm1_ch1, pwm1_ch2, pwm1_ch3, pwm1_ch4, pwm1_ch5, pwm1_ch6, pwm1_ch7, ext1_0, ext1_1, ext1_2, ext1_3, ext1_4, ext1_5, ext1_6, ext1_7, ext2_0, ext2_1, ext2_2, ext2_3, ext2_4, ext2_5, ext2_6, ext2_7, ext3_0, ext3_1, ext3_2, ext3_3, ext3_4, ext3_5, ext3_6, ext3_7, ext4_0, ext4_1, ext4_2, ext4_3, ext4_4, ext4_5, ext4_6, ext4_7, ext5_0, ext5_1, ext5_2, ext5_3, ext5_4, ext5_5, ext5_6, ext5_7, ext6_0, ext6_1, ext6_2, ext6_3, ext6_4, ext6_5, ext6_6, ext6_7, ext7_0, ext7_1, ext7_2, ext7_3, ext7_4, ext7_5, ext7_6, ext7_7, led_yellow_n, led_green_n, led_red_n, optocoupled ): """ Main module for robot IO stack Instanciates and wires up all necessary modules. clk25 -- 25 MHz clock input sspi_* -- Gumstix SPI signals (Gumstix is master, FPGA is slave) rcX_ch* -- Quadrature encoder X signals (channels A and B) motX_* -- pwm, dir and brake signals for DC motor X adc1_* -- SPI signals to ADC board 1 (FPGA is master, ADC chip is slave) pwm1_* -- PWM signals to PWM board 1 (for servo motors) ext1_* -- Extension port 1 signals ext2_* -- Extension port 2 signals ext3_* -- Extension port 3 signals ext4_* -- Extension port 4 signals ext5_* -- Extension port 5 signals ext6_* -- Extension port 6 signals ext7_* -- Extension port 7 signals led_*_n -- Active-low LED signal optocoupled -- motors and servos drivers account for optocouplers if this is set to True """ # chip-wide active low reset signal # brought low for 1 clk25 period when rst_n_consign changes rst_n, rst_n_consign, rst_n_consign_prev = Signal(HIGH), Signal(HIGH), Signal(HIGH) @always(clk25.posedge) def DriveReset(): """ Drives reset signal """ if rst_n_consign != rst_n_consign_prev: rst_n.next = LOW rst_n_consign_prev.next = rst_n_consign else: rst_n.next = HIGH # LEDs should be off by default led_green_consign = Signal(LOW) led_yellow_consign = Signal(LOW) @always_comb def DriveLEDs(): """ Drives green and yellow LEDs """ led_green_n.next = not led_green_consign led_yellow_n.next = not led_yellow_consign # Toggle red led every second Led1_inst = LEDDriver(led_red_n, clk25, rst_n) # !Odometers (rc1-4) rc1_count = Signal(intbv(0, min = -2**31, max = 2**31)) rc2_count = Signal(intbv(0, min = -2**31, max = 2**31)) rc3_count = Signal(intbv(0, min = -2**31, max = 2**31)) rc4_count = Signal(intbv(0, min = -2**31, max = 2**31)) Odometer1_inst = OdometerReader(rc1_count, rc1_cha, rc1_chb, clk25, rst_n) Odometer2_inst = OdometerReader(rc2_count, rc2_cha, rc2_chb, clk25, rst_n) Odometer3_inst = OdometerReader(rc3_count, rc3_cha, rc3_chb, clk25, rst_n) Odometer4_inst = OdometerReader(rc4_count, rc4_cha, rc4_chb, clk25, rst_n) # !Motors (mot1-8) motor1_speed = Signal(intbv(0, min = -2**10, max = 2**10)) motor2_speed = Signal(intbv(0, min = -2**10, max = 2**10)) motor3_speed = Signal(intbv(0, min = -2**10, max = 2**10)) motor4_speed = Signal(intbv(0, min = -2**10, max = 2**10)) motor5_speed = Signal(intbv(0, min = -2**10, max = 2**10)) motor6_speed = Signal(intbv(0, min = -2**10, max = 2**10)) motor7_speed = Signal(intbv(0, min = -2**10, max = 2**10)) motor8_speed = Signal(intbv(0, min = -2**10, max = 2**10)) Motor1_inst = MotorDriver(mot1_pwm, mot1_dir, mot1_brake, clk25, motor1_speed, rst_n, optocoupled) Motor2_inst = MotorDriver(mot2_pwm, mot2_dir, mot2_brake, clk25, motor2_speed, rst_n, optocoupled) Motor3_inst = MotorDriver(mot3_pwm, mot3_dir, mot3_brake, clk25, motor3_speed, rst_n, optocoupled) Motor4_inst = MotorDriver(mot4_pwm, mot4_dir, mot4_brake, clk25, motor4_speed, rst_n, optocoupled) Motor5_inst = MotorDriver(mot5_pwm, mot5_dir, mot5_brake, clk25, motor5_speed, rst_n, optocoupled) Motor6_inst = MotorDriver(mot6_pwm, mot6_dir, mot6_brake, clk25, motor6_speed, rst_n, optocoupled) Motor7_inst = MotorDriver(mot7_pwm, mot7_dir, mot7_brake, clk25, motor7_speed, rst_n, optocoupled) Motor8_inst = MotorDriver(mot8_pwm, mot8_dir, mot8_brake, clk25, motor8_speed, rst_n, optocoupled) # !Servo motors servo1_consign = Signal(intbv(0)[16:]) servo2_consign = Signal(intbv(0)[16:]) servo3_consign = Signal(intbv(0)[16:]) servo4_consign = Signal(intbv(0)[16:]) servo5_consign = Signal(intbv(0)[16:]) servo6_consign = Signal(intbv(0)[16:]) servo7_consign = Signal(intbv(0)[16:]) servo8_consign = Signal(intbv(0)[16:]) Servo1_ch0_inst = ServoDriver(pwm1_ch0, clk25, servo1_consign, rst_n, optocoupled) Servo1_ch1_inst = ServoDriver(pwm1_ch1, clk25, servo2_consign, rst_n, optocoupled) Servo1_ch2_inst = ServoDriver(pwm1_ch2, clk25, servo3_consign, rst_n, optocoupled) Servo1_ch3_inst = ServoDriver(pwm1_ch3, clk25, servo4_consign, rst_n, optocoupled) Servo1_ch4_inst = ServoDriver(pwm1_ch4, clk25, servo5_consign, rst_n, optocoupled) Servo1_ch5_inst = ServoDriver(pwm1_ch5, clk25, servo6_consign, rst_n, optocoupled) Servo1_ch6_inst = ServoDriver(pwm1_ch6, clk25, servo7_consign, rst_n, optocoupled) Servo1_ch7_inst = ServoDriver(pwm1_ch7, clk25, servo8_consign, rst_n, optocoupled) # !EXT ports ext1_port = ConcatSignal(ext1_7, ext1_6, ext1_5, ext1_4, ext1_3, ext1_2, ext1_1, ext1_0) ext2_port = ConcatSignal(ext2_7, ext2_6, ext2_5, ext2_4, ext2_3, ext2_2, ext2_1, ext2_0) ext3_port = ConcatSignal(ext3_7, ext3_6, ext3_5, ext3_4, ext3_3, ext3_2, ext3_1, ext3_0) ext4_port = ConcatSignal(ext4_7, ext4_6, ext4_5, ext4_4, ext4_3, ext4_2, ext4_1, ext4_0) ext5_port = ConcatSignal(ext5_7, ext5_6, ext5_5, ext5_4, ext5_3, ext5_2, ext5_1, ext5_0) ext6_port = ConcatSignal(ext6_7, ext6_6, ext6_5, ext6_4, ext6_3, ext6_2, ext6_1, ext6_0) ext7_port = ConcatSignal(ext7_7, ext7_6, ext7_5, ext7_4, ext7_3, ext7_2, ext7_1, ext7_0) # Registers for SPI read/write tests stored_uint8 = Signal(intbv(0)[8:]) stored_uint16 = Signal(intbv(0)[16:]) stored_uint32 = Signal(intbv(0)[32:]) stored_int8 = Signal(intbv(0, min = -2**7, max = 2**7)) stored_int16 = Signal(intbv(0, min = -2**15, max = 2**15)) stored_int32 = Signal(intbv(0, min = -2**31, max = 2**31)) # Communication with Microchip MCP3008 8-Channel 10-Bit A/D Converter # # The slave needs either SPI Mode 0 or 3. # # The SPI clock generated by our SPI Master (the Gumstix) is forwarded # to the MCP3008. It is inverted to use SPI Mode 3. # # The 17-bit data we send: # - start bit (a 1) # - single-ended bit (a 1) # - 3 bits for the channel (most significant bit first) # - 12 padding bits (we send zeros) # # The 17-bit data we get back # - 6 padding bits # - a null byte # - the 10-bit value # # Communication with MCP3008 during a KLV exchange # # The 17-bit exchange starts when the 7th bit of the key is received. # If the 7 first bits of the key correspond to one of the channel keys, # the start bit is sent. Thus, the remaining 16 bits are aligned with # the length byte and the first value byte. Bits 2 to 9 are received # during the length byte, and sent as the first value byte. Bits 10 to 17 # are received during the first value byte, and sent as the second value # byte. # bit counter (0 to 16, 17 when done) adc1_ws = 17 adc1_cnt = Signal(intbv(adc1_ws, min=0, max=adc1_ws+1)) # 3-bit channel number adc1_channel = Signal(intbv(0)[3:]) @always_comb def ADCClock(): """ Drives adc1_clk. """ adc1_clk.next = not sspi_clk @instance def ADCTX(): """ MCP3008 SPI transmission: drives adc1_mosi. """ while True: # Propagate on adc1_clk falling edge (mode 3) # == sspi_clk rising edge yield sspi_clk.posedge if adc1_cnt < adc1_ws: # Start bit if adc1_cnt == 0: adc1_mosi.next = HIGH # Single ended / differential bit elif adc1_cnt == 1: adc1_mosi.next = HIGH # 3-bit channel elif adc1_cnt >= 2 and adc1_cnt <= 4: adc1_mosi.next = adc1_channel[4-adc1_cnt] # 12-bit padding else: adc1_mosi.next = LOW # Communication with SPI Master. # # The master sends a stream of KLV (Key byte, Length byte, Value bytes) # encoded commands. Keys upto 0x7F are read commands. Keys from 0x80 are # write commands. # # SPI mode 1 (cpol = 0, cpha = 1) is used: # - the base value of the clock is LOW # - data is captured on the clock's falling edge and data is propagated # on a rising edge. # # To use mode 3 (cpol = 1, cpha = 1), switch the edges of sspi_clk in # TX() and RX(). # word size: 8 bits ws = 8 # next word to send txdata = Signal(intbv(0)[ws:]) # number of bits sent in txdata (sort of) spi_cnt = Signal(intbv(0, min=0, max=ws)) @instance def TX(): """ Low level SPI transmission: drives sspi_miso. Reacts on rising edges of the SPI clock to send txdata bit per bit. Drives spi_cnt for use by RX() to detect end of word. """ # shift register with bits to send to master txsreg = intbv(0)[ws:] # state in the SPI "protocol" state = SPI_State.IDLE while True: # Propagate on rising edge (mode 1) yield sspi_clk.posedge if sspi_cs == LOW: if state == SPI_State.IDLE: txsreg[:] = txdata state = SPI_State.TRANSFER spi_cnt.next = 0 elif state == SPI_State.TRANSFER: txsreg[ws:1] = txsreg[ws-1:] # ws-2 because 1st bit was sent without cnt++ if spi_cnt == ws-2: state = SPI_State.IDLE spi_cnt.next = spi_cnt + 1 sspi_miso.next = txsreg[ws-1] else: state = SPI_State.IDLE @instance def RX(): """ Low level SPI reception and higher level word handling. Reacts on falling edges of the SPI clock to store the received bits. When a word is received, RX() interprets it as the key, length, or one of the value bytes, depending on the current state in the KLV decoding. RX() drives txdata to send the value bytes one by one when the master is reading, or else to send null bytes. """ # shift register with bits received from MCP3008 adc1_rxsreg = intbv(0)[ws:] # shift register with bits received from master rxsreg = intbv(0)[ws:] # address sent by the master key = intbv(0)[ws:] # length of the value sent or expected by the master length = intbv(0)[ws:] # big intbv whose lower bytes are sent to the master when it is reading value_for_master = intbv(0)[MAX_LENGTH*ws:] # big intbv whose lower bytes are set by the master when it is writing value_from_master = intbv(0)[MAX_LENGTH*ws:] # index of the currently read or written value byte index = MAX_LENGTH*ws # state in the KLV protocol state = KLV_State.READ_KEY while True: # Capture on falling edge (mode 1) yield sspi_clk.negedge # ADC special: handle ADC RX if adc1_cnt < adc1_ws: if adc1_cnt >= 7: # shift in new bit adc1_rxsreg[ws:] = concat(adc1_rxsreg[ws-1:], adc1_miso) else: # ignore all but bits 7-16 adc1_rxsreg[ws:] = concat(adc1_rxsreg[ws-1:], LOW) if adc1_cnt + 1 == adc1_ws: adc1_cs.next = HIGH adc1_cnt.next = adc1_cnt + 1 if sspi_cs == LOW: # shift in new bit rxsreg[ws:] = concat(rxsreg[ws-1:], sspi_mosi) # ADC special: detect ADC keys early to send start bit if spi_cnt == ws-2: if state == KLV_State.READ_KEY: key[:] = concat(rxsreg[ws-1:], LOW) if key >= 0x50 and key <= 0x57: adc1_cs.next = LOW adc1_cnt.next = 0 # Read a whole word if spi_cnt == ws-1: txdata.next = 0 # handle the key sent by the master if state == KLV_State.READ_KEY: # read key sent by master key[:] = rxsreg # ADC Special: set channel, go to special state if key >= 0x50 and key <= 0x57: adc1_channel.next = key - 0x50 length[:] = 3 # length + 2 value bytes index = ws*(length-1) state = KLV_State.MASTER_ADC # Master reads elif key[ws-1] == 0: state = KLV_State.GET_READ_LENGTH # Master writes else: state = KLV_State.GET_WRITE_LENGTH # handle the length of the value sent by the master elif state == KLV_State.GET_WRITE_LENGTH: # read length sent by master length[:] = rxsreg value_from_master[:] = 0 if length > 0: # write some bytes index = ws*(length-1) state = KLV_State.MASTER_WRITE else: # write 0 byte: done state = KLV_State.READ_KEY # handle the length of the value expected by the master elif state == KLV_State.GET_READ_LENGTH: # read length sent by master length[:] = rxsreg value_for_master[:] = 0 if length > 0: # read some bytes index = ws*(length-1) state = KLV_State.MASTER_READ # Odometers: use bit slicing to convert signed to unsigned if key == 0x11: value_for_master[len(rc1_count):] = rc1_count[len(rc1_count):] elif key == 0x12: value_for_master[len(rc2_count):] = rc2_count[len(rc2_count):] elif key == 0x13: value_for_master[len(rc3_count):] = rc3_count[len(rc3_count):] elif key == 0x14: value_for_master[len(rc4_count):] = rc4_count[len(rc4_count):] # EXT ports elif key == 0x31: value_for_master[len(ext1_port):] = ext1_port elif key == 0x32: value_for_master[len(ext2_port):] = ext2_port elif key == 0x33: value_for_master[len(ext3_port):] = ext3_port elif key == 0x34: value_for_master[len(ext4_port):] = ext4_port elif key == 0x35: value_for_master[len(ext5_port):] = ext5_port elif key == 0x36: value_for_master[len(ext6_port):] = ext6_port elif key == 0x37: value_for_master[len(ext7_port):] = ext7_port # Fixed value for testing elif key == 0x42: value_for_master[32:] = 0xDEADC0DE # Read stored values for testing elif key == 0x71: value_for_master[len(stored_uint8):] = stored_uint8 elif key == 0x72: value_for_master[len(stored_uint16):] = stored_uint16 elif key == 0x73: value_for_master[len(stored_uint32):] = stored_uint32 # use bit slicing to convert signed to unsigned elif key == 0x74: value_for_master[len(stored_int8):] = stored_int8[len(stored_int8):] elif key == 0x75: value_for_master[len(stored_int16):] = stored_int16[len(stored_int16):] elif key == 0x76: value_for_master[len(stored_int32):] = stored_int32[len(stored_int32):] else: # Dummy value sent when key is unknown. # The value is fixed. The master read 'length' # bytes from it. value_for_master[:] = 0xDEADBEEFBAADF00D # send first byte immediately txdata.next = value_for_master[(index + ws):index] else: # read 0 byte: done state = KLV_State.READ_KEY # handle the value bytes sent by the master elif state == KLV_State.MASTER_WRITE: # read value byte sent by master and store it value_from_master[(index + ws):index] = rxsreg if index >= ws: # Get next byte index -= ws else: # Got everything state = KLV_State.READ_KEY # Reset if key == 0x81: rst_n_consign.next = not rst_n_consign # Green LED elif key == 0x82: led_green_consign.next = value_from_master[0] # Yellow LED elif key == 0x83: led_yellow_consign.next = value_from_master[0] # Motors elif key == 0x91: motor1_speed.next = value_from_master[len(motor1_speed):].signed() elif key == 0x92: motor2_speed.next = value_from_master[len(motor2_speed):].signed() elif key == 0x93: motor3_speed.next = value_from_master[len(motor3_speed):].signed() elif key == 0x94: motor4_speed.next = value_from_master[len(motor4_speed):].signed() elif key == 0x95: motor5_speed.next = value_from_master[len(motor5_speed):].signed() elif key == 0x96: motor6_speed.next = value_from_master[len(motor6_speed):].signed() elif key == 0x97: motor7_speed.next = value_from_master[len(motor7_speed):].signed() elif key == 0x98: motor8_speed.next = value_from_master[len(motor8_speed):].signed() # Servos elif key == 0xA1: servo1_consign.next = value_from_master[len(servo1_consign):] elif key == 0xA2: servo2_consign.next = value_from_master[len(servo2_consign):] elif key == 0xA3: servo3_consign.next = value_from_master[len(servo3_consign):] elif key == 0xA4: servo4_consign.next = value_from_master[len(servo4_consign):] elif key == 0xA5: servo5_consign.next = value_from_master[len(servo5_consign):] elif key == 0xA6: servo6_consign.next = value_from_master[len(servo6_consign):] elif key == 0xA7: servo7_consign.next = value_from_master[len(servo7_consign):] elif key == 0xA8: servo8_consign.next = value_from_master[len(servo8_consign):] # Store values for testing elif key == 0xF1: stored_uint8.next = value_from_master[len(stored_uint8):] elif key == 0xF2: stored_uint16.next = value_from_master[len(stored_uint16):] elif key == 0xF3: stored_uint32.next = value_from_master[len(stored_uint32):] elif key == 0xF4: stored_int8.next = value_from_master[len(stored_int8):].signed() elif key == 0xF5: stored_int16.next = value_from_master[len(stored_int16):].signed() elif key == 0xF6: stored_int32.next = value_from_master[len(stored_int32):].signed() # Convert to case block else: pass # decrement index when each value byte expected by the master has been sent elif state == KLV_State.MASTER_READ: if index >= ws: # Send next byte index -= ws txdata.next = value_for_master[(index + ws):index] else: # Sent everything state = KLV_State.READ_KEY # send adc bytes elif state == KLV_State.MASTER_ADC: if index >= ws: # Send next byte index -= ws txdata.next = adc1_rxsreg else: # Sent everything state = KLV_State.READ_KEY # Deselected else: state = KLV_State.READ_KEY txdata.next = 0 return instances()
def test_dim0(n=10, step_a=0.5, step_b=0.5): """Testing bench around zero in dimension 0.""" dim = 3 fix_min = -2**7 fix_max = -fix_min fix_res = 2**-8 fix_width = 1 + 7 + 8 # signals y = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) y_da_vec = Signal(intbv(0)[dim * fix_width:]) y_db_vec = Signal(intbv(0)[dim * fix_width:]) y_da_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(dim) ] y_db_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(dim) ] for j in range(dim): y_da_list[j].assign(y_da_vec((j + 1) * fix_width, j * fix_width)) y_db_list[j].assign(y_db_vec((j + 1) * fix_width, j * fix_width)) a_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(dim) ] a_vec = ConcatSignal(*reversed(a_list)) b_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(dim) ] b_vec = ConcatSignal(*reversed(b_list)) clk = Signal(bool(False)) # modules dot = DotProduct(y, y_da_vec, y_db_vec, a_vec, b_vec, dim, fix_min, fix_max, fix_res) # test stimulus HALF_PERIOD = delay(5) @always(HALF_PERIOD) def clk_gen(): clk.next = not clk @instance def stimulus(): yield clk.negedge for i in range(n): # new values a_list[0].next = fixbv(step_a * i - step_a * n // 2, min=fix_min, max=fix_max, res=fix_res) b_list[0].next = fixbv(step_b * i, min=fix_min, max=fix_max, res=fix_res) yield clk.negedge print "%3s a_list: %s, b_list: %s, y: %f, y_da: %s, y_db: %s" % ( now(), [float(el.val) for el in a_list], [float(el.val) for el in b_list], y, [float(el.val) for el in y_da_list], [float(el.val) for el in y_db_list]) raise StopSimulation() return clk_gen, stimulus, dot
def train(x_vocab, y_skipgram, vocab_size): """Training stimulus.""" embedding_dim = 3 leaky_val = 0.01 rate_val = 0.1 emb_spread = 0.1 ema_weight = 0.01 fix_min = -2**7 fix_max = -fix_min fix_res = 2**-8 fix_width = 1 + 7 + 8 # signals y = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) error = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) new_word_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_context_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] new_context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] for j in range(embedding_dim): new_word_emb[j].assign(new_word_embv((j + 1) * fix_width, j * fix_width)) new_context_emb[j].assign(new_context_embv((j + 1) * fix_width, j * fix_width)) y_actual = Signal(fixbv(1.0, min=fix_min, max=fix_max, res=fix_res)) word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] word_embv = ConcatSignal(*reversed(word_emb)) context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] context_embv = ConcatSignal(*reversed(context_emb)) wram_dout = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) wram_din = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) wram_default = Signal(fixbv(emb_spread, min=fix_min, max=fix_max, res=fix_res)) wram_addr = Signal(intbv(0)[24:]) wram_rd = Signal(bool(False)) wram_wr = Signal(bool(False)) cram_dout = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) cram_din = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) cram_default = Signal(fixbv(emb_spread, min=fix_min, max=fix_max, res=fix_res)) cram_addr = Signal(intbv(0)[24:]) cram_rd = Signal(bool(False)) cram_wr = Signal(bool(False)) error_ema = Signal(fixbv(1.0, min=fix_min, max=fix_max, res=fix_res)) error_ema_weight = Signal(fixbv(ema_weight, min=fix_min, max=fix_max, res=fix_res)) clk = Signal(bool(False)) # modules wcupdated = WordContextUpdated(y, error, new_word_embv, new_context_embv, y_actual, word_embv, context_embv, embedding_dim, leaky_val, rate_val, fix_min, fix_max, fix_res) wram = RamSim(wram_dout, wram_din, wram_default, wram_addr, wram_rd, wram_wr, clk) cram = RamSim(cram_dout, cram_din, cram_default, cram_addr, cram_rd, cram_wr, clk) # driver HALF_PERIOD = delay(5) @always(HALF_PERIOD) def clk_gen(): clk.next = not clk @instance def driver(): doc_pass = 0 while True: doc_pass += 1 for i in range(len(x_vocab[0]) - 1): yield clk.negedge ### POSITIVE SAMPLING # read positive training data using Python word_id = int(x_vocab[0][i]) context_id = int(x_vocab[0][i + 1]) y_actual.next = fixbv(1.0, min=fix_min, max=fix_max, res=fix_res) # read word-context embeddings for j in range(embedding_dim): # randomize default values wram_default.next = fixbv(random.uniform(0.0, emb_spread), min=fix_min, max=fix_max, res=fix_res) cram_default.next = fixbv(random.uniform(0.0, emb_spread), min=fix_min, max=fix_max, res=fix_res) # initiate reading from wram and cram wram_addr.next = intbv(embedding_dim * word_id + j) wram_rd.next = True cram_addr.next = intbv(embedding_dim * context_id + j) cram_rd.next = True # wait for both yield join(wram_rd.negedge, cram_rd.negedge) #print "%6s wram read, word_id: %s, addr: %s, dout: %s" % (now(), word_id, wram_addr, wram_dout) #print "%6s cram read, context_id: %s, addr: %s, dout: %s" % (now(), context_id, cram_addr, cram_dout) # read parts of embeddings word_emb[j].next = wram_dout context_emb[j].next = cram_dout # wait for word-context updated to finish yield clk.negedge print "%6s %d mse_ema: %f, mse: %f, word: %s, context: %s" % (now(), doc_pass, error_ema, error, [ float(el.val) for el in word_emb ], [ float(el.val) for el in context_emb ]) # compute exponential moving average of error error_delta = fixbv(error_ema_weight * (error - error_ema), min=fix_min, max=fix_max, res=fix_res) error_ema.next = error_ema + error_delta # write new word-context embeddings for j in range(embedding_dim): # initiate writing to wram and cram wram_addr.next = intbv(embedding_dim * word_id + j) wram_din.next = new_word_emb[j] wram_wr.next = True cram_addr.next = intbv(embedding_dim * context_id + j) cram_din.next = new_context_emb[j] cram_wr.next = True # wait for both yield join(wram_wr.negedge, cram_wr.negedge) #print "%6s wram write, word_id: %s, addr: %s, din: %s" % (now(), word_id, wram_addr, wram_din) #print "%6s cram write, context_id: %s, addr: %s, din: %s" % (now(), context_id, cram_addr, cram_din) ### NEGATIVE SAMPLING # read negative training data using Python word_id = word_id context_id = int(random.randrange(vocab_size)) y_actual.next = fixbv(0.0, min=fix_min, max=fix_max, res=fix_res) # read word-context embeddings for j in range(embedding_dim): # randomize default values wram_default.next = fixbv(random.uniform(0.0, emb_spread), min=fix_min, max=fix_max, res=fix_res) cram_default.next = fixbv(random.uniform(0.0, emb_spread), min=fix_min, max=fix_max, res=fix_res) # initiate reading from wram and cram wram_addr.next = intbv(embedding_dim * word_id + j) wram_rd.next = True cram_addr.next = intbv(embedding_dim * context_id + j) cram_rd.next = True # wait for both yield join(wram_rd.negedge, cram_rd.negedge) #print "%6s wram read, word_id: %s, addr: %s, dout: %s" % (now(), word_id, wram_addr, wram_dout) #print "%6s cram read, context_id: %s, addr: %s, dout: %s" % (now(), context_id, cram_addr, cram_dout) # read parts of embeddings word_emb[j].next = wram_dout context_emb[j].next = cram_dout # wait for word-context updated to finish yield clk.negedge print "%6s %d mse_ema: %f, mse: %f, word: %s, context: %s" % (now(), doc_pass, error_ema, error, [ float(el.val) for el in word_emb ], [ float(el.val) for el in context_emb ]) # compute exponential moving average of error error_delta = fixbv(error_ema_weight * (error - error_ema), min=fix_min, max=fix_max, res=fix_res) error_ema.next = error_ema + error_delta # write new word-context embeddings for j in range(embedding_dim): # initiate writing to wram and cram wram_addr.next = intbv(embedding_dim * word_id + j) wram_din.next = new_word_emb[j] wram_wr.next = True cram_addr.next = intbv(embedding_dim * context_id + j) cram_din.next = new_context_emb[j] cram_wr.next = True # wait for both yield join(wram_wr.negedge, cram_wr.negedge) #print "%6s wram write, word_id: %s, addr: %s, din: %s" % (now(), word_id, wram_addr, wram_din) #print "%6s cram write, context_id: %s, addr: %s, din: %s" % (now(), context_id, cram_addr, cram_din) return clk_gen, driver, wcupdated, wram, cram