def test_ram():
    main = m.DefineCircuit("main", "rdata", m.Out(m.Bit), "CLKIN",
                           m.In(m.Clock))

    ram = mantle.RAM(4, 1, name="ram")

    waddr = mantle.Counter(2, cout=False)
    wdata = mantle.Counter(1, cout=False)
    we = 1
    raddr = mantle.Counter(2, cout=False)

    ram(raddr, waddr, wdata, we, CLK=main.CLKIN)

    m.wire(ram.RDATA[0], main.rdata)
    m.EndDefine()
    if m.mantle_target == "coreir":
        output = "coreir"
        suffix = "json"
    else:
        output = "verilog"
        suffix = "v"
    m.compile(f"build/test_common_ram_{m.mantle_target}", main, output)
    assert check_files_equal(
        __file__, f"build/test_common_ram_{m.mantle_target}.{suffix}",
        f"gold/test_common_ram_{m.mantle_target}.{suffix}")
Exemple #2
0
	def __init__(self, ARES_design_type, depth):
		#这个self.name 和self.io必须得有
		#self.name = "ARES_FIFO_DESIGN"
		self.io = io = m.IO(ARES_design = ARES_design_type)
		#io += m.ClockIO()
		
		addr_width = m.bitutils.clog2(depth)
		print ("ARES addr width : " + str(addr_width) )
		buffer = mantle.RAM(2**addr_width, io.ARES_design.WData.flat_length())
		
		buffer.WDATA @= m.as_bits(io.ARES_design.WData)
		io.ARES_design.RData @= buffer.RDATA
		
		read_pointer = mantle.Register(addr_width + 1)
		write_pointer = mantle.Register(addr_width + 1)
		buffer.RADDR @= read_pointer.O[:addr_width]
		buffer.WADDR @= write_pointer.O[:addr_width]
		
		reset = io.ARES_design.RESET

		full = \
			(read_pointer.O[:addr_width] == write_pointer.O[:addr_width]) \
			& \
			(read_pointer.O[addr_width] != write_pointer.O[addr_width])
		
		empty = read_pointer.O == write_pointer.O
		write_valid = io.ARES_design.Write & ~full
		read_valid = io.ARES_design.Read & ~empty
	
		io.ARES_design.Full @= full
		
		buffer.WE @= write_valid

		write_p = mantle.mux([
			write_pointer.O, m.uint(write_pointer.O) + 1
		], write_valid)
		
		write_pointer.I @= mantle.mux([
			write_p, 0
		], reset)
	
		io.ARES_design.Empty @= empty
		
		read_p = mantle.mux([
			read_pointer.O, m.uint(read_pointer.O) + 1
		], read_valid)

		read_pointer.I @= mantle.mux([
			read_p, 0 
		], reset)
Exemple #3
0
def test_ram():
    main = m.DefineCircuit("main", "rdata", m.Out(m.Bit), "CLKIN",
                           m.In(m.Clock))

    ram = mantle.RAM(4, 1)

    waddr = mantle.Counter(4)
    wdata = mantle.Counter(1)
    we = 1
    raddr = mantle.FF()(mantle.Counter(4))

    ram(raddr, waddr, wdata, we, CLK=main.CLKIN)

    m.wire(ram.RDATA, main.rdata)
    m.EndDefine()
    m.compile("build/test_common_ram", main)
Exemple #4
0
	class FIFO(m.Circuit):
		io = m.IO(ARES_design = ARES_design_type)
		#io += m.ClockIO()
		
		addr_width = m.bitutils.clog2(depth)
		buffer = mantle.RAM(2**addr_width, io.ARES_design.WData.flat_length())
		
		buffer.WDATA @= m.as_bits(io.ARES_design.WData)
		io.ARES_design.RData @= buffer.RDATA
		
		read_pointer = mantle.Register(addr_width + 1)
		write_pointer = mantle.Register(addr_width + 1)
		buffer.RADDR @= read_pointer.O[:addr_width]
		buffer.WADDR @= write_pointer.O[:addr_width]
		
		reset = io.ARES_design.RESET

		full = \
			(read_pointer.O[:addr_width] == write_pointer.O[:addr_width]) \
			& \
			(read_pointer.O[addr_width] != write_pointer.O[addr_width])
		
		empty = read_pointer.O == write_pointer.O
		write_valid = io.ARES_design.Write & ~full
		read_valid = io.ARES_design.Read & ~empty
	
		io.ARES_design.Full @= full
		
		buffer.WE @= write_valid

		write_p = mantle.mux([
			write_pointer.O, m.uint(write_pointer.O) + 1
		], write_valid)
		
		write_pointer.I @= mantle.mux([
			write_p, 0
		], reset)
	
		io.ARES_design.Empty @= empty
		
		read_p = mantle.mux([
			read_pointer.O, m.uint(read_pointer.O) + 1
		], read_valid)

		read_pointer.I @= mantle.mux([
			read_p, 0 
		], reset)
