def visit_Cat(self, node): left = [] right = [] for v in node.vars: val = self.visit(v) right = vtypes.IntX() if val is None else val.right left.append(v) right.append(right) return vtypes.Subst(vtypes.Cat(tuple(left)), vtypes.Cat(tuple(right)))
def mkMultiplierCore(name, lsigned=True, rsigned=True, depth=6, with_update=True): m = module.Module(name + '_core') lwidth = m.Parameter('lwidth', 32) rwidth = m.Parameter('rwidth', 32) retwidth = lwidth + rwidth clk = m.Input('CLK') if with_update: update = m.Input('update') a = m.Input('a', lwidth) b = m.Input('b', rwidth) c = m.Output('c', retwidth) _a = m.Reg('_a', lwidth, signed=lsigned) _b = m.Reg('_b', rwidth, signed=rsigned) _mul = m.Wire('_mul', retwidth, signed=True) _pipe_mul = [ m.Reg('_pipe_mul%d' % i, retwidth, signed=True) for i in range(depth - 1) ] __a = _a __b = _b if not lsigned: __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _a)) if not rsigned: __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _b)) m.Assign(_mul(__a * __b)) m.Assign(c(_pipe_mul[depth - 2])) body = (_a(a), _b(b), _pipe_mul[0](_mul), [_pipe_mul[i](_pipe_mul[i - 1]) for i in range(1, depth - 1)]) if with_update: body = vtypes.If(update)(body) m.Always(vtypes.Posedge(clk))(body) return m
def mkMaddCore(index, awidth=32, bwidth=32, cwidth=32, asigned=True, bsigned=True, csigned=True, depth=6): retwidth = max(awidth + bwidth, cwidth) m = module.Module('madd_core_%d' % index) clk = m.Input('CLK') update = m.Input('update') a = m.Input('a', awidth) b = m.Input('b', bwidth) c = m.Input('c', cwidth) d = m.Output('d', retwidth) _a = m.Reg('_a', awidth, signed=asigned) _b = m.Reg('_b', bwidth, signed=bsigned) _c = m.Reg('_c', cwidth, signed=csigned) _mul = m.Wire('_mul', retwidth, signed=True) _madd = m.Wire('_madd', retwidth, signed=True) _pipe_madd = [m.Reg('_pipe_madd%d' % i, retwidth, signed=True) for i in range(depth - 1)] __a = _a __b = _b __c = _c if not asigned: __a = vtypes.SystemTask( 'signed', vtypes.Cat(vtypes.Int(0, width=1), _a)) if not bsigned: __b = vtypes.SystemTask( 'signed', vtypes.Cat(vtypes.Int(0, width=1), _b)) if not csigned: __c = vtypes.SystemTask( 'signed', vtypes.Cat(vtypes.Int(0, width=1), _c)) m.Assign(_mul(__a * __b)) m.Assign(_madd(_mul + __c)) m.Assign(d(_pipe_madd[depth - 2])) m.Always(vtypes.Posedge(clk))( vtypes.If(update)( _a(a), _b(b), _c(c), _pipe_madd[0](_madd), [_pipe_madd[i](_pipe_madd[i - 1]) for i in range(1, depth - 1)] )) return m
def mkMultiplierCore(index, lwidth=32, rwidth=32, lsigned=True, rsigned=True, depth=6): if lwidth <= 0: raise ValueError("data width must be greater than 0.") if rwidth <= 0: raise ValueError("data width must be greater than 0.") if depth < 2: raise ValueError("depth must be greater than 1.") retwidth = lwidth + rwidth m = module.Module('multiplier_core_%d' % index) clk = m.Input('CLK') update = m.Input('update') a = m.Input('a', lwidth) b = m.Input('b', rwidth) c = m.Output('c', retwidth) _a = m.Reg('_a', lwidth, signed=lsigned) _b = m.Reg('_b', rwidth, signed=rsigned) _mul = m.Wire('_mul', retwidth, signed=True) _pipe_mul = [ m.Reg('_pipe_mul%d' % i, retwidth, signed=True) for i in range(depth - 1) ] __a = _a __b = _b if not lsigned: __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _a)) if not rsigned: __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _b)) m.Assign(_mul(__a * __b)) m.Assign(c(_pipe_mul[depth - 2])) m.Always(vtypes.Posedge(clk))(vtypes.If(update)( _a(a), _b(b), _pipe_mul[0](_mul), [_pipe_mul[i](_pipe_mul[i - 1]) for i in range(1, depth - 1)])) return m
def mkMultiplierCore(index, lwidth=32, rwidth=32, lsigned=True, rsigned=True, depth=6): retwidth = lwidth + rwidth m = module.Module('multiplier_core_%d' % index) clk = m.Input('CLK') update = m.Input('update') a = m.Input('a', lwidth) b = m.Input('b', rwidth) c = m.Output('c', retwidth) _a = m.Reg('_a', lwidth, signed=lsigned) _b = m.Reg('_b', rwidth, signed=rsigned) tmpval = [ m.Reg('_tmpval%d' % i, retwidth, signed=True) for i in range(depth - 1) ] rslt = m.Wire('rslt', retwidth, signed=True) __a = _a __b = _b if not lsigned: __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _a)) if not rsigned: __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _b)) m.Assign(rslt(__a * __b)) m.Assign(c(tmpval[depth - 2])) m.Always(vtypes.Posedge(clk))(vtypes.If(update)( _a(a), _b(b), tmpval[0](rslt), [tmpval[i](tmpval[i - 1]) for i in range(1, depth - 1)])) return m
def visit_Cat(self, node): left_values = [] right_values = [] for v in node.vars: val = self.visit(v) width = v.bit_length() if width is None: width = 1 if val is None: right = vtypes.IntX(width) elif isinstance(val.right, int): right = vtypes.Int(val.right, width) elif isinstance(val.right, vtypes._Constant): right = copy.deepcopy(val.right) right.width = width else: right = v._get_module().TmpLocalparam(val.right, width) left_values.append(v) right_values.append(right) return vtypes.Subst(vtypes.Cat(*left_values), vtypes.Cat(*right_values))
def mkUartRx(baudrate=19200, clockfreq=100 * 1000 * 1000): m = Module("UartRx") waitnum = int(clockfreq / baudrate) clk = m.Input('CLK') rst = m.Input('RST') rxd = m.Input('rxd') dout = m.OutputReg('dout', 8, initval=0) valid = m.OutputReg('valid', initval=0) fsm = FSM(m, 'fsm', clk, rst) mem = m.TmpReg(9, initval=0) waitcount = m.TmpReg(int(math.log(waitnum, 2)) + 1, initval=0) fsm(valid(0), waitcount(int(waitnum / 2) - 1), mem(vtypes.Cat(rxd, mem[1:9]))) fsm.If(rxd == 0).goto_next() for i in range(10): if i == 0: # check the start bit again fsm.If(vtypes.Ands(waitcount == 1, rxd != 0)).goto_init() fsm.If(waitcount > 0)(waitcount.dec()).Else( mem(vtypes.Cat(rxd, mem[1:9])), waitcount(waitnum - 1)) fsm.Then().goto_next() fsm(valid(1), dout(mem[0:9])) fsm.goto_init() fsm.make_always() return m
def mkUartTx(baudrate=19200, clockfreq=100 * 1000 * 1000): m = Module("UartTx") waitnum = int(clockfreq / baudrate) clk = m.Input('CLK') rst = m.Input('RST') din = m.Input('din', 8) enable = m.Input('enable') ready = m.OutputReg('ready', initval=1) txd = m.OutputReg('txd', initval=1) fsm = FSM(m, 'fsm', clk, rst) mem = m.TmpReg(9, initval=0) waitcount = m.TmpReg(int(math.log(waitnum, 2)) + 1, initval=0) fsm(waitcount(waitnum - 1), txd(1), mem(vtypes.Cat(din, vtypes.Int(0, 1)))) fsm.If(enable)(ready(0)) fsm.Then().goto_next() for i in range(10): fsm.If(waitcount > 0)(waitcount.dec()).Else( txd(mem[0]), mem(vtypes.Cat(vtypes.Int(1, 1), mem[1:9])), waitcount(waitnum - 1)) fsm.Then().goto_next() fsm(ready(1)) fsm.goto_init() fsm.make_always() return m
def visit_LConcat(self, node): vars = [self.visit(var) for var in node.list] return vtypes.Cat(*vars)
def visit_Repeat(self, node): var = (self.visit(node.var) if isinstance(node.var, vtypes.Cat) else self.visit(vtypes.Cat(node.var))) times = self.visit(node.times) return vast.Repeat(var, times)
def visit_Cat(self, node): vars = [self.visit(var) for var in node.vars] return vtypes.Cat(*vars)
def _synthesize_read_fsm_fifo_narrow(self, fifo, fifo_datawidth): """ axi.datawidth < fifo.datawidth """ if fifo_datawidth % self.datawidth != 0: raise ValueError( 'fifo_datawidth must be multiple number of axi.datawidth') pack_size = fifo_datawidth // self.datawidth dma_size = (self.read_size << int(math.log(pack_size, 2)) if math.log(pack_size, 2) % 1.0 == 0.0 else self.read_size * pack_size) op_id = self._get_read_op_id_fifo(fifo) if op_id in self.read_ops: """ already synthesized op """ return if pack_size in self.read_narrow_fsms: """ new op """ self.read_ops.append(op_id) fsm = self.read_narrow_fsms[pack_size] pack_count = self.read_narrow_pack_counts[pack_size] data = self.read_narrow_data_wires[pack_size] valid = self.read_narrow_valid_wires[pack_size] rest_size = self.read_narrow_rest_size_wires[pack_size] # state 0 fsm.set_index(0) cond = vtypes.Ands(self.read_start, self.read_op_sel == op_id) fsm.If(cond).goto_next() # state 1 fsm.set_index(1) wdata = self.m.Reg('_'.join(['', self.name, 'read_narrow', str(pack_size), 'wdata']), fifo_datawidth, initval=0) wvalid = self.m.Reg('_'.join(['', self.name, 'read_narrow', str(pack_size), 'wvalid'])) valid_cond = vtypes.Ands(valid, self.read_op_sel == op_id) ack, _ = fifo.enq_rtl(wdata, cond=wvalid) fsm.Delay(1)( wvalid(0) ) fsm.If(rest_size == 0, pack_count > 0)( wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])), wvalid(0), pack_count.inc() ) fsm.If(valid_cond)( wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])), wvalid(0), pack_count.inc() ) fsm.If(rest_size == 0, pack_count == pack_size - 1)( wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])), wvalid(1), pack_count(0) ) fsm.If(valid_cond, pack_count == pack_size - 1)( wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])), wvalid(1), pack_count(0) ) fsm.If(valid_cond)( rest_size.dec() ) return """ new op and fsm """ fsm = FSM(self.m, '_'.join(['', self.name, 'read_narrow', str(pack_size), 'fsm']), self.clk, self.rst, as_module=self.fsm_as_module) self.read_narrow_fsms[pack_size] = fsm self.read_ops.append(op_id) rest_size = self.m.Reg('_'.join(['', self.name, 'read_narrow', str(pack_size), 'rest_size']), self.addrwidth + 1, initval=0) self.read_narrow_rest_size_wires[pack_size] = rest_size # state 0 cond = vtypes.Ands(self.read_start, self.read_op_sel == op_id) fsm.If(self.read_start)( rest_size(dma_size) ) fsm.If(cond).goto_next() # state 1 pack_count = self.m.Reg('_'.join(['', self.name, 'read_narrow', str(pack_size), 'pack_count']), int(math.ceil(math.log(pack_size, 2))), initval=0) self.read_narrow_pack_counts[pack_size] = pack_count ready = vtypes.Not(fifo.almost_full) read_cond = vtypes.Ands(fsm.here, ready) data, last, _id, user, dest, valid = self.read_data(cond=read_cond) self.read_narrow_data_wires[pack_size] = data self.read_narrow_valid_wires[pack_size] = valid wdata = self.m.Reg('_'.join(['', self.name, 'read_narrow', str(pack_size), 'wdata']), fifo_datawidth, initval=0) wvalid = self.m.Reg('_'.join(['', self.name, 'read_narrow', str(pack_size), 'wvalid'])) valid_cond = vtypes.Ands(valid, self.read_op_sel == op_id) ack, _ = fifo.enq_rtl(wdata, cond=wvalid) fsm.Delay(1)( wvalid(0) ) fsm.If(rest_size == 0, pack_count > 0)( wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])), wvalid(0), pack_count.inc() ) fsm.If(valid_cond)( wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])), wvalid(0), pack_count.inc() ) fsm.If(rest_size == 0, pack_count == pack_size - 1)( wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])), wvalid(1), pack_count(0) ) fsm.If(valid_cond, pack_count == pack_size - 1)( wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])), wvalid(1), pack_count(0) ) fsm.If(valid_cond)( rest_size.dec() ) fsm.If(wvalid, rest_size == 0).goto_next() # state 2 set_idle = self._set_flag(fsm) self.seq.If(set_idle)( self.read_idle(1) ) fsm.goto_init()
def _synthesize_read_fsm_narrow(self, ram, port, ram_method, ram_datawidth): """ axi.datawidth < ram.datawidth """ if ram_datawidth % self.datawidth != 0: raise ValueError( 'ram_datawidth must be multiple number of axi.datawidth') pack_size = ram_datawidth // self.datawidth dma_size = (self.read_size << int(math.log(pack_size, 2)) if math.log(pack_size, 2) % 1.0 == 0.0 else self.read_size * pack_size) op_id = self._get_read_op_id(ram, port, ram_method) port = vtypes.to_int(port) if op_id in self.read_ops: """ already synthesized op """ return if pack_size in self.read_narrow_fsms: """ new op """ self.read_ops.append(op_id) fsm = self.read_narrow_fsms[pack_size] pack_count = self.read_narrow_pack_counts[pack_size] data = self.read_narrow_data_wires[pack_size] valid = self.read_narrow_valid_wires[pack_size] rest_size = self.read_narrow_rest_size_wires[pack_size] # state 0 fsm.set_index(0) wdata, wvalid, w = self._get_op_write_dataflow(ram_datawidth) cond = vtypes.Ands(self.read_start, self.read_op_sel == op_id) ram_method(port, self.read_local_addr, w, self.read_size, stride=self.read_local_stride, cond=cond) fsm.If(cond).goto_next() # state 1 fsm.set_index(1) valid_cond = vtypes.Ands(valid, self.read_op_sel == op_id) fsm.Delay(1)( wvalid(0) ) fsm.If(rest_size == 0, pack_count > 0)( wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])), wvalid(0), pack_count.inc() ) fsm.If(valid_cond)( wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])), wvalid(0), pack_count.inc() ) fsm.If(rest_size == 0, pack_count == pack_size - 1)( wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])), wvalid(1), pack_count(0) ) fsm.If(valid_cond, pack_count == pack_size - 1)( wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])), wvalid(1), pack_count(0) ) fsm.If(valid_cond)( rest_size.dec() ) return """ new op and fsm """ fsm = FSM(self.m, '_'.join(['', self.name, 'read_narrow', str(pack_size), 'fsm']), self.clk, self.rst, as_module=self.fsm_as_module) self.read_narrow_fsms[pack_size] = fsm self.read_ops.append(op_id) rest_size = self.m.Reg('_'.join(['', self.name, 'read_narrow', str(pack_size), 'rest_size']), self.addrwidth + 1, initval=0) self.read_narrow_rest_size_wires[pack_size] = rest_size # state 0 wdata, wvalid, w = self._get_op_write_dataflow(ram_datawidth) cond = vtypes.Ands(self.read_start, self.read_op_sel == op_id) ram_method(port, self.read_local_addr, w, self.read_size, stride=self.read_local_stride, cond=cond) fsm.If(self.read_start)( rest_size(dma_size) ) fsm.If(cond).goto_next() # state 1 pack_count = self.m.Reg('_'.join(['', self.name, 'read_narrow', str(pack_size), 'pack_count']), int(math.ceil(math.log(pack_size, 2))), initval=0) self.read_narrow_pack_counts[pack_size] = pack_count data, last, _id, user, dest, valid = self.read_data(cond=fsm) self.read_narrow_data_wires[pack_size] = data self.read_narrow_valid_wires[pack_size] = valid valid_cond = vtypes.Ands(valid, self.read_op_sel == op_id) fsm.Delay(1)( wvalid(0) ) fsm.If(rest_size == 0, pack_count > 0)( wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])), wvalid(0), pack_count.inc() ) fsm.If(valid_cond)( wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])), wvalid(0), pack_count.inc() ) fsm.If(rest_size == 0, pack_count == pack_size - 1)( wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])), wvalid(1), pack_count(0) ) fsm.If(valid_cond, pack_count == pack_size - 1)( wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])), wvalid(1), pack_count(0) ) fsm.If(valid_cond)( rest_size.dec() ) fsm.If(wvalid, rest_size == 0).goto_next() for _ in range(self.num_data_delay): fsm.goto_next() # state 2 set_idle = self._set_flag(fsm) self.seq.If(set_idle)( self.read_idle(1) ) fsm.goto_init()