reorganization WIP: flatten core structure (SDRAM still needs to be done)
This commit is contained in:
parent
01be953e30
commit
83509163df
|
@ -1,8 +1,8 @@
|
|||
[submodule "extcores/lm32/submodule"]
|
||||
path = extcores/lm32/submodule
|
||||
[submodule "misoc/lm32/verilog/submodule"]
|
||||
path = misoc/lm32/verilog/submodule
|
||||
url = https://github.com/m-labs/lm32.git
|
||||
[submodule "extcores/mor1kx/submodule"]
|
||||
path = extcores/mor1kx/submodule
|
||||
[submodule "misoc/mor1kx/verilog"]
|
||||
path = misoc/mor1kx/verilog
|
||||
url = https://github.com/openrisc/mor1kx.git
|
||||
[submodule "software/compiler-rt"]
|
||||
path = software/compiler-rt
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 84b3e3ca0ad9535acaef201c1482342871358b08
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 95fc8e432d762e48b42991663cf9d0cdb918e27e
|
|
@ -1,58 +0,0 @@
|
|||
from migen import *
|
||||
from migen.bank.description import *
|
||||
from migen.bank.eventmanager import *
|
||||
from migen.genlib.record import Record
|
||||
from migen.actorlib.fifo import SyncFIFO, AsyncFIFO
|
||||
|
||||
|
||||
def _get_uart_fifo(depth, sink_cd="sys", source_cd="sys"):
|
||||
if sink_cd != source_cd:
|
||||
fifo = AsyncFIFO([("data", 8)], depth)
|
||||
return ClockDomainsRenamer({"write": sink_cd, "read": source_cd})(fifo)
|
||||
else:
|
||||
return SyncFIFO([("data", 8)], depth)
|
||||
|
||||
|
||||
class UART(Module, AutoCSR):
|
||||
def __init__(self, phy,
|
||||
tx_fifo_depth=16,
|
||||
rx_fifo_depth=16,
|
||||
phy_cd="sys"):
|
||||
self._rxtx = CSR(8)
|
||||
self._txfull = CSRStatus()
|
||||
self._rxempty = CSRStatus()
|
||||
|
||||
self.submodules.ev = EventManager()
|
||||
self.ev.tx = EventSourceProcess()
|
||||
self.ev.rx = EventSourceProcess()
|
||||
self.ev.finalize()
|
||||
|
||||
# # #
|
||||
|
||||
# TX
|
||||
tx_fifo = _get_uart_fifo(tx_fifo_depth, source_cd=phy_cd)
|
||||
self.submodules += tx_fifo
|
||||
|
||||
self.comb += [
|
||||
tx_fifo.sink.stb.eq(self._rxtx.re),
|
||||
tx_fifo.sink.data.eq(self._rxtx.r),
|
||||
self._txfull.status.eq(~tx_fifo.sink.ack),
|
||||
Record.connect(tx_fifo.source, phy.sink),
|
||||
# Generate TX IRQ when tx_fifo becomes non-full
|
||||
self.ev.tx.trigger.eq(~tx_fifo.sink.ack)
|
||||
]
|
||||
|
||||
|
||||
# RX
|
||||
rx_fifo = _get_uart_fifo(rx_fifo_depth, sink_cd=phy_cd)
|
||||
self.submodules += rx_fifo
|
||||
|
||||
|
||||
self.comb += [
|
||||
Record.connect(phy.source, rx_fifo.sink),
|
||||
self._rxempty.status.eq(~rx_fifo.source.stb),
|
||||
self._rxtx.w.eq(rx_fifo.source.data),
|
||||
rx_fifo.source.ack.eq(self.ev.rx.clear),
|
||||
# Generate RX IRQ when tx_fifo becomes non-empty
|
||||
self.ev.rx.trigger.eq(~rx_fifo.source.stb)
|
||||
]
|
|
@ -1,9 +0,0 @@
|
|||
from migen import *
|
||||
|
||||
from misoc.tools.wishbone import WishboneStreamingBridge
|
||||
from misoc.com.uart.phy.serial import UARTPHYSerial
|
||||
|
||||
class UARTWishboneBridge(WishboneStreamingBridge):
|
||||
def __init__(self, pads, clk_freq, baudrate=115200):
|
||||
self.submodules.phy = UARTPHYSerial(pads, clk_freq, baudrate)
|
||||
WishboneStreamingBridge.__init__(self, self.phy, clk_freq)
|
|
@ -1,8 +0,0 @@
|
|||
def UARTPHY(pads, *args, **kwargs):
|
||||
# Autodetect PHY
|
||||
if hasattr(pads, "source_stb"):
|
||||
from misoc.com.uart.phy.sim import UARTPHYSim
|
||||
return UARTPHYSim(pads, *args, **kwargs)
|
||||
else:
|
||||
from misoc.com.uart.phy.serial import UARTPHYSerial
|
||||
return UARTPHYSerial(pads, *args, **kwargs)
|
|
@ -1,33 +0,0 @@
|
|||
import os
|
||||
import pty
|
||||
import time
|
||||
|
||||
from migen import *
|
||||
from migen.flow.actor import Sink, Source
|
||||
|
||||
|
||||
class UARTPHYSim(Module):
|
||||
def __init__(self, pads, *args, **kwargs):
|
||||
self.sink = Sink([("data", 8)])
|
||||
self.source = Source([("data", 8)])
|
||||
|
||||
self.comb += [
|
||||
pads.source_stb.eq(self.sink.stb),
|
||||
pads.source_data.eq(self.sink.data),
|
||||
self.sink.ack.eq(pads.source_ack),
|
||||
|
||||
self.source.stb.eq(pads.sink_stb),
|
||||
self.source.data.eq(pads.sink_data),
|
||||
pads.sink_ack.eq(self.source.ack)
|
||||
]
|
||||
|
||||
m, s = pty.openpty()
|
||||
name = os.ttyname(s)
|
||||
print("UART tty: "+name)
|
||||
time.sleep(0.5) # pause for user
|
||||
f = open("/tmp/simserial", "w")
|
||||
f.write(os.ttyname(s))
|
||||
f.close()
|
||||
|
||||
def do_exit(self, *args, **kwargs):
|
||||
os.remove("/tmp/simserial")
|
|
@ -1,55 +0,0 @@
|
|||
import csv
|
||||
|
||||
|
||||
class MappedReg:
|
||||
def __init__(self, readfn, writefn, name, addr, length, busword, mode):
|
||||
self.readfn = readfn
|
||||
self.writefn = writefn
|
||||
self.addr = addr
|
||||
self.length = length
|
||||
self.busword = busword
|
||||
self.mode = mode
|
||||
|
||||
def read(self):
|
||||
if self.mode not in ["rw", "ro"]:
|
||||
raise KeyError(name + "register not readable")
|
||||
datas = self.readfn(self.addr, burst_length=self.length)
|
||||
if isinstance(datas, int):
|
||||
return datas
|
||||
else:
|
||||
data = 0
|
||||
for i in range(self.length):
|
||||
data = data << self.busword
|
||||
data |= datas[i]
|
||||
return data
|
||||
|
||||
def write(self, value):
|
||||
if self.mode not in ["rw", "wo"]:
|
||||
raise KeyError(name + "register not writable")
|
||||
datas = []
|
||||
for i in range(self.length):
|
||||
datas.append((value >> ((self.length-1-i)*self.busword)) & (2**self.busword-1))
|
||||
self.writefn(self.addr, datas)
|
||||
|
||||
|
||||
class MappedRegs:
|
||||
def __init__(self, d):
|
||||
self.d = d
|
||||
|
||||
def __getattr__(self, attr):
|
||||
try:
|
||||
return self.__dict__['d'][attr]
|
||||
except KeyError:
|
||||
pass
|
||||
raise KeyError("No such register " + attr)
|
||||
|
||||
|
||||
def build_map(addrmap, busword, readfn, writefn):
|
||||
csv_reader = csv.reader(open(addrmap), delimiter=',', quotechar='#')
|
||||
d = {}
|
||||
for item in csv_reader:
|
||||
name, addr, length, mode = item
|
||||
addr = int(addr.replace("0x", ""), 16)
|
||||
length = int(length)
|
||||
d[name] = MappedReg(readfn, writefn, name, addr, length, busword, mode)
|
||||
return MappedRegs(d)
|
|
@ -1,75 +0,0 @@
|
|||
import serial
|
||||
from struct import *
|
||||
from misoc.com.uart.software.reg import *
|
||||
|
||||
|
||||
def write_b(uart, data):
|
||||
uart.write(pack('B', data))
|
||||
|
||||
|
||||
class UARTWishboneBridgeDriver:
|
||||
cmds = {
|
||||
"write": 0x01,
|
||||
"read": 0x02
|
||||
}
|
||||
def __init__(self, port, baudrate=115200, addrmap=None, busword=8, debug=False):
|
||||
self.port = port
|
||||
self.baudrate = str(baudrate)
|
||||
self.debug = debug
|
||||
self.uart = serial.Serial(port, baudrate, timeout=0.25)
|
||||
if addrmap is not None:
|
||||
self.regs = build_map(addrmap, busword, self.read, self.write)
|
||||
|
||||
def open(self):
|
||||
self.uart.flushOutput()
|
||||
self.uart.close()
|
||||
self.uart.open()
|
||||
self.uart.flushInput()
|
||||
|
||||
def close(self):
|
||||
self.uart.flushOutput()
|
||||
self.uart.close()
|
||||
|
||||
def read(self, addr, burst_length=1):
|
||||
datas = []
|
||||
self.uart.flushInput()
|
||||
write_b(self.uart, self.cmds["read"])
|
||||
write_b(self.uart, burst_length)
|
||||
word_addr = addr//4
|
||||
write_b(self.uart, (word_addr >> 24) & 0xff)
|
||||
write_b(self.uart, (word_addr >> 16) & 0xff)
|
||||
write_b(self.uart, (word_addr >> 8) & 0xff)
|
||||
write_b(self.uart, (word_addr >> 0) & 0xff)
|
||||
for i in range(burst_length):
|
||||
data = 0
|
||||
for k in range(4):
|
||||
data = data << 8
|
||||
data |= ord(self.uart.read())
|
||||
if self.debug:
|
||||
print("RD {:08X} @ {:08X}".format(data, addr + 4*i))
|
||||
datas.append(data)
|
||||
if burst_length == 1:
|
||||
return datas[0]
|
||||
else:
|
||||
return datas
|
||||
|
||||
def write(self, addr, data):
|
||||
if isinstance(data, list):
|
||||
burst_length = len(data)
|
||||
else:
|
||||
burst_length = 1
|
||||
data = [data]
|
||||
write_b(self.uart, self.cmds["write"])
|
||||
write_b(self.uart, burst_length)
|
||||
word_addr = addr//4
|
||||
write_b(self.uart, (word_addr >> 24) & 0xff)
|
||||
write_b(self.uart, (word_addr >> 16) & 0xff)
|
||||
write_b(self.uart, (word_addr >> 8) & 0xff)
|
||||
write_b(self.uart, (word_addr >> 0) & 0xff)
|
||||
for i in range(len(data)):
|
||||
dat = data[i]
|
||||
for j in range(4):
|
||||
write_b(self.uart, (dat >> 24) & 0xff)
|
||||
dat = dat << 8
|
||||
if self.debug:
|
||||
print("WR {:08X} @ {:08X}".format(data[i], addr + 4*i))
|
|
@ -0,0 +1 @@
|
|||
from misoc.dvisampler.core import DVISampler
|
|
@ -5,7 +5,7 @@ from migen.genlib.record import Record
|
|||
from migen.bank.description import *
|
||||
from migen.flow.actor import *
|
||||
|
||||
from misoc.video.dvisampler.common import channel_layout
|
||||
from misoc.dvisampler.common import channel_layout
|
||||
|
||||
|
||||
class SyncPolarity(Module):
|
|
@ -5,7 +5,7 @@ from migen.genlib.record import Record, layout_len
|
|||
from migen.genlib.misc import optree
|
||||
from migen.bank.description import *
|
||||
|
||||
from misoc.video.dvisampler.common import channel_layout
|
||||
from misoc.dvisampler.common import channel_layout
|
||||
|
||||
|
||||
class _SyncBuffer(Module):
|
|
@ -3,7 +3,7 @@ from migen.genlib.cdc import MultiReg
|
|||
from migen.genlib.misc import optree
|
||||
from migen.bank.description import *
|
||||
|
||||
from misoc.video.dvisampler.common import control_tokens
|
||||
from misoc.dvisampler.common import control_tokens
|
||||
|
||||
|
||||
class CharSync(Module, AutoCSR):
|
|
@ -1,15 +1,15 @@
|
|||
from migen import *
|
||||
from migen.bank.description import AutoCSR
|
||||
|
||||
from misoc.video.dvisampler.edid import EDID
|
||||
from misoc.video.dvisampler.clocking import Clocking
|
||||
from misoc.video.dvisampler.datacapture import DataCapture
|
||||
from misoc.video.dvisampler.charsync import CharSync
|
||||
from misoc.video.dvisampler.wer import WER
|
||||
from misoc.video.dvisampler.decoding import Decoding
|
||||
from misoc.video.dvisampler.chansync import ChanSync
|
||||
from misoc.video.dvisampler.analysis import SyncPolarity, ResolutionDetection, FrameExtraction
|
||||
from misoc.video.dvisampler.dma import DMA
|
||||
from misoc.dvisampler.edid import EDID
|
||||
from misoc.dvisampler.clocking import Clocking
|
||||
from misoc.dvisampler.datacapture import DataCapture
|
||||
from misoc.dvisampler.charsync import CharSync
|
||||
from misoc.dvisampler.wer import WER
|
||||
from misoc.dvisampler.decoding import Decoding
|
||||
from misoc.dvisampler.chansync import ChanSync
|
||||
from misoc.dvisampler.analysis import SyncPolarity, ResolutionDetection, FrameExtraction
|
||||
from misoc.dvisampler.dma import DMA
|
||||
|
||||
|
||||
class DVISampler(Module, AutoCSR):
|
|
@ -5,9 +5,9 @@ from migen.bank.description import AutoCSR
|
|||
from migen.actorlib import structuring, spi
|
||||
|
||||
from misoc.mem.sdram.frontend import dma_lasmi
|
||||
from misoc.video.dvisampler.edid import EDID
|
||||
from misoc.video.dvisampler.clocking import Clocking
|
||||
from misoc.video.dvisampler.datacapture import DataCapture
|
||||
from misoc.dvisampler.edid import EDID
|
||||
from misoc.dvisampler.clocking import Clocking
|
||||
from misoc.dvisampler.datacapture import DataCapture
|
||||
|
||||
|
||||
class RawDVISampler(Module, AutoCSR):
|
|
@ -1,7 +1,7 @@
|
|||
from migen import *
|
||||
from migen.genlib.record import Record
|
||||
|
||||
from misoc.video.dvisampler.common import control_tokens, channel_layout
|
||||
from misoc.dvisampler.common import control_tokens, channel_layout
|
||||
|
||||
|
||||
class Decoding(Module):
|
|
@ -3,7 +3,7 @@ from migen.bank.description import *
|
|||
from migen.genlib.misc import optree
|
||||
from migen.genlib.cdc import PulseSynchronizer
|
||||
|
||||
from misoc.video.dvisampler.common import control_tokens
|
||||
from misoc.dvisampler.common import control_tokens
|
||||
|
||||
|
||||
class WER(Module, AutoCSR):
|
|
@ -0,0 +1 @@
|
|||
from misoc.framebuffer.core import Framebuffer
|
|
@ -5,8 +5,8 @@ from migen.bank.description import AutoCSR
|
|||
from migen.actorlib import structuring, misc
|
||||
|
||||
from misoc.mem.sdram.frontend import dma_lasmi
|
||||
from misoc.video.framebuffer.format import bpp, pixel_layout, FrameInitiator, VTG
|
||||
from misoc.video.framebuffer.phy import Driver
|
||||
from misoc.framebuffer.format import bpp, pixel_layout, FrameInitiator, VTG
|
||||
from misoc.framebuffer.phy import Driver
|
||||
|
||||
|
||||
class Framebuffer(Module, AutoCSR):
|
|
@ -4,8 +4,8 @@ from migen.genlib.cdc import MultiReg
|
|||
from migen.bank.description import *
|
||||
from migen.flow.actor import *
|
||||
|
||||
from misoc.video.framebuffer.format import bpc_phy, phy_layout
|
||||
from misoc.video.framebuffer import dvi
|
||||
from misoc.framebuffer.format import bpc_phy, phy_layout
|
||||
from misoc.framebuffer import dvi
|
||||
|
||||
|
||||
class _FIFO(Module):
|
|
@ -0,0 +1,2 @@
|
|||
from misoc.integration.soc_core import SoCCore
|
||||
from misoc.integration.soc_sdram import SoCSDRAM
|
|
@ -4,17 +4,14 @@ from migen import *
|
|||
from migen.bank import csrgen
|
||||
from migen.bus import wishbone, csr, wishbone2csr
|
||||
|
||||
from misoc.com.uart.phy import UARTPHY
|
||||
from misoc.com import uart
|
||||
from misoc.cpu import lm32, mor1kx
|
||||
from misoc.cpu import identifier, timer
|
||||
from misoc import lm32, mor1kx, identifier, timer, uart
|
||||
|
||||
|
||||
def mem_decoder(address, start=26, end=29):
|
||||
return lambda a: a[start:end] == ((address >> (start+2)) & (2**(end-start))-1)
|
||||
|
||||
|
||||
class SoC(Module):
|
||||
class SoCCore(Module):
|
||||
csr_map = {
|
||||
"crg": 0, # user
|
||||
"uart_phy": 1, # provided by default (optional)
|
||||
|
@ -102,7 +99,7 @@ class SoC(Module):
|
|||
self.register_mem("csr", self.mem_map["csr"], self.wishbone2csr.wishbone)
|
||||
|
||||
if with_uart:
|
||||
self.submodules.uart_phy = UARTPHY(platform.request("serial"), clk_freq, uart_baudrate)
|
||||
self.submodules.uart_phy = uart.RS232PHY(platform.request("serial"), clk_freq, uart_baudrate)
|
||||
self.submodules.uart = uart.UART(self.uart_phy)
|
||||
|
||||
if with_identifier:
|
|
@ -6,10 +6,10 @@ from misoc.mem.sdram.core import SDRAMCore
|
|||
from misoc.mem.sdram.core.lasmicon import LASMIconSettings
|
||||
from misoc.mem.sdram.core.minicon import MiniconSettings
|
||||
from misoc.mem.sdram.frontend import memtest, wishbone2lasmi
|
||||
from misoc.soc import SoC
|
||||
from misoc.integration.soc_core import SoCCore
|
||||
|
||||
|
||||
class SDRAMSoC(SoC):
|
||||
class SoCSDRAM(SoCCore):
|
||||
csr_map = {
|
||||
"sdram": 8,
|
||||
"l2_cache": 9,
|
|
@ -0,0 +1 @@
|
|||
from misoc.spi.core import SPIMaster
|
|
@ -33,7 +33,6 @@ class SPIMaster(Module, AutoCSR):
|
|||
|
||||
# clk
|
||||
i = Signal(max=div)
|
||||
clk_en = Signal()
|
||||
set_clk = Signal()
|
||||
clr_clk = Signal()
|
||||
self.sync += [
|
||||
|
@ -124,7 +123,6 @@ class SPIMaster(Module, AutoCSR):
|
|||
|
||||
# mosi
|
||||
if hasattr(pads, "mosi"):
|
||||
mosi = Signal()
|
||||
sr_mosi = Signal(width)
|
||||
|
||||
# (cpha = 1: propagated on clk rising edge)
|
|
@ -1,149 +0,0 @@
|
|||
from migen import *
|
||||
from migen.bus import wishbone
|
||||
from migen.genlib.misc import chooser, Counter, WaitTimer
|
||||
from migen.genlib.record import Record
|
||||
from migen.genlib.fsm import FSM, NextState
|
||||
from migen.flow.actor import Sink, Source
|
||||
|
||||
|
||||
class WishboneStreamingBridge(Module):
|
||||
cmds = {
|
||||
"write": 0x01,
|
||||
"read": 0x02
|
||||
}
|
||||
|
||||
def __init__(self, phy, clk_freq):
|
||||
self.wishbone = wishbone.Interface()
|
||||
|
||||
# # #
|
||||
|
||||
byte_counter = Counter(3)
|
||||
word_counter = Counter(8)
|
||||
self.submodules += byte_counter, word_counter
|
||||
|
||||
cmd = Signal(8)
|
||||
cmd_ce = Signal()
|
||||
|
||||
length = Signal(8)
|
||||
length_ce = Signal()
|
||||
|
||||
address = Signal(32)
|
||||
address_ce = Signal()
|
||||
|
||||
data = Signal(32)
|
||||
rx_data_ce = Signal()
|
||||
tx_data_ce = Signal()
|
||||
|
||||
self.sync += [
|
||||
If(cmd_ce, cmd.eq(phy.source.data)),
|
||||
If(length_ce, length.eq(phy.source.data)),
|
||||
If(address_ce, address.eq(Cat(phy.source.data, address[0:24]))),
|
||||
If(rx_data_ce,
|
||||
data.eq(Cat(phy.source.data, data[0:24]))
|
||||
).Elif(tx_data_ce,
|
||||
data.eq(self.wishbone.dat_r)
|
||||
)
|
||||
]
|
||||
|
||||
fsm = InsertReset(FSM(reset_state="IDLE"))
|
||||
timer = WaitTimer(clk_freq//10)
|
||||
self.submodules += fsm, timer
|
||||
self.comb += [
|
||||
fsm.reset.eq(timer.done),
|
||||
phy.source.ack.eq(1)
|
||||
]
|
||||
fsm.act("IDLE",
|
||||
If(phy.source.stb,
|
||||
cmd_ce.eq(1),
|
||||
If((phy.source.data == self.cmds["write"]) |
|
||||
(phy.source.data == self.cmds["read"]),
|
||||
NextState("RECEIVE_LENGTH")
|
||||
),
|
||||
byte_counter.reset.eq(1),
|
||||
word_counter.reset.eq(1)
|
||||
)
|
||||
)
|
||||
fsm.act("RECEIVE_LENGTH",
|
||||
If(phy.source.stb,
|
||||
length_ce.eq(1),
|
||||
NextState("RECEIVE_ADDRESS")
|
||||
)
|
||||
)
|
||||
fsm.act("RECEIVE_ADDRESS",
|
||||
If(phy.source.stb,
|
||||
address_ce.eq(1),
|
||||
byte_counter.ce.eq(1),
|
||||
If(byte_counter.value == 3,
|
||||
If(cmd == self.cmds["write"],
|
||||
NextState("RECEIVE_DATA")
|
||||
).Elif(cmd == self.cmds["read"],
|
||||
NextState("READ_DATA")
|
||||
),
|
||||
byte_counter.reset.eq(1),
|
||||
)
|
||||
)
|
||||
)
|
||||
fsm.act("RECEIVE_DATA",
|
||||
If(phy.source.stb,
|
||||
rx_data_ce.eq(1),
|
||||
byte_counter.ce.eq(1),
|
||||
If(byte_counter.value == 3,
|
||||
NextState("WRITE_DATA"),
|
||||
byte_counter.reset.eq(1)
|
||||
)
|
||||
)
|
||||
)
|
||||
self.comb += [
|
||||
self.wishbone.adr.eq(address + word_counter.value),
|
||||
self.wishbone.dat_w.eq(data),
|
||||
self.wishbone.sel.eq(2**flen(self.wishbone.sel)-1)
|
||||
]
|
||||
fsm.act("WRITE_DATA",
|
||||
self.wishbone.stb.eq(1),
|
||||
self.wishbone.we.eq(1),
|
||||
self.wishbone.cyc.eq(1),
|
||||
If(self.wishbone.ack,
|
||||
word_counter.ce.eq(1),
|
||||
If(word_counter.value == (length-1),
|
||||
NextState("IDLE")
|
||||
).Else(
|
||||
NextState("RECEIVE_DATA")
|
||||
)
|
||||
)
|
||||
)
|
||||
fsm.act("READ_DATA",
|
||||
self.wishbone.stb.eq(1),
|
||||
self.wishbone.we.eq(0),
|
||||
self.wishbone.cyc.eq(1),
|
||||
If(self.wishbone.ack,
|
||||
tx_data_ce.eq(1),
|
||||
NextState("SEND_DATA")
|
||||
)
|
||||
)
|
||||
self.comb += \
|
||||
chooser(data, byte_counter.value, phy.sink.data, n=4, reverse=True)
|
||||
fsm.act("SEND_DATA",
|
||||
phy.sink.stb.eq(1),
|
||||
If(phy.sink.ack,
|
||||
byte_counter.ce.eq(1),
|
||||
If(byte_counter.value == 3,
|
||||
word_counter.ce.eq(1),
|
||||
If(word_counter.value == (length-1),
|
||||
NextState("IDLE")
|
||||
).Else(
|
||||
NextState("READ_DATA"),
|
||||
byte_counter.reset.eq(1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
self.comb += timer.wait.eq(~fsm.ongoing("IDLE"))
|
||||
|
||||
if phy.sink.description.packetized:
|
||||
self.comb += [
|
||||
phy.sink.sop.eq((byte_counter.value == 0) & (word_counter.value == 0)),
|
||||
phy.sink.eop.eq((byte_counter.value == 3) & (word_counter.value == (length-1)))
|
||||
]
|
||||
if hasattr(phy.sink, "length"):
|
||||
self.comb += phy.sink.length.eq(4*length)
|
|
@ -0,0 +1 @@
|
|||
from misoc.uart.core import UART, RS232PHY
|
|
@ -1,13 +1,16 @@
|
|||
from migen import *
|
||||
from migen.genlib.cdc import MultiReg
|
||||
from migen.bank.description import *
|
||||
from migen.flow.actor import Sink, Source
|
||||
from migen.bank.eventmanager import *
|
||||
from migen.genlib.record import Record
|
||||
from migen.actorlib.fifo import SyncFIFO, AsyncFIFO
|
||||
|
||||
|
||||
class UARTPHYSerialRX(Module):
|
||||
class RS232PHYRX(Module):
|
||||
def __init__(self, pads, tuning_word):
|
||||
self.source = Source([("data", 8)])
|
||||
|
||||
###
|
||||
|
||||
uart_clk_rxen = Signal()
|
||||
phase_accumulator_rx = Signal(32)
|
||||
|
||||
|
@ -54,10 +57,12 @@ class UARTPHYSerialRX(Module):
|
|||
)
|
||||
|
||||
|
||||
class UARTPHYSerialTX(Module):
|
||||
class RS232PHYTX(Module):
|
||||
def __init__(self, pads, tuning_word):
|
||||
self.sink = Sink([("data", 8)])
|
||||
|
||||
# # #
|
||||
|
||||
uart_clk_txen = Signal()
|
||||
phase_accumulator_tx = Signal(32)
|
||||
|
||||
|
@ -96,9 +101,60 @@ class UARTPHYSerialTX(Module):
|
|||
]
|
||||
|
||||
|
||||
class UARTPHYSerial(Module, AutoCSR):
|
||||
class RS232PHY(Module, AutoCSR):
|
||||
def __init__(self, pads, clk_freq, baudrate=115200):
|
||||
self._tuning_word = CSRStorage(32, reset=int((baudrate/clk_freq)*2**32))
|
||||
self.submodules.tx = UARTPHYSerialTX(pads, self._tuning_word.storage)
|
||||
self.submodules.rx = UARTPHYSerialRX(pads, self._tuning_word.storage)
|
||||
self.submodules.tx = RS232PHYTX(pads, self._tuning_word.storage)
|
||||
self.submodules.rx = RS232PHYRX(pads, self._tuning_word.storage)
|
||||
self.sink, self.source = self.tx.sink, self.rx.source
|
||||
|
||||
|
||||
def _get_uart_fifo(depth, sink_cd="sys", source_cd="sys"):
|
||||
if sink_cd != source_cd:
|
||||
fifo = AsyncFIFO([("data", 8)], depth)
|
||||
return ClockDomainsRenamer({"write": sink_cd, "read": source_cd})(fifo)
|
||||
else:
|
||||
return SyncFIFO([("data", 8)], depth)
|
||||
|
||||
|
||||
class UART(Module, AutoCSR):
|
||||
def __init__(self, phy,
|
||||
tx_fifo_depth=16,
|
||||
rx_fifo_depth=16,
|
||||
phy_cd="sys"):
|
||||
self._rxtx = CSR(8)
|
||||
self._txfull = CSRStatus()
|
||||
self._rxempty = CSRStatus()
|
||||
|
||||
self.submodules.ev = EventManager()
|
||||
self.ev.tx = EventSourceProcess()
|
||||
self.ev.rx = EventSourceProcess()
|
||||
self.ev.finalize()
|
||||
|
||||
# # #
|
||||
|
||||
# TX
|
||||
tx_fifo = _get_uart_fifo(tx_fifo_depth, source_cd=phy_cd)
|
||||
self.submodules += tx_fifo
|
||||
|
||||
self.comb += [
|
||||
tx_fifo.sink.stb.eq(self._rxtx.re),
|
||||
tx_fifo.sink.data.eq(self._rxtx.r),
|
||||
self._txfull.status.eq(~tx_fifo.sink.ack),
|
||||
Record.connect(tx_fifo.source, phy.sink),
|
||||
# Generate TX IRQ when tx_fifo becomes non-full
|
||||
self.ev.tx.trigger.eq(~tx_fifo.sink.ack)
|
||||
]
|
||||
|
||||
# RX
|
||||
rx_fifo = _get_uart_fifo(rx_fifo_depth, sink_cd=phy_cd)
|
||||
self.submodules += rx_fifo
|
||||
|
||||
self.comb += [
|
||||
Record.connect(phy.source, rx_fifo.sink),
|
||||
self._rxempty.status.eq(~rx_fifo.source.stb),
|
||||
self._rxtx.w.eq(rx_fifo.source.data),
|
||||
rx_fifo.source.ack.eq(self.ev.rx.clear),
|
||||
# Generate RX IRQ when tx_fifo becomes non-empty
|
||||
self.ev.rx.trigger.eq(~rx_fifo.source.stb)
|
||||
]
|
7
setup.py
7
setup.py
|
@ -5,10 +5,9 @@ from setuptools import setup
|
|||
from setuptools import find_packages
|
||||
|
||||
|
||||
required_version = (3, 3)
|
||||
if sys.version_info < required_version:
|
||||
raise SystemExit("MiSoC requires python {0} or greater".format(
|
||||
".".join(map(str, required_version))))
|
||||
if sys.version_info[:3] < (3, 3):
|
||||
raise SystemExit("You need Python 3.3+")
|
||||
|
||||
|
||||
setup(
|
||||
name="misoc",
|
||||
|
|
Loading…
Reference in New Issue