Exemple #5
0
    def definition(io):
        # save the weights to memory (ROM)
        weights_rom = ROMB(len(weights_list), 16, weights_list)
        wire(io.CYCLE, weights_rom.RADDR[:n])
        wire(io.IDX, weights_rom.RADDR[n:n + b])
        if n + b < 8:
            wire(bits(0, 8 - n - b), weights_rom.RADDR[n + b:])
        wire(1, weights_rom.RE)
        wire(weights_rom.RDATA, io.WEIGHT)
        wire(io.CLK, weights_rom.RCLK)

        # save the image to RAM, 16 bits at a time
        image_ram = mantle.RAM(4, 16)
        wire(io.WE, image_ram.WE)
        wire(io.CLK, image_ram.CLK)
        wire(io.CYCLE, image_ram.RADDR)
        wire(io.WADDR, image_ram.WADDR)
        wire(io.DATA, image_ram.WDATA)
        wire(image_ram.RDATA, io.IMAGE)
Exemple #6
0
def test_ram():
    main = m.DefineCircuit("main", "rdata", m.Out(m.Bit), "CLKIN",
                           m.In(m.Clock))

    ram = mantle.RAM(4, 1)

    waddr = mantle.Counter(4, cout=False)
    wdata = mantle.Counter(1, cout=False)
    we = 1
    raddr = mantle.Counter(4, cout=False)

    ram(raddr, waddr, wdata, we, CLK=main.CLKIN)

    m.wire(ram.RDATA[0], main.rdata)
    m.EndDefine()
    if m.mantle_target == "coreir":
        output = "coreir"
    else:
        output = "verilog"
    m.compile("build/test_common_ram", main, output)
