def setBind(self, var, value, cond=None): if var is None: cond = None if not isinstance(var, fxd._FixedVariable) and isinstance( value, fxd._FixedBase): raise ValueError( "type mismatch of destination and source: '%s' and '%s'" % (str(type(var)), str(type(value)))) if isinstance(var, fxd._FixedVariable) and isinstance( value, fxd._FixedBase): if var.point != value.point: raise ValueError("type mismatch of fixed point: %d != %d" % (var.point, value.point)) value = optimize(value) cond = optimize(cond) if cond is not None else None subst = (vtypes.SingleStatement(value) if var is None else var.write(value)) if var is not None: if hasattr(var, '_fsm') and id(var._fsm) != id(self.fsm): raise ValueError("variable '%s' has multiple drivers" % str(var)) if not hasattr(var, '_fsm'): var._fsm = self.fsm self.fsm._add_statement([subst], cond=cond) state = self.getFsmCount() self.scope.addBind(state, var, value, cond)
def setBind(self, var, value, cond=None): if var is None: cond = None if not isinstance(var, fxd._FixedVariable) and isinstance(value, fxd._FixedBase): raise ValueError("type mismatch of destination and source: '%s' and '%s'" % (str(type(var)), str(type(value)))) if isinstance(var, fxd._FixedVariable) and isinstance(value, fxd._FixedBase): if var.point != value.point: raise ValueError("type mismatch of fixed point: %d != %d" % (var.point, value.point)) value = optimize(value) cond = optimize(cond) if cond is not None else None subst = (vtypes.SingleStatement(value) if var is None else var.write(value)) if var is not None: if hasattr(var, '_fsm') and id(var._fsm) != id(self.fsm): raise ValueError( "variable '%s' has multiple drivers" % str(var)) if not hasattr(var, '_fsm'): var._fsm = self.fsm self.fsm._add_statement([subst], cond=cond) state = self.getFsmCount() self.scope.addBind(state, var, value, cond)
def _extslice(self, node): value = self.visit(node.value) for dim in node.slice.dims: lower = (self.visit(dim.lower) if dim.lower is not None else None) upper = (self.visit(dim.upper) if dim.upper is not None else None) step = (self.visit(dim.step) if dim.step is not None else None) lower = vtypes.raw_value(optimize(lower)) upper = vtypes.raw_value(optimize(upper)) step = vtypes.raw_value(optimize(step)) value = value[lower:upper:step] return value
def _slice(self, node): value = self.visit(node.value) lower = (self.visit(node.slice.lower) if node.slice.lower is not None else None) upper = (self.visit(node.slice.upper) if node.slice.upper is not None else None) step = (self.visit(node.slice.step) if node.slice.step is not None else None) lower = vtypes.raw_value(optimize(lower)) upper = vtypes.raw_value(optimize(upper)) step = vtypes.raw_value(optimize(step)) return value[lower:upper:step]
def visit_BinOp(self, node): left = self.visit(node.left) right = self.visit(node.right) if isinstance(left, vtypes.Str) or isinstance(right, vtypes.Str): if not isinstance(node.op, ast.Add): raise TypeError("Can not generate a corresponding node") return self._string_operation_plus(left, right) if (not isinstance(left, fxd._FixedBase) and isinstance(right, fxd._FixedBase)): raise TypeError("type mismatch of operator arguments: '%s' and '%s'" % (str(type(left)), str(type(right)))) try: method = getMethodName(node.op) rslt = applyMethod(left, method, right) except NotImplementedError: op = getVeriloggenOp(node.op) if op is None: raise TypeError("unsupported BinOp: %s" % str(node.op)) rslt = op(left, right) return optimize(rslt)
def visit_AugAssign(self, node): if self.skip(): return right = self.visit(node.value) _type = self._variable_type(right) left_name = self.visit(node.target) left = self.getVariable(left_name, store=True, _type=_type) if (not isinstance(left, fxd._FixedBase) and isinstance(right, fxd._FixedBase)): raise TypeError( "type mismatch of operator arguments: '%s' and '%s'" % (str(type(left)), str(type(right)))) try: method = getMethodName(node.op) rslt = applyMethod(left, method, right) except NotImplementedError: op = getVeriloggenOp(node.op) if op is None: raise TypeError("unsupported BinOp: %s" % str(node.op)) rslt = op(left, right) rslt = optimize(rslt) self.setBind(left, rslt) self.setFsm() self.incFsmCount()
def visit_AugAssign(self, node): if self.skip(): return right = self.visit(node.value) _type = self._variable_type(right) left_name = self.visit(node.target) left = self.getVariable(left_name, store=True, _type=_type) if (not isinstance(left, fxd._FixedBase) and isinstance(right, fxd._FixedBase)): raise TypeError("type mismatch of operator arguments: '%s' and '%s'" % (str(type(left)), str(type(right)))) try: method = getMethodName(node.op) rslt = applyMethod(left, method, right) except NotImplementedError: op = getVeriloggenOp(node.op) if op is None: raise TypeError("unsupported BinOp: %s" % str(node.op)) rslt = op(left, right) rslt = optimize(rslt) self.setBind(left, rslt) self.setFsm() self.incFsmCount()
def visit_BinOp(self, node): left = self.visit(node.left) right = self.visit(node.right) if isinstance(left, vtypes.Str) or isinstance(right, vtypes.Str): if not isinstance(node.op, ast.Add): raise TypeError("Can not generate a corresponding node") return self._string_operation_plus(left, right) if (not isinstance(left, fxd._FixedBase) and isinstance(right, fxd._FixedBase)): raise TypeError( "type mismatch of operator arguments: '%s' and '%s'" % (str(type(left)), str(type(right)))) try: method = getMethodName(node.op) rslt = applyMethod(left, method, right) except NotImplementedError: op = getVeriloggenOp(node.op) if op is None: raise TypeError("unsupported BinOp: %s" % str(node.op)) rslt = op(left, right) return optimize(rslt)
def setArgBind(self, name, value): if not isinstance(value, numerical_types): self.scope.addVariable(name, value) return right = optimize(value) left = self.getVariable(name, store=True) self.setBind(left, right)
def visit_UnaryOp(self, node): value = self.visit(node.operand) try: method = getMethodName(node.op) rslt = applyMethod(value, method) except NotImplementedError: op = getVeriloggenOp(node.op) rslt = op(value) return optimize(rslt)
def setVarargBind(self, name, values): lefts = [] for value in values: if isinstance(value, numerical_types): right = optimize(value) left = self.getTmpVariable() self.setBind(left, right) lefts.append(left) else: lefts.append(value) self.scope.addVariable(name, lefts)
def visit_Subscript(self, node): if isinstance(node.slice, ast.Slice): return self._subscript_slice(node) if isinstance(node.slice, ast.ExtSlice): return self._subscript_extslice(node) if isinstance(node.slice, ast.Index): return self._subscript_index(node) value = self.visit(node.value) index = self.visit(node.slice) index = vtypes.raw_value(optimize(index)) return value[index]
def visit_BoolOp(self, node): values = [self.visit(v) for v in node.values] try: method = getMethodName(node.op) rslt = values[0] for v in values[1:]: rslt = applyMethod(rslt, method, v) except NotImplementedError: op = getVeriloggenOp(node.op) if op is None: raise TypeError("unsupported BinOp: %s" % str(node.op)) rslt = values[0] for v in values[1:]: rslt = op(rslt, v) return optimize(rslt)
def visit_BinOp(self, node): left = self.visit(node.left) right = self.visit(node.right) if isinstance(left, vtypes.Str) or isinstance(right, vtypes.Str): if isinstance(node.op, ast.Add): raise TypeError("Can not generate a corresponding node") return self._string_operation_plus(left, right) try: method = getMethodName(node.op) rslt = applyMethod(left, method, right) except NotImplementedError: op = getVeriloggenOp(node.op) if op is None: raise TypeError("Unsupported BinOp: %s" % str(node.op)) rslt = op(left, right) return optimize(rslt)
def visit_AugAssign(self, node): if self.skip(): return right = self.visit(node.value) left_name = self.visit(node.target) left = self.getVariable(left_name, store=True) try: method = getMethodName(node.op) rslt = applyMethod(left, method, right) except NotImplementedError: op = getVeriloggenOp(node.op) if op is None: raise TypeError("Unsupported BinOp: %s" % str(node.op)) rslt = op(left, right) rslt = optimize(rslt) self.setBind(left, rslt) self.setFsm() self.incFsmCount()
def _index(self, node): value = self.visit(node.value) index = self.visit(node.slice.value) index = vtypes.raw_value(optimize(index)) return value[index]
def _synthesize_write_fsm(self): op_id = 1 if op_id in self.write_ops: """ already synthesized op """ return if self.write_fsm is not None: """ new op """ self.write_ops.append(op_id) return """ new op and fsm """ fsm = FSM(self.m, '_'.join(['', self.name, 'write_fsm']), self.clk, self.rst, as_module=self.fsm_as_module) self.write_fsm = fsm self.write_ops.append(op_id) cur_global_addr = self.m.Reg('_'.join(['', self.name, 'write_cur_global_addr']), self.addrwidth, initval=0) cur_size = self.m.Reg('_'.join(['', self.name, 'write_cur_size']), self.addrwidth + 1, initval=0) rest_size = self.m.Reg('_'.join(['', self.name, 'write_rest_size']), self.addrwidth + 1, initval=0) max_burstlen = 2 ** self.burst_size_width # state 0 if not self.use_global_base_addr: gaddr = self.write_global_addr else: gaddr = self.write_global_addr + self.global_base_addr fsm.If(self.write_start)( cur_global_addr(self.mask_addr(gaddr)), rest_size(self.write_size) ) fsm.If(self.write_start).goto_next() # state 1 check_state = fsm.current self._check_4KB_boundary(fsm, max_burstlen, cur_global_addr, cur_size, rest_size) # state 2 ack, counter = self.write_request_counter(cur_global_addr, cur_size, cond=fsm) self.write_data_counter = counter fsm.If(ack).goto_next() # state 3 cond = fsm.here data, last, _id, user, dest, done = self.in_streamout.read_dataflow(cond=cond) done_out = self.write_dataflow(data, counter, cond=cond) self.write_data_done.assign(done_out) fsm.If(self.write_data_done)( cur_global_addr.add(optimize(cur_size * (self.datawidth // 8))) ) fsm.If(self.write_data_done, rest_size > 0).goto(check_state) fsm.If(self.write_data_done, rest_size == 0).goto_next() # state 4 set_idle = self._set_flag(fsm) self.seq.If(set_idle)( self.write_idle(1) ) fsm.goto_init()
def control_sequence(self, fsm): arg = self.args[0] ram = self.input_rams[0] shape = self.get_aligned_shape() arg_shape = arg.get_aligned_shape() # burst read, scatter write write_order = list( reversed([self.transpose_perm.index(i) for i in range(len(shape))])) write_pattern = bt.shape_to_pattern(shape, write_order) read_offset = self.m.TmpReg(self.maxi.addrwidth, initval=0) write_offsets = [ self.m.TmpReg(self.maxi.addrwidth, initval=0) for _ in write_pattern ] write_all_offset = self.objaddr for write_offset in write_offsets: write_all_offset += write_offset read_counts = [ self.m.TmpReg(self.maxi.addrwidth, initval=0) for _ in write_pattern ] # initialize fsm(read_offset(0), [write_offset(0) for write_offset in write_offsets], [read_count(0) for read_count in read_counts]) fsm.goto_next() # DMA read read_state = fsm.current laddr = 0 gaddr = self.arg_objaddrs[0] + read_offset read_size = arg_shape[-1] bt.bus_lock(self.maxi, fsm) bt.dma_read(self.maxi, fsm, ram, laddr, gaddr, read_size) bt.bus_unlock(self.maxi, fsm) # read-modify-write modify_state = fsm.current laddr = read_counts[0] gaddr = write_all_offset bt.read_modify_write(self.m, fsm, self.maxi, ram, self.output_rams[0], laddr, gaddr) prev_done = 1 for (read_count, maxval, write_offset, (out_size, out_stride)) in zip(read_counts, reversed(arg_shape), write_offsets, write_pattern): fsm.If(prev_done)( read_count.inc(), write_offset.add( optimize(bt.to_byte(out_stride * self.get_ram_width())))) fsm.If(prev_done, read_count == maxval - 1)(read_count(0), write_offset(0)) prev_done = vg.Ands(prev_done, (read_count == maxval - 1)) fsm.If(laddr == read_size - 1)(read_offset.add( optimize(bt.to_byte(read_size * arg.get_ram_width())))) fsm.If(laddr < read_size - 1).goto(modify_state) fsm.If(laddr == read_size - 1).goto(read_state) fsm.If(prev_done).goto_next()
def _synthesize_read_fsm(self): op_id = 1 if op_id in self.read_ops: """ already synthesized op """ return if self.read_fsm is not None: """ new op """ self.read_ops.append(op_id) return """ new op and fsm """ fsm = FSM(self.m, '_'.join(['', self.name, 'read_fsm']), self.clk, self.rst, as_module=self.fsm_as_module) self.read_fsm = fsm self.read_ops.append(op_id) cur_global_addr = self.m.Reg('_'.join(['', self.name, 'read_cur_global_addr']), self.addrwidth, initval=0) cur_size = self.m.Reg('_'.join(['', self.name, 'read_cur_size']), self.addrwidth + 1, initval=0) rest_size = self.m.Reg('_'.join(['', self.name, 'read_rest_size']), self.addrwidth + 1, initval=0) max_burstlen = 2 ** self.burst_size_width # state 0 if not self.use_global_base_addr: gaddr = self.read_global_addr else: gaddr = self.read_global_addr + self.global_base_addr fsm.If(self.read_start)( cur_global_addr(self.mask_addr(gaddr)), rest_size(self.read_size) ) fsm.If(self.read_start).goto_next() # state 1 check_state = fsm.current self._check_4KB_boundary(fsm, max_burstlen, cur_global_addr, cur_size, rest_size) # state 2 ack = self.read_request(cur_global_addr, cur_size, cond=fsm) fsm.If(ack).goto_next() accept = vtypes.Ands(self.raddr.arvalid, self.raddr.arready) fsm.If(accept)( cur_global_addr.add(optimize(cur_size * (self.datawidth // 8))) ) fsm.If(accept, rest_size > 0).goto(check_state) fsm.If(accept, rest_size == 0).goto_next() for _ in range(self.num_data_delay): fsm.goto_next() # state 3 set_idle = self._set_flag(fsm) self.seq.If(set_idle)( self.read_idle(1) ) fsm.goto_init()