litex/miscope/com/uart2csr/__init__.py

183 lines
3.1 KiB
Python
Raw Normal View History

2013-03-18 16:45:07 -04:00
from migen.fhdl.structure import *
from migen.fhdl.module import *
2013-03-18 16:45:07 -04:00
from migen.bus import csr
2013-09-21 07:04:07 -04:00
from migen.genlib.fsm import FSM, NextState
2013-03-18 16:45:07 -04:00
2013-09-21 07:04:07 -04:00
from miscope.com.uart2csr.uart import *
2013-03-18 16:45:07 -04:00
WRITE_CMD = 0x01
READ_CMD = 0x02
CLOSE_CMD = 0x03
class Uart2Csr(Module):
def __init__(self, clk_freq, baud):
# Uart interface
self.rx = Signal()
self.tx = Signal()
# Csr interface
2013-03-22 08:50:16 -04:00
self.csr = csr.Interface()
2013-03-18 16:45:07 -04:00
###
self.submodules.uart = UART(clk_freq, baud)
uart = self.uart
2013-03-18 16:45:07 -04:00
#
# In/Out
#
self.comb +=[
uart.rx.eq(self.rx),
self.tx.eq(uart.tx)
]
cmd = Signal(8)
cnt = Signal(3)
sr = Signal(32)
burst_cnt = Signal(8)
addr = Signal(32)
data = Signal(8)
# FSM
2013-09-21 07:04:07 -04:00
self.submodules.fsm = FSM(reset_state="IDLE")
fsm = self.fsm
2013-03-18 18:57:51 -04:00
2013-03-18 16:45:07 -04:00
#
# Global
#
self.sync +=[
2013-09-21 07:04:07 -04:00
If(fsm.ongoing("IDLE"), cnt.eq(0)
).Elif(uart.rx_ev, cnt.eq(cnt + 1)),
2013-03-18 16:45:07 -04:00
2013-03-18 18:57:51 -04:00
If(uart.rx_ev, sr.eq(Cat(uart.rx_dat, sr[0:24])))
2013-03-18 16:45:07 -04:00
]
2013-03-18 18:57:51 -04:00
# State done signals
2013-03-18 16:45:07 -04:00
get_bl_done = Signal()
get_addr_done = Signal()
2013-03-18 18:57:51 -04:00
get_addr_done_d = Signal()
2013-03-18 16:45:07 -04:00
get_data_done = Signal()
send_data_done = Signal()
#
# Idle
#
2013-09-21 07:04:07 -04:00
fsm.act("IDLE",
If(uart.rx_ev & ((uart.rx_dat == WRITE_CMD) | (uart.rx_dat == READ_CMD)),
2013-09-21 07:04:07 -04:00
NextState("GET_BL")
2013-03-18 16:45:07 -04:00
)
)
2013-09-21 07:04:07 -04:00
self.sync += If(fsm.ongoing("IDLE") & uart.rx_ev, cmd.eq(uart.rx_dat))
2013-03-18 16:45:07 -04:00
#
2013-03-21 07:23:44 -04:00
# Get burst length
#
2013-09-21 07:04:07 -04:00
fsm.act("GET_BL",
2013-03-18 16:45:07 -04:00
If(get_bl_done,
2013-09-21 07:04:07 -04:00
NextState("GET_ADDR")
2013-03-18 16:45:07 -04:00
)
)
2013-09-21 07:04:07 -04:00
self.comb += get_bl_done.eq(uart.rx_ev & fsm.ongoing("GET_BL"))
2013-03-18 16:45:07 -04:00
2013-03-18 18:57:51 -04:00
self.sync += If(get_bl_done, burst_cnt.eq(uart.rx_dat))
2013-03-18 16:45:07 -04:00
#
# Get address
#
2013-09-21 07:04:07 -04:00
fsm.act("GET_ADDR",
If(get_addr_done & (cmd == WRITE_CMD),
2013-09-21 07:04:07 -04:00
NextState("GET_DATA")
).Elif(get_addr_done & (cmd == READ_CMD),
2013-09-21 07:04:07 -04:00
NextState("READ_CSR0")
2013-03-18 16:45:07 -04:00
)
)
2013-09-21 07:04:07 -04:00
self.comb += get_addr_done.eq(uart.rx_ev & (cnt == 4) & fsm.ongoing("GET_ADDR"))
2013-03-18 18:57:51 -04:00
self.sync += get_addr_done_d.eq(get_addr_done)
2013-03-18 16:45:07 -04:00
2013-03-18 18:57:51 -04:00
self.sync += [
If(get_addr_done_d,
2013-03-18 16:45:07 -04:00
addr.eq(sr)
2013-09-21 07:04:07 -04:00
).Elif(fsm.leaving("WRITE_CSR") | send_data_done,
2013-03-18 18:57:51 -04:00
addr.eq(addr + 1)
2013-03-18 16:45:07 -04:00
)
]
#
# Get data
#
2013-09-21 07:04:07 -04:00
fsm.act("GET_DATA",
2013-03-18 16:45:07 -04:00
If(get_data_done,
2013-09-21 07:04:07 -04:00
NextState("WRITE_CSR")
2013-03-18 16:45:07 -04:00
)
)
2013-09-21 07:04:07 -04:00
self.comb += get_data_done.eq(uart.rx_ev & fsm.ongoing("GET_DATA"))
2013-03-18 18:57:51 -04:00
self.sync += [
2013-03-18 16:45:07 -04:00
If(get_data_done,
burst_cnt.eq(burst_cnt-1),
data.eq(uart.rx_dat)
)
]
#
# Write Csr
#
2013-09-21 07:04:07 -04:00
fsm.act("WRITE_CSR",
2013-03-18 18:57:51 -04:00
If((burst_cnt==0),
2013-09-21 07:04:07 -04:00
NextState("IDLE")
).Else(NextState("GET_DATA"))
2013-03-18 16:45:07 -04:00
)
2013-03-18 18:57:51 -04:00
#
# Read Csr0
#
2013-09-21 07:04:07 -04:00
fsm.act("READ_CSR0",
NextState("READ_CSR1")
2013-03-18 18:57:51 -04:00
)
2013-09-21 07:04:07 -04:00
self.sync += If(fsm.entering("READ_CSR0"), burst_cnt.eq(burst_cnt-1))
2013-03-18 18:57:51 -04:00
2013-03-18 16:45:07 -04:00
#
2013-03-18 18:57:51 -04:00
# Read Csr1
2013-03-18 16:45:07 -04:00
#
2013-09-21 07:04:07 -04:00
fsm.act("READ_CSR1",
NextState("SEND_DATA")
2013-03-18 16:45:07 -04:00
)
2013-03-18 18:57:51 -04:00
2013-03-18 16:45:07 -04:00
#
# Send Data
#
2013-09-21 07:04:07 -04:00
fsm.act("SEND_DATA",
2013-03-18 18:57:51 -04:00
If(send_data_done & (burst_cnt==0),
2013-09-21 07:04:07 -04:00
NextState("IDLE")
2013-03-18 16:45:07 -04:00
).Elif(send_data_done,
2013-09-21 07:04:07 -04:00
NextState("READ_CSR0")
2013-03-18 16:45:07 -04:00
)
)
2013-09-21 07:04:07 -04:00
self.comb += send_data_done.eq(fsm.ongoing("SEND_DATA") & uart.tx_ev)
2013-03-18 18:57:51 -04:00
self.sync += [
uart.tx_dat.eq(self.csr.dat_r),
2013-09-21 07:04:07 -04:00
uart.tx_we.eq(fsm.entering("SEND_DATA")),
2013-03-18 16:45:07 -04:00
]
2013-03-18 18:57:51 -04:00
2013-03-18 16:45:07 -04:00
#
# Csr access
#
2013-03-18 18:57:51 -04:00
self.comb += self.csr.adr.eq(addr)
2013-03-18 16:45:07 -04:00
self.sync +=[
self.csr.dat_w.eq(data),
2013-09-21 07:04:07 -04:00
If(fsm.ongoing("WRITE_CSR"),
2013-03-18 16:45:07 -04:00
self.csr.we.eq(1)
).Else(
self.csr.we.eq(0)
)
2013-03-18 18:57:51 -04:00
]