--- /dev/null
+from migen.fhdl.std import *
+from migen.genlib.cdc import MultiReg
+from migen.bank.description import *
+
+
+class GPIOIn(Module, AutoCSR):
+ def __init__(self, signal):
+ self._in = CSRStatus(flen(signal))
+ self.specials += MultiReg(signal, self._in.status)
+
+
+class GPIOOut(Module, AutoCSR):
+ def __init__(self, signal):
+ self._out = CSRStorage(flen(signal))
+ self.comb += signal.eq(self._out.storage)
+
+
+class GPIOInOut(Module):
+ def __init__(self, in_signal, out_signal):
+ self.submodules.gpio_in = GPIOIn(in_signal)
+ self.submodules.gpio_out = GPIOOut(out_signal)
+
+ def get_csrs(self):
+ return self.gpio_in.get_csrs() + self.gpio_out.get_csrs()
+
+
+class Blinker(Module):
+ def __init__(self, signal, divbits=26):
+ counter = Signal(divbits)
+ self.comb += signal.eq(counter[divbits-1])
+ self.sync += counter.eq(counter + 1)
+++ /dev/null
-from migen.fhdl.std import *
-from migen.genlib.cdc import MultiReg
-from migen.bank.description import *
-
-
-class GPIOIn(Module, AutoCSR):
- def __init__(self, signal):
- self._in = CSRStatus(flen(signal))
- self.specials += MultiReg(signal, self._in.status)
-
-
-class GPIOOut(Module, AutoCSR):
- def __init__(self, signal):
- self._out = CSRStorage(flen(signal))
- self.comb += signal.eq(self._out.storage)
-
-
-class GPIOInOut(Module):
- def __init__(self, in_signal, out_signal):
- self.submodules.gpio_in = GPIOIn(in_signal)
- self.submodules.gpio_out = GPIOOut(out_signal)
-
- def get_csrs(self):
- return self.gpio_in.get_csrs() + self.gpio_out.get_csrs()
-
-
-class Blinker(Module):
- def __init__(self, signal, divbits=26):
- counter = Signal(divbits)
- self.comb += signal.eq(counter[divbits-1])
- self.sync += counter.eq(counter + 1)
from misoclib.tools.litescope.core.port import LiteScopeTerm
from misoclib.com.liteeth.common import *
-from misoclib.com.liteeth.generic import *
from targets.base import BaseSoC
from misoclib.com.liteeth.frontend.tty import LiteEthTTY
--- /dev/null
+from misoclib.com.liteeth.common import *
+
+
+class LiteEthTTYTX(Module):
+ def __init__(self, ip_address, udp_port, fifo_depth=None):
+ self.sink = sink = Sink(eth_tty_description(8))
+ self.source = source = Source(eth_udp_user_description(8))
+
+ # # #
+
+ if fifo_depth is None:
+ self.comb += [
+ source.stb.eq(sink.stb),
+ source.sop.eq(1),
+ source.eop.eq(1),
+ source.length.eq(1),
+ source.data.eq(sink.data),
+ sink.ack.eq(source.ack)
+ ]
+ else:
+ self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth)
+ self.comb += Record.connect(sink, fifo.sink)
+
+ self.submodules.level = level = FlipFlop(max=fifo_depth)
+ self.comb += level.d.eq(fifo.fifo.level)
+
+ self.submodules.counter = counter = Counter(max=fifo_depth)
+
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ If(fifo.source.stb,
+ level.ce.eq(1),
+ counter.reset.eq(1),
+ NextState("SEND")
+ )
+ )
+ fsm.act("SEND",
+ source.stb.eq(fifo.source.stb),
+ source.sop.eq(counter.value == 0),
+ If(level.q == 0,
+ source.eop.eq(1),
+ ).Else(
+ source.eop.eq(counter.value == (level.q-1)),
+ ),
+ source.src_port.eq(udp_port),
+ source.dst_port.eq(udp_port),
+ source.ip_address.eq(ip_address),
+ If(level.q == 0,
+ source.length.eq(1),
+ ).Else(
+ source.length.eq(level.q),
+ ),
+ source.data.eq(fifo.source.data),
+ fifo.source.ack.eq(source.ack),
+ If(source.stb & source.ack,
+ counter.ce.eq(1),
+ If(source.eop,
+ NextState("IDLE")
+ )
+ )
+ )
+
+
+class LiteEthTTYRX(Module):
+ def __init__(self, ip_address, udp_port, fifo_depth=None):
+ self.sink = sink = Sink(eth_udp_user_description(8))
+ self.source = source = Source(eth_tty_description(8))
+
+ # # #
+
+ valid = Signal()
+ self.comb += valid.eq(
+ (sink.ip_address == ip_address) &
+ (sink.dst_port == udp_port)
+ )
+ if fifo_depth is None:
+ self.comb += [
+ source.stb.eq(sink.stb & valid),
+ source.data.eq(sink.data),
+ sink.ack.eq(source.ack)
+ ]
+ else:
+ self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth)
+ self.comb += [
+ fifo.sink.stb.eq(sink.stb & valid),
+ fifo.sink.data.eq(sink.data),
+ sink.ack.eq(fifo.sink.ack),
+ Record.connect(fifo.source, source)
+ ]
+
+
+class LiteEthTTY(Module):
+ def __init__(self, udp, ip_address, udp_port,
+ rx_fifo_depth=64,
+ tx_fifo_depth=64):
+ self.submodules.tx = tx = LiteEthTTYTX(ip_address, udp_port, tx_fifo_depth)
+ self.submodules.rx = rx = LiteEthTTYRX(ip_address, udp_port, rx_fifo_depth)
+ udp_port = udp.crossbar.get_port(udp_port, dw=8)
+ self.comb += [
+ Record.connect(tx.source, udp_port.sink),
+ Record.connect(udp_port.source, rx.sink)
+ ]
+ self.sink, self.source = self.tx.sink, self.rx.source
+++ /dev/null
-from misoclib.com.liteeth.common import *
-
-
-class LiteEthTTYTX(Module):
- def __init__(self, ip_address, udp_port, fifo_depth=None):
- self.sink = sink = Sink(eth_tty_description(8))
- self.source = source = Source(eth_udp_user_description(8))
-
- # # #
-
- if fifo_depth is None:
- self.comb += [
- source.stb.eq(sink.stb),
- source.sop.eq(1),
- source.eop.eq(1),
- source.length.eq(1),
- source.data.eq(sink.data),
- sink.ack.eq(source.ack)
- ]
- else:
- self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth)
- self.comb += Record.connect(sink, fifo.sink)
-
- self.submodules.level = level = FlipFlop(max=fifo_depth)
- self.comb += level.d.eq(fifo.fifo.level)
-
- self.submodules.counter = counter = Counter(max=fifo_depth)
-
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- If(fifo.source.stb,
- level.ce.eq(1),
- counter.reset.eq(1),
- NextState("SEND")
- )
- )
- fsm.act("SEND",
- source.stb.eq(fifo.source.stb),
- source.sop.eq(counter.value == 0),
- If(level.q == 0,
- source.eop.eq(1),
- ).Else(
- source.eop.eq(counter.value == (level.q-1)),
- ),
- source.src_port.eq(udp_port),
- source.dst_port.eq(udp_port),
- source.ip_address.eq(ip_address),
- If(level.q == 0,
- source.length.eq(1),
- ).Else(
- source.length.eq(level.q),
- ),
- source.data.eq(fifo.source.data),
- fifo.source.ack.eq(source.ack),
- If(source.stb & source.ack,
- counter.ce.eq(1),
- If(source.eop,
- NextState("IDLE")
- )
- )
- )
-
-
-class LiteEthTTYRX(Module):
- def __init__(self, ip_address, udp_port, fifo_depth=None):
- self.sink = sink = Sink(eth_udp_user_description(8))
- self.source = source = Source(eth_tty_description(8))
-
- # # #
-
- valid = Signal()
- self.comb += valid.eq(
- (sink.ip_address == ip_address) &
- (sink.dst_port == udp_port)
- )
- if fifo_depth is None:
- self.comb += [
- source.stb.eq(sink.stb & valid),
- source.data.eq(sink.data),
- sink.ack.eq(source.ack)
- ]
- else:
- self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth)
- self.comb += [
- fifo.sink.stb.eq(sink.stb & valid),
- fifo.sink.data.eq(sink.data),
- sink.ack.eq(fifo.sink.ack),
- Record.connect(fifo.source, source)
- ]
-
-
-class LiteEthTTY(Module):
- def __init__(self, udp, ip_address, udp_port,
- rx_fifo_depth=64,
- tx_fifo_depth=64):
- self.submodules.tx = tx = LiteEthTTYTX(ip_address, udp_port, tx_fifo_depth)
- self.submodules.rx = rx = LiteEthTTYRX(ip_address, udp_port, rx_fifo_depth)
- udp_port = udp.crossbar.get_port(udp_port, dw=8)
- self.comb += [
- Record.connect(tx.source, udp_port.sink),
- Record.connect(udp_port.source, rx.sink)
- ]
- self.sink, self.source = self.tx.sink, self.rx.source
--- /dev/null
+import subprocess
+
+
+def get_id():
+ output = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("ascii")
+ return int(output[:8], 16)
--- /dev/null
+from migen.fhdl.std import *
+from migen.bank.description import *
+
+from misoclib.cpu import git
+
+
+class Identifier(Module, AutoCSR):
+ def __init__(self, sysid, frequency, revision=None):
+ self._sysid = CSRStatus(16)
+ self._revision = CSRStatus(32)
+ self._frequency = CSRStatus(32)
+
+ ###
+
+ if revision is None:
+ revision = git.get_id()
+
+ self.comb += [
+ self._sysid.status.eq(sysid),
+ self._revision.status.eq(revision),
+ self._frequency.status.eq(frequency)
+ ]
--- /dev/null
+import os
+
+from migen.fhdl.std import *
+from migen.bus import wishbone
+
+
+class LM32(Module):
+ def __init__(self, platform, eba_reset):
+ self.ibus = i = wishbone.Interface()
+ self.dbus = d = wishbone.Interface()
+ self.interrupt = Signal(32)
+
+ ###
+
+ i_adr_o = Signal(32)
+ d_adr_o = Signal(32)
+ self.specials += Instance("lm32_cpu",
+ p_eba_reset=Instance.PreformattedParam("32'h{:08x}".format(eba_reset)),
+
+ i_clk_i=ClockSignal(),
+ i_rst_i=ResetSignal(),
+
+ i_interrupt=self.interrupt,
+
+ o_I_ADR_O=i_adr_o,
+ o_I_DAT_O=i.dat_w,
+ o_I_SEL_O=i.sel,
+ o_I_CYC_O=i.cyc,
+ o_I_STB_O=i.stb,
+ o_I_WE_O=i.we,
+ o_I_CTI_O=i.cti,
+ o_I_BTE_O=i.bte,
+ i_I_DAT_I=i.dat_r,
+ i_I_ACK_I=i.ack,
+ i_I_ERR_I=i.err,
+ i_I_RTY_I=0,
+
+ o_D_ADR_O=d_adr_o,
+ o_D_DAT_O=d.dat_w,
+ o_D_SEL_O=d.sel,
+ o_D_CYC_O=d.cyc,
+ o_D_STB_O=d.stb,
+ o_D_WE_O=d.we,
+ o_D_CTI_O=d.cti,
+ o_D_BTE_O=d.bte,
+ i_D_DAT_I=d.dat_r,
+ i_D_ACK_I=d.ack,
+ i_D_ERR_I=d.err,
+ i_D_RTY_I=0)
+
+ self.comb += [
+ self.ibus.adr.eq(i_adr_o[2:]),
+ self.dbus.adr.eq(d_adr_o[2:])
+ ]
+
+ # add Verilog sources
+ platform.add_sources(os.path.join("extcores", "lm32", "submodule", "rtl"),
+ "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
+ "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
+ "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v",
+ "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
+ "lm32_dcache.v", "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v")
+ platform.add_verilog_include_path(os.path.join("extcores", "lm32"))
+++ /dev/null
-import os
-
-from migen.fhdl.std import *
-from migen.bus import wishbone
-
-
-class LM32(Module):
- def __init__(self, platform, eba_reset):
- self.ibus = i = wishbone.Interface()
- self.dbus = d = wishbone.Interface()
- self.interrupt = Signal(32)
-
- ###
-
- i_adr_o = Signal(32)
- d_adr_o = Signal(32)
- self.specials += Instance("lm32_cpu",
- p_eba_reset=Instance.PreformattedParam("32'h{:08x}".format(eba_reset)),
-
- i_clk_i=ClockSignal(),
- i_rst_i=ResetSignal(),
-
- i_interrupt=self.interrupt,
-
- o_I_ADR_O=i_adr_o,
- o_I_DAT_O=i.dat_w,
- o_I_SEL_O=i.sel,
- o_I_CYC_O=i.cyc,
- o_I_STB_O=i.stb,
- o_I_WE_O=i.we,
- o_I_CTI_O=i.cti,
- o_I_BTE_O=i.bte,
- i_I_DAT_I=i.dat_r,
- i_I_ACK_I=i.ack,
- i_I_ERR_I=i.err,
- i_I_RTY_I=0,
-
- o_D_ADR_O=d_adr_o,
- o_D_DAT_O=d.dat_w,
- o_D_SEL_O=d.sel,
- o_D_CYC_O=d.cyc,
- o_D_STB_O=d.stb,
- o_D_WE_O=d.we,
- o_D_CTI_O=d.cti,
- o_D_BTE_O=d.bte,
- i_D_DAT_I=d.dat_r,
- i_D_ACK_I=d.ack,
- i_D_ERR_I=d.err,
- i_D_RTY_I=0)
-
- self.comb += [
- self.ibus.adr.eq(i_adr_o[2:]),
- self.dbus.adr.eq(d_adr_o[2:])
- ]
-
- # add Verilog sources
- platform.add_sources(os.path.join("extcores", "lm32", "submodule", "rtl"),
- "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
- "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
- "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v",
- "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
- "lm32_dcache.v", "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v")
- platform.add_verilog_include_path(os.path.join("extcores", "lm32"))
--- /dev/null
+import os
+
+from migen.fhdl.std import *
+from migen.bus import wishbone
+
+
+class MOR1KX(Module):
+ def __init__(self, platform, reset_pc):
+ self.ibus = i = wishbone.Interface()
+ self.dbus = d = wishbone.Interface()
+ self.interrupt = Signal(32)
+
+ ###
+
+ i_adr_o = Signal(32)
+ d_adr_o = Signal(32)
+ self.specials += Instance("mor1kx",
+ p_FEATURE_INSTRUCTIONCACHE="ENABLED",
+ p_OPTION_ICACHE_BLOCK_WIDTH=4,
+ p_OPTION_ICACHE_SET_WIDTH=8,
+ p_OPTION_ICACHE_WAYS=1,
+ p_OPTION_ICACHE_LIMIT_WIDTH=31,
+ p_FEATURE_DATACACHE="ENABLED",
+ p_OPTION_DCACHE_BLOCK_WIDTH=4,
+ p_OPTION_DCACHE_SET_WIDTH=8,
+ p_OPTION_DCACHE_WAYS=1,
+ p_OPTION_DCACHE_LIMIT_WIDTH=31,
+ p_FEATURE_TIMER="NONE",
+ p_OPTION_PIC_TRIGGER="LEVEL",
+ p_FEATURE_SYSCALL="NONE",
+ p_FEATURE_TRAP="NONE",
+ p_FEATURE_RANGE="NONE",
+ p_FEATURE_OVERFLOW="NONE",
+ p_FEATURE_ADDC="NONE",
+ p_FEATURE_CMOV="NONE",
+ p_FEATURE_FFL1="NONE",
+ p_OPTION_CPU0="CAPPUCCINO",
+ p_OPTION_RESET_PC=reset_pc,
+ p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
+ p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
+
+ i_clk=ClockSignal(),
+ i_rst=ResetSignal(),
+
+ i_irq_i=self.interrupt,
+
+ o_iwbm_adr_o=i_adr_o,
+ o_iwbm_dat_o=i.dat_w,
+ o_iwbm_sel_o=i.sel,
+ o_iwbm_cyc_o=i.cyc,
+ o_iwbm_stb_o=i.stb,
+ o_iwbm_we_o=i.we,
+ o_iwbm_cti_o=i.cti,
+ o_iwbm_bte_o=i.bte,
+ i_iwbm_dat_i=i.dat_r,
+ i_iwbm_ack_i=i.ack,
+ i_iwbm_err_i=i.err,
+ i_iwbm_rty_i=0,
+
+ o_dwbm_adr_o=d_adr_o,
+ o_dwbm_dat_o=d.dat_w,
+ o_dwbm_sel_o=d.sel,
+ o_dwbm_cyc_o=d.cyc,
+ o_dwbm_stb_o=d.stb,
+ o_dwbm_we_o=d.we,
+ o_dwbm_cti_o=d.cti,
+ o_dwbm_bte_o=d.bte,
+ i_dwbm_dat_i=d.dat_r,
+ i_dwbm_ack_i=d.ack,
+ i_dwbm_err_i=d.err,
+ i_dwbm_rty_i=0)
+
+ self.comb += [
+ self.ibus.adr.eq(i_adr_o[2:]),
+ self.dbus.adr.eq(d_adr_o[2:])
+ ]
+
+ # add Verilog sources
+ platform.add_source_dir(os.path.join("extcores", "mor1kx", "submodule",
+ "rtl", "verilog"))
+++ /dev/null
-import os
-
-from migen.fhdl.std import *
-from migen.bus import wishbone
-
-
-class MOR1KX(Module):
- def __init__(self, platform, reset_pc):
- self.ibus = i = wishbone.Interface()
- self.dbus = d = wishbone.Interface()
- self.interrupt = Signal(32)
-
- ###
-
- i_adr_o = Signal(32)
- d_adr_o = Signal(32)
- self.specials += Instance("mor1kx",
- p_FEATURE_INSTRUCTIONCACHE="ENABLED",
- p_OPTION_ICACHE_BLOCK_WIDTH=4,
- p_OPTION_ICACHE_SET_WIDTH=8,
- p_OPTION_ICACHE_WAYS=1,
- p_OPTION_ICACHE_LIMIT_WIDTH=31,
- p_FEATURE_DATACACHE="ENABLED",
- p_OPTION_DCACHE_BLOCK_WIDTH=4,
- p_OPTION_DCACHE_SET_WIDTH=8,
- p_OPTION_DCACHE_WAYS=1,
- p_OPTION_DCACHE_LIMIT_WIDTH=31,
- p_FEATURE_TIMER="NONE",
- p_OPTION_PIC_TRIGGER="LEVEL",
- p_FEATURE_SYSCALL="NONE",
- p_FEATURE_TRAP="NONE",
- p_FEATURE_RANGE="NONE",
- p_FEATURE_OVERFLOW="NONE",
- p_FEATURE_ADDC="NONE",
- p_FEATURE_CMOV="NONE",
- p_FEATURE_FFL1="NONE",
- p_OPTION_CPU0="CAPPUCCINO",
- p_OPTION_RESET_PC=reset_pc,
- p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
- p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
-
- i_clk=ClockSignal(),
- i_rst=ResetSignal(),
-
- i_irq_i=self.interrupt,
-
- o_iwbm_adr_o=i_adr_o,
- o_iwbm_dat_o=i.dat_w,
- o_iwbm_sel_o=i.sel,
- o_iwbm_cyc_o=i.cyc,
- o_iwbm_stb_o=i.stb,
- o_iwbm_we_o=i.we,
- o_iwbm_cti_o=i.cti,
- o_iwbm_bte_o=i.bte,
- i_iwbm_dat_i=i.dat_r,
- i_iwbm_ack_i=i.ack,
- i_iwbm_err_i=i.err,
- i_iwbm_rty_i=0,
-
- o_dwbm_adr_o=d_adr_o,
- o_dwbm_dat_o=d.dat_w,
- o_dwbm_sel_o=d.sel,
- o_dwbm_cyc_o=d.cyc,
- o_dwbm_stb_o=d.stb,
- o_dwbm_we_o=d.we,
- o_dwbm_cti_o=d.cti,
- o_dwbm_bte_o=d.bte,
- i_dwbm_dat_i=d.dat_r,
- i_dwbm_ack_i=d.ack,
- i_dwbm_err_i=d.err,
- i_dwbm_rty_i=0)
-
- self.comb += [
- self.ibus.adr.eq(i_adr_o[2:]),
- self.dbus.adr.eq(d_adr_o[2:])
- ]
-
- # add Verilog sources
- platform.add_source_dir(os.path.join("extcores", "mor1kx", "submodule",
- "rtl", "verilog"))
+++ /dev/null
-from migen.fhdl.std import *
-from migen.bank.description import *
-
-from misoclib.cpu.peripherals.identifier import git
-
-
-class Identifier(Module, AutoCSR):
- def __init__(self, sysid, frequency, revision=None):
- self._sysid = CSRStatus(16)
- self._revision = CSRStatus(32)
- self._frequency = CSRStatus(32)
-
- ###
-
- if revision is None:
- revision = git.get_id()
-
- self.comb += [
- self._sysid.status.eq(sysid),
- self._revision.status.eq(revision),
- self._frequency.status.eq(frequency)
- ]
+++ /dev/null
-import subprocess
-
-
-def get_id():
- output = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("ascii")
- return int(output[:8], 16)
+++ /dev/null
-from migen.fhdl.std import *
-from migen.bank.description import *
-from migen.bank.eventmanager import *
-
-
-class Timer(Module, AutoCSR):
- def __init__(self, width=32):
- self._load = CSRStorage(width)
- self._reload = CSRStorage(width)
- self._en = CSRStorage()
- self._update_value = CSR()
- self._value = CSRStatus(width)
-
- self.submodules.ev = EventManager()
- self.ev.zero = EventSourceProcess()
- self.ev.finalize()
-
- ###
-
- value = Signal(width)
- self.sync += [
- If(self._en.storage,
- If(value == 0,
- # set reload to 0 to disable reloading
- value.eq(self._reload.storage)
- ).Else(
- value.eq(value - 1)
- )
- ).Else(
- value.eq(self._load.storage)
- ),
- If(self._update_value.re, self._value.status.eq(value))
- ]
- self.comb += self.ev.zero.trigger.eq(value != 0)
--- /dev/null
+from migen.fhdl.std import *
+from migen.bank.description import *
+from migen.bank.eventmanager import *
+
+
+class Timer(Module, AutoCSR):
+ def __init__(self, width=32):
+ self._load = CSRStorage(width)
+ self._reload = CSRStorage(width)
+ self._en = CSRStorage()
+ self._update_value = CSR()
+ self._value = CSRStatus(width)
+
+ self.submodules.ev = EventManager()
+ self.ev.zero = EventSourceProcess()
+ self.ev.finalize()
+
+ ###
+
+ value = Signal(width)
+ self.sync += [
+ If(self._en.storage,
+ If(value == 0,
+ # set reload to 0 to disable reloading
+ value.eq(self._reload.storage)
+ ).Else(
+ value.eq(value - 1)
+ )
+ ).Else(
+ value.eq(self._load.storage)
+ ),
+ If(self._update_value.re, self._value.status.eq(value))
+ ]
+ self.comb += self.ev.zero.trigger.eq(value != 0)
--- /dev/null
+from migen.fhdl.std import *
+from migen.bus import wishbone
+from migen.genlib.fsm import FSM, NextState
+
+
+class NorFlash16(Module):
+ def __init__(self, pads, rd_timing, wr_timing):
+ self.bus = wishbone.Interface()
+
+ ###
+
+ data = TSTriple(16)
+ lsb = Signal()
+
+ self.specials += data.get_tristate(pads.d)
+ self.comb += [
+ data.oe.eq(pads.oe_n),
+ pads.ce_n.eq(0)
+ ]
+
+ load_lo = Signal()
+ load_hi = Signal()
+ store = Signal()
+
+ pads.oe_n.reset, pads.we_n.reset = 1, 1
+ self.sync += [
+ pads.oe_n.eq(1),
+ pads.we_n.eq(1),
+
+ # Register data/address to avoid off-chip glitches
+ If(self.bus.cyc & self.bus.stb,
+ pads.adr.eq(Cat(lsb, self.bus.adr)),
+ If(self.bus.we,
+ # Only 16-bit writes are supported. Assume sel=0011 or 1100.
+ If(self.bus.sel[0],
+ data.o.eq(self.bus.dat_w[:16])
+ ).Else(
+ data.o.eq(self.bus.dat_w[16:])
+ )
+ ).Else(
+ pads.oe_n.eq(0)
+ )
+ ),
+
+ If(load_lo, self.bus.dat_r[:16].eq(data.i)),
+ If(load_hi, self.bus.dat_r[16:].eq(data.i)),
+ If(store, pads.we_n.eq(0))
+ ]
+
+ # Typical timing of the flash chips:
+ # - 110ns address to output
+ # - 50ns write pulse width
+ counter = Signal(max=max(rd_timing, wr_timing)+1)
+ counter_en = Signal()
+ counter_wr_mode = Signal()
+ counter_done = Signal()
+ self.comb += counter_done.eq(counter == Mux(counter_wr_mode, wr_timing, rd_timing))
+ self.sync += If(counter_en & ~counter_done,
+ counter.eq(counter + 1)
+ ).Else(
+ counter.eq(0)
+ )
+
+ fsm = FSM()
+ self.submodules += fsm
+
+ fsm.act("IDLE",
+ If(self.bus.cyc & self.bus.stb,
+ If(self.bus.we,
+ NextState("WR")
+ ).Else(
+ NextState("RD_HI")
+ )
+ )
+ )
+ fsm.act("RD_HI",
+ lsb.eq(0),
+ counter_en.eq(1),
+ If(counter_done,
+ load_hi.eq(1),
+ NextState("RD_LO")
+ )
+ )
+ fsm.act("RD_LO",
+ lsb.eq(1),
+ counter_en.eq(1),
+ If(counter_done,
+ load_lo.eq(1),
+ NextState("ACK")
+ )
+ )
+ fsm.act("WR",
+ # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0]
+ lsb.eq(self.bus.sel[0]),
+ counter_wr_mode.eq(1),
+ counter_en.eq(1),
+ store.eq(1),
+ If(counter_done, NextState("ACK"))
+ )
+ fsm.act("ACK",
+ self.bus.ack.eq(1),
+ NextState("IDLE")
+ )
+++ /dev/null
-from migen.fhdl.std import *
-from migen.bus import wishbone
-from migen.genlib.fsm import FSM, NextState
-
-
-class NorFlash16(Module):
- def __init__(self, pads, rd_timing, wr_timing):
- self.bus = wishbone.Interface()
-
- ###
-
- data = TSTriple(16)
- lsb = Signal()
-
- self.specials += data.get_tristate(pads.d)
- self.comb += [
- data.oe.eq(pads.oe_n),
- pads.ce_n.eq(0)
- ]
-
- load_lo = Signal()
- load_hi = Signal()
- store = Signal()
-
- pads.oe_n.reset, pads.we_n.reset = 1, 1
- self.sync += [
- pads.oe_n.eq(1),
- pads.we_n.eq(1),
-
- # Register data/address to avoid off-chip glitches
- If(self.bus.cyc & self.bus.stb,
- pads.adr.eq(Cat(lsb, self.bus.adr)),
- If(self.bus.we,
- # Only 16-bit writes are supported. Assume sel=0011 or 1100.
- If(self.bus.sel[0],
- data.o.eq(self.bus.dat_w[:16])
- ).Else(
- data.o.eq(self.bus.dat_w[16:])
- )
- ).Else(
- pads.oe_n.eq(0)
- )
- ),
-
- If(load_lo, self.bus.dat_r[:16].eq(data.i)),
- If(load_hi, self.bus.dat_r[16:].eq(data.i)),
- If(store, pads.we_n.eq(0))
- ]
-
- # Typical timing of the flash chips:
- # - 110ns address to output
- # - 50ns write pulse width
- counter = Signal(max=max(rd_timing, wr_timing)+1)
- counter_en = Signal()
- counter_wr_mode = Signal()
- counter_done = Signal()
- self.comb += counter_done.eq(counter == Mux(counter_wr_mode, wr_timing, rd_timing))
- self.sync += If(counter_en & ~counter_done,
- counter.eq(counter + 1)
- ).Else(
- counter.eq(0)
- )
-
- fsm = FSM()
- self.submodules += fsm
-
- fsm.act("IDLE",
- If(self.bus.cyc & self.bus.stb,
- If(self.bus.we,
- NextState("WR")
- ).Else(
- NextState("RD_HI")
- )
- )
- )
- fsm.act("RD_HI",
- lsb.eq(0),
- counter_en.eq(1),
- If(counter_done,
- load_hi.eq(1),
- NextState("RD_LO")
- )
- )
- fsm.act("RD_LO",
- lsb.eq(1),
- counter_en.eq(1),
- If(counter_done,
- load_lo.eq(1),
- NextState("ACK")
- )
- )
- fsm.act("WR",
- # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0]
- lsb.eq(self.bus.sel[0]),
- counter_wr_mode.eq(1),
- counter_en.eq(1),
- store.eq(1),
- If(counter_done, NextState("ACK"))
- )
- fsm.act("ACK",
- self.bus.ack.eq(1),
- NextState("IDLE")
- )
--- /dev/null
+from migen.fhdl.std import *
+from migen.bus.transactions import *
+from migen.bus import wishbone
+from migen.genlib.misc import timeline
+from migen.genlib.record import Record
+from migen.bank.description import AutoCSR, CSRStorage, CSRStatus
+
+_FAST_READ = 0x0b
+_DIOFR = 0xbb
+_QIOFR = 0xeb
+
+
+def _format_cmd(cmd, spi_width):
+ """
+ `cmd` is the read instruction. Since everything is transmitted on all
+ dq lines (cmd, adr and data), extend/interleave cmd to full pads.dq
+ width even if dq1-dq3 are don't care during the command phase:
+ For example, for N25Q128, 0xeb is the quad i/o fast read, and
+ extended to 4 bits (dq1,dq2,dq3 high) is: 0xfffefeff
+ """
+ c = 2**(8*spi_width)-1
+ for b in range(8):
+ if not (cmd>>b)%2:
+ c &= ~(1<<(b*spi_width))
+ return c
+
+
+class SpiFlash(Module, AutoCSR):
+ def __init__(self, pads, dummy=15, div=2, with_bitbang=True):
+ """
+ Simple SPI flash, e.g. N25Q128 on the LX9 Microboard.
+
+ Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast
+ Read). Only supports mode0 (cpol=0, cpha=0).
+ Optionally supports software bitbanging (for write, erase, or other commands).
+ """
+ self.bus = bus = wishbone.Interface()
+ spi_width = flen(pads.dq)
+ if with_bitbang:
+ self.bitbang = CSRStorage(4)
+ self.miso = CSRStatus()
+ self.bitbang_en = CSRStorage()
+
+ ###
+
+ cs_n = Signal(reset=1)
+ clk = Signal()
+ dq_oe = Signal()
+ wbone_width = flen(bus.dat_r)
+
+
+ read_cmd_params = {
+ 4: (_format_cmd(_QIOFR, 4), 4*8),
+ 2: (_format_cmd(_DIOFR, 2), 2*8),
+ 1: (_format_cmd(_FAST_READ, 1), 1*8)
+ }
+ read_cmd, cmd_width = read_cmd_params[spi_width]
+ addr_width = 24
+
+ pads.cs_n.reset = 1
+
+ dq = TSTriple(spi_width)
+ self.specials.dq = dq.get_tristate(pads.dq)
+
+ sr = Signal(max(cmd_width, addr_width, wbone_width))
+ dqs = Replicate(1, spi_width-1)
+
+ self.comb += bus.dat_r.eq(sr)
+
+ hw_read_logic = [
+ pads.clk.eq(clk),
+ pads.cs_n.eq(cs_n),
+ dq.o.eq(sr[-spi_width:]),
+ dq.oe.eq(dq_oe)
+ ]
+
+ if with_bitbang:
+ bitbang_logic = [
+ pads.clk.eq(self.bitbang.storage[1]),
+ pads.cs_n.eq(self.bitbang.storage[2]),
+ dq.o.eq(Cat(self.bitbang.storage[0], dqs)),
+ If(self.bitbang.storage[3],
+ dq.oe.eq(0)
+ ).Else(
+ dq.oe.eq(1)
+ ),
+ If(self.bitbang.storage[1],
+ self.miso.status.eq(dq.i[-1])
+ )
+ ]
+
+ self.comb += \
+ If(self.bitbang_en.storage,
+ bitbang_logic
+ ).Else(
+ hw_read_logic
+ )
+ else:
+ self.comb += hw_read_logic
+
+ if div < 2:
+ raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))
+ else:
+ i = Signal(max=div)
+ dqi = Signal(spi_width)
+ self.sync += [
+ If(i == div//2 - 1,
+ clk.eq(1),
+ dqi.eq(dq.i),
+ ),
+ If(i == div - 1,
+ i.eq(0),
+ clk.eq(0),
+ sr.eq(Cat(dqi, sr[:-spi_width]))
+ ).Else(
+ i.eq(i + 1),
+ ),
+ ]
+
+ # spi is byte-addressed, prefix by zeros
+ z = Replicate(0, log2_int(wbone_width//8))
+
+ seq = [
+ (cmd_width//spi_width*div,
+ [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
+ (addr_width//spi_width*div,
+ [sr[-addr_width:].eq(Cat(z, bus.adr))]),
+ ((dummy + wbone_width//spi_width)*div,
+ [dq_oe.eq(0)]),
+ (1,
+ [bus.ack.eq(1), cs_n.eq(1)]),
+ (div, # tSHSL!
+ [bus.ack.eq(0)]),
+ (0,
+ []),
+ ]
+
+ # accumulate timeline deltas
+ t, tseq = 0, []
+ for dt, a in seq:
+ tseq.append((t, a))
+ t += dt
+
+ self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
+
+
+class SpiFlashTB(Module):
+ def __init__(self):
+ self.submodules.master = wishbone.Initiator(self.gen_reads())
+ self.pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)])
+ self.submodules.slave = SpiFlash(self.pads)
+ self.submodules.tap = wishbone.Tap(self.slave.bus)
+ self.submodules.intercon = wishbone.InterconnectPointToPoint(
+ self.master.bus, self.slave.bus)
+ self.cycle = 0
+
+ def gen_reads(self):
+ for a in range(10):
+ t = TRead(a)
+ yield t
+ print("read {} in {} cycles(s)".format(t.data, t.latency))
+
+ def do_simulation(self, selfp):
+ if selfp.pads.cs_n:
+ self.cycle = 0
+ else:
+ self.cycle += 1
+ if not selfp.slave.dq.oe:
+ selfp.slave.dq.i = self.cycle & 0xf
+ do_simulation.passive = True
+
+if __name__ == "__main__":
+ from migen.sim.generic import run_simulation
+ from migen.fhdl import verilog
+
+ pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)])
+ s = SpiFlash(pads)
+ print(verilog.convert(s, ios={pads.clk, pads.cs_n, pads.dq, s.bus.adr,
+ s.bus.dat_r, s.bus.cyc, s.bus.ack, s.bus.stb}))
+
+ run_simulation(SpiFlashTB(), vcd_name="spiflash.vcd")
+++ /dev/null
-from migen.fhdl.std import *
-from migen.bus.transactions import *
-from migen.bus import wishbone
-from migen.genlib.misc import timeline
-from migen.genlib.record import Record
-from migen.bank.description import AutoCSR, CSRStorage, CSRStatus
-
-_FAST_READ = 0x0b
-_DIOFR = 0xbb
-_QIOFR = 0xeb
-
-
-def _format_cmd(cmd, spi_width):
- """
- `cmd` is the read instruction. Since everything is transmitted on all
- dq lines (cmd, adr and data), extend/interleave cmd to full pads.dq
- width even if dq1-dq3 are don't care during the command phase:
- For example, for N25Q128, 0xeb is the quad i/o fast read, and
- extended to 4 bits (dq1,dq2,dq3 high) is: 0xfffefeff
- """
- c = 2**(8*spi_width)-1
- for b in range(8):
- if not (cmd>>b)%2:
- c &= ~(1<<(b*spi_width))
- return c
-
-
-class SpiFlash(Module, AutoCSR):
- def __init__(self, pads, dummy=15, div=2, with_bitbang=True):
- """
- Simple SPI flash, e.g. N25Q128 on the LX9 Microboard.
-
- Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast
- Read). Only supports mode0 (cpol=0, cpha=0).
- Optionally supports software bitbanging (for write, erase, or other commands).
- """
- self.bus = bus = wishbone.Interface()
- spi_width = flen(pads.dq)
- if with_bitbang:
- self.bitbang = CSRStorage(4)
- self.miso = CSRStatus()
- self.bitbang_en = CSRStorage()
-
- ###
-
- cs_n = Signal(reset=1)
- clk = Signal()
- dq_oe = Signal()
- wbone_width = flen(bus.dat_r)
-
-
- read_cmd_params = {
- 4: (_format_cmd(_QIOFR, 4), 4*8),
- 2: (_format_cmd(_DIOFR, 2), 2*8),
- 1: (_format_cmd(_FAST_READ, 1), 1*8)
- }
- read_cmd, cmd_width = read_cmd_params[spi_width]
- addr_width = 24
-
- pads.cs_n.reset = 1
-
- dq = TSTriple(spi_width)
- self.specials.dq = dq.get_tristate(pads.dq)
-
- sr = Signal(max(cmd_width, addr_width, wbone_width))
- dqs = Replicate(1, spi_width-1)
-
- self.comb += bus.dat_r.eq(sr)
-
- hw_read_logic = [
- pads.clk.eq(clk),
- pads.cs_n.eq(cs_n),
- dq.o.eq(sr[-spi_width:]),
- dq.oe.eq(dq_oe)
- ]
-
- if with_bitbang:
- bitbang_logic = [
- pads.clk.eq(self.bitbang.storage[1]),
- pads.cs_n.eq(self.bitbang.storage[2]),
- dq.o.eq(Cat(self.bitbang.storage[0], dqs)),
- If(self.bitbang.storage[3],
- dq.oe.eq(0)
- ).Else(
- dq.oe.eq(1)
- ),
- If(self.bitbang.storage[1],
- self.miso.status.eq(dq.i[-1])
- )
- ]
-
- self.comb += \
- If(self.bitbang_en.storage,
- bitbang_logic
- ).Else(
- hw_read_logic
- )
- else:
- self.comb += hw_read_logic
-
- if div < 2:
- raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))
- else:
- i = Signal(max=div)
- dqi = Signal(spi_width)
- self.sync += [
- If(i == div//2 - 1,
- clk.eq(1),
- dqi.eq(dq.i),
- ),
- If(i == div - 1,
- i.eq(0),
- clk.eq(0),
- sr.eq(Cat(dqi, sr[:-spi_width]))
- ).Else(
- i.eq(i + 1),
- ),
- ]
-
- # spi is byte-addressed, prefix by zeros
- z = Replicate(0, log2_int(wbone_width//8))
-
- seq = [
- (cmd_width//spi_width*div,
- [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
- (addr_width//spi_width*div,
- [sr[-addr_width:].eq(Cat(z, bus.adr))]),
- ((dummy + wbone_width//spi_width)*div,
- [dq_oe.eq(0)]),
- (1,
- [bus.ack.eq(1), cs_n.eq(1)]),
- (div, # tSHSL!
- [bus.ack.eq(0)]),
- (0,
- []),
- ]
-
- # accumulate timeline deltas
- t, tseq = 0, []
- for dt, a in seq:
- tseq.append((t, a))
- t += dt
-
- self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
-
-
-class SpiFlashTB(Module):
- def __init__(self):
- self.submodules.master = wishbone.Initiator(self.gen_reads())
- self.pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)])
- self.submodules.slave = SpiFlash(self.pads)
- self.submodules.tap = wishbone.Tap(self.slave.bus)
- self.submodules.intercon = wishbone.InterconnectPointToPoint(
- self.master.bus, self.slave.bus)
- self.cycle = 0
-
- def gen_reads(self):
- for a in range(10):
- t = TRead(a)
- yield t
- print("read {} in {} cycles(s)".format(t.data, t.latency))
-
- def do_simulation(self, selfp):
- if selfp.pads.cs_n:
- self.cycle = 0
- else:
- self.cycle += 1
- if not selfp.slave.dq.oe:
- selfp.slave.dq.i = self.cycle & 0xf
- do_simulation.passive = True
-
-if __name__ == "__main__":
- from migen.sim.generic import run_simulation
- from migen.fhdl import verilog
-
- pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)])
- s = SpiFlash(pads)
- print(verilog.convert(s, ios={pads.clk, pads.cs_n, pads.dq, s.bus.adr,
- s.bus.dat_r, s.bus.cyc, s.bus.ack, s.bus.stb}))
-
- run_simulation(SpiFlashTB(), vcd_name="spiflash.vcd")
--- /dev/null
+from fractions import Fraction
+
+from migen.fhdl.std import *
+
+
+class MXCRG(Module):
+ def __init__(self, pads, outfreq1x):
+ self.clock_domains.cd_sys = ClockDomain()
+ self.clock_domains.cd_sdram_half = ClockDomain()
+ self.clock_domains.cd_sdram_full_wr = ClockDomain()
+ self.clock_domains.cd_sdram_full_rd = ClockDomain()
+ self.clock_domains.cd_base50 = ClockDomain(reset_less=True)
+
+ self.clk4x_wr_strb = Signal()
+ self.clk4x_rd_strb = Signal()
+
+ ###
+
+ infreq = 50*1000000
+ ratio = Fraction(outfreq1x)/Fraction(infreq)
+ in_period = float(Fraction(1000000000)/Fraction(infreq))
+
+ self.specials += Instance("mxcrg",
+ Instance.Parameter("in_period", in_period),
+ Instance.Parameter("f_mult", ratio.numerator),
+ Instance.Parameter("f_div", ratio.denominator),
+ Instance.Input("clk50_pad", pads.clk50),
+ Instance.Input("trigger_reset", pads.trigger_reset),
+
+ Instance.Output("sys_clk", self.cd_sys.clk),
+ Instance.Output("sys_rst", self.cd_sys.rst),
+ Instance.Output("clk2x_270", self.cd_sdram_half.clk),
+ Instance.Output("clk4x_wr", self.cd_sdram_full_wr.clk),
+ Instance.Output("clk4x_rd", self.cd_sdram_full_rd.clk),
+ Instance.Output("base50_clk", self.cd_base50.clk),
+
+ Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
+ Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
+ Instance.Output("norflash_rst_n", pads.norflash_rst_n),
+ Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
+ Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n))
--- /dev/null
+module mxcrg #(
+ parameter in_period = 0.0,
+ parameter f_mult = 0,
+ parameter f_div = 0,
+ parameter clk2x_period = (in_period*f_div)/(2.0*f_mult)
+) (
+ input clk50_pad,
+ input trigger_reset,
+
+ output sys_clk,
+ output reg sys_rst,
+
+ /* Reset NOR flash */
+ output norflash_rst_n,
+
+ /* DDR PHY clocks */
+ output clk2x_270,
+ output clk4x_wr,
+ output clk4x_wr_strb,
+ output clk4x_rd,
+ output clk4x_rd_strb,
+
+ /* DDR off-chip clocking */
+ output ddr_clk_pad_p,
+ output ddr_clk_pad_n,
+
+ /* Base clock, buffered */
+ output base50_clk
+);
+
+/*
+ * Reset
+ */
+
+reg [19:0] rst_debounce;
+always @(posedge sys_clk) begin
+ if(trigger_reset)
+ rst_debounce <= 20'hFFFFF;
+ else if(rst_debounce != 20'd0)
+ rst_debounce <= rst_debounce - 20'd1;
+ sys_rst <= rst_debounce != 20'd0;
+end
+
+initial rst_debounce <= 20'hFFFFF;
+
+/*
+ * We must release the Flash reset before the system reset
+ * because the Flash needs some time to come out of reset
+ * and the CPU begins fetching instructions from it
+ * as soon as the system reset is released.
+ * From datasheet, minimum reset pulse width is 100ns
+ * and reset-to-read time is 150ns.
+ */
+
+reg [7:0] flash_rstcounter;
+
+always @(posedge sys_clk) begin
+ if(trigger_reset)
+ flash_rstcounter <= 8'd0;
+ else if(~flash_rstcounter[7])
+ flash_rstcounter <= flash_rstcounter + 8'd1;
+end
+
+initial flash_rstcounter <= 8'd0;
+
+assign norflash_rst_n = flash_rstcounter[7];
+
+/*
+ * Clock management. Inspired by the NWL reference design.
+ */
+
+wire sdr_clk50;
+wire clkdiv;
+
+IBUF #(
+ .IOSTANDARD("DEFAULT")
+) clk2_iob (
+ .I(clk50_pad),
+ .O(sdr_clk50)
+);
+
+BUFIO2 #(
+ .DIVIDE(1),
+ .DIVIDE_BYPASS("FALSE"),
+ .I_INVERT("FALSE")
+) bufio2_inst2 (
+ .I(sdr_clk50),
+ .IOCLK(),
+ .DIVCLK(clkdiv),
+ .SERDESSTROBE()
+);
+
+wire pll_lckd;
+wire buf_pll_fb_out;
+wire pllout0;
+wire pllout1;
+wire pllout2;
+wire pllout3;
+wire pllout4;
+wire pllout5;
+
+PLL_ADV #(
+ .BANDWIDTH("OPTIMIZED"),
+ .CLKFBOUT_MULT(4*f_mult),
+ .CLKFBOUT_PHASE(0.0),
+ .CLKIN1_PERIOD(in_period),
+ .CLKIN2_PERIOD(in_period),
+
+ .CLKOUT0_DIVIDE(f_div),
+ .CLKOUT0_DUTY_CYCLE(0.5),
+ .CLKOUT0_PHASE(0.0),
+
+ .CLKOUT1_DIVIDE(f_div),
+ .CLKOUT1_DUTY_CYCLE(0.5),
+ .CLKOUT1_PHASE(0.0),
+
+ .CLKOUT2_DIVIDE(2*f_div),
+ .CLKOUT2_DUTY_CYCLE(0.5),
+ .CLKOUT2_PHASE(270.0),
+
+ .CLKOUT3_DIVIDE(4*f_div),
+ .CLKOUT3_DUTY_CYCLE(0.5),
+ .CLKOUT3_PHASE(0.0),
+
+ .CLKOUT4_DIVIDE(4*f_mult),
+ .CLKOUT4_DUTY_CYCLE(0.5),
+ .CLKOUT4_PHASE(0.0),
+
+ .CLKOUT5_DIVIDE(2*f_div),
+ .CLKOUT5_DUTY_CYCLE(0.5),
+ .CLKOUT5_PHASE(250.0),
+
+ .COMPENSATION("INTERNAL"),
+ .DIVCLK_DIVIDE(1),
+ .REF_JITTER(0.100),
+ .CLK_FEEDBACK("CLKFBOUT"),
+ .SIM_DEVICE("SPARTAN6")
+) pll (
+ .CLKFBDCM(),
+ .CLKFBOUT(buf_pll_fb_out),
+ .CLKOUT0(pllout0), /* < x4 clock for writes */
+ .CLKOUT1(pllout1), /* < x4 clock for reads */
+ .CLKOUT2(pllout2), /* < x2 270 clock for DQS, memory address and control signals */
+ .CLKOUT3(pllout3), /* < x1 clock for system and memory controller */
+ .CLKOUT4(pllout4), /* < buffered clk50 */
+ .CLKOUT5(pllout5), /* < x2 clock to off-chip DDR */
+ .CLKOUTDCM0(),
+ .CLKOUTDCM1(),
+ .CLKOUTDCM2(),
+ .CLKOUTDCM3(),
+ .CLKOUTDCM4(),
+ .CLKOUTDCM5(),
+ .DO(),
+ .DRDY(),
+ .LOCKED(pll_lckd),
+ .CLKFBIN(buf_pll_fb_out),
+ .CLKIN1(clkdiv),
+ .CLKIN2(1'b0),
+ .CLKINSEL(1'b1),
+ .DADDR(5'b00000),
+ .DCLK(1'b0),
+ .DEN(1'b0),
+ .DI(16'h0000),
+ .DWE(1'b0),
+ .RST(1'b0),
+ .REL(1'b0)
+);
+
+BUFPLL #(
+ .DIVIDE(4)
+) wr_bufpll (
+ .PLLIN(pllout0),
+ .GCLK(sys_clk),
+ .LOCKED(pll_lckd),
+ .IOCLK(clk4x_wr),
+ .LOCK(),
+ .SERDESSTROBE(clk4x_wr_strb)
+);
+
+BUFPLL #(
+ .DIVIDE(4)
+) rd_bufpll (
+ .PLLIN(pllout1),
+ .GCLK(sys_clk),
+ .LOCKED(pll_lckd),
+ .IOCLK(clk4x_rd),
+ .LOCK(),
+ .SERDESSTROBE(clk4x_rd_strb)
+);
+
+BUFG bufg_x2_2(
+ .I(pllout2),
+ .O(clk2x_270)
+);
+
+BUFG bufg_x1(
+ .I(pllout3),
+ .O(sys_clk)
+);
+
+wire base50_clk;
+BUFG bufg_50(
+ .I(pllout4),
+ .O(base50_clk)
+);
+
+wire clk2x_off;
+BUFG bufg_x2_offclk(
+ .I(pllout5),
+ .O(clk2x_off)
+);
+
+
+/*
+ * SDRAM clock
+ */
+
+ODDR2 #(
+ .DDR_ALIGNMENT("NONE"),
+ .INIT(1'b0),
+ .SRTYPE("SYNC")
+) sd_clk_forward_p (
+ .Q(ddr_clk_pad_p),
+ .C0(clk2x_off),
+ .C1(~clk2x_off),
+ .CE(1'b1),
+ .D0(1'b1),
+ .D1(1'b0),
+ .R(1'b0),
+ .S(1'b0)
+);
+ODDR2 #(
+ .DDR_ALIGNMENT("NONE"),
+ .INIT(1'b0),
+ .SRTYPE("SYNC")
+) sd_clk_forward_n (
+ .Q(ddr_clk_pad_n),
+ .C0(clk2x_off),
+ .C1(~clk2x_off),
+ .CE(1'b1),
+ .D0(1'b0),
+ .D1(1'b1),
+ .R(1'b0),
+ .S(1'b0)
+);
+
+endmodule
+++ /dev/null
-from fractions import Fraction
-
-from migen.fhdl.std import *
-
-
-class MXCRG(Module):
- def __init__(self, pads, outfreq1x):
- self.clock_domains.cd_sys = ClockDomain()
- self.clock_domains.cd_sdram_half = ClockDomain()
- self.clock_domains.cd_sdram_full_wr = ClockDomain()
- self.clock_domains.cd_sdram_full_rd = ClockDomain()
- self.clock_domains.cd_base50 = ClockDomain(reset_less=True)
-
- self.clk4x_wr_strb = Signal()
- self.clk4x_rd_strb = Signal()
-
- ###
-
- infreq = 50*1000000
- ratio = Fraction(outfreq1x)/Fraction(infreq)
- in_period = float(Fraction(1000000000)/Fraction(infreq))
-
- self.specials += Instance("mxcrg",
- Instance.Parameter("in_period", in_period),
- Instance.Parameter("f_mult", ratio.numerator),
- Instance.Parameter("f_div", ratio.denominator),
- Instance.Input("clk50_pad", pads.clk50),
- Instance.Input("trigger_reset", pads.trigger_reset),
-
- Instance.Output("sys_clk", self.cd_sys.clk),
- Instance.Output("sys_rst", self.cd_sys.rst),
- Instance.Output("clk2x_270", self.cd_sdram_half.clk),
- Instance.Output("clk4x_wr", self.cd_sdram_full_wr.clk),
- Instance.Output("clk4x_rd", self.cd_sdram_full_rd.clk),
- Instance.Output("base50_clk", self.cd_base50.clk),
-
- Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
- Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
- Instance.Output("norflash_rst_n", pads.norflash_rst_n),
- Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
- Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n))
+++ /dev/null
-module mxcrg #(
- parameter in_period = 0.0,
- parameter f_mult = 0,
- parameter f_div = 0,
- parameter clk2x_period = (in_period*f_div)/(2.0*f_mult)
-) (
- input clk50_pad,
- input trigger_reset,
-
- output sys_clk,
- output reg sys_rst,
-
- /* Reset NOR flash */
- output norflash_rst_n,
-
- /* DDR PHY clocks */
- output clk2x_270,
- output clk4x_wr,
- output clk4x_wr_strb,
- output clk4x_rd,
- output clk4x_rd_strb,
-
- /* DDR off-chip clocking */
- output ddr_clk_pad_p,
- output ddr_clk_pad_n,
-
- /* Base clock, buffered */
- output base50_clk
-);
-
-/*
- * Reset
- */
-
-reg [19:0] rst_debounce;
-always @(posedge sys_clk) begin
- if(trigger_reset)
- rst_debounce <= 20'hFFFFF;
- else if(rst_debounce != 20'd0)
- rst_debounce <= rst_debounce - 20'd1;
- sys_rst <= rst_debounce != 20'd0;
-end
-
-initial rst_debounce <= 20'hFFFFF;
-
-/*
- * We must release the Flash reset before the system reset
- * because the Flash needs some time to come out of reset
- * and the CPU begins fetching instructions from it
- * as soon as the system reset is released.
- * From datasheet, minimum reset pulse width is 100ns
- * and reset-to-read time is 150ns.
- */
-
-reg [7:0] flash_rstcounter;
-
-always @(posedge sys_clk) begin
- if(trigger_reset)
- flash_rstcounter <= 8'd0;
- else if(~flash_rstcounter[7])
- flash_rstcounter <= flash_rstcounter + 8'd1;
-end
-
-initial flash_rstcounter <= 8'd0;
-
-assign norflash_rst_n = flash_rstcounter[7];
-
-/*
- * Clock management. Inspired by the NWL reference design.
- */
-
-wire sdr_clk50;
-wire clkdiv;
-
-IBUF #(
- .IOSTANDARD("DEFAULT")
-) clk2_iob (
- .I(clk50_pad),
- .O(sdr_clk50)
-);
-
-BUFIO2 #(
- .DIVIDE(1),
- .DIVIDE_BYPASS("FALSE"),
- .I_INVERT("FALSE")
-) bufio2_inst2 (
- .I(sdr_clk50),
- .IOCLK(),
- .DIVCLK(clkdiv),
- .SERDESSTROBE()
-);
-
-wire pll_lckd;
-wire buf_pll_fb_out;
-wire pllout0;
-wire pllout1;
-wire pllout2;
-wire pllout3;
-wire pllout4;
-wire pllout5;
-
-PLL_ADV #(
- .BANDWIDTH("OPTIMIZED"),
- .CLKFBOUT_MULT(4*f_mult),
- .CLKFBOUT_PHASE(0.0),
- .CLKIN1_PERIOD(in_period),
- .CLKIN2_PERIOD(in_period),
-
- .CLKOUT0_DIVIDE(f_div),
- .CLKOUT0_DUTY_CYCLE(0.5),
- .CLKOUT0_PHASE(0.0),
-
- .CLKOUT1_DIVIDE(f_div),
- .CLKOUT1_DUTY_CYCLE(0.5),
- .CLKOUT1_PHASE(0.0),
-
- .CLKOUT2_DIVIDE(2*f_div),
- .CLKOUT2_DUTY_CYCLE(0.5),
- .CLKOUT2_PHASE(270.0),
-
- .CLKOUT3_DIVIDE(4*f_div),
- .CLKOUT3_DUTY_CYCLE(0.5),
- .CLKOUT3_PHASE(0.0),
-
- .CLKOUT4_DIVIDE(4*f_mult),
- .CLKOUT4_DUTY_CYCLE(0.5),
- .CLKOUT4_PHASE(0.0),
-
- .CLKOUT5_DIVIDE(2*f_div),
- .CLKOUT5_DUTY_CYCLE(0.5),
- .CLKOUT5_PHASE(250.0),
-
- .COMPENSATION("INTERNAL"),
- .DIVCLK_DIVIDE(1),
- .REF_JITTER(0.100),
- .CLK_FEEDBACK("CLKFBOUT"),
- .SIM_DEVICE("SPARTAN6")
-) pll (
- .CLKFBDCM(),
- .CLKFBOUT(buf_pll_fb_out),
- .CLKOUT0(pllout0), /* < x4 clock for writes */
- .CLKOUT1(pllout1), /* < x4 clock for reads */
- .CLKOUT2(pllout2), /* < x2 270 clock for DQS, memory address and control signals */
- .CLKOUT3(pllout3), /* < x1 clock for system and memory controller */
- .CLKOUT4(pllout4), /* < buffered clk50 */
- .CLKOUT5(pllout5), /* < x2 clock to off-chip DDR */
- .CLKOUTDCM0(),
- .CLKOUTDCM1(),
- .CLKOUTDCM2(),
- .CLKOUTDCM3(),
- .CLKOUTDCM4(),
- .CLKOUTDCM5(),
- .DO(),
- .DRDY(),
- .LOCKED(pll_lckd),
- .CLKFBIN(buf_pll_fb_out),
- .CLKIN1(clkdiv),
- .CLKIN2(1'b0),
- .CLKINSEL(1'b1),
- .DADDR(5'b00000),
- .DCLK(1'b0),
- .DEN(1'b0),
- .DI(16'h0000),
- .DWE(1'b0),
- .RST(1'b0),
- .REL(1'b0)
-);
-
-BUFPLL #(
- .DIVIDE(4)
-) wr_bufpll (
- .PLLIN(pllout0),
- .GCLK(sys_clk),
- .LOCKED(pll_lckd),
- .IOCLK(clk4x_wr),
- .LOCK(),
- .SERDESSTROBE(clk4x_wr_strb)
-);
-
-BUFPLL #(
- .DIVIDE(4)
-) rd_bufpll (
- .PLLIN(pllout1),
- .GCLK(sys_clk),
- .LOCKED(pll_lckd),
- .IOCLK(clk4x_rd),
- .LOCK(),
- .SERDESSTROBE(clk4x_rd_strb)
-);
-
-BUFG bufg_x2_2(
- .I(pllout2),
- .O(clk2x_270)
-);
-
-BUFG bufg_x1(
- .I(pllout3),
- .O(sys_clk)
-);
-
-wire base50_clk;
-BUFG bufg_50(
- .I(pllout4),
- .O(base50_clk)
-);
-
-wire clk2x_off;
-BUFG bufg_x2_offclk(
- .I(pllout5),
- .O(clk2x_off)
-);
-
-
-/*
- * SDRAM clock
- */
-
-ODDR2 #(
- .DDR_ALIGNMENT("NONE"),
- .INIT(1'b0),
- .SRTYPE("SYNC")
-) sd_clk_forward_p (
- .Q(ddr_clk_pad_p),
- .C0(clk2x_off),
- .C1(~clk2x_off),
- .CE(1'b1),
- .D0(1'b1),
- .D1(1'b0),
- .R(1'b0),
- .S(1'b0)
-);
-ODDR2 #(
- .DDR_ALIGNMENT("NONE"),
- .INIT(1'b0),
- .SRTYPE("SYNC")
-) sd_clk_forward_n (
- .Q(ddr_clk_pad_n),
- .C0(clk2x_off),
- .C1(~clk2x_off),
- .CE(1'b1),
- .D0(1'b0),
- .D1(1'b1),
- .R(1'b0),
- .S(1'b0)
-);
-
-endmodule
from misoclib.com.uart.phy import UARTPHY
from misoclib.com import uart
from misoclib.cpu import lm32, mor1kx
-from misoclib.cpu.peripherals import identifier, timer
+from misoclib.cpu import identifier, timer
def mem_decoder(address, start=26, end=29):
INST "mxcrg/wr_bufpll" LOC = "BUFPLL_X0Y2";
INST "mxcrg/rd_bufpll" LOC = "BUFPLL_X0Y3";
""")
- platform.add_source_dir(os.path.join("misoclib", "others", "mxcrg"))
+ platform.add_source_dir(os.path.join("misoclib", "others"))
class MiniSoC(BaseSoC):