Exemple #7
0
        def definition(io):
            addr_width = m.bitutils.clog2(depth)

            buffer = mantle.RAM(addr_width, flat_length(io.data_in.data))

            # pack data into bits
            buffer.WDATA <= flatten_fields_to_bits(io.data_in.data)

            # unpack bits into tuple
            io.data_out.data <= unflatten_bits_to_fields(
                io.data_out.data, buffer.RDATA)

            read_pointer = mantle.Register(addr_width + 1)
            write_pointer = mantle.Register(addr_width + 1)
            buffer.RADDR <= read_pointer.O[:addr_width]
            buffer.WADDR <= write_pointer.O[:addr_width]

            full = \
                (read_pointer.O[:addr_width] == write_pointer.O[:addr_width]) \
                & \
                (read_pointer.O[addr_width] != write_pointer.O[addr_width])

            empty = read_pointer == write_pointer
            write_valid = io.data_in.valid & ~full
            read_valid = io.data_out.ready & ~empty

            io.data_in.ready <= ~full

            buffer.WE <= write_valid
            write_pointer.I <= mantle.mux(
                [write_pointer.O, m.uint(write_pointer.O) + 1], write_valid)

            io.data_out.valid <= read_valid

            read_pointer.I <= mantle.mux(
                [read_pointer.O, m.uint(read_pointer.O) + 1], read_valid)
    class AXI(m.Circuit):
        interface = make_HandshakeData(data_type)
        io = m.IO(ARES_design=interface)

        addr_width = m.bitutils.clog2(depth)

        reset = io.ARES_design.RESET

        #data_buffer
        #===============================================================

        buffer = mantle.RAM(2**addr_width, io.ARES_design.W_data.flat_length())

        #WReq	操作
        #===============================================================
        WReq_size_reg = mantle.Register(32)
        WReq_addr_reg = mantle.Register(32)

        #不要改! 这个have_WReq_signal 代表我现在有一个WReq要处理
        have_WReq_signal = ~(WReq_size_reg.O == 0)
        #不要改! 有WReq就不能再接新的了!所以WReq_ready要为0
        io.ARES_design.WReq_ready @= mantle.mux([~have_WReq_signal, 1], reset)

        WReq_valid_signal = io.ARES_design.WReq_valid & ~have_WReq_signal

        receive_WReq_size_signal = mantle.mux(
            [m.uint(0, 32), io.ARES_design.WReq_size], WReq_valid_signal)
        receive_WReq_addr_signal = mantle.mux(
            [m.uint(0, 32), io.ARES_design.WReq_addr], WReq_valid_signal)

        #这个是真Write_valid 这个东西的意思就是,我用have_WReq_signal代表W_ready。假如W_valid为1,那就是握手完成
        #本来应该放在Write 操作里的,我放在这里是要reduce WReq_size
        W_valid_signal = io.ARES_design.W_valid & have_WReq_signal

        reduce_WReq_size_signal = mantle.mux(
            [WReq_size_reg.O, m.uint(WReq_size_reg.O) - 1], W_valid_signal)

        #有WReq则处理size,没有则准备好从外面拿
        WReq_size_signal = mantle.mux(
            [receive_WReq_size_signal, reduce_WReq_size_signal],
            have_WReq_signal)
        WReq_size_reg.I @= mantle.mux([WReq_size_signal, m.uint(0, 32)], reset)

        #有WReq则保留addr,没有则准备好从外面拿
        WReq_addr_signal = mantle.mux(
            [receive_WReq_addr_signal, WReq_addr_reg.O], have_WReq_signal)
        WReq_addr_reg.I @= mantle.mux([WReq_addr_signal, m.uint(0, 32)], reset)

        #Write 操作
        #===============================================================
        #W_ready
        io.ARES_design.W_ready @= mantle.mux([have_WReq_signal, 0], reset)

        #W_size_reg
        W_size_reg = mantle.Register(32)
        W_size_reg_increase_signal = mantle.mux(
            [W_size_reg.O, m.uint(W_size_reg.O) + 1], W_valid_signal)
        W_size_signal = mantle.mux([m.uint(0, 32), W_size_reg_increase_signal],
                                   have_WReq_signal)

        W_size_reg.I @= mantle.mux([W_size_signal, 0], reset)

        #buffer
        buffer.WDATA @= io.ARES_design.W_data
        buffer.WADDR @= mantle.add(WReq_addr_reg.O[:addr_width],
                                   W_size_reg.O[:addr_width])

        #have_WReq_signal 就是W_ready,这意味着W_valid和W_ready 同时为1
        buffer.WE @= W_valid_signal

        #RReq	操作
        #===============================================================

        RReq_size_reg = mantle.Register(32)
        RReq_addr_reg = mantle.Register(32)

        #不要改! 这个have_RReq_signal 代表我现在有一个WReq要处理
        have_RReq_signal = ~(RReq_size_reg.O == 0)
        #TODO 关于RReq,我现在的办法是从reset起我就能接受RReq,外面随便发读请求,但是读出什么来不好说,大不了就是X
        io.ARES_design.RReq_ready @= mantle.mux([~have_RReq_signal, 1], reset)

        RReq_valid_signal = io.ARES_design.RReq_valid & ~have_RReq_signal

        receive_RReq_size_signal = mantle.mux(
            [m.uint(0, 32), io.ARES_design.RReq_size], RReq_valid_signal)
        receive_RReq_addr_signal = mantle.mux(
            [m.uint(0, 32), io.ARES_design.RReq_addr], RReq_valid_signal)

        #这个是真.R_valid。这个东西的意思就是,我用have_RReq_signal代表R_valid。假如R_ready为1,那就是握手完成
        #其实这个信号应该放在Read操作里,但是由于我要用R_valid_signal来让RReq_size减少,所以放在这弄
        R_valid_signal = io.ARES_design.R_ready & have_RReq_signal

        #减少RReq_size
        reduce_RReq_size_signal = mantle.mux(
            [RReq_size_reg.O, m.uint(RReq_size_reg.O) - 1], R_valid_signal)

        #有RReq则处理size,没有则准备好从外面拿
        RReq_size_signal = mantle.mux(
            [receive_RReq_size_signal, reduce_RReq_size_signal],
            have_RReq_signal)
        RReq_size_reg.I @= mantle.mux([RReq_size_signal, m.uint(0, 32)], reset)

        #有RReq则保留addr,没有则准备好从外面拿
        RReq_addr_signal = mantle.mux(
            [receive_RReq_addr_signal, RReq_addr_reg.O], have_RReq_signal)
        RReq_addr_reg.I @= mantle.mux([RReq_addr_signal, m.uint(0, 32)], reset)

        #Read操作
        #===============================================================
        io.ARES_design.R_valid @= mantle.mux([have_RReq_signal, 0], reset)

        #R_size_reg
        R_size_reg = mantle.Register(32)
        R_size_reg_increase_signal = mantle.mux(
            [R_size_reg.O, m.uint(R_size_reg.O) + 1], R_valid_signal)
        R_size_signal = mantle.mux([m.uint(0, 32), R_size_reg_increase_signal],
                                   have_RReq_signal)

        R_size_reg.I @= mantle.mux([R_size_signal, 0], reset)

        buffer.RADDR @= mantle.add(RReq_addr_reg.O[:addr_width],
                                   R_size_reg.O[:addr_width])
        io.ARES_design.R_data @= buffer.RDATA