-import os
from mibuild.platforms import de0nano
-from mibuild.altera_quartus import _add_period_constraint
import top
def main():
soc = top.SoC()
# set pin constraints
- plat.request("clk50", obj=soc.clk50)
- plat.request("key", obj=soc.key)
plat.request("led", obj=soc.led)
plat.request("gpio_2", obj=soc.gpio_2)
set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO"
""")
- _add_period_constraint(plat, "sys_clk", 20.0)
- cd = dict()
- cd["sys"] = soc.cd_sys
- plat.build_cmdline(soc.get_fragment(), clock_domains=cd)
+ plat.build_cmdline(soc.get_fragment())
if __name__ == "__main__":
main()
\ No newline at end of file
+++ /dev/null
-#
-# Clocks
-#
-create_clock -period 50MHz [get_ports clk50]
\ No newline at end of file
+++ /dev/null
-#
-# Clocks
-#
-create_clock -period 50MHz [get_ports clk50]
\ No newline at end of file
from migen.fhdl.structure import *
+from migen.genlib.misc import *
+from migen.genlib.cdc import *
from migen.bus import csr
-from migen.bank import description, csrgen
-from migen.bank.description import *
-class Spi2Csr :
- def __init__(self, a_width, d_width, max_burst = 8):
- self.a_width = a_width
- self.d_width = d_width
- self.max_burst = 8
+class Spi2Csr(Module):
+ def __init__(self, a_w, d_w, burst_length=8):
+ self.a_w = a_w
+ self.d_w = d_w
+ self.burst_length = 8
+
# Csr interface
- self.csr = csr.Interface(self.a_width, self.d_width)
+ self.csr = csr.Interface(self.a_w, self.d_w)
+
# Spi interface
self.spi_clk = Signal()
self.spi_cs_n = Signal(reset=1)
self.spi_mosi = Signal()
self.spi_miso = Signal()
- self.spi_int_n = Signal(reset=1)
- def get_fragment(self):
- comb = []
- sync = []
+ ###
# Resychronisation
- spi_clk_d1 = Signal()
- spi_clk_d2 = Signal()
- spi_clk_d3 = Signal()
-
- sync += [
- spi_clk_d1.eq(self.spi_clk),
- spi_clk_d2.eq(spi_clk_d1),
- spi_clk_d3.eq(spi_clk_d2)
- ]
-
- spi_cs_n_d1 = Signal()
- spi_cs_n_d2 = Signal()
- spi_cs_n_d3 = Signal()
-
- sync += [
- spi_cs_n_d1.eq(self.spi_cs_n),
- spi_cs_n_d2.eq(spi_cs_n_d1),
- spi_cs_n_d3.eq(spi_cs_n_d2)
- ]
-
- spi_mosi_d1 = Signal()
- spi_mosi_d2 = Signal()
- spi_mosi_d3 = Signal()
-
- sync += [
- spi_mosi_d1.eq(self.spi_mosi),
- spi_mosi_d2.eq(spi_mosi_d1),
- spi_mosi_d3.eq(spi_mosi_d2)
- ]
-
+ clk_synchro = Synchronizer(i=self.spi_clk)
+ cs_n_synchro = Synchronizer(i=self.spi_cs_n)
+ mosi_synchro = Synchronizer(i=self.spi_mosi)
+
+ self.specials += {clk_synchro, cs_n_synchro, mosi_synchro}
+
# Decode
spi_clk_rising = Signal()
spi_clk_falling = Signal()
spi_cs_n_active = Signal()
spi_mosi_dat = Signal()
- comb += [
- spi_clk_rising.eq(spi_clk_d2 & ~spi_clk_d3),
- spi_clk_falling.eq(~spi_clk_d2 & spi_clk_d3),
- spi_cs_n_active.eq(~spi_cs_n_d3),
- spi_mosi_dat.eq(spi_mosi_d3)
+ self.specials += RisingEdge(i=clk_synchro.o, o=spi_clk_rising)
+ self.specials += FallingEdge(i=clk_synchro.o, o=spi_clk_falling)
+
+ self.sync +=[
+ spi_cs_n_active.eq(~cs_n_synchro.o),
+ spi_mosi_dat.eq(~mosi_synchro.o),
]
#
# Spi --> Csr
#
- spi_cnt = Signal(bits_for(self.a_width+self.max_burst*self.d_width))
- spi_addr = Signal(self.a_width)
- spi_w_dat = Signal(self.d_width)
- spi_r_dat = Signal(self.d_width)
+ spi_cnt = Signal(bits_for(self.a_w + self.burst_length*self.d_w))
+ spi_addr = Signal(self.a_w)
+ spi_w_dat = Signal(self.d_w)
+ spi_r_dat = Signal(self.d_w)
spi_we = Signal()
spi_re = Signal()
- spi_we_re_done = Signal(reset = 1)
+ spi_we_re_done = Signal(reset=1)
spi_miso_dat = Signal()
# Re/We Signals Decoding
first_b = Signal()
last_b = Signal()
- comb +=[
- first_b.eq(spi_cnt[0:bits_for(self.d_width)-1] == 0),
- last_b.eq(spi_cnt[0:bits_for(self.d_width)-1] == 2**(bits_for(self.d_width)-1)-1)
+ self.comb +=[
+ first_b.eq(spi_cnt[0:bits_for(self.d_w)-1] == 0),
+ last_b.eq(spi_cnt[0:bits_for(self.d_w)-1] == 2**(bits_for(self.d_w-1))-1)
]
- sync +=[
- If((spi_cnt >= (self.a_width + self.d_width)) & first_b,
- spi_we.eq(spi_addr[self.a_width-1] & ~spi_we_re_done),
- spi_re.eq(~spi_addr[self.a_width-1] & ~spi_we_re_done),
+ self.sync +=[
+ If((spi_cnt >= (self.a_w + self.d_w)) & first_b,
+ spi_we.eq(spi_addr[self.a_w-1] & ~spi_we_re_done),
+ spi_re.eq(~spi_addr[self.a_w-1] & ~spi_we_re_done),
spi_we_re_done.eq(1)
- ).Elif((spi_cnt >= self.a_width) & first_b,
- spi_re.eq(~spi_addr[self.a_width-1] & ~spi_we_re_done),
+ ).Elif((spi_cnt >= self.a_w) & first_b,
+ spi_re.eq(~spi_addr[self.a_w-1] & ~spi_we_re_done),
spi_we_re_done.eq(1)
).Else(
spi_we.eq(0),
]
# Spi Addr / Data Decoding
- sync +=[
+ self.sync +=[
If(~spi_cs_n_active,
spi_cnt.eq(0),
).Elif(spi_clk_rising,
# addr
- If(spi_cnt < self.a_width,
- spi_addr.eq(Cat(spi_mosi_dat,spi_addr[:self.a_width-1]))
- ).Elif((spi_cnt >= (self.a_width+self.d_width)) & last_b,
+ If(spi_cnt < self.a_w,
+ spi_addr.eq(Cat(spi_mosi_dat,spi_addr[:self.a_w-1]))
+ ).Elif((spi_cnt >= (self.a_w+self.d_w)) & last_b,
spi_addr.eq(spi_addr+1)
- ).Elif((spi_cnt >= self.a_width) & last_b & (spi_addr[self.a_width-1] == 0),
+ ).Elif((spi_cnt >= self.a_w) & last_b & (spi_addr[self.a_w-1] == 0),
spi_addr.eq(spi_addr+1)
),
# dat
- If(spi_cnt >= self.a_width,
- spi_w_dat.eq(Cat(spi_mosi_dat,spi_w_dat[:self.d_width-1]))
+ If(spi_cnt >= self.a_w,
+ spi_w_dat.eq(Cat(spi_mosi_dat,spi_w_dat[:self.d_w-1]))
),
# spi_cnt
#
# Csr --> Spi
#
- spi_r_dat_shift = Signal(self.d_width)
- sync +=[
+ spi_r_dat_shift = Signal(self.d_w)
+ self.sync +=[
If(spi_re,
spi_r_dat_shift.eq(spi_r_dat)
),
If(~spi_cs_n_active,
spi_miso_dat.eq(0)
).Elif(spi_clk_falling,
- spi_miso_dat.eq(spi_r_dat_shift[self.d_width-1]),
- spi_r_dat_shift.eq(Cat(0,spi_r_dat_shift[:self.d_width-1]))
+ spi_miso_dat.eq(spi_r_dat_shift[self.d_w-1]),
+ spi_r_dat_shift.eq(Cat(0,spi_r_dat_shift[:self.d_w-1]))
)
- ]
+ ]
#
# Csr Interface
#
- comb += [
+ self.comb += [
self.csr.adr.eq(spi_addr),
self.csr.dat_w.eq(spi_w_dat),
self.csr.we.eq(spi_we)
#
# Spi Interface
#
- comb += [
+ self.comb += [
spi_r_dat.eq(self.csr.dat_r),
self.spi_miso.eq(spi_miso_dat)
- ]
- return Fragment(comb=comb,sync=sync)
\ No newline at end of file
+ ]
\ No newline at end of file
--- /dev/null
+from migen.fhdl.structure import *
+from migen.genlib.misc import *
+from migen.genlib.cdc import *
+from migen.bus import csr
+
+from miscope.bridges.uart2csr.uart import *
+
+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
+ self.csr = csr.Interface(32, 8)
+
+ ###
+
+ uart = Uart(clk_freq, baud)
+ self.specials +=uart
+
+ #
+ # 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)
+
+ #
+ # Global
+ #
+ self.sync +=[
+ If(fsm.ongoing(fsm.IDLE), cnt.eq(0)
+ ).Elif(uart_rx_ev, cnt.eq(cnt + 1)),
+
+ sr.eq(Cat(uart.rx_dat, sr[0:24]))
+ ]
+
+ # FSM
+ fsm = FSM("IDLE",
+ "GET_BL", "GET_ADDR",
+ "GET_DATA", "WRITE_CSR",
+ "READ_CSR", "SEND_DATA")
+
+ # State done
+ get_bl_done = Signal()
+ get_addr_done = Signal()
+ get_data_done = Signal()
+ send_data_done = Signal()
+
+ #
+ # Idle
+ #
+ fsm.act(fsm.IDLE,
+ If(uart.rx_ev and (uart.rx_dat == WRITE_CMD or uart.rx_dat == READ_CMD),
+ fsm.next_state(fsm.GET_BL)
+ )
+ )
+
+ self.sync +=[
+ If(fsm.ongoing(fsm.IDLE) and uart_rx_env,
+ cmd.eq(uart.rx_dat)
+ )
+
+ ]
+
+ #
+ # Get burst length
+ #
+ fsm.act(fsm.GET_BL,
+ If(get_bl_done,
+ fsm.next_state(fsm.GET_ADDR)
+ )
+ )
+
+ self.comb += get_bl_done.eq(uart_rx_ev and fsm.ongoing(fsm.GET_BL))
+
+ self.sync +=[
+ If(get_bl_done,
+ burst_cnt.eq(uart.rx_dat)
+ )
+ ]
+
+ #
+ # Get address
+ #
+ fsm.act(fsm.GET_ADDR,
+ If(get_addr_done and cmd == WRITE_CMD,
+ fsm.next_state(fsm.GET_DATA)
+ ).Elif(get_addr_done and cmd == READ_CMD,
+ fsm.next_state(fsm.READ_CSR)
+ )
+ )
+
+ self.comb += get_addr_done.eq(uart_rx_ev and rx_cnt == 4 and fsm.ongoing(fsm.GET_ADDR))
+
+ self.sync +=[
+ If(get_addr_done,
+ addr.eq(sr)
+ ).Elif(write_data_done or send_data_done,
+ addr.eq(addr + 4)
+ )
+ ]
+
+ #
+ # Get data
+ #
+ fsm.act(fsm.GET_DATA,
+ If(get_data_done,
+ fsm.next_state(fsm.IDLE)
+ )
+ )
+
+ self.comb += get_data_done.eq(uart_rx_ev and fsm.ongoing(fsm.GET_DATA))
+
+ self.sync +=[
+ If(get_data_done,
+ burst_cnt.eq(burst_cnt-1),
+ data.eq(uart.rx_dat)
+ )
+ ]
+
+ #
+ # Write Csr
+ #
+ fsm.act(fsm.WRITE_CSR,
+ If((not burst_cnt),
+ fsm.next_state(fsm.IDLE)
+ ).Else(fsm.next_state(fsm.GET_DATA))
+ )
+
+ #
+ # Read Csr
+ #
+ fsm.act(fsm.READ_CSR,
+ fsm.next_state(fsm.SEND_DATA)
+ )
+
+ #
+ # Send Data
+ #
+ fsm.act(fsm.SEND_DATA,
+ If(send_data_done and (not burst_cnt),
+ fsm.next_state(fsm.IDLE)
+ ).Elif(send_data_done,
+ fsm.next_state(fsm.READ_CSR)
+ )
+ )
+
+ self.comb += [
+ uart.tx_dat.eq(csr.dat_r),
+ uart.we.eq(fsm.entering(fsm.SEND_DATA)),
+ send_data_done.eq(~uart.we or uart.tx_ev)
+ ]
+
+ #
+ # Csr access
+ #
+ self.sync +=[
+ self.csr.adr.eq(addr),
+ self.csr.dat_w.eq(data),
+ If(fsm.ongoing(fsm.WRITE_CSR,
+ self.csr.we.eq(1)
+ ).Else(
+ self.csr.we.eq(0)
+ )
+ ]
+
+
--- /dev/null
+from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.genlib.cdc import MultiReg
+from migen.bank.description import *
+from migen.bank.eventmanager import *
+
+class UART(Module):
+ def __init__(self, clk_freq, baud=115200):
+
+ self.rx_ev = Signal()
+ self.rx_dat = Signal(8)
+
+ self.tx_we = Signal()
+ self.tx_ev = Signal()
+ self.tx_dat = Signal(8)
+
+ self.divisor = Signal(16, reset=int(clk_freq/baud/16))
+
+ self.tx = Signal(reset=1)
+ self.rx = Signal()
+
+ ###
+
+ enable16 = Signal()
+ enable16_counter = Signal(16)
+ self.comb += enable16.eq(enable16_counter == 0)
+ self.sync += [
+ enable16_counter.eq(enable16_counter - 1),
+ If(enable16,
+ enable16_counter.eq(self.divisor - 1))
+ ]
+
+ # TX
+ tx_reg = Signal(8)
+ tx_bitcount = Signal(4)
+ tx_count16 = Signal(4)
+ tx_busy = self.tx_ev
+ self.sync += [
+ If(self.tx_we,
+ tx_reg.eq(self.tx_dat),
+ tx_bitcount.eq(0),
+ tx_count16.eq(1),
+ tx_busy.eq(1),
+ self.tx.eq(0)
+ ).Elif(enable16 & tx_busy,
+ tx_count16.eq(tx_count16 + 1),
+ If(tx_count16 == 0,
+ tx_bitcount.eq(tx_bitcount + 1),
+ If(tx_bitcount == 8,
+ self.tx.eq(1)
+ ).Elif(tx_bitcount == 9,
+ self.tx.eq(1),
+ tx_busy.eq(0)
+ ).Else(
+ self.tx.eq(tx_reg[0]),
+ tx_reg.eq(Cat(tx_reg[1:], 0))
+ )
+ )
+ )
+ ]
+
+ # RX
+ rx = Signal()
+ self.specials += MultiReg(self.rx, "ext", rx, "sys")
+ rx_r = Signal()
+ rx_reg = Signal(8)
+ rx_bitcount = Signal(4)
+ rx_count16 = Signal(4)
+ rx_busy = Signal()
+ rx_done = self.rx_ev
+ rx_data = self.rx_dat
+ self.sync += [
+ rx_done.eq(0),
+ If(enable16,
+ rx_r.eq(rx),
+ If(~rx_busy,
+ If(~rx & rx_r, # look for start bit
+ rx_busy.eq(1),
+ rx_count16.eq(7),
+ rx_bitcount.eq(0)
+ )
+ ).Else(
+ rx_count16.eq(rx_count16 + 1),
+ If(rx_count16 == 0,
+ rx_bitcount.eq(rx_bitcount + 1),
+
+ If(rx_bitcount == 0,
+ If(rx, # verify start bit
+ rx_busy.eq(0)
+ )
+ ).Elif(rx_bitcount == 9,
+ rx_busy.eq(0),
+ If(rx, # verify stop bit
+ rx_data.eq(rx_reg),
+ rx_done.eq(1)
+ )
+ ).Else(
+ rx_reg.eq(Cat(rx_reg[1:], rx))
+ )
+ )
+ )
+ )
+ ]
#
# Definition
#
- def __init__(self, address, width, mode = "IO", interface=None):
+ def __init__(self, address, width, mode="IO", interface=None):
self.address = address
self.width = width
- self.mode = mode
+ self.mode = mode.upper()
self.interface = interface
- self.words = int(2**bits_for(width-1)/8)
+ self.words = int((2**bits_for(width-1))/8)
if "I" in self.mode:
self.i = Signal(self.width)
self.ireg = description.RegisterField("i", self.width, READ_ONLY, WRITE_ONLY)
- self.ireg.field.w.name_override = "inputs"
if "O" in self.mode:
self.o = Signal(self.width)
self.oreg = description.RegisterField("o", self.width)
- self.oreg.field.r.name_override = "ouptuts"
self.bank = csrgen.Bank([self.oreg, self.ireg], address=self.address)
comb = []
if "I" in self.mode:
- comb += [self.ireg.field.w.eq(self.i)]
+ comb += self.ireg.field.w.eq(self.i)
if "O" in self.mode:
- comb += [self.o.eq(self.oreg.field.r)]
+ comb += self.o.eq(self.oreg.field.r)
return Fragment(comb) + self.bank.get_fragment()
#
#Driver
#
def write(self, data):
- self.interface.write_n(self.address, data, self.width)
+ self.interface.write(self.address, data, self.width)
def read(self):
- r = self.interface.read_n(self.address + self.words, self.width)
+ r = self.interface.read(self.address + self.words, self.width)
return r
\ No newline at end of file