def mk_ipgen_slave_lite_memory(): m = module.Module('ipgen_slave_lite_memory') name = m.Parameter('NAME', 'undefined') _id = m.Parameter('ID', 0) addr_width = m.Parameter('ADDR_WIDTH', 32) data_width = m.Parameter('DATA_WIDTH', 32) clk = m.Input('CLK') rst = m.Input('RST') awvalid = m.Output('awvalid') awaddr = m.Output('awaddr', addr_width) awready = m.Input('awready') wdata = m.Output('wdata', data_width) wstrb = m.Output('wstrb', data_width / 8) wvalid = m.Output('wvalid') wready = m.Input('wready') arvalid = m.Output('arvalid') araddr = m.Output('araddr', addr_width) arready = m.Input('arready') rdata = m.Input('rdata', data_width) rvalid = m.Input('rvalid') rready = m.Output('rready') return m
def mkMultiplier(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 2.") retwidth = lwidth + rwidth mult = mkMultiplierCore(index, lwidth, rwidth, lsigned, rsigned, depth) m = module.Module('multiplier_%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) ports = [('CLK', clk), ('update', update), ('a', a), ('b', b), ('c', c)] m.Instance(mult, 'mult', ports=ports) return m
def mkCoramMemoryDefinition(numports): name = 'CoramMemory%dP' % numports m = module.Module(name) coram_thread_name = m.Parameter('CORAM_THREAD_NAME', 'none') coram_thread_id = m.Parameter('CORAM_THREAD_ID', 0) coram_id = m.Parameter('CORAM_ID', 0) coram_sub_id = m.Parameter('CORAM_SUB_ID', 0) coram_addr_len = m.Parameter('CORAM_ADDR_LEN', 10) coram_data_width = m.Parameter('CORAM_DATA_WIDTH', 32) clk = m.Input('CLK') interfaces = [] for i in range(numports): index = i if numports > 1 else None interface = CoramMemorySlaveInterface(m, datawidth=coram_data_width, addrwidth=coram_addr_len, index=index) delay_addr_name = 'D_ADDR%d' % i if numports > 1 else 'D_ADDR' interface.delay_addr = m.Reg(delay_addr_name, coram_addr_len) interfaces.append(interface) mem = m.Reg('mem', coram_data_width, length=vtypes.Int(2)**coram_addr_len) for interface in interfaces: m.Always(vtypes.Posedge(clk))(vtypes.If(interface.wenable)( mem[interface.addr](interface.wdata)), interface.delay_addr(interface.addr)) m.Assign(interface.rdata(mem[interface.delay_addr])) return m
def mkMadd(index, awidth=32, bwidth=32, cwidth=32, asigned=True, bsigned=True, csigned=True, depth=6): if awidth < 0: raise ValueError("data width must be greater than 0.") if bwidth < 0: raise ValueError("data width must be greater than 0.") if cwidth < 0: raise ValueError("data width must be greater than 0.") if depth < 2: raise ValueError("depth must be greater than 2.") retwidth = max(awidth + bwidth, cwidth) madd = mkMaddCore(index, awidth, bwidth, cwidth, asigned, bsigned, csigned, depth) m = module.Module('madd_%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) ports = [('CLK', clk), ('update', update), ('a', a), ('b', b), ('c', c), ('d', d)] m.Instance(madd, 'madd', ports=ports) return m
def generate_top(m, name, clkname='CLK', rstname='RST'): if not isinstance(m, module.Module): raise TypeError("'m' must be Module, not %s" % str(type(m))) masterbus = m.masterbus if hasattr(m, 'masterbus') else () slavebus = m.slavebus if hasattr(m, 'slavebus') else () include_names = [master.name for master in masterbus] include_names += [slave.name for slave in slavebus] top = module.Module(name) params = top.copy_params(m) ports = top.copy_ports(m, exclude=tuple(include_names)) bus_ports = top.copy_sim_ports( m, include=tuple(include_names), use_wire=True) body = top.Instance(m, 'inst_' + m.name, params=top.connect_params(m), ports=top.connect_ports(m)) clk = ports[clkname] rst = ports[rstname] _id_count = 0 for master in masterbus: port_list = OrderedDict([(k, v) for k, v in top.get_vars().items() if k.startswith(master.name)]) name = master.name _id = _id_count _id_count += 1 addr_width = port_list[master.name + '_awaddr'].width data_width = port_list[master.name + '_wdata'].width mod = ipgen_master_lite_memory() if master.lite else ipgen_master_memory() inst_params = (('NAME', name), ('ID', _id), ('ADDR_WIDTH', addr_width), ('DATA_WIDTH', data_width)) inst_ports = [('CLK', clk), ('RST', rst)] inst_ports += top.connect_ports(mod, prefix=name + '_') top.Instance(mod, 'inst_' + name, params=inst_params, ports=inst_ports) for slave in slavebus: port_list = OrderedDict([(k, v) for k, v in top.get_vars().items() if k.startswith(slave.name)]) name = slave.name _id = _id_count _id_count += 1 addr_width = port_list[slave.name + '_awaddr'].width data_width = port_list[slave.name + '_wdata'].width mod = ipgen_slave_lite_memory() if slave.lite else ipgen_slave_memory() inst_params = (('NAME', name), ('ID', _id), ('ADDR_WIDTH', addr_width), ('DATA_WIDTH', data_width)) inst_ports = [('CLK', clk), ('RST', rst)] inst_ports += top.connect_ports(mod, prefix=name + '_') top.Instance(mod, 'inst_' + name, params=inst_params, ports=inst_ports) return top
def mkMultiplier(name, lsigned=True, rsigned=True, depth=6, with_update=True, with_enable=True): mult = mkMultiplierCore(name, lsigned, rsigned, depth, with_update) m = module.Module(name) lwidth = m.Parameter('lwidth', 32) rwidth = m.Parameter('rwidth', 32) retwidth = lwidth + rwidth clk = m.Input('CLK') rst = m.Input('RST') if with_update: update = m.Input('update') if with_enable: enable = m.Input('enable') else: enable = 1 if with_enable: valid = m.Output('valid') a = m.Input('a', lwidth) b = m.Input('b', rwidth) c = m.Output('c', retwidth) if with_enable: valid_reg = [m.Reg('valid_reg%d' % i) for i in range(depth)] m.Assign(valid(valid_reg[depth - 1])) body = (valid_reg[0](enable), [valid_reg[i](valid_reg[i - 1]) for i in range(1, depth)]) if with_update: body = vtypes.If(update)(body) m.Always(vtypes.Posedge(clk))( vtypes.If(rst)([valid_reg[i](0) for i in range(depth)]).Else(body)) params = [('lwidth', lwidth), ('rwidth', rwidth)] ports = [('CLK', clk)] if with_update: ports.append(('update', update)) ports.extend([('a', a), ('b', b), ('c', c)]) m.Instance(mult, 'mult', params=params, ports=ports) return m
def visit_ModuleDef(self, node): # check module cache if node.name in self.converted_modules: return self.converted_modules[node.name] # create new Verilog module m = module.Module(node.name) self.push_module(m) self.generic_visit(node) self.pop_module() self.converted_modules[node.name] = m return m
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 mkFifoDefinition(name, datawidth=32, addrwidth=4): m = module.Module(name) clk = m.Input('CLK') rst = m.Input('RST') wif = FifoWriteSlaveInterface(m, name, datawidth) rif = FifoReadSlaveInterface(m, name, datawidth) mem = m.Reg('mem', datawidth, 2**addrwidth) head = m.Reg('head', addrwidth, initval=0) tail = m.Reg('tail', addrwidth, initval=0) is_empty = m.Wire('is_empty') is_almost_empty = m.Wire('is_almost_empty') is_full = m.Wire('is_full') is_almost_full = m.Wire('is_almost_full') mask = (2**addrwidth) - 1 is_empty.assign(head == tail) is_almost_empty.assign(head == ((tail + 1) & mask)) is_full.assign(((head + 1) & mask) == tail) is_almost_full.assign(((head + 2) & mask) == tail) rdata = m.Reg('rdata_reg', datawidth, initval=0) wif.full.assign(is_full) wif.almost_full.assign(vtypes.Ors(is_almost_full, is_full)) rif.empty.assign(is_empty) rif.almost_empty.assign(vtypes.Ors(is_almost_empty, is_empty)) seq = Seq(m, '', clk, rst) seq.If(vtypes.Ands(wif.enq, vtypes.Not(is_full)))(mem[head](wif.wdata), head.inc()) seq.If(vtypes.Ands(rif.deq, vtypes.Not(is_empty)))(rdata(mem[tail]), tail.inc()) rif.rdata.assign(rdata) seq.make_always() return m
def mkMultiplier(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 mult = mkMultiplierCore(index, lwidth, rwidth, lsigned, rsigned, depth) m = module.Module('multiplier_%d' % index) clk = m.Input('CLK') rst = m.Input('RST') update = m.Input('update') enable = m.Input('enable') valid = m.Output('valid') a = m.Input('a', lwidth) b = m.Input('b', rwidth) c = m.Output('c', retwidth) valid_reg = [m.Reg('valid_reg%d' % i) for i in range(depth)] m.Assign(valid(valid_reg[depth - 1])) m.Always(vtypes.Posedge(clk))( vtypes.If(rst)([valid_reg[i](0) for i in range(depth)]).Else( vtypes.If(update)( valid_reg[0](enable), [valid_reg[i](valid_reg[i - 1]) for i in range(1, depth)]))) ports = [('CLK', clk), ('update', update), ('a', a), ('b', b), ('c', c)] m.Instance(mult, 'mult', ports=ports) 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 mkCoramChannelDefinition(): name = 'CoramChannel' m = module.Module(name) coram_thread_name = m.Parameter('CORAM_THREAD_NAME', 'none') coram_thread_id = m.Parameter('CORAM_THREAD_ID', 0) coram_id = m.Parameter('CORAM_ID', 0) coram_sub_id = m.Parameter('CORAM_SUB_ID', 0) coram_addr_len = m.Parameter('CORAM_ADDR_LEN', 10) coram_data_width = m.Parameter('CORAM_DATA_WIDTH', 32) clk = m.Input('CLK') rst = m.Input('RST') wif = CoramChannelWriteSlaveInterface(m, datawidth=coram_data_width) rif = CoramChannelReadSlaveInterface(m, datawidth=coram_data_width) wif.full.assign(0) wif.almost_full.assign(0) rif.rdata.assign(1) rif.empty.assign(0) rif.almost_empty.assign(0) return m